{{/* Audit logs page (/audit): filter form, rid trace banner and the events table with infinite scroll. HTMX partial: block audit_rows renders the next page of rows */}} {{ template "head" . }}
{{ template "drawer_toggle" }}
{{ $appGlob := .Data.Filters.app_glob }}
{{ $op := .Data.Filters.operation }}
Advanced filters
{{ block "audit_trace_banner" . }} {{/* Trace mode: all events of one request. On HTMX row swaps the audit_rows partial re-renders this block with hx-swap-oob, so entering/leaving trace mode updates the banner without touching the filter inputs; the hidden rid input keeps later filter changes scoped to the trace */}}
{{ if .Data.Filters.rid }} {{ end }}
{{ end }}
{{ template "page_progress" }} {{ template "error_alert" .Data.FlashError }}
{{ block "audit_rows" . }} {{ $count := len .Data.Events }} {{ range $i, $e := .Data.Events }} {{ else }} {{ if not .Data.IsMore }} {{ end }} {{ end }} {{ if and .IsPartial (not .Data.IsMore) }} {{/* Out-of-band: keep the trace banner (and its hidden rid input) in sync on HTMX row swaps. Pagination continuations (IsMore) skip it: the banner did not change and replacing it mid-scroll would churn the DOM under the user */}} {{ template "audit_trace_banner" . }} {{ end }} {{ end }}
Trace Time Type Operation Target Status
{{/* Events recorded outside a request (schedulers, internal jobs) have no request id to trace. In trace mode the rows already show this request: a chevron would reload the same page */}} {{ if and $e.rid (ne $e.rid $.Data.Filters.rid) }} {{ template "drilldown_icon" }} {{ end }} {{ template "time_ago" $e.create_time }} {{ if eq $e.event_type "http" }} http {{ else if eq $e.event_type "system" }} system {{ else }} {{ $e.event_type }} {{ end }} {{ $e.operation }} {{ $e.target }} {{ if eq $e.status_style "ok" }} {{ $e.status }} {{ else if eq $e.status_style "error" }} {{ $e.status }} {{ else }} - {{ end }}

No audit events match the filters

{{ template "sidebar" . }}