17 file(s), +272 / -112 lines
| Path | Role | + | - |
|---|---|---|---|
| messages/en.json | Config | +2 | -2 |
| messages/hi.json | Config | +2 | -2 |
| src/app/[locale]/(workspace)/matters/[matterId]/filings/page.tsx | App route | +20 | -22 |
| src/app/[locale]/(workspace)/matters/[matterId]/hearings/page.tsx | App route | +18 | -23 |
| src/app/[locale]/(workspace)/matters/[matterId]/layout.tsx | App route | +34 | -0 |
| src/app/[locale]/(workspace)/matters/[matterId]/page.test.tsx | App route | +3 | -2 |
| src/app/[locale]/(workspace)/matters/[matterId]/page.tsx | App route | +7 | -5 |
| src/app/[locale]/(workspace)/matters/[matterId]/record/page.tsx | App route | +2 | -2 |
| src/components/matter-detail/matter-detail-header.tsx | Component | +3 | -1 |
| src/components/matter-detail/matter-worknav.tsx | Component | +78 | -16 |
| src/components/matters/live-matter-documents-page.tsx | Component | +13 | -15 |
| src/components/matters/matter-shell-chrome.tsx | Component | +53 | -0 |
| src/lib/agents/__tests__/client-tool-dispatcher.test.ts | Library | +4 | -4 |
| src/lib/matters/get-matter.ts | Library | +15 | -0 |
| src/lib/surface-registry/navigation.test.ts | Library | +3 | -3 |
| src/lib/surface-registry/route-registry.test.ts | Library | +1 | -1 |
| src/lib/surface-registry/route-registry.ts | Library | +14 | -14 |
The matter shell chrome — the Matter Ribbon, the Worknav, and the Matter
Action Rail — now lives once in a fat layout at
matters/[matterId]/layout.tsx. Every mode route under it
(Brief, Record, Filings, Hearings) renders only its body. Navigating
between modes swaps the body while the single chrome stays put. This
unblocks the remaining route-per-mode stories in EPIC-2018.
layout.tsx fetches the
matter once through getMatterCached (React
cache(), so the thin pages dedupe the same GET) and renders
MatterShellChrome (Ribbon + Worknav + Rail) around
{children}.
MatterBriefPage directly; Record / Filings / Hearings no
longer wrap their bodies in LiveMatterDetailPage /
MatterSubnav / CrumbTrail. The single header is
now the layout's, so the double-header regression is avoided. Bodies are
otherwise unchanged (the Record's Upload affordance moves to the head of
its body until the Ribbon/Action-Rail intake owns it in S2+).
<Link href={buildSurfacePath(...)}> (right-click /
open-in-new-tab work); the active tab is derived from
usePathname via resolveSurfaceForPath, not a
prop. The routeless modes (Inbox / Strategy / Chronology / Proof) keep
their lexicon and order and stay inert until their own routes land.
The durable surface keys move to the matter.* grammar:
matter-detail → matter.brief and
matter-detail.record → matter.record (joining the existing
matter.filings / matter.hearings). The paired
AgentSurfaces presence keys are renamed in both
messages/en.json and messages/hi.json, and
route-registry.ts was regenerated with pnpm gen:routes.
activeMode machine and LiveMatterShell /
LiveMatterDetailPage / MatterSubnav source files
are kept (no longer rendered on any matter route) — S7 owns final deletion.
pnpm lint, pnpm build, pnpm gen:routes
(no diff), pnpm check:routes, and the full
pnpm test suite (incl. route-registry.test,
navigation.test, and the matter page test) are green. The
Worknav / MatterDetailHeader Storybook stories continue to render via the
optional activeMode override.