From 8e56ceabf58f9c94afd643f8243f1722388d94cf Mon Sep 17 00:00:00 2001 From: cesnimda Date: Mon, 28 Sep 2026 17:26:02 +0200 Subject: [PATCH] feat(ui): redesign grouped application shell --- docs/redesign/phase-5/README.md | 2 +- docs/redesign/phase-5/p5-01/README.md | 97 ++++++++++ .../p5-01/visual/grouped-mobile-dark-en.png | Bin 0 -> 35984 bytes .../p5-01/visual/grouped-mobile-dark-nb.png | Bin 0 -> 37322 bytes .../p5-01/visual/grouped-mobile-light-en.png | Bin 0 -> 35734 bytes .../p5-01/visual/grouped-mobile-light-nb.png | Bin 0 -> 37034 bytes .../p5-01/visual/grouped-rail-dark-en.png | Bin 0 -> 56635 bytes .../p5-01/visual/grouped-rail-dark-nb.png | Bin 0 -> 55090 bytes .../p5-01/visual/grouped-rail-light-en.png | Bin 0 -> 54738 bytes .../p5-01/visual/grouped-rail-light-nb.png | Bin 0 -> 53813 bytes .../p5-01/visual/grouped-shell-dark-en.png | Bin 0 -> 70996 bytes .../p5-01/visual/grouped-shell-dark-nb.png | Bin 0 -> 70569 bytes .../p5-01/visual/grouped-shell-light-en.png | Bin 0 -> 69771 bytes .../p5-01/visual/grouped-shell-light-nb.png | Bin 0 -> 69821 bytes docs/roadmap/todo.md | 1 + job-tracker-ui/e2e/accessibility.spec.ts | 1 + job-tracker-ui/e2e/csv-export.spec.ts | 6 +- .../e2e/redesign-preservation.spec.ts | 1 + job-tracker-ui/e2e/shell-readiness.spec.ts | 40 ++++ job-tracker-ui/e2e/smoke.spec.ts | 15 +- job-tracker-ui/src/App.tsx | 29 +-- .../src/app-shell-navigation.test.tsx | 58 ++++++ .../src/components/QuickCommandDialog.tsx | 6 +- job-tracker-ui/src/confirm.tsx | 8 +- job-tracker-ui/src/i18n/translations.ts | 6 + job-tracker-ui/src/layout/AppShell.tsx | 174 ++++++++++++------ job-tracker-ui/src/layout/PageLayout.tsx | 7 +- job-tracker-ui/src/prompt.test.tsx | 1 + job-tracker-ui/src/prompt.tsx | 11 +- job-tracker-ui/src/sidebar-active-nav.test.ts | 27 ++- 30 files changed, 398 insertions(+), 92 deletions(-) create mode 100644 docs/redesign/phase-5/p5-01/README.md create mode 100644 docs/redesign/phase-5/p5-01/visual/grouped-mobile-dark-en.png create mode 100644 docs/redesign/phase-5/p5-01/visual/grouped-mobile-dark-nb.png create mode 100644 docs/redesign/phase-5/p5-01/visual/grouped-mobile-light-en.png create mode 100644 docs/redesign/phase-5/p5-01/visual/grouped-mobile-light-nb.png create mode 100644 docs/redesign/phase-5/p5-01/visual/grouped-rail-dark-en.png create mode 100644 docs/redesign/phase-5/p5-01/visual/grouped-rail-dark-nb.png create mode 100644 docs/redesign/phase-5/p5-01/visual/grouped-rail-light-en.png create mode 100644 docs/redesign/phase-5/p5-01/visual/grouped-rail-light-nb.png create mode 100644 docs/redesign/phase-5/p5-01/visual/grouped-shell-dark-en.png create mode 100644 docs/redesign/phase-5/p5-01/visual/grouped-shell-dark-nb.png create mode 100644 docs/redesign/phase-5/p5-01/visual/grouped-shell-light-en.png create mode 100644 docs/redesign/phase-5/p5-01/visual/grouped-shell-light-nb.png create mode 100644 job-tracker-ui/src/app-shell-navigation.test.tsx diff --git a/docs/redesign/phase-5/README.md b/docs/redesign/phase-5/README.md index 5d5f0a9..ee93383 100644 --- a/docs/redesign/phase-5/README.md +++ b/docs/redesign/phase-5/README.md @@ -1,6 +1,6 @@ # Phase 5 — Representative screens / major UI redesign plan -**Current successor: [P5-00 readiness implementation](p5-00/README.md).** The five bounded shell conditions are implemented and P5-00-D01 is closed with a deterministic test clock and **916/916** backend rerun. P5-01 has an explicit **GO**. No P5-01 visible redesign, B07 or production work has started. F04 remains open. +**Completed successor: [P5-01 AppShell and grouped navigation](p5-01/README.md).** The first major visible redesign groups every existing destination without changing the 31-pattern route/provider contract. Its inherited backend prerequisite repair established **918/918**, and the P5-01 shell route/focus/accessibility contract is protected. P5-02 and B07 have not started. F04 remains open. Historical planning checkpoint: source `2a2f9e48052c562ef599825458d0d3a6f9f9fc61`, inspected on 2026-09-13 on `codex/ui-redesign-phase4`. That checkpoint was documentation-only; the successor record above owns implementation/validation status. diff --git a/docs/redesign/phase-5/p5-01/README.md b/docs/redesign/phase-5/p5-01/README.md new file mode 100644 index 0000000..a407e77 --- /dev/null +++ b/docs/redesign/phase-5/p5-01/README.md @@ -0,0 +1,97 @@ +# P5-01 — AppShell and grouped navigation + +Source checkpoint: `38cf37e`, branch `codex/ui-redesign-phase4`. Validated locally on Windows with the disposable API/SQLite and Chromium environment. The containing checkpoint is discoverable with `git log -- docs/redesign/phase-5/p5-01`. + +This slice is the first major visible Phase 5 redesign. It implements the approved grouped shell in [NAVIGATION_MIGRATION](../NAVIGATION_MIGRATION.md) without changing the router, providers, authentication boundary, route patterns or business workflows. P5-02 utilities, P5-03 Jobs presentation, P5-05 quick preview, B07 and later redesign work are not included. F04 remains open. + +## Scope and result + +- Dashboard remains an immediate primary destination. +- **Job search** owns Jobs plus Discover, Follow-ups, Board, Companies, Offers and Trash. Job email remains a distinct destination in the same group. +- **Career** owns Career Profile and CVs. Longest-path ownership keeps `/career/builder/:id` with CVs, never Career Profile. +- **Admin** remains permission-filtered and retains Audit log, Users and System routes. +- **Account** owns Settings with Profile and Connected accounts as explicit secondary destinations; the existing account menu remains available. +- The expanded sidebar displays primary and secondary hierarchy. The persisted desktop rail uses labelled MUI tooltips and a keyboard-operable secondary menu. The mobile drawer keeps full labels and a scrollable hierarchy. +- The permanent drawer allocates navigation only the height remaining below the app bar; the upper destination group scrolls when necessary and Account links remain reachable at 900px desktop height. +- A selected secondary destination identifies itself with `aria-current="page"`; its owner is marked `aria-current="location"`. The visual selected indicator and keyboard focus remain separate. +- The shell now has a visible-on-focus skip link, one named navigation landmark, one named main target and one shared `PageHeader` h1. A successful shell route selection moves focus to the new h1. Escape from the drawer still returns focus through the existing MUI modal behavior; a cancelled dirty-editor transition does not produce a false route-focus change. +- Existing desktop collapse persistence remains separate from temporary mobile-open state and retains the accepted 1024px boundary from P5-00. + +No new route, navigation framework, store, API, dependency, branding asset, notification destination, Documents destination or Admin dashboard was introduced. The existing quick search, notifications, account menu, language controls and contextual Add Job action remain in place for P5-02. + +## Changed owners + +| File | Bounded responsibility | +|---|---| +| `job-tracker-ui/src/App.tsx` | Re-express the existing route destinations as the approved grouped navigation tree; retain callbacks, permissions and route elements. `/applications/:id` remains an explicit Jobs ownership alias. | +| `job-tracker-ui/src/layout/AppShell.tsx` | Render hierarchy in expanded/mobile modes and an accessible menu in rail mode; compute parent/child ownership; add skip/main/route-heading focus semantics; apply the visible selected indicator and bound the permanent drawer below the app bar. | +| `job-tracker-ui/src/layout/PageLayout.tsx` | Allow the existing shared `PageHeader` title to receive the shell focus ref. It does not alter section layout or consumer workflow behavior. | +| `job-tracker-ui/src/components/QuickCommandDialog.tsx` | Preserve the inherited command-dialog initial-focus contract after the shell transition by focusing the existing search field when the MUI transition has entered. The command catalogue and execution behavior are unchanged. | +| `job-tracker-ui/src/prompt.tsx`, `confirm.tsx`, `prompt.test.tsx` | Keep existing dialog keyboard entry deterministic; the prompt input is focused once after opening and the confirmation cancel action regains initial focus. No dialog result or action changed. | +| `job-tracker-ui/src/i18n/translations.ts` | English/Bokmål group names and skip-link label only. | +| `job-tracker-ui/src/sidebar-active-nav.test.ts` | Non-nested Jobs ownership, legacy application ownership and Career/CV specificity. | +| `job-tracker-ui/src/app-shell-navigation.test.tsx` | Group/current semantics, rail menu operation and successful route-heading focus. | +| `job-tracker-ui/e2e/shell-readiness.spec.ts` | Four real-App light/dark × English/Bokmål journeys across expanded, rail and phone navigation. | +| `job-tracker-ui/e2e/accessibility.spec.ts`, `redesign-preservation.spec.ts`, `smoke.spec.ts`, `csv-export.spec.ts` | Give long real-browser journeys sufficient time, target the exact created job ID, and set up API-owned data before opening the Dashboard so unrelated concurrent startup requests do not race setup writes. The separate UI login smoke case still protects sign-in. No domain assertions or routes were removed. | + +`PageLayout.tsx` is necessary because focus must land on the actual shared page heading rather than a duplicate or wrapper; its optional ref is unused elsewhere. The dialog changes preserve the inherited initial-focus contract exposed by the loaded shell browser run. A transition callback on the prompt was removed after it disturbed the mobile Tab wrap in the production build; a one-time open effect preserves initial focus in both dev and static-export modes. No dialog outcome or domain workflow changed. + +## Preservation trace + +| PRES → existing behavior | P5-01 change | Automated evidence | Visual/UX evidence | +|---|---|---|---| +| **PRES-E07** → authenticated shell, every existing destination, collapse/drawer and active route | Same destinations grouped under readable owners; rail children remain keyboard reachable | `sidebar-active-nav`, `app-shell-navigation`, all existing route-contract and shell-readiness coverage | Expanded/rail/mobile captures in all four theme/locale pairs | +| **PRES-E08** → focus, theme, locale and responsive shell behavior | Skip/main target, one h1, current parent/child semantics and route-heading focus | Unit focus contract; real route selection to Trash/Board; P5-00 drawer entry/Escape and dirty-CV fixtures retained | Focused rail menu and mobile drawer; light/dark and EN/NB | +| **PRES-E05/E06/E09** → auth/session disposal, permissions and protected shell | No provider/auth/session change; hidden admin rows remain filtered | Complete frontend/backend/account-isolation/browser baseline | Standard/admin shell states; no private data added to navigation | +| **PRES-S02/S03** → notification and Settings/account entry | Existing header utilities retained; Settings owns existing Profile/Connections links | Existing notification, Settings and account-switch tests plus grouped-shell tests | Account group in expanded/mobile shell | +| **PRES-A01–A03** → protected Admin audit/users/system and metadata | Same three permission-gated routes, now under a stable Admin group | Existing admin/API permission tests and complete browser baseline | Admin group in both locales/themes and narrow drawer | +| **PRES-J/W/C/M route entry contracts** | Presentation/ownership only; all approved entries and compatibility paths remain routed by unchanged `Routes` | Existing 31-pattern route contract plus complete domain suites; direct Jobs/Career ownership cases added | Actual populated Board and Trash states; no domain forms or mutations changed | + +Mapping a capability does not claim exhaustive coverage of that capability. This slice protects navigation entry and shell behavior; domain behavior remains owned by its existing tests and later gated slices. + +## Accessibility, responsive and visual validation + +The real-App fixture uses synthetic owned data and blocks external browser traffic. It verifies: + +- expanded desktop group labels, exact current parent/child semantics and fully visible Account destinations at 900px height; +- rail activation by keyboard and access to every Jobs secondary destination through a labelled MUI menu; +- mobile drawer labels, current state, route selection, close and h1 focus; +- skip-link target and named navigation/main regions; +- light/dark and English/Bokmål at 1440px and 390px, retaining P5-00 checks at 320/767/768/900/1023/1024px; +- axe WCAG A/AA scans for the loaded grouped navigation and mobile dialog. + +The first browser run found a serious list-structure violation: a secondary `