Skip to content

feat: reset filters in worksheets and block captions - #690

Merged
dmitriy-kostianetskiy merged 10 commits into
mainfrom
feat/reset-filters-button
Jun 5, 2026
Merged

dmitriy-kostianetskiy merged 10 commits into
mainfrom
feat/reset-filters-button

Conversation

@dmitriy-kostianetskiy

@dmitriy-kostianetskiy dmitriy-kostianetskiy commented Jun 4, 2026 •

Copy link
Copy Markdown
Collaborator

Summary by CodeRabbit

  • New Features

    • Dashboard-wide and per-panel "Reset filters" controls with contextual enable/disable, tooltips, and header actions
    • Editable dashboard titles and editable chart/data-table captions
    • More stable data-table explorer behavior to keep non-empty results visible during live interactions
  • UI Improvements

    • Unified Combobox component replaces assorted Selects for consistent selection UX
    • Icon-style reset buttons, reordered toolbar layout, and clearer header controls
  • Documentation

    • Added guides for Reset Filters and the Combobox component

@coderabbitai

coderabbitai Bot commented Jun 4, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: c7ccfd8d-c66d-4817-873f-ddfd6f83545d

📥 Commits

Reviewing files that changed from the base of the PR and between f65f3c7 and 73ab413.

📒 Files selected for processing (4)
  • packages/mosaic/README.md
  • packages/mosaic/src/dashboard/MosaicDashboardSlice.ts
  • packages/mosaic/src/dashboard/hooks/usePanelResetFilters.ts
  • packages/mosaic/src/useVgPlotChartRender.ts
✅ Files skipped from review due to trivial changes (2)
  • packages/mosaic/README.md
  • packages/mosaic/src/useVgPlotChartRender.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • packages/mosaic/src/dashboard/MosaicDashboardSlice.ts
  • packages/mosaic/src/dashboard/hooks/usePanelResetFilters.ts

📝 Walkthrough

Walkthrough

Adds panel- and dashboard-scoped filter-reset hooks and UI, refactors chart spec creators to take a CreateSpecOptions object (including selectionName), threads dashboard/panel context and client registration into chart rendering, decomposes the data-table-explorer into focused hooks and lifecycle wiring, introduces a Popover-based Combobox and migrates selectors, and applies UI/typing polish.

Changes

Main cohort

Layer / File(s) Summary
Combined checkpoint (review full change set)
*
All modifications: dashboard runtime/client registration and reset hooks/components, chart spec API changes and chart↔dashboard wiring, data-table-explorer modularization (store, lifecycles, selection, queries, status, visible page, clients), Combobox component and selector migrations, and miscellaneous typing/UI tweaks.

Estimated code review effort:
🎯 4 (Complex) | ⏱️ ~60 minutes

  • Possibly related PRs

    • sqlrooms/sqlrooms#637: Modifies histogram spec implementation—overlaps with this PR’s histogram/spec refactor.
    • sqlrooms/sqlrooms#673: Prior chart rendering/context refactor; this PR extends that flow to thread selectionName and dashboard/panel context.
    • sqlrooms/sqlrooms#651: Prior edits to DashboardArtifact and related dashboard AI/session wiring touching the same UI component.
  • Suggested reviewers

    • ilyabo

"🐰
I hopped through hooks and buttons bright,
I tied the charts to panels tight,
Specs take options now with names,
Explorers split and combobox claims,
Hooray — the dashboard feels just right!"

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 48.72% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: reset filters in worksheets and block captions' directly aligns with the main changes: adding reset filter functionality across dashboard panels, worksheets, and editable block captions.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/reset-filters-button

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (2)
packages/deck/src/dashboard.tsx (1)

129-130: ⚡ Quick win

Stabilize clients array to avoid unnecessary effect re-runs.

The inline array creation (client ? [client] : []) produces a new reference on every render, causing usePanelClientRegistration's effect to re-run and unregister/re-register the client repeatedly. While the registration operations are idempotent, this is wasteful.

⚡ Proposed fix to memoize the clients array
+ const panelClients = useMemo(() => client ? [client] : [], [client]);
  // Register client for panel reset button
