Skip to content

Unify cell detail, rows and documentation in a foldable desktop right inspector #488

Description

@BorisTyshkevich

Depends on: #425

Coordinate with: #487 so both docked sides share one centre-width policy and shell resize lifecycle.

Goal

Replace the current collection of unrelated right-side overlays/panes with one shell-owned, foldable desktop right inspector.

The inspector is the single desktop host for contextual content such as:

  • cell detail;
  • rows/detail viewer content currently using the cell-drawer scaffold;
  • function, aggregate-function, data-type and other Reference documentation;
  • future contextual diagnostic/detail tools that genuinely belong in the same right-side surface.

On desktop, the inspector is docked beside the main Query/Dashboard surface. It consumes normal layout width and pushes the centre surface left. It must not cover the editor or Dashboard with a backdrop.

The user opens/closes it through one vertical chevron handle at its left edge. Contextual actions such as clicking a result cell or invoking Reference/F1 still open the appropriate inspector tool automatically.

Mobile keeps its existing mobile/modal presentation and is not redesigned by this issue.

Current problem

The repository already shares some low-level drawer chrome, but the user experience remains split:

  • cell detail and rows viewer compose the drawer with modal backdrop/focus behaviour;
  • documentation is a separate persistent non-modal pane;
  • cell and documentation widths are stored independently;
  • each consumer owns its own DOM insertion, lifecycle, close control and Escape handling;
  • more contextual tools would create more independent right-side panels or overlays.

The result is inconsistent on desktop and wastes ultra-wide screen space: useful contextual information covers the editor instead of living beside it.

Final desktop shell geometry

The full-width application header remains above the shell.

Below it:

[right inspector closed]
[left navigation] [main Query/Dashboard surface] [chevron handle]

[right inspector open]
[left navigation] [main Query/Dashboard surface] [chevron] [right inspector]

When #487's left focused drawer is also open:

[rail] [left focused drawer] [main surface] [chevron] [right inspector]

The inspector begins below the header and uses the complete remaining vertical height.

On desktop:

  • no inspector tool creates a backdrop;
  • no inspector tool covers the centre surface;
  • no inspector tool traps focus;
  • exactly one right inspector host exists per application shell/document;
  • only one inspector tool is visible at a time.

Fold control

Use one narrow vertical chevron handle attached to the inspector's left boundary.

States:

closed: chevron points left, meaning open
open:   chevron points right, meaning fold closed

Requirements:

  • the handle remains visible at the right edge when the inspector is closed;
  • when open, the handle moves with the inspector's left edge;
  • clicking it toggles the inspector without changing the active tool/content;
  • folding closed preserves valid tool state in memory for the session;
  • reopening restores the most recently active still-valid tool;
  • do not add separate top-bar Open inspector or Function help buttons merely to control panel visibility;
  • remove redundant per-tool X close buttons from desktop inspector chrome;
  • existing contextual triggers remain: cell click, rows action, F1/reference actions, completion/hover links, schema type-reference links and similar feature-specific entry points.

The handle must have an accessible name reflecting its state, such as Open details panel or Close details panel.

Inspector tools

Define a narrow tool registry rather than allowing each feature to append an arbitrary panel to document.body.

Suggested initial IDs:

type RightInspectorToolId =
  | 'cell'
  | 'rows'
  | 'reference';

Suggested shell-facing API:

interface OpenRightInspectorRequest<T = unknown> {
  tool: RightInspectorToolId;
  payload: T;
  initiator?: Element | null;
}

openRightInspector(request: OpenRightInspectorRequest): void;
activateRightInspectorTool(tool: RightInspectorToolId): void;
foldRightInspector(): void;
unfoldRightInspector(): void;
closeRightInspectorTool(tool: RightInspectorToolId): void;

The shell owns geometry and active-tool selection. Each tool owns only its content model, rendering and validity lifecycle.

Do not expose inspector DOM internals to result, documentation or Dashboard application code.

Tool navigation

The inspector header displays the active tool title.

