Skip to content

feat(drawer): anchored what-if becomes a right-side editor drawer over Replay - #66

Merged
obvious-autobuild[bot] merged 5 commits into
release/task-mode-ia-redesign-20261011-170103from
feat/tmia-replay-drawer
Oct 11, 2026
Merged

obvious-autobuild[bot] merged 5 commits into
release/task-mode-ia-redesign-20261011-170103from
feat/tmia-replay-drawer

Conversation

@obvious-autobuild

@obvious-autobuild obvious-autobuild Bot commented Oct 11, 2026 •

Copy link
Copy Markdown
Contributor

Why

The audit (art_FbyR4w37) traced the UI's "crowded" feel to redundant renderings and implementation-shaped grouping. On Replay, opening the anchored what-if editor replaced the shot-state cell (setWhatIf swapped the cell's children away), so the panel you were reasoning about — state, limit gauges, logbook — vanished exactly when you started editing. The toolbar mixed transport, document actions and infrastructure status in one unlabelled row, and a failed OpenUSD export surfaced only in the devtools console.

What

Replay edit drawer (spec L2). The anchored what-if editor is now a modal <dialog> drawer (420px, right side, role implied by the element, aria-modal, Esc + ✕ close with focus returned to the opening control). The state cell, limit gauges and session logbook stay visible and live underneath while you edit — gauges follow edits (verified: Troyon 0.92 → 1.01 at ×1.6 beam power). Sliders start from the measured programme, edits persist in the wi state object across close/reopen (verified: ×1.5 survives), and "Reset edits" restores the measured values. ?edit=1 on a #/replay/… deep link auto-opens the drawer. The geometry overrides the UA dialog inset/fit-content defaults explicitly (left:auto; height:auto) — without that, the drawer shrink-wraps top-left.

Toolbar regrouped into three labelled clusters. TRANSPORT (shot select, play, speed, time scrubber), SHOT ACTIONS (Edit this shot · OpenUSD · Share · Field lines · Compare…), STATUS (compute chip, load chip, transient notice chip). Share copies the current routed URL; Field lines toggles the Warp field-line traces and q95 chips; Compare… navigates to the Compare workspace via window.FusionLabRouter.navigate. The bar and cluster bodies wrap as whole units, so a tight cluster can never paint over its neighbour. All data-guide anchors (bar, shot, play, time, …) survive the move.

USD export failures surface. A failed POST /replay/{id}/usd now renders in the fallback banner ("OpenUSD export of shot #30166 failed. …") and flashes a transient chip in the status cluster, instead of console-only. Compute-fallback notices keep priority; dismissal is per-visit; recovery re-arms.

Hygiene folded in. Stored energy is MJ on every Replay surface (strip, live value, readout, compare traces, ΔW strip, lessons) — the kJ/MJ drift the audit flagged is gone; sliceState.W_kJ is unchanged (guided-study event contract, L3). The 3D panel states that magnetic-surface reconstruction is lossy (axisymmetric only) so field lines are indicative.

House style kept: ES5 IIFEs, no build step, token-only CSS (--drawer added), copy says "compared with" — never "validated"/"predictive".

Sibling PRs (lane A)

How to Review

web/replay.js carries almost the whole diff; web/style.css adds the drawer and cluster styles; web/lessons.json is label-copy only. Deliberately excluded: backend/Python, the Compare workspace itself (sibling PR), any framework or build step. Non-obvious: the drawer is anchored to #tab-replay (not the page) so it slides under the header, and renderFallback keeps its pinned name/shape for the web tests.

Acceptance criteria

  • Drawer over Replay: state cell, gauges, logbook visible and live during edits (Troyon 0.92 → 1.01 verified)
  • Esc and ✕ close; focus returns to the opening control (verified: focus → rp-whatif)
  • Edits persist across close/reopen (verified: ×1.5); reset restores measured (verified: gauge back to 0.92)
  • Entry label "Edit this shot"; sliders start from the measured programme
  • Toolbar in three labelled clusters; clusters wrap, no overlap
  • USD errors in fallback banner + status chip (screenshot shows the banner text live)
  • 3D panel lossy-reconstruction note
  • ?edit=1 auto-opens the drawer
  • data-guide anchors kept; pytest 352 passed + ruff + mypy clean; node --check clean
  • V7 lesson-1 walkthrough (see QA evidence)
  • Evidence: QA uploads via obvious autobuild upload against tested head 8035ea771e57493a8e2308cb54c4408636bbbe8b — tc-1 drawer flow (before/after screenshots + flow), tc-2 USD-error banner. Recording caveat: agent-browser record wrote sub-second stubs on every daemon this session; the flow evidence is before/after screenshots plus DOM-state assertions.

Human author: Tapan Ganatma Nakkina ([email protected])

🔗 Obvious Project · 🧵 Obvious Thread · 🔀 Obvious PR Artifact

Test Evidence

V7: guided lesson-1 walkthrough and Lab-mode ? panel help over the reworked UI
V7: guided lesson-1 walkthrough and Lab-mode ? panel help over the reworked UI — result

USD export failure surfaces in the fallback banner and status cluster, not console only
USD export failure surfaces in the fallback banner and status cluster, not console only — before
USD export failure surfaces in the fallback banner and status cluster, not console only — error

V4: drawer open-edit-close-reopen with the state cell visible and edits preserved
V4: drawer open-edit-close-reopen with the state cell visible and edits preserved — before
V4: drawer open-edit-close-reopen with the state cell visible and edits preserved — after
V4: drawer open-edit-close-reopen with the state cell visible and edits preserved — result
V4: drawer open-edit-close-reopen with the state cell visible and edits preserved — after

ObviousApp and others added 5 commits October 11, 2026 20:54
Replace the cell swap (setWhatIf hiding the state cell's children) with a
right-side <dialog> drawer (~420px, role=dialog, aria-modal): the shot state,
limit gauges and logbook underneath stay live and follow every edit, because
scrub() repaints them from the what-if result without any hiding.

- Entry: the toolbar button is now "Edit this shot" (aria-haspopup=dialog,
  aria-expanded mirrors state); Esc and the drawer's close button both close
  natively, and focus returns to the opening control (wi.opener).
- Sliders start from the measured programme (data-zero), persist across
  close/reopen (persistent DOM + memoized gate), and "Reset edits" restores.
- Gate failure opens the drawer just enough to carry a one-line error with a
  working Retry button, instead of an unopenable hidden panel.
- Drawer styling composes from the token system: --drawer token, anchored to
  #tab-replay, single-column .wi-grid inside.
- ?edit=1 now owns the drawer (workspaces.js comment); lesson 8.1 copy names
  the new label.

data-guide anchors and the window.FusionLab / fusionlab:* contracts unchanged.

Co-authored-by: Tapan Ganatma Nakkina <[email protected]>
…ons, status

The toolbar row mixed transport, document actions and infrastructure status in
one flat line (audit H1). It now reads in three labelled clusters:

- transport: shot select, play, speed, time scrubber
- shot actions: Edit this shot, OpenUSD, Share (copy this view's URL), Field
  lines (toggle — off stops line fetches and clears them from the 3D panel,
  q95 chips go quiet), Compare… (navigates to the Compare workspace)
- status: load chip, transient flash chip (role=status), compute chip

Share reproduces the current view (explicit hash routes pass through; the bare
landing builds #/replay/{id}?t=SECONDS). The 3D panel gains a visible note
that magnetic-surface reconstruction is lossy — field lines are indicative.
Also restores the drawer CSS block lost from the previous commit's style.css
(the --drawer token had survived, the rules had not). Clusters wrap as units
in the ≤1100px container query. data-guide anchors unchanged.

Co-authored-by: Tapan Ganatma Nakkina <[email protected]>
… status chip, not console only

A failed export previously did console.error and nothing else (audit
state-handling gap): the button's aria-busy was the sole signal, and only
while the request was in flight. Now renderFallback is the single painter
for the notice row — a compute fallback outranks a failed export, which
outranks the onboarding hint; one notice per grid row, with the reason
escaped. The banner takes an error severity (red edge) when it carries the
export failure; the status chip flashes wait → ok/bad through the new
role=status flash element. Dismiss is per-visit; a clean /compute or a
successful export re-arms the row. Recovery paths unchanged.

Co-authored-by: Tapan Ganatma Nakkina <[email protected]>
The W strip, its live value, the shot-state readout, the compare traces and
the ΔW difference strip all multiplied the MJ data by 1e3 and labelled it kJ,
while the catalog table and the search filters already used MJ — adjacent
surfaces flipped the scale of the same quantity (audit consistency finding).
One unit now: the arrays render directly, the ΔW difference drops the ×1e3,
and the guided-study lessons read 0.01 MJ / 0.13 MJ. The sliceState contract
field W_kJ is unchanged (guided-study surface, L3).

Also: the SHOT ACTIONS cluster could overflow its box and paint over the
status cluster when the toolbar ran tight — the bar and cluster bodies now
wrap as whole units at any width, and the time label stays on one line.

Co-authored-by: Tapan Ganatma Nakkina <[email protected]>
The UA stylesheet gives modal dialogs inset:0 and height:fit-content; with a
fixed width, LTR resolution takes the UA's left:0 over the rule's right:0 and
the fixed height defeats the top/bottom stretch — the drawer rendered as a
shrink-wrapped panel at the room's top-left instead of a 420px right sheet.
left:auto and height:auto restore the intended anchor (verified in-browser:
x=1005, w=420, h=900 at 1440x900).

Co-authored-by: Tapan Ganatma Nakkina <[email protected]>
@obvious-autobuild
obvious-autobuild Bot marked this pull request as ready for review October 11, 2026 21:47
@obvious-autobuild
obvious-autobuild Bot merged commit 65cd9a5 into release/task-mode-ia-redesign-20261011-170103 Oct 11, 2026
3 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

Development

Successfully merging this pull request may close these issues.

2 participants