- usePanelClientRegistration(dashboard.id, panel.id, client ? [client] : []);
+ usePanelClientRegistration(dashboard.id, panel.id, panelClients);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/deck/src/dashboard.tsx` around lines 129 - 130, The clients array
passed to usePanelClientRegistration is recreated each render causing its effect
to re-run; fix by memoizing the array before calling usePanelClientRegistration
(e.g. create a stable "clients" value derived from "client" using useMemo or a
ref) and pass that memoized "clients" into
usePanelClientRegistration(dashboard.id, panel.id, clients) so the reference
only changes when "client" actually changes.
packages/mosaic/src/dashboard/MosaicDashboardSlice.ts (1)

983-1007: 💤 Low value

Consider consolidating state updates for efficiency.

The removePanel method performs three separate state updates: deleting the panel clients entry, evicting panel runtime, and removing the panel from config. While this is functionally correct, combining these into a single state update would reduce intermediate renders and improve performance.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/mosaic/src/dashboard/MosaicDashboardSlice.ts` around lines 983 -
1007, The code does three separate state updates in removePanel—deleting
mosaicDashboard.runtime.panelClients[key], calling
get().mosaicDashboard.evictPanelRuntime(dashboardId, panelId), and updating the
dashboards config (dashboard.panels, dashboard.layout, dashboard.updatedAt);
consolidate the two direct state mutations into a single set(produce(...)) call
to avoid intermediate renders by: build one produce block that deletes
state.mosaicDashboard.runtime.panelClients[getMosaicDashboardPanelId(dashboardId,
panelId)] and updates the corresponding dashboard (filter panels, call
removePanelFromLayout, set updatedAt) in the same draft, and keep
get().mosaicDashboard.evictPanelRuntime(dashboardId, panelId) as an external
side-effect call (before or after the combined set) so runtime eviction still
runs but state mutations happen atomically.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/mosaic/src/dashboard/toolbar/MosaicDashboardAddPanelDropdown.tsx`:
- Around line 30-36: The icon-only add-panel Button in
MosaicDashboardAddPanelDropdown.tsx lacks an accessible name; update the Button
(the one rendering <Plus /> inside) to provide an explicit accessible label
(e.g., add aria-label="Add panel" or aria-label based on localized text) or hook
it to a visually hidden text/aria-labelledby so assistive tech can announce it;
ensure the label string is descriptive and, if applicable, uses existing
i18n/localization utilities in the component.

In
`@packages/mosaic/src/data-table-explorer/dashboard/MosaicDashboardDataTableExplorerPanelRenderer.tsx`:
- Around line 31-35: The code calls useDataTableExplorer with a non-null
asserted selectedTable (selectedTable!) which can be undefined; change the call
to pass selectedTable (no !) so tableName can be undefined, and update the hook
useDataTableExplorer (and downstream helpers it uses) to accept tableName?:
string and return a safe no-op explorer state when tableName is undefined (e.g.,
empty data, loading=false, no-op selection handlers) so the component can render
safely; alternatively, if you prefer not to change the hook, move rendering of
MosaicDashboardDataTableExplorerPanelRenderer up so it is not mounted when
selectedTable is falsy, but do not use a non-null assertion inside this
component.

In
`@packages/mosaic/src/data-table-explorer/hooks/useDataTableExplorerSelection.ts`:
- Around line 53-61: The hook creates fallbackSelection eagerly causing
selection identity to change once existingSelection is registered; update
useDataTableExplorerSelection to either (A) stop creating an immediate
fallbackSelection and let selection be providedSelection ?? existingSelection ??
MosaicSelection.crossfilter() inline so the effect's getSelection call supplies
the same instance, or (B) if the store API allows, synchronously obtain/register
the selection by calling getSelection(selectionKey, 'crossfilter') during
initialization and use that returned instance as fallbackSelection—adjust
references to fallbackSelection, getSelection, existingSelection,
providedSelection, and selectionKey accordingly to ensure a stable selection
object identity across renders.

---

Nitpick comments:
In `@packages/deck/src/dashboard.tsx`:
- Around line 129-130: The clients array passed to usePanelClientRegistration is
recreated each render causing its effect to re-run; fix by memoizing the array
before calling usePanelClientRegistration (e.g. create a stable "clients" value
derived from "client" using useMemo or a ref) and pass that memoized "clients"
into usePanelClientRegistration(dashboard.id, panel.id, clients) so the
reference only changes when "client" actually changes.

In `@packages/mosaic/src/dashboard/MosaicDashboardSlice.ts`:
- Around line 983-1007: The code does three separate state updates in
removePanel—deleting mosaicDashboard.runtime.panelClients[key], calling
get().mosaicDashboard.evictPanelRuntime(dashboardId, panelId), and updating the
dashboards config (dashboard.panels, dashboard.layout, dashboard.updatedAt);
consolidate the two direct state mutations into a single set(produce(...)) call
to avoid intermediate renders by: build one produce block that deletes
state.mosaicDashboard.runtime.panelClients[getMosaicDashboardPanelId(dashboardId,
panelId)] and updates the corresponding dashboard (filter panels, call
removePanelFromLayout, set updatedAt) in the same draft, and keep
get().mosaicDashboard.evictPanelRuntime(dashboardId, panelId) as an external
side-effect call (before or after the combined set) so runtime eviction still
runs but state mutations happen atomically.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 7a2c4745-e8d0-43f7-89e2-607d86f27778

📥 Commits

Reviewing files that changed from the base of the PR and between ddd5a86 and c20ab90.

📒 Files selected for processing (47)
  • apps/sqlrooms-cli-ui/src/workspace/dashboard/DashboardArtifact.tsx
  • packages/deck/src/dashboard.tsx
  • packages/mosaic/src/MosaicSlice.ts
  • packages/mosaic/src/charts/MosaicChart.tsx
  • packages/mosaic/src/charts/MosaicChartView.tsx
  • packages/mosaic/src/charts/chart-types/base-types.ts
  • packages/mosaic/src/charts/chart-types/bubble-chart/spec.ts
  • packages/mosaic/src/charts/chart-types/count-plot/spec.ts
  • packages/mosaic/src/charts/chart-types/custom-spec/spec.ts
  • packages/mosaic/src/charts/chart-types/heatmap/spec.ts
  • packages/mosaic/src/charts/chart-types/histogram/spec.ts
  • packages/mosaic/src/charts/chart-types/line-chart/spec.ts
  • packages/mosaic/src/charts/dashboard/MosaicDashboardChartHeaderActions.tsx
  • packages/mosaic/src/charts/dashboard/MosaicDashboardChartRenderer.tsx
  • packages/mosaic/src/charts/useChartPanelClients.ts
  • packages/mosaic/src/charts/useMosaicChartRenderContext.ts
  • packages/mosaic/src/charts/worksheet/ChartBlockHeader.tsx
  • packages/mosaic/src/charts/worksheet/ChartBlockRenderer.tsx
  • packages/mosaic/src/dashboard/DefaultMosaicDashboardBlock.tsx
  • packages/mosaic/src/dashboard/MosaicDashboardSlice.ts
  • packages/mosaic/src/dashboard/components/ResetFiltersButton.tsx
  • packages/mosaic/src/dashboard/hooks/useDashboardResetFilters.ts
  • packages/mosaic/src/dashboard/hooks/usePanelResetFilters.ts
  • packages/mosaic/src/dashboard/toolbar/MosaicDashboardAddPanelDropdown.tsx
  • packages/mosaic/src/dashboard/toolbar/MosaicDashboardResetFiltersButton.tsx
  • packages/mosaic/src/dashboard/toolbar/MosaicDashboardToolbar.tsx
  • packages/mosaic/src/dashboard/usePanelClientRegistration.ts
  • packages/mosaic/src/dashboard/usePanelClients.ts
  • packages/mosaic/src/data-table-explorer/DataTableExplorer.tsx
  • packages/mosaic/src/data-table-explorer/DataTableExplorerCategoryClient.ts
  • packages/mosaic/src/data-table-explorer/createDataTableExplorerStore.ts
  • packages/mosaic/src/data-table-explorer/dashboard/MosaicDashboardDataTableExplorerHeaderActions.tsx
  • packages/mosaic/src/data-table-explorer/dashboard/MosaicDashboardDataTableExplorerPanelRenderer.tsx
  • packages/mosaic/src/data-table-explorer/dashboard/useDataTableExplorerPanelClients.ts
  • packages/mosaic/src/data-table-explorer/dataTableExplorerController.ts
  • packages/mosaic/src/data-table-explorer/hooks/useDataTableExplorerColumns.ts
  • packages/mosaic/src/data-table-explorer/hooks/useDataTableExplorerLifecycles.ts
  • packages/mosaic/src/data-table-explorer/hooks/useDataTableExplorerQueryState.ts
  • packages/mosaic/src/data-table-explorer/hooks/useDataTableExplorerSelection.ts
  • packages/mosaic/src/data-table-explorer/hooks/useDataTableExplorerStatus.ts
  • packages/mosaic/src/data-table-explorer/hooks/useDataTableExplorerStoreState.ts
  • packages/mosaic/src/data-table-explorer/hooks/useDataTableExplorerVisiblePage.ts
  • packages/mosaic/src/data-table-explorer/types.ts
  • packages/mosaic/src/data-table-explorer/useDataTableExplorer.ts
  • packages/mosaic/src/data-table-explorer/worksheet/DataTableBlockHeader.tsx
  • packages/mosaic/src/data-table-explorer/worksheet/DataTableBlockRenderer.tsx
  • packages/mosaic/src/index.ts
💤 Files with no reviewable changes (1)
  • packages/mosaic/src/charts/worksheet/ChartBlockRenderer.tsx

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/mosaic/src/charts/chart-settings/MosaicChartTypeSelector.tsx`:
- Around line 46-47: Selected chart type labels are optional and can render
empty spans; update the render in MosaicChartTypeSelector (the trigger span
using selectedChartType.label and the list row span using chartType.label) to
fall back to the chart id by using the nullish fallback (e.g., "?? chartType.id"
/ "?? selectedChartType.id") so the UI always shows a non-empty identifier.

