feat(dashboards): move tile editor to a drawer with docked settings panel - #2721
feat(dashboards): move tile editor to a drawer with docked settings panel#2721elizabetdev wants to merge 16 commits into
Conversation
…anel Convert the dashboard tile create/edit modal into a right-side drawer. Display Settings (and the heatmap variant) now dock as a full-height side panel beside the editor/preview instead of stacking a second drawer, so the tile stays visible while its options change and a single Esc closes only the panel. The display-type tabs sit in a full-width bar above the editor+panel row so they never wrap, and switching to a tab without settings (Search / Patterns / Markdown) or the other variant closes the non-applicable panel. Co-authored-by: Cursor <cursoragent@cursor.com>
🦋 Changeset detectedLatest commit: 0413fc1 The changes in this PR will be included in the next version bump. This PR includes changesets to release 3 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
🔴 Tier 4 — CriticalTouches auth, data models, config, tasks, OTel pipeline, ClickHouse, or CI/CD. Why this tier:
Review process: Deep review from a domain expert. Synchronous walkthrough may be required. Stats
|
Greptile SummaryMoves dashboard tile editing into a right-side drawer with docked display and heatmap settings panels.
Confidence Score: 5/5The PR appears safe to merge. No blocking failure remains within the scope of the previous Escape-handling threads.
|
| Filename | Overview |
|---|---|
| packages/app/src/DBDashboardPage.tsx | Replaces the tile editor modal with a drawer and coordinates its Escape behavior with docked settings panels. |
| packages/app/src/components/DBEditTimeChartForm/EditTimeChartForm.tsx | Adds the docked settings layout, panel lifecycle handling, and nested-overlay-aware Escape behavior; no additional eligible blocking failure was identified. |
| packages/app/src/components/ChartDisplaySettingsDrawer.tsx | Adds in-place panel rendering and resets abandoned edits when the settings form is reopened. |
| packages/app/src/components/HeatmapSettingsDrawer.tsx | Adds opt-in docked-panel rendering while retaining the existing overlay-drawer behavior elsewhere. |
| packages/app/src/components/SettingsSidePanel.tsx | Introduces the shared full-height shell for docked settings content. |
Reviews (13): Last reviewed commit: "fix(dashboards): drive number format E2E..." | Re-trigger Greptile
E2E Test Results✅ All tests passed • 242 passed • 1 skipped • 783s
Tests ran across 4 shards in parallel. |
|
<!-- deep-review --> Deep Review🔴 P0/P1 -- must fix
🟡 P2 -- recommended
🔵 P3 nitpicks (4)
Reviewers (9): correctness, adversarial, testing, maintainability, project-standards, kieran-typescript, julik-frontend-races, agent-native, learnings-researcher. Testing gaps:
Note: |
The dashboard tile editor was converted from a Modal to a Drawer, with Display Settings now rendered as a docked side panel instead of a nested Drawer. Update the shared ChartEditorComponent page object to match: - Preview table helpers now target .mantine-Drawer-body instead of .mantine-Modal-body - Display Settings helpers match either the dashboard side panel (data-testid) or the Chart Explorer drawer (role=dialog) so both contexts work Co-authored-by: Cursor <cursoragent@cursor.com>
setGroupByColumnsOnLeft still targeted the Display Settings dialog directly, which times out in the dashboard where Display Settings is now a docked side panel. Route it through the shared displaySettingsContainer locator so it matches either the panel or the drawer. Co-authored-by: Cursor <cursoragent@cursor.com>
…p swallowing nested Esc The tile editor's Esc interceptor and tab-change cleanup close the settings panels via the bare useDisclosure close(), bypassing each child's handleClose reset. Abandoned sub-form edits therefore stayed latched and were written into the tile config by the next Apply. Reset the sub-form on the closed→open transition in both ChartDisplaySettingsDrawer and HeatmapSettingsDrawer so every dismiss path behaves like cancel. Also stop the capture-phase Esc handler from calling stopPropagation on every Escape: bail out when the key originated inside a nested overlay (popover dropdown, code editor, select listbox, dialog) or was already handled, so those widgets can consume their own Esc instead of having it swallowed before they ever see it. Co-authored-by: Cursor <cursoragent@cursor.com>
The tile editor's own Drawer has role="dialog", so target.closest() matched it and the handler bailed before stopping propagation, closing the whole editor on Esc. Ignore a match that wraps the form (the containing drawer) and only bail for overlays genuinely nested inside the panel. Co-authored-by: Cursor <cursoragent@cursor.com>
Deep ReviewWhy it haltedThe review requires the PR diff as its primary input. No tool available in this session could retrieve it:
Because Why no degraded review was substituted
Findings were also not derived from the PR title or description, which are advisory context for intent only and not a substitute for reading the code. UnblockingAny one of these is sufficient to get a full review:
Reviewers (0): none dispatched — halted at scope detection before Stage 4 fan-out. Testing gaps: not assessed; requires diff access. |
…lied edits Disable the tile Drawer's Esc-to-close while a settings panel is docked and let the panel own Esc, so Esc closes only the panel — even from inside the code editor — instead of dismissing the whole tile editor. Also edge-trigger the display-settings reset on the closed->open transition (via a ref) rather than on appliedDefaults identity, so editing a series in the main form no longer wipes the panel's unapplied edits and dirty state. Co-authored-by: Cursor <cursoragent@cursor.com>
Ref identifiers must end in "Ref"; the unsuffixed name added one warning that tripped the app package's max-warnings cap and failed CI lint. Co-authored-by: Cursor <cursoragent@cursor.com>
…anel A Mantine Select keeps DOM focus on its input via aria-activedescendant, so neither [role="listbox"] nor .mantine-Popover-dropdown matches the Esc target and the whole panel closed instead of the open dropdown. Also bail when the target is inside an expanded combobox ([aria-expanded="true"]). Co-authored-by: Cursor <cursoragent@cursor.com>
…column Cap the panel at min(340px, 45%) so it yields on narrow viewports inside the 90% tile drawer, and give the editor column a 320px minWidth floor when a panel can dock beside it (kept at 0 on Chart Explorer). Co-authored-by: Cursor <cursoragent@cursor.com>
Dropped the blanket .cm-editor exemption from the settings-panel Esc handler. CodeMirror only calls preventDefault when it actually consumes Esc (e.g. closing an open autocomplete), which the defaultPrevented guard already handles; exempting it wholesale left Esc doing nothing — and the panel open — whenever a SQL editor was focused without a completion showing. Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
…close the panel Native <select> exposes no open/closed state to JS, so the docked settings panel's window-level Escape handler could not tell whether Esc dismissed the select popup or should close the panel. Chrome/Safari fire no keydown while a native select popup is open (so the panel stayed open) but Firefox/IE do (so the panel closed, discarding unapplied settings); exempting native <select> wholesale then broke closing the panel when a closed select had focus. Convert the number-format controls to Mantine Select, whose open state is visible via aria-expanded/role="listbox" (already matched by the handler) and which does not swallow Esc when closed, and drop the native-select exemption. Co-authored-by: Cursor <cursoragent@cursor.com>
- Remove now-unused no-unsafe-type-assertion eslint-disable in NumberFormat (Mantine Select's onChange value no longer trips the rule), which had pushed app warnings to 741 over the --max-warnings 740 lint budget. - Update ChartDisplaySettingsDrawer test to drive the output format via the Mantine combobox (click + option) instead of native selectOptions, and mock HTMLElement.prototype.scrollIntoView as the other Combobox tests do. Co-authored-by: Cursor <cursoragent@cursor.com>
The chart-wide/per-series number format E2E helper still used the native
selectOption API against getByLabel('Output format'), which now resolves to
both the Mantine Select input and its listbox (strict-mode violation). Open the
combobox and click the option, matching the pattern used by the other Select
helpers in this component.
Co-authored-by: Cursor <cursoragent@cursor.com>
Summary
Moves dashboard tile creation/editing from a centered modal into a right-side drawer, and reworks Display Settings so it no longer stacks a second drawer on top of the editor.
Closes HDX-4897
Why
Previously the tile editor was a
Modaland Display Settings opened as a separateDraweron top of it. With two stacked overlays, a single Esc press closed both at once, and the nested drawer-on-drawer felt wrong. This makes the editor a single drawer with settings docked inside it.What changed
EditTileModalis nowEditTileDrawer(right-side,90%, full-height flex body). Unsaved-changes confirm, z-index/ZIndexContext, andIsolatedChartSyncProviderbehavior are preserved.HeatmapSettingsDrawer) uses the same docked panel via a new sharedSettingsSidePanelshell. Its use on the Search page (DBSearchHeatmapChart) is unchanged (still a Drawer,asPanelis opt-in).border-leftmeets the tab underline cleanly (semantic--color-bordertoken).isDashboardForm; there the editor still uses the overlay Drawer.Screenshots
Before
After
Testing
make ci-lintequivalent:yarn lint:fix+yarn tsc --noEmitclean.ChartDisplaySettingsDrawer,DBSearchHeatmapChart,DBEditTimeChartFormsuites pass.Changeset
.changeset/tile-editor-drawer.md—@hyperdx/apppatch.Made with Cursor