Add permanent table index rail layout

This commit is contained in:
2026-03-21 14:56:36 +01:00
parent 338842dba9
commit bed85b9778
5 changed files with 230 additions and 270 deletions

View File

@@ -11,16 +11,7 @@
<PageTitle>Critical Tables</PageTitle>
<section class="panel tables-page">
<TablesPageHeader
ReferenceData="referenceData"
SelectedTableReference="SelectedTableReference"
SelectedTableSlug="selectedTableSlug"
IsTableMenuOpen="isTableMenuOpen"
IsTableSelectionDisabled="IsTableSelectionDisabled"
IsPinned="PinnedTablesState.IsPinned"
OnToggleTableMenu="ToggleTableMenu"
OnCloseTableMenu="CloseTableMenu"
OnSelectTable="SelectTableAsync" />
<TablesPageHeader />
@if (referenceData is null)
{
@@ -30,34 +21,49 @@
{
<p class="muted">No critical tables are available yet.</p>
}
else if (!hasResolvedStoredTableSelection)
else
{
<p class="muted">Restoring table context...</p>
}
else if (isDetailLoading)
{
<p class="muted">Loading the selected table...</p>
}
else if (!string.IsNullOrWhiteSpace(detailError))
{
<p class="error-text">@detailError</p>
}
else if (tableDetail is null)
{
<p class="muted">The selected table could not be loaded.</p>
}
else if (tableDetail is { } detail)
{
<div class="table-shell">
<TablesContextBar
Detail="detail"
IsPinned="PinnedTablesState.IsPinned(detail.Slug)"
OnTogglePin="TogglePinnedTableAsync" />
<div class="tables-reference-layout">
<aside class="tables-reference-rail">
<TablesIndexRail
Tables="referenceData.CriticalTables"
SelectedTableSlug="selectedTableSlug"
IsPinned="PinnedTablesState.IsPinned"
OnSelectTable="SelectTableAsync" />
</aside>
<TablesCanvas
Detail="detail"
OnOpenCuration="OpenCellCurationAsync"
OnOpenEditor="OpenCellEditorAsync" />
<div class="tables-reference-main">
@if (!hasResolvedStoredTableSelection)
{
<p class="muted">Restoring table context...</p>
}
else if (isDetailLoading)
{
<p class="muted">Loading the selected table...</p>
}
else if (!string.IsNullOrWhiteSpace(detailError))
{
<p class="error-text">@detailError</p>
}
else if (tableDetail is null)
{
<p class="muted">The selected table could not be loaded.</p>
}
else if (tableDetail is { } detail)
{
<div class="table-shell">
<TablesContextBar
Detail="detail"
IsPinned="PinnedTablesState.IsPinned(detail.Slug)"
OnTogglePin="TogglePinnedTableAsync" />
<TablesCanvas
Detail="detail"
OnOpenCuration="OpenCellCurationAsync"
OnOpenEditor="OpenCellEditorAsync" />
</div>
}
</div>
</div>
}
</section>
@@ -127,7 +133,6 @@
private string? curationQuickParseError;
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));
@@ -138,25 +143,9 @@
isReferenceDataLoading = false;
}
private void ToggleTableMenu()
{
if (IsTableSelectionDisabled)
{
return;
}
isTableMenuOpen = !isTableMenuOpen;
}
private void CloseTableMenu()
{
isTableMenuOpen = false;
}
private async Task SelectTableAsync(string tableSlug)
{
selectedTableSlug = tableSlug;
isTableMenuOpen = false;
await LoadTableDetailAsync();
await PersistAndSyncTableContextAsync();
}

View File

@@ -0,0 +1,59 @@
<section class="tables-index-rail" aria-labelledby="tables-index-heading">
<div class="tables-index-rail-header">
<h2 id="tables-index-heading" class="tables-index-title">Table Index</h2>
<p class="tables-index-copy">Choose a table, then read from the roll band across to the result you need.</p>
</div>
<div class="tables-index-list" role="listbox" aria-label="Critical tables">
@foreach (var table in Tables)
{
<button
type="button"
role="option"
aria-selected="@string.Equals(table.Key, SelectedTableSlug, StringComparison.OrdinalIgnoreCase)"
class="table-index-option @GetTableOptionCssClass(table)"
@onclick="() => OnSelectTable.InvokeAsync(table.Key)">
<span class="table-index-option-copy">
<strong class="table-index-option-title">@table.Label</strong>
<span class="table-index-option-meta">@table.Family</span>
</span>
<span class="table-index-option-chips">
@if (GetIsPinned(table.Key))
{
<StatusChip Tone="accent">Pinned</StatusChip>
}
<span class="chip">@($"{table.CurationPercentage}%")</span>
</span>
</button>
}
</div>
</section>
@code {
[Parameter]
public IReadOnlyList<CriticalTableReference> Tables { get; set; } = Array.Empty<CriticalTableReference>();
[Parameter]
public string SelectedTableSlug { get; set; } = string.Empty;
[Parameter]
public Func<string, bool>? IsPinned { get; set; }
[Parameter]
public EventCallback<string> OnSelectTable { get; set; }
private bool GetIsPinned(string tableSlug) => IsPinned?.Invoke(tableSlug) ?? false;
private string GetTableOptionCssClass(CriticalTableReference table)
{
var classes = new List<string>();
if (string.Equals(table.Key, SelectedTableSlug, StringComparison.OrdinalIgnoreCase))
{
classes.Add("is-selected");
}
classes.Add(table.CurationPercentage >= 100 ? "is-curated" : "needs-curation");
return string.Join(' ', classes);
}
}

View File

@@ -1,105 +1,7 @@
<div class="table-browser-toolbar">
<div class="table-selector">
<label id="critical-table-selector-label">Table</label>
<div class="table-select-shell">
<button
type="button"
class="input-shell table-select-trigger"
aria-haspopup="listbox"
aria-expanded="@IsTableMenuOpen"
aria-labelledby="critical-table-selector-label critical-table-selector-value"
@onclick="() => OnToggleTableMenu.InvokeAsync()"
disabled="@IsTableSelectionDisabled">
<span class="table-select-trigger-copy">
<span id="critical-table-selector-value" class="table-select-trigger-title">@GetSelectedTableLabel()</span>
</span>
@if (SelectedTableReference is { } selected)
{
<span class="table-select-trigger-chips">
@if (GetIsPinned(selected.Key))
{
<StatusChip Tone="accent">Pinned</StatusChip>
}
<span class="chip">@($"{selected.CurationPercentage}%")</span>
</span>
}
</button>
@if (IsTableMenuOpen && ReferenceData is not null)
{
<button type="button" class="table-selector-backdrop" @onclick="() => OnCloseTableMenu.InvokeAsync()" aria-label="Close table selector"></button>
<div class="table-select-menu" role="listbox" aria-labelledby="critical-table-selector-label">
@foreach (var table in ReferenceData.CriticalTables)
{
<button
type="button"
role="option"
aria-selected="@string.Equals(table.Key, SelectedTableSlug, StringComparison.OrdinalIgnoreCase)"
class="table-select-option @GetTableOptionCssClass(table)"
@onclick="() => OnSelectTable.InvokeAsync(table.Key)">
<span class="table-select-option-main">
<strong class="table-select-option-title">@table.Label</strong>
</span>
<span class="table-select-option-chips">
@if (GetIsPinned(table.Key))
{
<StatusChip Tone="accent">Pinned</StatusChip>
}
<span class="chip">@($"{table.CurationPercentage}%")</span>
</span>
</button>
}
</div>
}
</div>
<header class="tables-page-header">
<div class="tables-page-header-copy">
<p class="tables-page-eyebrow">Reference</p>
<h1 class="panel-title">Critical Tables</h1>
<p class="tables-page-intro">Browse the index, open a table, and read the result directly from the grid without leaving the page.</p>
</div>
<p class="table-browser-toolbar-copy">Choose a table, then read from the roll band on the left across to the result you need.</p>
</div>
@code {
[Parameter]
public LookupReferenceData? ReferenceData { get; set; }
[Parameter]
public CriticalTableReference? SelectedTableReference { get; set; }
[Parameter]
public string SelectedTableSlug { get; set; } = string.Empty;
[Parameter]
public bool IsTableMenuOpen { get; set; }
[Parameter]
public bool IsTableSelectionDisabled { get; set; }
[Parameter]
public Func<string, bool>? IsPinned { get; set; }
[Parameter]
public EventCallback OnToggleTableMenu { get; set; }
[Parameter]
public EventCallback OnCloseTableMenu { get; set; }
[Parameter]
public EventCallback<string> OnSelectTable { get; set; }
private bool GetIsPinned(string tableSlug) => IsPinned?.Invoke(tableSlug) ?? false;
private string GetSelectedTableLabel() => SelectedTableReference?.Label ?? "Select a table";
private string GetTableOptionCssClass(CriticalTableReference table)
{
var classes = new List<string>();
if (string.Equals(table.Key, SelectedTableSlug, StringComparison.OrdinalIgnoreCase))
{
classes.Add("is-selected");
}
classes.Add(table.CurationPercentage >= 100 ? "is-curated" : "needs-curation");
return string.Join(' ', classes);
}
}
</header>