diff --git a/src/ScadaLink.CentralUI/Components/Audit/AuditResultsGrid.razor b/src/ScadaLink.CentralUI/Components/Audit/AuditResultsGrid.razor
index 3610cc8..af2fb0d 100644
--- a/src/ScadaLink.CentralUI/Components/Audit/AuditResultsGrid.razor
+++ b/src/ScadaLink.CentralUI/Components/Audit/AuditResultsGrid.razor
@@ -17,7 +17,13 @@
@foreach (var col in OrderedColumns())
{
+ // @key keeps Blazor reusing one DOM node per column across
+ // re-renders (reorder/resize), so audit-grid.js binds drag
+ // listeners exactly once per | and never leaks them onto
+ // discarded nodes — the __auditGridCellBound guard relies on
+ // this node stability to be fully sound.
|
diff --git a/src/ScadaLink.CentralUI/Components/Audit/AuditResultsGrid.razor.cs b/src/ScadaLink.CentralUI/Components/Audit/AuditResultsGrid.razor.cs
index 928a050..d6b08c4 100644
--- a/src/ScadaLink.CentralUI/Components/Audit/AuditResultsGrid.razor.cs
+++ b/src/ScadaLink.CentralUI/Components/Audit/AuditResultsGrid.razor.cs
@@ -37,6 +37,16 @@ namespace ScadaLink.CentralUI.Components.Audit;
/// rows) — that's the conventional "we've reached the
/// end" signal for keyset paging without a count query.
///
+///
+///
+/// Accessibility. Column resize and reorder are mouse/pointer-only —
+/// they use a pointer-driven resize handle and native HTML5 drag-and-drop with
+/// no keyboard equivalent and no ARIA for the reorder. This is a conscious
+/// scope decision for an internal tool, not an oversight: only the column-
+/// customisation gesture is mouse-only. The persisted layout itself
+/// renders as plain HTML, so keyboard and assistive-technology users still get
+/// a fully readable, navigable grid.
+///
///
public partial class AuditResultsGrid : IAsyncDisposable
{
@@ -99,6 +109,9 @@ public partial class AuditResultsGrid : IAsyncDisposable
/// data-test + the column-order parameter); the label is the user-facing
/// header text. Mirrors Component-AuditLog.md §10.
///
+ // Label intentionally equals Key for every column today; the separate Label
+ // field is future-proofing for humanised headers (e.g. "Occurred (UTC)") —
+ // populating it is a deliberate later change, out of scope here.
private static readonly IReadOnlyList<(string Key, string Label)> AllColumns = new[]
{
("OccurredAtUtc", "OccurredAtUtc"),
@@ -251,6 +264,12 @@ public partial class AuditResultsGrid : IAsyncDisposable
// is idempotent — already-bound cells are skipped, and the .NET
// reference is refreshed — so a re-render after a reorder still leaves
// every header cell wired without leaking handlers.
+ //
+ // OnColumnResized/OnColumnReordered both call StateHasChanged(), which
+ // re-runs this method and calls init again. That repeat call is an
+ // intentional cheap no-op: the @key-stable | nodes plus the
+ // __auditGridCellBound guard mean init re-scans the header and rebinds
+ // nothing — so there is deliberately no gating logic here.
if (_selfRef is not null)
{
try
diff --git a/src/ScadaLink.CentralUI/wwwroot/js/audit-grid.js b/src/ScadaLink.CentralUI/wwwroot/js/audit-grid.js
index a1ce628..3ede5ed 100644
--- a/src/ScadaLink.CentralUI/wwwroot/js/audit-grid.js
+++ b/src/ScadaLink.CentralUI/wwwroot/js/audit-grid.js
@@ -171,6 +171,12 @@ window.auditGrid = {
// Apply a width to a | via a CSS custom property. The scoped stylesheet
// reads --audit-col-width; absent it, the column falls back to auto.
+ //
+ // Known, intentional behaviour: during a live resize drag this updates the
+ // | width immediately, but the | body cells only catch up on the next
+ // .NET re-render (driven by OnColumnResized at pointer-up). The brief
+ // header/body width mismatch mid-drag is an accepted trade-off for an
+ // internal tool — not a bug.
_applyWidth: function (th, widthPx) {
th.style.setProperty("--audit-col-width", widthPx + "px");
},
|