When more than one valid tool currently has session content, provide compact tabs or an equivalent accessible selector:

Cell | Rows | Reference

Rules:

  • only tools with live/available content need to appear;
  • opening a new tool activates it and unfolds the inspector;
  • opening another cell replaces the current Cell content rather than creating another Cell tab;
  • opening another documentation target replaces the current Reference entry while preserving Reference's existing back stack;
  • switching tools must not destroy valid inactive tool state;
  • closing one tool activates the most recently used remaining tool;
  • if no tool remains, fold the inspector closed;
  • the fold chevron is panel-level chrome, not a tool tab.

Cell detail tool

Migrate current single-cell detail into the inspector.

Requirements:

  • clicking a supported result cell opens/unfolds the inspector and activates Cell;
  • preserve current formatting, copy and structured-value rendering behaviour;
  • identify the originating result through a stable result-generation token plus tab/query identity;
  • replacing/rerunning the originating result invalidates the Cell tool;
  • closing the originating tab invalidates it;
  • switching workspaces or signing out invalidates it;
  • stale asynchronous formatting/render work cannot repaint a newer Cell payload;
  • no modal backdrop or focus trap on desktop;
  • opening Cell does not steal editor selection unnecessarily;
  • folding/reopening preserves Cell only while its origin remains valid.

A stale cell must never continue to appear as though it belongs to the current result.

Rows/detail viewer tool

Migrate every existing rows/detail consumer that currently shares the cell-drawer chrome.

Requirements:

  • opening a rows/detail view unfolds the inspector and activates Rows;
  • preserve current table/detail rendering, paging/copy actions and result semantics;
  • tie validity to the originating result generation;
  • result replacement, tab closure, workspace switch or sign-out invalidates the tool;
  • no desktop modal backdrop;
  • one Rows tool instance per shell; a new request replaces its payload.

If a current consumer truly requires a modal decision rather than passive inspection, leave that decision dialog modal and move only its passive result/detail content into the inspector.

Reference documentation tool

Move the existing persistent documentation pane into the shared inspector host without losing its mature behaviour.

Preserve:

  • one Reference session per document/shell;
  • loading, found, missing and unavailable states;
  • Retry;
  • related/alias navigation;
  • disambiguation lists;
  • bounded back stack;
  • safe Markdown rendering;
  • embedded code-viewer lifecycle;
  • stale lookup token/generation protection;
  • existing catalog capability semantics;
  • contextual opening from F1, hover, completion, schema type-reference and future Reference actions.

Reference lifecycle differs from result-bound tools:

  • switching Query tabs does not invalidate Reference;
  • switching Query/Dashboard surfaces may preserve Reference;
  • changing workspace may preserve it only when the connection/catalog identity is unchanged and the current target remains meaningful;
  • connection change, catalog invalidation or sign-out closes/invalidates Reference and destroys embedded viewers;
  • a fresh external Reference open starts a new browsing session according to current semantics.

Reference back-stack state remains owned by the Reference tool, not the inspector shell.

Width and resizing

The inspector is resized from its left edge.

Suggested bounds:

const RIGHT_INSPECTOR_DEFAULT_PX = 480;
const RIGHT_INSPECTOR_MIN_PX = 320;
const RIGHT_INSPECTOR_MAX_VIEWPORT_RATIO = 0.55;
const MAIN_SURFACE_MIN_PX = 640;

Final clamping must account for:

The inspector must never force the main surface to negative or unusable width. When the viewport cannot fit the saved inspector width, clamp the effective width without destroying the saved preferred width.

The left-edge resize separator must support pointer and keyboard operation and use the repository's shared splitter controller.

Do not use arbitrary delayed window-resize events. Notify centre content through ResizeObserver or established explicit layout hooks.

Preference migration

Current state has separate persisted widths:

cellDrawerPx
docPanePx

Replace them with one browser preference:

rightInspectorPx