In `@packages/mosaic/src/components/useCombobox.ts`:
- Around line 3-6: The generic T for UseComboboxOptions/useCombobox should be
constrained to string because selection flow (handleSelect) and
Combobox/Combobox.Item use string values; change the signature to use T extends
string (e.g. UseComboboxOptions<T extends string>) and update useCombobox's
generic accordingly so value: T and onChange: (value: T) => void are truly
string-based, then remove any unsafe casts like value as T in handleSelect and
let TypeScript enforce string types end-to-end.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 2468f9df-0b7a-4959-8e82-00ed14c9dc83

📥 Commits

Reviewing files that changed from the base of the PR and between c20ab90 and 60f9ca4.

📒 Files selected for processing (6)
  • packages/mosaic/src/charts/chart-settings/MosaicChartTypeSelector.tsx
  • packages/mosaic/src/components/AggregationSelector.tsx
  • packages/mosaic/src/components/Combobox.tsx
  • packages/mosaic/src/components/FieldSelectorInput.tsx
  • packages/mosaic/src/components/TemporalGranularitySelector.tsx
  • packages/mosaic/src/components/useCombobox.ts

Comment on lines 46 to 47
<span>{selectedChartType.label}</span>
</div>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Use an ID fallback when chart labels are missing.

label is optional for chart types, so these spans can render empty text. Add ?? chartType.id fallback in both trigger and list rows.

Suggested fix
-              <span>{selectedChartType.label}</span>
+              <span>{selectedChartType.label ?? selectedChartType.id}</span>
@@
-                <span className="truncate text-xs">{chartType.label}</span>
+                <span className="truncate text-xs">
+                  {chartType.label ?? chartType.id}
+                </span>

Also applies to: 66-66

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/mosaic/src/charts/chart-settings/MosaicChartTypeSelector.tsx` around
lines 46 - 47, Selected chart type labels are optional and can render empty
spans; update the render in MosaicChartTypeSelector (the trigger span using
selectedChartType.label and the list row span using chartType.label) to fall
back to the chart id by using the nullish fallback (e.g., "?? chartType.id" /
"?? selectedChartType.id") so the UI always shows a non-empty identifier.

Comment thread packages/mosaic/src/components/useCombobox.ts Outdated
@dmitriy-kostianetskiy
dmitriy-kostianetskiy merged commit f9f87cd into main Jun 5, 2026
4 checks passed
@dmitriy-kostianetskiy
dmitriy-kostianetskiy deleted the feat/reset-filters-button branch June 5, 2026 12:21
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