Document phase 0 frontend overhaul baseline

This commit is contained in:
2026-03-21 13:01:27 +01:00
parent a188aa9c63
commit 62322bb620

View File

@@ -26,6 +26,27 @@ It is intentionally implementation-focused:
- treat route and UI changes as frontend/presentation refactors unless an additive backend endpoint is explicitly approved later - treat route and UI changes as frontend/presentation refactors unless an additive backend endpoint is explicitly approved later
- keep changes incremental and shippable by phase - keep changes incremental and shippable by phase
## Working Status
- Branch: `frontend/tables-overhaul`
- Last updated: `2026-03-21`
- Current focus: `Phase 1`
- Document mode: living plan and progress log
### Progress Log
| Date | Phase | Status | Notes |
| --- | --- | --- | --- |
| 2026-03-21 | Phase 0 | Completed | Created overhaul branch, audited the current frontend, and locked the route map, component boundaries, migration path, and shared-state ownership. |
### Lessons Learned
- The current app shell is simple enough that the redesign can land incrementally in `MainLayout.razor` without changing the hosting model in `Program.cs`.
- The current `Tables.razor` page already contains three different concerns: reference browsing, curation queue work, and full editing. Splitting by workflow is the highest-value maintainability move.
- Existing contracts in `LookupContracts.cs` already contain the identifiers needed for deep links and cross-surface navigation: table slug, group key, column key, roll band, and result id.
- Diagnostics already behaves like a separate workflow and should be moved under `Tools` early, before the `Tables` page is rewritten further.
- `localStorage` access is currently page-local and ad hoc. Theme, recents, pins, and table context need one shared storage boundary before more UI work starts.
## Target Outcomes ## Target Outcomes
The overhaul is complete when the app behaves as one coherent product with four clear destination families: The overhaul is complete when the app behaves as one coherent product with four clear destination families:
@@ -67,6 +88,10 @@ Recommended order:
## Phase 0: Discovery And Technical Baseline ## Phase 0: Discovery And Technical Baseline
### Status
`Completed`
### Goal ### Goal
Create the implementation foundation so the visual overhaul does not start with uncontrolled edits in page files. Create the implementation foundation so the visual overhaul does not start with uncontrolled edits in page files.
@@ -105,6 +130,113 @@ Create the implementation foundation so the visual overhaul does not start with
- no unresolved structural ambiguity remains around shell, routes, state ownership, or shared primitives - no unresolved structural ambiguity remains around shell, routes, state ownership, or shared primitives
### Current Repo Audit
| Area | Current owner | Current responsibility | Phase 0 decision |
| --- | --- | --- | --- |
| App host | `src/RolemasterDb.App/Components/App.razor` | document shell, fonts, global CSS/script includes | keep as the document root; only update fonts and global assets during Phase 1 |
| Router | `src/RolemasterDb.App/Components/Routes.razor` | route resolution and layout selection | keep single router; add compatibility route components instead of special middleware redirects |
| App shell | `src/RolemasterDb.App/Components/Layout/MainLayout.razor` | current sidebar layout and page body host | replace with the new top app bar shell and mobile bottom nav |
| Primary nav | `src/RolemasterDb.App/Components/Layout/NavMenu.razor` | implementation-bucket navigation | retire after the new shell lands; replace with destination navigation primitives |
| Home page | `src/RolemasterDb.App/Components/Pages/Home.razor` | live lookup flow | keep behavior, later restyle and reframe as `Play` |
| Tables page | `src/RolemasterDb.App/Components/Pages/Tables.razor` | table selection, table rendering, persisted selection, editor launch, curation queue work | split into page shell, selection state, index rail, context bar, table canvas, inspector, and action services |
| Diagnostics page | `src/RolemasterDb.App/Components/Pages/Diagnostics.razor` | engineering inspection of a selected cell | move under `Tools` and reuse shared table-selection state |
| API page | `src/RolemasterDb.App/Components/Pages/Api.razor` | static API docs page | move under `Tools` with updated framing |
| Shared editor and curation UI | `src/RolemasterDb.App/Components/Shared/CriticalCellEditorDialog.razor`, `src/RolemasterDb.App/Components/Shared/CriticalCellCurationDialog.razor` | full editing and quick curation interactions | preserve behavior; change launch points and page ownership |
| Lookup and table contracts | `src/RolemasterDb.App/Features/LookupContracts.cs` | frontend-facing DTOs for tables, lookups, editing, and diagnostics | preserve contracts; build frontend state and deep links around them |
### Behaviors To Preserve
| Behavior | Current source | Preserve as | Notes |
| --- | --- | --- | --- |
| Selected table persistence | `Tables.razor` local storage key `rolemaster.tables.selectedTable` | shared per-destination context persistence service | move out of page code during Phase 2 |
| Full cell editor flow | `Tables.razor` + `CriticalCellEditorDialog.razor` | stable editor entry from inspector, curation, and tools | editor remains modal for now |
| Quick curation flow and save-next behavior | `Tables.razor` + `CriticalCellCurationDialog.razor` | dedicated `Curation` workflow with reused quick-parse components | queue logic moves off the reference page |
| Diagnostics selection model | `Diagnostics.razor` | shared table-position selector model used by `Tools` | existing selection order is a good starting point |
| Attack and direct critical lookup flows | `Home.razor` | `Play` page behaviors | preserve contracts and calculation behavior |
| Result preview components | `CriticalLookupResultCard.razor`, `CompactCriticalCell.razor`, related shared components | reusable reference and inspector content | keep and adapt instead of rewriting presentation logic from scratch |
### Resolved Route Map
| Surface | Target route | Compatibility handling | Owner page/component |
| --- | --- | --- | --- |
| Play | `/` | none | `Pages/Home.razor` until renamed later |
| Tables | `/tables` | none | `Pages/Tables.razor`, later split into page components under `Components/Tables` |
| Curation | `/curation` | none | new page introduced in Phase 4 |
| Tools landing | `/tools` | none | new page introduced in Phase 5 |
| Diagnostics | `/tools/diagnostics` | keep `/diagnostics` as compatibility page that forwards to `/tools/diagnostics` | new page in `Pages/Tools/Diagnostics.razor` |
| API docs | `/tools/api` | keep `/api` as compatibility page that forwards to `/tools/api` | new page in `Pages/Tools/Api.razor` |
### Route Compatibility Strategy
- Use lightweight compatibility pages instead of server-side redirects so route behavior stays inside the Blazor app.
- Compatibility pages should preserve query string values and replace browser history when forwarding, so old bookmarks do not create noisy back-stack entries.
- New deep-link work should target the destination routes only. Compatibility pages are temporary migration aids and should not gain new UI.
### Target Frontend Structure
| Area | Planned location | Responsibility |
| --- | --- | --- |
| Shell components | `src/RolemasterDb.App/Components/Shell` | app frame, top app bar, bottom nav, destination nav, shell actions |
| Shared app state | `src/RolemasterDb.App/Frontend/AppState` | theme, recents, pins, selected context, URL serialization, storage access |
| Shared primitives | `src/RolemasterDb.App/Components/Primitives` | chips, tabs, buttons, drawers, inspector sections, empty states |
| Tables-specific components | `src/RolemasterDb.App/Components/Tables` | index rail, context bar, table canvas, inspector, state adapters |
| Curation-specific components | `src/RolemasterDb.App/Components/Curation` | queue layout, quick parse surface, save-and-advance actions |
| Tools-specific components | `src/RolemasterDb.App/Components/Tools` | diagnostics inspector, API docs framing, context links |
| Play-specific components | `src/RolemasterDb.App/Components/Play` | lookup forms, result rail, deep-link actions |
### Shared State Strategy
| Concern | Planned owner | Persistence | Consumers |
| --- | --- | --- | --- |
| Theme mode | `ThemeState` service | `localStorage` | shell, all pages |
| Recent tables | `RecentTablesState` service | `localStorage` | shell omnibox, tables rail, curation |
| Pinned tables | `PinnedTablesState` service | `localStorage` | shell shortcuts, tables rail, curation |
| Selected table context | `TableContextState` service | URL first, `localStorage` fallback per destination | tables, curation, tools |
| Table deep-link parsing and serialization | `TableContextUrlSerializer` helper | URL only | tables, curation, tools, play deep links |
| Local storage access | `BrowserStorageService` | wrapper around JS interop | all frontend state services |
### State Ownership Rules
- URL state is the source of truth for sharable context.
- Local storage is only for preferences and last-used convenience state.
- Page components should consume state services and emit intents. They should not own persistence logic directly.
- Editor and curation dialog transient state stays local to the workflow component that opened it.
### Shared Primitive Boundaries
| Primitive | First consumer | Notes |
| --- | --- | --- |
| App bar and destination nav | shell | replaces `NavMenu.razor` |
| Bottom nav | shell | mobile-only persistent destination nav |
| Omnibox trigger and panel | shell, tables | foundation in Phase 2; full search later |
| Chip and status pill primitives | shell, tables, curation, tools | replace ad hoc chip styling in `app.css` |
| Tabs and segmented controls | tables, tools | mode switching and filtered views |
| Drawer and bottom sheet primitives | tables, curation | inspector on small screens |
| Inspector section cards | tables, tools, curation | unify right-rail and sheet layout |
### Migration Path
1. Land the new shell and theme infrastructure in `MainLayout.razor` and `wwwroot/app.css` without changing page internals.
2. Add shared state and compatibility routes before splitting the largest pages.
3. Move diagnostics and API docs under `Tools` early to reduce noise in the main navigation.
4. Split `Tables.razor` into composable pieces while preserving existing editor and curation behaviors.
5. Extract the dedicated `Curation` workflow once the shared selector and table context code already exists.
6. Restyle and reconnect `Play` after shell, deep links, and shared primitives are stable.
### Phase 0 Exit Criteria
- the route map above is treated as implementation truth unless a later change is explicitly recorded here
- page, shell, and shared-state ownership are defined strongly enough to begin Phase 1 without structural rework
- compatibility handling for `/diagnostics` and `/api` is decided
- preserved behaviors are identified so later phases do not regress them accidentally
### Next Implementation Slice
- Start Phase 1 with the shell and design-token foundation in `MainLayout.razor`, `App.razor`, and `wwwroot/app.css`.
- Introduce the shared theme state and browser storage wrapper before rewriting destination pages.
- Replace the current sidebar navigation first so later page work lands inside the target shell instead of the legacy layout.
## Phase 1: Design System And Application Shell ## Phase 1: Design System And Application Shell
### Goal ### Goal