From de670c98cdfc34bfd4ffb312e71d1d64cd27657f Mon Sep 17 00:00:00 2001 From: Frank Tovar Date: Sat, 21 Mar 2026 11:08:40 +0100 Subject: [PATCH] Persist selected table on tables page --- .../Components/Pages/Tables.razor | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/src/RolemasterDb.App/Components/Pages/Tables.razor b/src/RolemasterDb.App/Components/Pages/Tables.razor index 4de9b3e..146655e 100644 --- a/src/RolemasterDb.App/Components/Pages/Tables.razor +++ b/src/RolemasterDb.App/Components/Pages/Tables.razor @@ -311,6 +311,7 @@ } @code { + private const string SelectedTableStorageKey = "rolemaster.tables.selectedTable"; private LookupReferenceData? referenceData; private CriticalTableDetail? tableDetail; private string selectedTableSlug = string.Empty; @@ -341,6 +342,7 @@ private int? curatingResultId; private CriticalCellEditorModel? curationModel; private bool isTableMenuOpen; + private bool hasResolvedStoredTableSelection; private CriticalTableReference? SelectedTableReference => referenceData?.CriticalTables.FirstOrDefault(item => string.Equals(item.Key, selectedTableSlug, StringComparison.OrdinalIgnoreCase)); @@ -372,6 +374,7 @@ { selectedTableSlug = tableSlug; isTableMenuOpen = false; + await PersistSelectedTableAsync(tableSlug); await LoadTableDetailAsync(); } @@ -412,6 +415,34 @@ protected override async Task OnAfterRenderAsync(bool firstRender) { + if (!hasResolvedStoredTableSelection && referenceData?.CriticalTables.Count > 0) + { + try + { + var storedTableSlug = await JSRuntime.InvokeAsync("localStorage.getItem", SelectedTableStorageKey); + hasResolvedStoredTableSelection = true; + + var resolvedTableSlug = ResolveSelectedTableSlug(storedTableSlug); + if (!string.Equals(resolvedTableSlug, selectedTableSlug, StringComparison.OrdinalIgnoreCase)) + { + selectedTableSlug = resolvedTableSlug; + await LoadTableDetailAsync(); + await PersistSelectedTableAsync(selectedTableSlug); + await InvokeAsync(StateHasChanged); + return; + } + + if (!string.Equals(storedTableSlug, selectedTableSlug, StringComparison.OrdinalIgnoreCase)) + { + await PersistSelectedTableAsync(selectedTableSlug); + } + } + catch (InvalidOperationException) + { + // During prerender localStorage is unavailable. Retry after interactive render. + } + } + if (tableDetail is null || appliedLayoutVersion == tableLayoutVersion) { return; @@ -812,6 +843,25 @@ private string GetSelectedTableLabel() => SelectedTableReference?.Label ?? "Select a table"; + private string ResolveSelectedTableSlug(string? storedTableSlug) + { + if (referenceData is null || referenceData.CriticalTables.Count == 0) + { + return string.Empty; + } + + if (!string.IsNullOrWhiteSpace(storedTableSlug) && + referenceData.CriticalTables.Any(item => string.Equals(item.Key, storedTableSlug, StringComparison.OrdinalIgnoreCase))) + { + return storedTableSlug; + } + + return referenceData.CriticalTables.First().Key; + } + + private Task PersistSelectedTableAsync(string tableSlug) => + JSRuntime.InvokeVoidAsync("localStorage.setItem", SelectedTableStorageKey, tableSlug).AsTask(); + private string GetTableOptionCssClass(CriticalTableReference table) { var classes = new List();