close out the navigation audit's remaining decide-or-skip items
Jobs step deep-link: skipped, and measured first — selectedKey is plain useState, not a channel, so it breaks none of this document's rules. The only thing anchor semantics would buy is a deep link nobody asked for. Preview slug: void, there is no Preview app. FileBrowser widget: stays local, and M4 turned that shrug into a rule — only a workspace guaranteed to host one browser may own the address bar. Phases 1-4 are now closed except H4 and the New Chat button, both of which live in the chat nucleus. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
+26
-10
@@ -1,11 +1,19 @@
|
||||
# Frontend Navigation Audit — the "opaque click" anti-pattern
|
||||
|
||||
> **Status, 2026-07-31.** H1 (jobs), H2 (dashboards) and H4's groundwork are **done** — rows are real
|
||||
> `<Link>`s and selection lives in `?selected=` / `useParams`. **H3 is void: the Projects feature was
|
||||
> deleted**, so every reference to `Projects/`, `SELECTED_PROJECT` and `/projects/:id` below is historical
|
||||
> and should be read as an example of the pattern, not as work to do. **H4 (chat detail reading
|
||||
> `sessionId` from `useParams` rather than the `chat:selected-session` channel) is the one item still
|
||||
> open.** The rules in this file are current and authoritative; the findings table is a snapshot.
|
||||
> **Status, 2026-08-07. Phases 1–4 are closed except the two chat items.** Every finding H1–H5 and M1–M10
|
||||
> is done, void, or decided-and-recorded, and so is every Phase 4 line. What remains, and only this:
|
||||
> **H4** (chat detail reading `sessionId` from `useParams` instead of the `chat:selected-session` channel)
|
||||
> and the **"New Chat"** button that depends on it. Both are inside the chat nucleus, which has its own
|
||||
> owner — they are not stalled here, they are somebody else's to land.
|
||||
>
|
||||
> Three findings turned out to be wrong on inspection and are marked as such rather than quietly dropped:
|
||||
> **H3** is void (Projects was deleted, so every `Projects/`, `SELECTED_PROJECT` and `/projects/:id`
|
||||
> reference below is historical), **M7**'s "every caller inherits the opaque click" was false (it had no
|
||||
> callers, and the component is deleted), and the **Preview slug** item names an app that does not exist.
|
||||
> Two components — `Combobox` and `BackButton` — were deleted rather than fixed, having never been used.
|
||||
>
|
||||
> The rules in this file are current and authoritative; the findings table is a snapshot.
|
||||
> **Nothing below has had a runtime click-through.** Every "Needs runtime test" note is still true.
|
||||
|
||||
|
||||
**Date:** 2026-07-30 · **Origin:** written as exploration before any of the routing work was done.
|
||||
@@ -125,9 +133,17 @@ is **one design decision** that cascades across many files:
|
||||
costs no extra request. En route: the row's Focus and Close buttons were nested *inside* the row
|
||||
`<button>`, which is invalid HTML and only worked because of two `stopPropagation` calls; they are
|
||||
siblings of the anchor now. And its "Set up in Integrations" was a raw `<a href>` that reloaded the SPA.
|
||||
- **Jobs step/iteration** (`Jobs/JobDetail.tsx:234,255`) — intra-detail sub-selection; only if we want `/jobs/:id/:stepKey` deep links.
|
||||
- **Preview slug** (`Preview/PreviewApp.tsx:23`) — Preview usually derives its target from the surrounding dashboard/project `cwd`; the manual picker is a fallback. Probably leave URL-less.
|
||||
- **FileBrowser widget** (`FileBrowserWidget/.../BrowseTab.tsx:36`) — compact sidebar widget; keeping its browse cursor local is defensible.
|
||||
- **Jobs step/iteration** (`Jobs/JobDetail.tsx`) — **decided: skipped, and it is not an anti-pattern.**
|
||||
Measured rather than assumed: `selectedKey` is plain `useState` behind a context, not a channel and not a
|
||||
global, so it breaks none of the rules this document sets. What it lacks is anchor semantics, and the only
|
||||
thing that buys is a `/jobs/:id/:stepKey` deep link — a feature nobody has asked for, on keys that are
|
||||
array indexes and iteration labels. Building it is a product call, not a fix. **Owner's if he wants it.**
|
||||
- ~~**Preview slug**~~ (`Preview/PreviewApp.tsx:23`) — **void.** There is no Preview app. Nothing in the tree
|
||||
matches `PreviewApp`, and it is in no registry. It went with the Projects removal on 2026-07-30, or earlier.
|
||||
- **FileBrowser widget** (`FileBrowserWidget/.../BrowseTab.tsx`) — **decided: stays local**, and M4 turned
|
||||
the shrug into a rule. A widget sits on dashboards next to other browsers, and one shared `?path=` would
|
||||
drive all of them; only a workspace guaranteed to host exactly one browser may own the address bar, which
|
||||
is why the widget passes no `searchForPath` and its breadcrumb stays buttons. Same test, same answer.
|
||||
- **Music favorites view** — the channel is `music:favorites`, not `music:fav`. **Decided: it stays a channel.**
|
||||
It is a view of the detail panel rather than a location, it survives no reload worth surviving, and the one
|
||||
case where its being off-URL shows is handled explicitly: going Home or opening a favorite closes it by hand,
|
||||
@@ -246,7 +262,7 @@ publishers means changing the chat panel, which is another agent's, so it is wri
|
||||
shape that fits none of the icon-only back controls in the app. Adopting it would have been a visual
|
||||
redesign of the Jobs header dressed up as a navigation fix, so it is deleted instead. The two sibling
|
||||
panes (`ScriptJobDetail`, `DownloadJobDetail`) were already `<Link to="/jobs">`; this was the odd one out.
|
||||
- [ ] Decide/skip: Jobs step deep-link, Preview slug, FileBrowser widget. (Browser tabs: **done** — see the LOW section. Monitor scope: **done** as M10, it was not a view toggle. Music favorites: **decided** — stays a channel, reasoning in the LOW section.)
|
||||
- [x] Decided/skipped: Jobs step deep-link (a feature, not a fix — owner's call), Preview slug (**void**: no such app), FileBrowser widget (stays local, on M4's rule). Reasoning for each in the LOW section. (Browser tabs: **done** — see the LOW section. Monitor scope: **done** as M10, it was not a view toggle. Music favorites: **decided** — stays a channel, reasoning in the LOW section.)
|
||||
|
||||
### Cross-cutting for the refactor itself
|
||||
- [ ] Standardise a URL-as-source-of-truth pattern for panel selection (replace the `usePanelChannel`/`useGlobal`
|
||||
|
||||
Reference in New Issue
Block a user