2.5.8 The `[Tree ▾]` view-switcher — Tree ↔ flat sortable List (URL-driven)
Estimate: 16m · Depends on: 2.5.3, 2.5.7
Make the [Tree ▾] control in the 2.5.3 toolbar FUNCTIONAL: a real menu (Popover/Combobox) toggling between the existing Tree view and a new flat, sortable List view, per 2.5.7's design. The 2.5.3 toolbar ships the control disabled as a forward-compatible seam; this replaces that placeholder with the working switcher.
Durable shape: view + sort live in the URL (e.g. ?view=list&sort=key:asc), exactly like 2.5.4's filter params — shareable / reload-safe and the same serialization Epic 6's saved views will persist. The Server Component reads them: view=tree (default) renders the nested TreeTable (2.5.2); view=list renders a flat table (the project's issues un-nested, sorted by the active key) reusing the same row cells. List sorting is a flat ORDER BY over the existing project read — add a flat, sorted variant of 2.5.1's read; do NOT re-nest then flatten in JS.
Scope guard. v1 = the Tree/List toggle + single-column sort with the drawn affordance. Saved / named views, multi-sort, and column show/hide config stay Epic 6 (saved views & advanced search) — not invented here (no complexity for nothing).
Acceptance criteria
- The
[Tree ▾]control opens a menu with Tree (default) + List; choosing one switches the view and reflects the choice in the URL (?view=), reload-/share-safe. - List renders the project's issues FLAT, sorted by the active column; clicking a sortable header updates
?sort=(asc/desc) with the drawn active-sort indicator; default sort =keyasc. - Both views reuse the same row cells + the whole-row link to
/issues/[key]; matcheslist.mock.html(2.5.7); colours via--el-*, status viaPilltones. - 4-layer + explicit workspace gate; the flat read reuses/extends 2.5.1 (no N+1, no JS re-nesting).
- Component test (toggle view + sort updates the URL + re-queries). The Tree↔List switch + sort round-trip is driven end-to-end by the Story E2E (2.5.6), which also adds the List view to the strict shell-a11y sweep — so the sortable headers must carry
aria-sort.
Context refs
design/work-items/list.mock.html+design-notes.md(2.5.7) — the layout authority- 2.5.3
app/(authed)/issues/page.tsx+_components/IssueListToolbar(the disabled[Tree ▾]to wire) +IssueTreeTable/issueRows - 2.5.1
getProjectTree/findProjectForest(add the flat, sorted variant); 2.5.4's URL-param pattern;components/ui/Popover/Combobox motir-core/CLAUDE.md— 4-layer ·--el-*tokens