Skip to content

fix: deep-link master-detail selections (#2025)#2053

Merged
atomantic merged 5 commits into
mainfrom
claim/issue-2025
Jul 2, 2026
Merged

fix: deep-link master-detail selections (#2025)#2053
atomantic merged 5 commits into
mainfrom
claim/issue-2025

Conversation

@atomantic

Copy link
Copy Markdown
Owner

Closes #2025

What

Several master-detail views kept their selected record in useState, so a pasted URL or a reload dropped you back on an empty list — violating the repo's "ID-based deep linking for every selectable UI element" convention. This moves each selection into the URL.

View Before After
Authors selectedId state /authors/:authorId (:authorId also captures the new create sentinel — UUIDs never collide)
Music (Artists / Albums / Tracks) selectedId state per manager /music/:tab/:id (new = create)
Sharing buckets selectedId state /sharing/:section/:bucketId (auto-selects first bucket with replace when none is named)
Prompt Manager selectedStage / selectedVar state ?stage= / ?var= search params (drawer-tab style)
JIRA Reports selectedReport state ?reportApp=&reportDate= (appId+date is the stable report id)

Each: selection handlers navigate() to the id'd route; deletes/clears navigate() to the index; a stale/deleted id renders a "could not be found" fallback. Form state is hydrated from the URL selection via an effect keyed on the id, with a hydratedRef guard so a list refresh (create/update/delete) doesn't clobber the open form.

Verify-first items

  • JiraReports — confirmed reports have a stable persisted id (getJiraReport(appId, date), card key ${appId}-${date}), so it was fixed (deep-linked).
  • OpenClawexempt (documented in the component header). selectedSessionId is ephemeral runtime state, not a user-owned record: the session list is discovered from an external runtime, selection is auto-managed (preferredSessionIddefaultSession → first), and it's wired into live SSE streaming with in-flight refs.

Routes added (App.jsx)

authors/:authorId, music/:tab/:id, sharing/:section/:bucketId. Base paths were already registered in NAV_COMMANDS; no new manifest entries needed. Prompt Manager stays at /prompts (search params), so no Layout scroll-mode change.

Test plan

  • cd client && npm test -- --run285 files / 3076 tests pass (updated Authors.test.jsx to mount inside a MemoryRouter with the authors routes, since selection is now navigation-driven).
  • cd client && npm run build → clean.
  • cd client && npm run lint → no new errors/warnings on changed files (3 pre-existing warnings in the untouched MusicGenPanel.jsx).
  • Manual: pasting/reloading each id'd URL restores the selection; delete returns to the index; a bogus id shows the not-found fallback.

atomantic added 5 commits July 2, 2026 02:53
…mpt Manager) (#2025)

Move the open record into the URL for the master-detail views that kept it in
local state, so every selection is shareable, bookmarkable, reload-safe, and
reachable from ⌘K / voice / the back button:

- Authors: /authors/:authorId (:authorId also captures the `new` create sentinel)
- Music tabs: /music/:tab/:id (artists, albums, tracks)
- Sharing buckets: /sharing/:section/:bucketId
- Prompt Manager: ?stage= / ?var= search params
- JIRA Reports: ?reportApp=&reportDate= (appId+date is the stable report id)

Selection handlers navigate to the id'd route; deletes/clears navigate back to
the index; a stale/deleted id renders a not-found fallback. OpenClaw's session
picker is documented as an intentional exemption (ephemeral runtime state).

Claude-Session: https://claude.ai/code/session_016N3afFZfp7gFiXLM4LEjkp
…ds (#2025)

Review-gate follow-ups:
- Sharing: distinguish "no bucket selected" from a stale/removed bucketId with an
  explicit "could not be found" fallback (matches the other master-detail views).
- JiraReports: clear selectedReport when the URL-named report fails to resolve
  (deleted / bad deep link) instead of stranding the previously-open report.

Claude-Session: https://claude.ai/code/session_016N3afFZfp7gFiXLM4LEjkp
#2025)

Codex review: record selection in Prompt Manager (?stage/?var) and JIRA Reports
(?reportApp/?reportDate) used history-replace, so the back button skipped past
prior selections — inconsistent with Authors/Music/Sharing (which push). Selection
is now a push; the tab toggle and auto-select canonicalization keep replace.

Claude-Session: https://claude.ai/code/session_016N3afFZfp7gFiXLM4LEjkp
Claude review: the hydration effect's idle/not-found branch skipped
clearGeneration()/setConfirmDelete() (and resetTrackViewState for tracks), so
navigating from an editing record to the index or a stale id could let a stray
render land on the prior record. Restructured all four effects (Authors, Artists,
Albums, Tracks) to run the resets for every selection change via a normalized
selectionKey guard.

Claude-Session: https://claude.ai/code/session_016N3afFZfp7gFiXLM4LEjkp
@atomantic atomantic merged commit 445a93e into main Jul 2, 2026
2 checks passed
@atomantic atomantic deleted the claim/issue-2025 branch July 2, 2026 14:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Deep-link master-detail selections: Authors, Music managers, Sharing bucket, Prompt Manager

1 participant