feat(audit): clickable column headers with asc/desc sort
CI / Build (windows/amd64) (pull_request) Successful in 23s
CI / Lint (pull_request) Successful in 34s
CI / Build (linux/amd64) (pull_request) Successful in 23s
CI / Build (linux/arm64) (pull_request) Successful in 21s
CI / Test (linux/amd64) (pull_request) Successful in 3m41s

This commit is contained in:
2026-05-05 08:15:22 +01:00
parent 1d0d994bc4
commit ba425c9766
7 changed files with 207 additions and 8 deletions
File diff suppressed because one or more lines are too long
+10
View File
@@ -328,6 +328,16 @@
text-transform: uppercase; letter-spacing: 0.08em;
}
.audit-row.head:hover { background: transparent; }
.audit-row.head .sort-header {
color: inherit; text-decoration: none; cursor: pointer;
display: inline-flex; align-items: baseline; gap: 4px;
}
.audit-row.head .sort-header:hover { color: var(--ink); }
.audit-row.head .sort-glyph {
font-size: 9px; color: var(--accent);
/* keep the row height stable when the glyph appears/disappears */
min-width: 8px; display: inline-block;
}
/* ---------- schedule rows (Schedules tab) ---------- */
.schd-row {
+25 -6
View File
@@ -26,7 +26,7 @@
{{/* Export carries the current filter querystring so the
download is exactly what the operator sees on screen
(up to a higher row cap of 5000 vs 500 in the table). */}}
<a href="/audit.csv?range={{$rng}}{{if $filter.UserID}}&user_id={{$filter.UserID}}{{end}}{{if $filter.Actor}}&actor={{$filter.Actor}}{{end}}{{if $filter.ActionLike}}&action={{$filter.ActionLike}}{{end}}{{if $filter.TargetKind}}&target_kind={{$filter.TargetKind}}{{end}}"
<a href="{{$page.CSVHref}}"
class="btn"
title="Download the current filter as CSV (up to 5000 rows, UTF-8, RFC 4180)">
Export CSV ↓
@@ -109,12 +109,31 @@
{{/* table */}}
<div class="panel mt-3.5 rounded-[7px] overflow-hidden">
{{/* Header — every column except the payload one is a clickable
sort link. Hrefs are pre-built server-side ($page.SortHrefs)
so the URL escaping rules don't trip on the '=' chars when
html/template encodes <a href> attributes. */}}
<div class="audit-row head">
<div>When</div>
<div>Actor</div>
<div>User</div>
<div>Action</div>
<div>Target</div>
<div>
<a href="{{index $page.SortHrefs "ts"}}"
class="sort-header">When <span class="sort-glyph">{{sortGlyph "ts" $page.Sort $page.Dir}}</span></a>
</div>
<div>
<a href="{{index $page.SortHrefs "actor"}}"
class="sort-header">Actor <span class="sort-glyph">{{sortGlyph "actor" $page.Sort $page.Dir}}</span></a>
</div>
<div>
<a href="{{index $page.SortHrefs "user_id"}}"
class="sort-header">User <span class="sort-glyph">{{sortGlyph "user_id" $page.Sort $page.Dir}}</span></a>
</div>
<div>
<a href="{{index $page.SortHrefs "action"}}"
class="sort-header">Action <span class="sort-glyph">{{sortGlyph "action" $page.Sort $page.Dir}}</span></a>
</div>
<div>
<a href="{{index $page.SortHrefs "target_kind"}}"
class="sort-header">Target <span class="sort-glyph">{{sortGlyph "target_kind" $page.Sort $page.Dir}}</span></a>
</div>
<div></div>
</div>