Use a deterministic compatibility read:

  1. use a valid rightInspectorPx when present;
  2. otherwise use valid docPanePx;
  3. otherwise use valid cellDrawerPx;
  4. otherwise use the default.

Write only rightInspectorPx after this feature lands. Keep legacy keys readable for the compatibility period required by repository conventions; do not write them independently again.

Inspector open/closed state and active payload are session state, not workspace persistence. Width is a browser preference and must never enter StoredWorkspaceV3, portable bundles or share links.

Suggested state

interface RightInspectorState {
  folded: boolean;
  preferredWidthPx: number;
  activeTool: RightInspectorToolId | null;
  availableTools: RightInspectorToolId[];
}

Tool payloads and lifecycle tokens remain in their tool controllers, not in one untyped shell object.

folded means hidden while valid content may remain cached. activeTool === null means there is no valid inspector content.

Surface and workspace behaviour

Query -> Dashboard

  • preserve Reference when valid;
  • invalidate or hide Cell/Rows when their result origin is no longer valid under existing result ownership;
  • never destroy the Query surface merely to show/hide the inspector;
  • resize the Dashboard layout when the inspector opens/closes.

Dashboard -> Query

  • preserve Reference;
  • restore a valid folded Cell/Rows session only when the same originating result still exists;
  • resize CodeMirror/results immediately through normal layout hooks.

Workspace switch

  • invalidate all result-bound tools;
  • clear initiators from the old shell/workspace;
  • preserve only connection-scoped Reference content when explicitly safe; otherwise close it;
  • late async callbacks from the previous workspace cannot repaint the inspector.

Sign-out / auth loss

  • invalidate every tool;
  • destroy embedded viewers/listeners;
  • cancel active resize;
  • remove/fold inspector content before showing Login;
  • late writes or lookups cannot remount it.

Escape and focus behaviour

Desktop inspector is non-modal.

  • focus is allowed to move between inspector and editor/results normally;
  • no focus trap;
  • Escape while focus is inside the inspector folds it closed;
  • that Escape must call preventDefault/stopPropagation through the existing topmost-overlay/shortcut contract so it does not also cancel a running query;
  • Escape outside the inspector follows existing global shortcut semantics;
  • folding through the chevron restores focus to the most recent connected initiator when appropriate;
  • switching tools moves focus only when initiated through keyboard navigation or required for accessibility;
  • the resize separator and chevron are keyboard reachable with visible focus.

Keyboard/accessibility

Inspector host:

role="complementary"
aria-label="Details and reference"

Tool selector:

  • proper tabs/tablist semantics when rendered as tabs;
  • active state announced;
  • unavailable tools are absent rather than disabled placeholders.

Resize separator:

role="separator"
aria-orientation="vertical"
aria-valuemin / aria-valuemax / aria-valuenow

Keys:

  • Left/Right Arrow resize by a small step;
  • Shift+Left/Right resize by a larger step;
  • Home uses minimum width;
  • End uses current maximum width.

The chevron's visible direction and accessible label must stay in sync.

Mobile

At the existing mobile breakpoint:

  • do not force the desktop docked inspector geometry;
  • retain current mobile/full-screen/modal cell and detail experiences where needed;
  • Reference may use the established mobile pane pattern;
  • reuse the same tool content/controllers when practical;
  • desktop width/fold preferences remain stored but do not control mobile layout.

This issue must not make the mobile centre surface permanently narrower.

Main-surface reflow

Opening, folding or resizing the inspector must correctly reflow:

  • CodeMirror/editor measurement;
  • result table columns and virtualised rows;
  • editor/results split layout;
  • Dashboard grids, flow layouts and charts;
  • sticky toolbars/filter bars;
  • detached or fullscreen views where applicable.

A presentation change must not cancel a running editor query or Dashboard execution.

Implementation boundaries

App shell

Owns:

  • inspector host and chevron;
  • open/fold geometry;
  • active tool selection;
  • width preference and resize separator;
  • interaction with left navigation and main minimum width;
  • high-level teardown on workspace/sign-out.

Tool controllers

