Skip to content

feat(native-filters): drive cascade dependencies from chart metadata - #43223

Merged
rusackas merged 1 commit into
apache:masterfrom
daviddallakyan2005:cascade-filter-registry
Sep 16, 2026
Merged

rusackas merged 1 commit into
apache:masterfrom
daviddallakyan2005:cascade-filter-registry

Conversation

@daviddallakyan2005

Copy link
Copy Markdown
Contributor

SUMMARY

This is the registry-only slice @rusackas asked for on #40905. The original implementation is @ashah65's — I am landing just the part that was already called clean, as a new PR rather than pushing over that branch.

Dashboard cascade used to consult a hardcoded ALLOW_DEPENDENCIES list (filter_select / filter_range / filter_time). Third-party native filters could not join cascade without a core change. This replaces that list with ChartMetadata.supportsCascadeDependencies:

  • Select, Range, and Time filters set the flag to true. Parent picker and child "Values are dependent on other filters" stay as they are today.
  • Time column and Time grain set it to false. They stay out of both gates — I did not take the feat(native-filters): make filter dependency support extensible via plugin registry #40905 child-side widening that would have shown the dependency section on those types.
  • If a plugin leaves the flag unset, we fall back to Behavior.NativeFilter so existing third-party filters keep working.

isColumnSelect, the divider change-tracking rewrite, and the ControlLabel work from #40905 are not in this PR. Those can come later if still wanted.

I do not think this needs a SIP. It is the same cascade feature, driven from plugin metadata instead of a list, and rusackas already said the core swap is clean.

Related: #40905, discussion #26084.

BEFORE/AFTER SCREENSHOTS OR ANIMATED GIF

Not applicable. Core filter UI is unchanged. Time column / time grain still do not offer the child dependency control.

TESTING INSTRUCTIONS

cd superset-frontend && npm run test -- --testPathPatterns='FiltersConfigModal|useFilterOperations|getControlItemsMap|ChartMetadata.test'

On a dashboard:

  1. Open Manage filters.
  2. Add a Value (select) filter and a Range filter. Confirm "Values are dependent on other filters" still appears for those types, and that each can be chosen as a parent of the other.
  3. Add a Time column or Time grain filter. Confirm they do not show that child control and cannot be selected as a cascade parent.
  4. Save and confirm existing select/range/time cascade still applies on the dashboard.

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

@dosubot dosubot Bot added change:frontend Requires changing the frontend dashboard:native-filters Related to the native filters of the Dashboard labels Aug 15, 2026
@bito-code-review

bito-code-review Bot commented Aug 15, 2026 •

Copy link
Copy Markdown
Contributor

Code Review Agent Run #19c4ae

Actionable Suggestions - 0
Additional Suggestions - 1
  • superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/NativeFiltersModal.test.tsx - 1
    • Unverified mock property in test · Line 44-44
      The `supportsCascadeDependencies: true` property is added to the mock at lines 44 and 53 but never asserted or verified. According to rule [6262], tests should verify the business logic they claim to test. Either add an assertion validating cascade dependency behavior (e.g., check `filterSupportsDependencies('filter_select')` returns `true`) or remove the unused mock property.
Review Details
  • Files reviewed - 13 · Commit Range: 3a344e6..3a344e6
    • superset-frontend/packages/superset-ui-core/src/chart/models/ChartMetadata.ts
    • superset-frontend/packages/superset-ui-core/test/chart/models/ChartMetadata.test.ts
    • superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FiltersConfigForm.tsx
    • superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigModal.tsx
    • superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/NativeFiltersModal.test.tsx
    • superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/hooks/index.ts
    • superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/hooks/useFilterOperations.test.ts
    • superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/hooks/useFilterOperations.ts
    • superset-frontend/src/filters/components/Range/index.ts
    • superset-frontend/src/filters/components/Select/index.ts
    • superset-frontend/src/filters/components/Time/index.ts
    • superset-frontend/src/filters/components/TimeColumn/index.ts
    • superset-frontend/src/filters/components/TimeGrain/index.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 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

component &&
'filterType' in component &&
ALLOW_DEPENDENCIES.includes(component.filterType)
filterSupportsDependencies(component.filterType)

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.

Suggestion: Changing a filter to a type whose metadata sets supportsCascadeDependencies to false only prevents it from appearing in newly computed available-parent options; existing child dependencies are still retained by the form and consumed by buildDependencyMap and the dependency preview until the modal is saved. This leaves an unsupported parent actively affecting other filters while the modal remains open, and cancelling the modal can preserve the stale in-memory relationship. Remove or filter existing dependency edges as soon as the parent capability changes, rather than only relying on save-time cleanup. [stale reference]

Severity Level: Minor 🧹
- ⚠️ Filter previews can temporarily use unsupported cascade parents.
- ⚠️ Unmounted child forms retain stale dependency IDs until save.
- ⚠️ Save-time cleanup prevents persisted invalid relationships.
- ⚠️ Cancel resets form state, so cancellation does not preserve them.

Fix in Cursor Fix in VSCode Claude

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/hooks/useFilterOperations.ts
**Line:** 173:173
**Comment:**
	*Stale Reference: Changing a filter to a type whose metadata sets `supportsCascadeDependencies` to `false` only prevents it from appearing in newly computed available-parent options; existing child dependencies are still retained by the form and consumed by `buildDependencyMap` and the dependency preview until the modal is saved. This leaves an unsupported parent actively affecting other filters while the modal remains open, and cancelling the modal can preserve the stale in-memory relationship. Remove or filter existing dependency edges as soon as the parent capability changes, rather than only relying on save-time cleanup.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
👍 | 👎

@bito-code-review

Copy link
Copy Markdown
Contributor

The reviewer's suggestion is valid. The current implementation only prevents unsupported filters from appearing in the available parent options, but it does not actively remove existing dependency edges if a filter's capability changes while the modal is open. To resolve this, you should update the filter operations to explicitly prune dependencies when a filter's supportsCascadeDependencies status changes.

I have analyzed the PR and confirmed that the issue is correct. Would you like me to fetch all other comments on this PR to validate them and implement a minimal fix for all of them?

Comment on lines +475 to 477
const canDependOnOtherFilters = filterSupportsDependencies(
formFilter?.filterType,
);

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.

Suggestion: The dependency gate uses formFilter?.filterType directly, unlike the rest of this form which uses itemTypeField to fall back to filterToEdit?.filterType or the default filter_select while form values are not initialized. On the initial render after opening an existing filter or creating a new one, formFilter?.filterType can be undefined, so the dependency editor is hidden even though the active filter type supports cascade dependencies. Pass itemTypeField to keep this gate consistent with the effective filter type used by the surrounding rendering logic. [incorrect variable usage]

Severity Level: Major ⚠️
- ❌ Cascade dependency editor can disappear initially.
- ⚠️ Existing filters may require a form change before appearing.
- ⚠️ New select filters initially omit dependency configuration.

Fix in Cursor Fix in VSCode Claude

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FiltersConfigForm.tsx
**Line:** 475:477
**Comment:**
	*Incorrect Variable Usage: The dependency gate uses `formFilter?.filterType` directly, unlike the rest of this form which uses `itemTypeField` to fall back to `filterToEdit?.filterType` or the default `filter_select` while form values are not initialized. On the initial render after opening an existing filter or creating a new one, `formFilter?.filterType` can be undefined, so the dependency editor is hidden even though the active filter type supports cascade dependencies. Pass `itemTypeField` to keep this gate consistent with the effective filter type used by the surrounding rendering logic.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
👍 | 👎

@codecov

codecov Bot commented Aug 15, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 66.63%. Comparing base (936f073) to head (5d42976).
⚠️ Report is 678 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master   #43223      +/-   ##
==========================================
- Coverage   66.63%   66.63%   -0.01%     
==========================================
  Files        2874     2874              
  Lines      163887   163894       +7     
  Branches    37816    37819       +3     
==========================================
+ Hits       109209   109210       +1     
- Misses      52535    52541       +6     
  Partials     2143     2143              
Flag Coverage Δ
javascript 73.78% <100.00%> (-0.01%) ⬇️

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.

@netlify

netlify Bot commented Aug 18, 2026 •

Copy link
Copy Markdown

✅ Deploy Preview for superset-docs-preview ready!

Name Link
🔨 Latest commit 5d42976
🔍 Latest deploy log https://app.netlify.com/projects/superset-docs-preview/deploys/6a8446964cada60008ad8225
😎 Deploy Preview https://deploy-preview-43223--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.

@daviddallakyan2005

Copy link
Copy Markdown
Contributor Author

@ashah65 @rusackas This is the registry-only follow-up to #40905. Original implementation is ashah65's. I split out the riders and kept Time column / Time grain out of the child gate.

#40905 stays open. Happy to close this if you would rather land the split on that branch instead.

Replace the hardcoded ALLOW_DEPENDENCIES list with
ChartMetadata.supportsCascadeDependencies so plugin filters can opt into
dashboard cascade without a core allowlist change. Core select, range,
and time filters keep the same parent and child gate; time grain and
time column stay opted out.

Co-authored-by: ashah65 <137852504+ashah65@users.noreply.github.com>
@bito-code-review

bito-code-review Bot commented Aug 18, 2026 •

Copy link
Copy Markdown
Contributor

Code Review Agent Run #4f98f6

Actionable Suggestions - 0
Additional Suggestions - 1
  • superset-frontend/packages/superset-ui-core/test/chart/models/ChartMetadata.test.ts - 1
    • Incomplete clone preservation test · Line 73-92
      The clone() assertion only tests the `optedOut` (false) case. Missing assertions for `unset` (undefined→undefined) and `optedIn` (true→true) mean a regression where clone() incorrectly defaults unset values to false would go undetected.
Filtered by Review Rules

Bito filtered these suggestions based on rules created automatically for your feedback. Manage rules.

  • superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/hooks/useFilterOperations.test.ts - 1
Review Details
  • Files reviewed - 13 · Commit Range: 5d42976..5d42976
    • superset-frontend/packages/superset-ui-core/src/chart/models/ChartMetadata.ts
    • superset-frontend/packages/superset-ui-core/test/chart/models/ChartMetadata.test.ts
    • superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FiltersConfigForm.tsx
    • superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigModal.tsx
    • superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/NativeFiltersModal.test.tsx
    • superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/hooks/index.ts
    • superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/hooks/useFilterOperations.test.ts
    • superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/hooks/useFilterOperations.ts
    • superset-frontend/src/filters/components/Range/index.ts
    • superset-frontend/src/filters/components/Select/index.ts
    • superset-frontend/src/filters/components/Time/index.ts
    • superset-frontend/src/filters/components/TimeColumn/index.ts
    • superset-frontend/src/filters/components/TimeGrain/index.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 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

@rusackas rusackas left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is exactly the split I hoped to see for #40905. Glad to see the registry-driven swap land on its own without the extra riders. Nice work landing just the clean part.

@rusackas
rusackas merged commit 461fdaa into apache:master Sep 16, 2026
80 checks passed
rusackas added a commit that referenced this pull request Sep 28, 2026
…ilter type

Follow-up to #43223. Two bot review comments on that PR were never
addressed before merge:

- FiltersConfigForm.tsx: canDependOnOtherFilters read
  formFilter?.filterType directly, unlike itemTypeField's own fallback
  chain (formFilter?.filterType || filterToEdit?.filterType ||
  'filter_select') used everywhere else in this component.
  formFilter?.filterType can be undefined on the first render before
  the antd Form hydrates, which hid the "Values are dependent on other
  filters" section even for filter types that do support cascading.

- useFilterOperations.ts: buildDependencyMap read each filter's
  dependencies array as-is, without re-checking that a listed parent
  still supports cascading. If a parent's type changes to one that no
  longer supports dependencies within the same open-modal editing
  session, the stale relationship lingered in the live dependency map
  and preview until save. Now filters each parent id through the
  existing canBeUsedAsDependency check on every rebuild.

Added regression tests for the buildDependencyMap fix (confirmed they
fail against the pre-fix code). Did not add a FiltersConfigForm.tsx-level
test for the itemTypeField fix - no existing test harness covers this
component at that level (matches #43223's own testing approach, which
relied on manual QA there and unit tests only for the hooks).

Co-Authored-By: Evan Rusackas <evan@preset.io>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

change:frontend Requires changing the frontend dashboard:native-filters Related to the native filters of the Dashboard packages size/L

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants