Skip to content

feat(dashboard): add column allowlist to Group By native filter - #43736

Open
eschutho wants to merge 4 commits into
masterfrom
eschutho/sc-119327/group-by-dashboard-filter-allowlist
Open

feat(dashboard): add column allowlist to Group By native filter#43736
eschutho wants to merge 4 commits into
masterfrom
eschutho/sc-119327/group-by-dashboard-filter-allowlist

Conversation

@eschutho

@eschutho eschutho commented Aug 31, 2026

Copy link
Copy Markdown
Member

SUMMARY

Dashboard builders can configure a Group By native filter (the Dynamic Group By chart customization, chart_customization_dynamic_groupby), but until now viewers could group by any groupable column of the underlying dataset. This PR lets the builder curate an allowlist of columns that viewers are allowed to group by.

Tracking: Shortcut sc-119327

What changed

  • Builder config panel (FiltersConfigForm.tsx): adds a multi-select "Groupable columns" control for the Group By filter, reusing the existing ColumnSelect in mode="multiple". The selection is the allowlist. It renders only for the Dynamic Group By customization and only once a dataset is chosen. Changing the dataset clears the allowlist so it can't hold stale, dataset-specific column names.
  • Persistence: the selection is stored in the customization's controlValues.columnsAllowlist. controlValues is already serialized with the customization, so the allowlist survives save/reload and dashboard export/import with no backend changes.
  • Viewer (GroupByFilterCard.tsx): filters the offered column options through the allowlist via a small pure helper applyColumnAllowlist.
  • Backwards compatible: an unset or empty allowlist means no restriction. Existing Group By filters (which never stored an allowlist) keep offering every groupable column exactly as before.

BEFORE/AFTER SCREENSHOTS OR ANIMATED GIF

sc-119327-groupby-allowlist-demo.webm

TESTING INSTRUCTIONS

Automated (frontend):

cd superset-frontend
npm test -- \
  src/dashboard/components/nativeFilters/FilterBar/FilterControls/GroupByFilterCard.test.tsx \
  src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/GroupByColumnAllowlist.test.tsx \
  src/dashboard/components/nativeFilters/FiltersConfigModal/transformers/customizationTransformer.test.ts

Covers: the filtering helper (allowlist unset/empty → all columns; non-empty → only allowlisted, ignoring non-existent entries), the viewer only rendering allowlisted options (and all options when unconfigured), the config-form control rendering and reading back its persisted value, and controlValues.columnsAllowlist surviving the save transform.

Manual:

  1. On a dashboard, add a Group By native filter and pick a dataset.
  2. In its config, set "Groupable columns" to a subset of columns; save.
  3. As a viewer, confirm the Group By filter only offers that subset.
  4. Clear the selection (empty) and confirm all groupable columns are offered again (backwards-compatible default).
  5. Export the dashboard and re-import it; confirm the allowlist is preserved.

ADDITIONAL INFORMATION

  • Has associated issue:
  • Required feature flags:
  • Changes UI
  • Includes DB Migration (follow approval process in SIP-59)
    • Migration is atomic, supports rollback & is backwards-compatible
    • Confirm DB migration upgrade and downgrade tested
    • Runtime estimates and downtime expectations provided
  • Introduces new feature or API
  • Removes existing feature or API

…19327]

Let dashboard builders curate which columns viewers may group by in a
Dynamic Group By native filter (chart_customization_dynamic_groupby).

- Add a multi-select "Groupable columns" control to the filter's config
  panel (reusing ColumnSelect in mode="multiple"), stored in the
  customization's controlValues.columnsAllowlist.
- Respect the allowlist in the viewer (GroupByFilterCard): only allowed
  columns are offered. An unset or empty allowlist means no restriction,
  so existing filters behave exactly as before (backwards compatible).
- The allowlist rides along in controlValues, so it survives save/reload
  and dashboard export/import with no backend changes.
- Clear the allowlist when the builder changes the dataset to avoid
  stale, dataset-specific column entries.
- Add unit/RTL tests for the filtering helper, the viewer rendering, the
  config-form control, and controlValues persistence.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@bito-code-review

bito-code-review Bot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Code Review Agent Run #3d365c

Actionable Suggestions - 0
Additional Suggestions - 2
  • superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterControls/GroupByFilterCard.tsx - 1
    • Active selection hidden by allowlist · Line 378-381
      If a viewer has an active group-by selection and the builder later configures a `columnsAllowlist` that excludes it, `allowedColumnOptions` drops the option while `value={currentValue}` still holds it. antd Select renders nothing for a value with no matching option, so the active selection silently disappears from the control. Consider merging `currentValue` into `allowedColumnOptions`.
  • superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/GroupByColumnAllowlist.test.tsx - 1
    • Ambiguous test assertion · Line 123-123
      The read-back assertion is ambiguous: 'country' is both the persisted allowlist value (line 62) and a column in the mocked dataset (line 47). If the allowlist read-back were broken but the dataset option rendered, findByText('country') could still pass, masking the bug. Use an allowlist value absent from the dataset columns to prove the persisted value is rendered.
Review Details
  • Files reviewed - 5 · Commit Range: 2651cea..2651cea
    • superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterControls/GroupByFilterCard.test.tsx
    • superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterControls/GroupByFilterCard.tsx
    • superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FiltersConfigForm.tsx
    • superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/GroupByColumnAllowlist.test.tsx
    • superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/transformers/customizationTransformer.test.ts
  • Files skipped - 0
  • Tools
    • Whispers (Secret Scanner) - ✔︎ Successful
    • Detect-secrets (Secret Scanner) - ✔︎ Successful
    • Eslint (Linter) - ✔︎ Successful

Bito Usage Guide

Commands

Type the following command in the pull request comment and save the comment.

  • /review - Manually triggers an incremental AI Review.

  • /review full - Manually triggers a full AI Review.

  • /pause - Pauses automatic reviews on this pull request.

  • /resume - Resumes automatic reviews.

  • /resolve - Marks all Bito-posted review comments as resolved.

  • /abort - Cancels all in-progress reviews.

Refer to the documentation for additional commands.

Configuration

This repository uses Superset You can customize the agent settings here or contact your Bito workspace admin at evan@preset.io.

Documentation & Help

AI Code Review powered by Bito Logo

@codecov

codecov Bot commented Aug 31, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 80.55556% with 7 lines in your changes missing coverage. Please review.
✅ Project coverage is 79.29%. Comparing base (1f1539f) to head (b87e6ab).
⚠️ Report is 42 commits behind head on master.

Files with missing lines Patch % Lines
...onfigModal/FiltersConfigForm/FiltersConfigForm.tsx 71.42% 6 Missing ⚠️
...tersConfigModal/FiltersConfigForm/ColumnSelect.tsx 83.33% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master   #43736      +/-   ##
==========================================
+ Coverage   79.26%   79.29%   +0.02%     
==========================================
  Files        2888     2888              
  Lines      166456   166489      +33     
  Branches    38532    38544      +12     
==========================================
+ Hits       131938   132014      +76     
+ Misses      32030    31987      -43     
  Partials     2488     2488              
Flag Coverage Δ
javascript 74.80% <80.55%> (+0.06%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

…nfig [sc-119327]

Wrap the new "Groupable columns" allowlist Form.Item in the same
StyledRowContainer used by the Datasource control directly above it, so it
inherits the standard padded container (sizeUnit * 4) and its left edge lines
up with the sibling sections instead of stretching toward the panel edge.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@netlify

netlify Bot commented Sep 1, 2026

Copy link
Copy Markdown

Deploy Preview for superset-docs-preview ready!

Name Link
🔨 Latest commit 81a27a1
🔍 Latest deploy log https://app.netlify.com/projects/superset-docs-preview/deploys/6a9743a3f7e5b500081d6176
😎 Deploy Preview https://deploy-preview-43736--superset-docs-preview.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

…[sc-119327]

Seed a newly created Dynamic Group By display control's "Groupable
columns" allowlist with every groupable column of the chosen dataset, so
it defaults to "all selected" and builders deselect to restrict.

- Add an onColumnsLoaded callback to ColumnSelect that reports the exact
  column names backing the rendered options (already narrowed by
  filterValues), so the seeded default matches the available options.
- In FiltersConfigForm, seed controlValues.columnsAllowlist from that
  callback, but only when no allowlist is set yet. An existing selection,
  including a deliberately narrowed or emptied one, is never overwritten,
  so editing a configured control is untouched. Seeding does not mark the
  form changed, so editing a legacy control that never stored an
  allowlist stays a no-op unless the builder narrows the selection.
- On dataset switch, keep clearing the allowlist to undefined so the
  seeding effect re-seeds all columns of the new dataset (dropping stale,
  dataset-specific entries).
- Viewer semantics are unchanged: an unset/empty allowlist still means
  "no restriction", preserving backwards compatibility.
- Add config-form tests for the new-control seed and the no-overwrite
  edit cases; existing viewer tests already cover empty/unset = no
  restriction.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@bito-code-review

bito-code-review Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Code Review Agent Run #6f4af7

Actionable Suggestions - 0
Additional Suggestions - 1
  • superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FiltersConfigForm.tsx - 1
    • Frozen allowlist snapshot · Line 640-640
      Seeding stores an explicit snapshot of the current columns. Once set, `columnsAllowlist` is a fixed array, so columns added to the same dataset later are never included (the `!== undefined` guard skips re-seeding). The 'all columns' default silently becomes frozen to the seed-time set, changing filter behavior over time. Consider keeping `undefined` as the 'all' state and only materializing a list when the builder narrows, or re-syncing on column-set changes.
Review Details
  • Files reviewed - 3 · Commit Range: 2651cea..cfb19c9
    • superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FiltersConfigForm.tsx
    • superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/ColumnSelect.tsx
    • superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/GroupByColumnAllowlist.test.tsx
  • Files skipped - 0
  • Tools
    • Whispers (Secret Scanner) - ✔︎ Successful
    • Detect-secrets (Secret Scanner) - ✔︎ Successful

Bito Usage Guide

Commands

Type the following command in the pull request comment and save the comment.

  • /review - Manually triggers an incremental AI Review.

  • /review full - Manually triggers a full AI Review.

  • /pause - Pauses automatic reviews on this pull request.

  • /resume - Resumes automatic reviews.

  • /resolve - Marks all Bito-posted review comments as resolved.

  • /abort - Cancels all in-progress reviews.

Refer to the documentation for additional commands.

Configuration

This repository uses Superset You can customize the agent settings here or contact your Bito workspace admin at evan@preset.io.

Documentation & Help

AI Code Review powered by Bito Logo

…[sc-119327]

Relocate the "Groupable columns" control from the top Settings area (under
Datasource) into the collapsible "Display control configuration" section,
above the Sort display control values checkbox. Drop the StyledRowContainer
wrapper so it aligns with the section's other items (e.g. dependencies,
Sort type) via StyledRowFormItem. Pure reposition/restyle; the create-time
seeding, no-clobber-on-edit rule, dataset-switch re-seed, and viewer
empty=no-restriction behavior are unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@bito-code-review

bito-code-review Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Code Review Agent Run #571669

Actionable Suggestions - 0
Review Details
  • Files reviewed - 1 · Commit Range: cfb19c9..b87e6ab
    • superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FiltersConfigForm.tsx
  • Files skipped - 0
  • Tools
    • Whispers (Secret Scanner) - ✔︎ Successful
    • Detect-secrets (Secret Scanner) - ✔︎ Successful

Bito Usage Guide

Commands

Type the following command in the pull request comment and save the comment.

  • /review - Manually triggers an incremental AI Review.

  • /review full - Manually triggers a full AI Review.

  • /pause - Pauses automatic reviews on this pull request.

  • /resume - Resumes automatic reviews.

  • /resolve - Marks all Bito-posted review comments as resolved.

  • /abort - Cancels all in-progress reviews.

Refer to the documentation for additional commands.

Configuration

This repository uses Superset You can customize the agent settings here or contact your Bito workspace admin at evan@preset.io.

Documentation & Help

AI Code Review powered by Bito Logo

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant