From afd81c32ef9ff8d0b52a58941532bb7e9aaab81f Mon Sep 17 00:00:00 2001 From: Joseph Doherty Date: Thu, 21 May 2026 20:35:20 -0400 Subject: [PATCH] fix(centralui): marshal Audit Log LocationChanged handler through InvokeAsync MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Code-review follow-ups on the same-page drill-in fix (3f1c0e5): - Wrap HandleLocationChanged's body in InvokeAsync — LocationChanged can fire off the renderer's synchronization context. - Document that a paramless /audit/log navigation intentionally preserves the last applied filter (drill-ins always carry query params). --- .../Pages/Audit/AuditLogPage.razor.cs | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/ScadaLink.CentralUI/Components/Pages/Audit/AuditLogPage.razor.cs b/src/ScadaLink.CentralUI/Components/Pages/Audit/AuditLogPage.razor.cs index 2aeb593..b7c7a5c 100644 --- a/src/ScadaLink.CentralUI/Components/Pages/Audit/AuditLogPage.razor.cs +++ b/src/ScadaLink.CentralUI/Components/Pages/Audit/AuditLogPage.razor.cs @@ -66,14 +66,19 @@ public partial class AuditLogPage : IDisposable /// navigates to /audit/log?executionId=…). Reassigning /// to a fresh instance is what kicks the results /// grid into reloading; we also close the drawer so the operator sees the - /// newly filtered grid, and call - /// because this fires outside the normal render lifecycle. + /// newly filtered grid. The body is marshalled through + /// because + /// can fire off the renderer's + /// synchronization context. /// private void HandleLocationChanged(object? sender, LocationChangedEventArgs e) { - ApplyQueryStringFilters(); - _drawerOpen = false; - StateHasChanged(); + _ = InvokeAsync(() => + { + ApplyQueryStringFilters(); + _drawerOpen = false; + StateHasChanged(); + }); } public void Dispose() @@ -86,6 +91,10 @@ public partial class AuditLogPage : IDisposable var uri = Navigation.ToAbsoluteUri(Navigation.Uri); var query = QueryHelpers.ParseQuery(uri.Query); + // A paramless navigation (e.g. clicking the "Audit Log" nav link while + // already here) intentionally preserves the last applied filter rather + // than clearing the grid: this method is a drill-in mechanism and every + // drill-in carries query params. The operator clears via the filter bar. if (query.Count == 0) { return;