Own:

  • typed payload;
  • content rendering;
  • result/catalog validity;
  • async generation tokens;
  • tool-specific back stacks/viewers/actions;
  • initiator focus restoration metadata.

Existing feature call sites

Call openRightInspector() with typed payloads. They must not append panels/backdrops directly or set shell widths.

Shared drawer module

Refactor or retire buildDrawerChrome/attachDrawerResize only as needed. Preserve reusable content/chrome helpers, but the shell becomes the owner of desktop panel geometry.

Migration plan

  1. Add shell inspector host, state, chevron and unified width preference.
  2. Move Reference into the host while preserving all tests and behaviour.
  3. Move Cell into the host and remove its desktop backdrop/focus trap.
  4. Move Rows/detail consumers.
  5. Remove obsolete independent desktop pane insertion, close buttons and width writes.
  6. Keep mobile-specific composition behind the existing breakpoint.
  7. Verify simultaneous left/right docking and both Query/Dashboard surfaces.

Do not leave two desktop inspector implementations active behind different entry points.

Tests

Shell and fold state

  • one inspector host per shell/document;
  • closed state leaves only the chevron and consumes no panel width;
  • open state reduces centre width;
  • chevron direction/label is correct;
  • folding preserves valid tool state;
  • no desktop backdrop or focus trap exists;
  • left and right docked panels coexist within centre-width limits.

Tool selection

  • opening Cell/Rows/Reference unfolds and activates it;
  • opening another payload replaces only that tool's payload;
  • switching tools preserves valid inactive state;
  • closing one activates the most recent remaining tool;
  • no valid tools folds the inspector;
  • duplicate independent panels cannot be created.

Cell and Rows validity

  • result rerun invalidates stale content;
  • result/tab/workspace removal invalidates it;
  • stale async work cannot repaint;
  • copy/format/detail behaviour remains intact;
  • desktop no longer uses a modal backdrop;
  • mobile behaviour remains intact.

Reference

  • loading/found/missing/unavailable/Retry remain;
  • back stack, aliases, related links and disambiguation remain;
  • embedded viewers are destroyed on retarget/close;
  • stale lookups are ignored;
  • surface switching preserves valid Reference;
  • sign-out/catalog invalidation tears it down.

Width and preference migration

  • rightInspectorPx restores and clamps;
  • fallback reads docPanePx, then cellDrawerPx;
  • only the unified key is written;
  • effective viewport clamping does not overwrite preferred width;
  • resize cancellation/window blur leave no listeners;
  • keyboard resizing matches pointer resizing.

Escape/focus/accessibility

  • Escape inside folds inspector only;
  • it does not also cancel a query;
  • Escape outside retains current shortcuts;
  • initiator focus restoration is safe;
  • complementary, tabs, separator and chevron semantics are correct.

Reflow and regression

  • editor/results/Dashboard resize correctly;
  • opening/folding never cancels execution;
  • Query surface state survives Dashboard round trips;
  • existing cell, rows and Reference triggers still work;
  • no detached/fullscreen regression;
  • no mobile regression.

Acceptance criteria

  • Desktop has one foldable right inspector for cell, rows/detail and Reference content.
  • The inspector is docked, consumes layout width and never overlays the desktop editor/Dashboard.
  • One chevron handle opens/folds the whole inspector; redundant desktop open/close controls are removed.
  • Contextual triggers automatically open the correct tool.
  • Result-bound tools cannot show stale content.
  • Reference retains its existing navigation and async safety.
  • Width is unified into one browser preference with deterministic migration.
  • Left navigation, Query surface and Dashboard surface all reflow correctly.
  • Mobile behaviour is unchanged.

Non-goals

  • Moving unrelated modal confirmations into the inspector.
  • Making several inspector tools visible side by side.
  • Persisting inspector payloads in workspace data.
  • Redesigning cell/reference content itself beyond required host integration.
  • Replacing detached/fullscreen views that serve a different use case.
  • Changing mobile navigation or mobile screen structure.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions