Skip to content

feat(#288, #302): Dashboard v1 phase 6 — direct + full-screen viewing (one-time IndexedDB handoff) + File-menu restructure#306

Merged
BorisTyshkevich merged 2 commits into
mainfrom
feat/dashboard-viewing-288
Jul 18, 2026
Merged

feat(#288, #302): Dashboard v1 phase 6 — direct + full-screen viewing (one-time IndexedDB handoff) + File-menu restructure#306
BorisTyshkevich merged 2 commits into
mainfrom
feat/dashboard-viewing-288

Conversation

@BorisTyshkevich

Copy link
Copy Markdown
Collaborator

What & why

Dashboard v1 Phase 6 — direct + full-screen viewing with a one-time IndexedDB handoff (#288, the final phase of #280), landed together with the File-menu restructure (#302). Also closes the "open in its own window" half of #153.

Owner-refined two-mode model (recorded in ADR-0003):

Edit mode View mode
Entry Workbench header Dashboard → (new tab) Dashboard page File → "Open for viewing…" (new tab)
Source current-workspace?ws=&dash= detached snapshot of the current dashboard
Storage shared primary workspace store its own detached store, fresh id
Editable yes (reorder/relayout persist) read-only
Survives relogin/reload yes yes (own persisted record)

Highlights:

  • DashboardOpenSource route contract parsed as query params on /dashboard (?ws=&dash= edit, ?st=&dash= one-time view handoff) — pathname stays /dashboard so configBase/isDashboardRoute/OAuth-redirect are untouched and the params survive the OAuth strip. The token param is st, never state (that's bootstrap's OAuth CSRF value).
  • Current-workspace route verifies BOTH ids, showing Dashboard unavailable rather than silently opening a different dashboard.
  • One-time IndexedDB token handoff for view mode: the validated PortableBundleV1 snapshot is written under an unguessable 256-bit token before the tab opens, atomically consumed exactly once (get+delete in one txn), and the token stripped from the URL via history.replaceState. It materializes into a persistent detached-views store under its own id, so the view survives relogin while staying detached from later Workbench edits. sessionStorage alone is insufficient. Credential auth-handoff is unchanged (the token carries state, not credentials).
  • Move Dashboard navigation and file operations out of the Workbench File menu #302: the Workbench File menu now owns workspace/query operations only; Dashboard nav moved to the header Dashboard → control (shown only when a Dashboard exists), and Import/Export Dashboard moved to the Dashboard page's own resource-scoped File menu (which also hosts "Open for viewing…"). Import still runs the transactional planner and commits atomically; no portable-format/schema/persistence semantics change.
  • Read-only viewer path builds no Workbench/editor modules (boundary test extended to src/workspace).

New modules: dashboard/application/dashboard-open-source.ts, dashboard/application/session-bundle.ts, core/handoff-token.ts, workspace/indexeddb-handoff-store.ts, workspace/indexeddb-detached-views-store.ts (+ their type seams), all behind the injected IndexedDB/crypto seams.

Verification beyond the unit gate: the two new IndexedDB stores + the full handoff→materialize→detached-views round-trip were driven against real browser IndexedDB in Chromium and WebKit (the fake-vs-real gap that hid two transaction auto-commit bugs during development — now fixed: get+delete are issued synchronously within one active transaction).

Closes #288. Closes #302. Completes the #280 epic (6/6). Reconciled: #149 architecture note, #68 roadmap, CHANGELOG.md, and the #288/#302 issue bodies (reconciled-design banners).

Checklist

  • npm test passes (the per-file coverage gate is non-negotiable) — 3559 tests, per-file thresholds met
  • Tests added/updated in the same change as the code
  • npm run build succeeds (single-file dist/sql.html)
  • Layers kept honest: pure logic in src/core/ + src/dashboard/**, side-effects behind injected seams, DOM in src/ui/
  • No new runtime dependency
  • README / CHANGELOG.md ([Unreleased]) updated
  • Reconciled affected tracked work (roadmap Roadmap to 1.0.0 #68, issue bodies, ADR-0003/CHANGELOG, Interactive Dashboards #149 note)

🤖 Generated with Claude Code

https://claude.ai/code/session_01GLMprUnwnz4oaz3cnLRKcz

BorisTyshkevich and others added 2 commits July 18, 2026 16:42
…+ File-menu restructure

WIP checkpoint (gate green: 3559 tests, per-file coverage, build OK).

- DashboardOpenSource contract + ?ws/?dash/?st route parsing (never ?state)
- one-time IndexedDB token handoff store + persistent detached-views store
- session-bundle glue (build/materialize/mode-resolve), viewer edit/view/not-found
- Dashboard header File menu (import/export/open-for-viewing); workbench header
  Dashboard→ nav; Dashboard section removed from the Workbench File menu (#302)
- ADR-0003; boundary test extended to src/workspace

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GLMprUnwnz4oaz3cnLRKcz
…p) + CHANGELOG

- openDashboardForViewing: skip the token write + handoff grant when the popup is
  blocked (openWindow → null), so a blocked "Open for viewing" leaves no
  un-consumable (up-to-10MB) IndexedDB record; toast to allow pop-ups instead.
- CHANGELOG [Unreleased]: Phase 6 viewing + #302 File-menu restructure.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GLMprUnwnz4oaz3cnLRKcz
@BorisTyshkevich
BorisTyshkevich merged commit 5693391 into main Jul 18, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant