feat: redesign notebook cell toolbar with view toggles and auto-refresh intervals#581
feat: redesign notebook cell toolbar with view toggles and auto-refresh intervals#581emrberk wants to merge 11 commits into
Conversation
…intervals, and cell names Rework the notebook cell header into a width-aware tiered toolbar (compact / standard / expanded) with table/chart view toggles, and let users switch a cell between grid and chart without re-querying — the result is mirrored across views. - Add fixed auto-refresh intervals (1s/5s/10s/30s/1m) alongside adaptive polling - Move the chart title to a cell-level name (inline rename), with a load-time migration from the legacy chartConfig.name - Add MCP bridge version-mismatch detection (major blocks, minor warns) with upgrade/setup command prompts in the pairing UI - Share dropdown/context menu styles and add the dropdown theme tokens Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- migrate auto-refresh interval picker to Radix RadioGroup/RadioItem - refresh path re-runs the whole cell, ignoring stray editor selection - hide chart-only commands when a compact chart is collapsed to SQL - gate persisted snapshot hydration through resultMatchesQueries Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…nt duplicate network request
Code Review — PR #581feat: redesign notebook cell toolbar with view toggles and auto-refresh intervals Reviewed at level 3 (all 13 review agents + Agent 13 fresh-context adversarial + per-finding verification + full quality gate). Quality gate — all green: Issues#1 — Grid⇄chart transfer & poll orchestration is untested; no notebook e2e
#2 — No cancel affordance for a running query in the compact tier
#3 — Transient: draw-cell first paint drops the loading spinner; toggle shows active state mid-hydration
#4 — Grid mirror loses the real error message and can diverge from a real run
#5 — Accessibility gaps in the new toolbar / version-mismatch UI
#6 — Auto-refresh submenu trigger lacks a leading icon (menu misalignment)
#7 — Minor code-quality: redundant
|
| Category | Reported issue | Why it's not a bug |
|---|---|---|
| Query execution & data integrity | resultsEquivalent O(1) fast-path could suppress a needed chart update (show stale data) |
The new fast-path block only ever does early return false (force-update); it never returns true or skips the authoritative O(rows×cols) walk. It can only make updates more frequent. Verified in drawCanvasUtils.ts:85-104. |
| Query execution & data integrity | resultMatchesQueries could transfer stale (edited-but-not-rerun) SQL data into the chart |
It rejects on per-statement normalizeQueryText mismatch and count mismatch, and the transfer pipes through successResults (DQL-with-rows only). Stale/error/empty frames yield [] → falls back to fetch. |
| React correctness / Async | Cmd/Ctrl+Enter could run twice (window listener + Monaco action) | Mutually exclusive: the window handler bails when editorContainerRef.current?.contains(document.activeElement), true exactly when Monaco's own keybinding fires. Only the single focused/maximized cell registers a window listener. |
| State & context / Performance | mirrorCellResult persists / leaks chart data into saved notebook state |
It uses hydrateCells (non-persisting by design), and stripCellResults strips result from the persist payload anyway. No churn, no leak. |
| Async, timers & cancellation | Double fetchAll on mount via the stale pollEnabledRef read |
Only triggers when bufferId === undefined, unreachable in practice (notebook buffers always have numeric Dexie ids); on the real path an await lets the ref-sync effect run first, and the up-front abort/supersede prevents any stale-data corruption regardless. |
| Persistence & migrations | Missing migration for isChartMaximized → isViewMaximized on old persisted notebooks |
Intentional, confirmed decision — losing a maximized-view boolean is cosmetic and there is deliberately no upgrade migration. |
| State & context | CHART_ZOOM has no unmount reset (could leave useChartZoomed stuck true) |
Both consumers gate the reset-zoom control on view === "chart", only true while DrawCanvas is mounted; re-entering draw remounts and re-publishes the real isZoomed. The stale flag is always masked. |
| State & context | MCPBridgeProvider / NotebookActions context values could be unstable / miss versionMismatch |
The provider useMemo deps include versionMismatch (and every field); the actions value is a stable proxy over liveActionsRef with auto-included new keys. |
| Browser compatibility & security | Major-version bridge mislabelled "minor" if it acks instead of closing 4004 | Only reachable if the bridge violates its own contract (a corrupted/misbehaving bridge). The bridge is localhost/non-adversarial and validates its own tool args, so this is not a real-world issue. |
Summary
Verdict: approve with minor follow-ups. This is a large (80-file) but well-engineered redesign — strong util extraction, proper discriminated unions, thorough unit tests for the pure logic, and a fully green quality gate. The cross-context pass confirmed every changed contract (the isChartMaximized → isViewMaximized / chartConfig.name → cell.name / autoRefresh widening / interface renames / new MCP tools) is consistent at all callsites, with no broken consumers.
- Nothing Critical or blocking. The one Moderate item is a coverage gap (wip test for error range #1: the riskiest grid⇄chart transfer/poll logic is untested and there are no notebook e2e specs). Everything else is Minor.
- Tradeoff to confirm: the shared
menuStylesconsolidation changes the menu hover-highlight from teal (tableSelection) to neutral gray (background) across all menus app-wide (schema context menu, every dropdown, help). Intended redesign — just confirm the design sign-off. - Findings: 7 verified, 9 draft findings dropped as false positives.
- In-diff vs out-of-diff: 7 in-diff, 0 out-of-diff. The zero out-of-diff count is expected here, not an underrun signal — the cross-context pass ran a wide grep sweep and
tscis clean, confirming the mechanical renames were applied exhaustively and no unchanged consumer was left reading an old contract.
Reworks the notebook cell experience and adds MCP bridge version awareness.
Cell toolbar & views
chartConfig.nameon load).MCP bridge
Internal
ctrlCmd/altOptioncentralized inutils/platform;useWidthObserversplit out ofuseContainerWidth.Adds unit tests for the new utilities (auto-refresh tokens, view/tier resolution, cell-height math, name migration, version-mismatch parsing).
Resolves:
@questdb/mcp-bridgeversion (install hint) and warn on version mismatch #573Tandem PR: questdb/mcp-bridge#1
🤖 Generated with Claude Code