Skip to content

fix(ui): use Untitled-UI dropdowns for Add Assets drawer quick-filters#29161

Closed
siddhant1 wants to merge 1 commit into
mainfrom
trenton
Closed

fix(ui): use Untitled-UI dropdowns for Add Assets drawer quick-filters#29161
siddhant1 wants to merge 1 commit into
mainfrom
trenton

Conversation

@siddhant1

@siddhant1 siddhant1 commented Jun 18, 2026

Copy link
Copy Markdown
Member

Describe your changes:

The Domains / Data Products → Add Assets drawer quick-filters (Entity Type, Owners, Tag, Tier, Service) are now interactive.

Why: The Add Assets drawer is an Untitled-UI SlideoutMenu (react-aria Modal/Dialog). The quick filters used the Ant Design SearchDropdown, whose popup portals to document.bodyoutside the dialog subtree, where react-aria's inert attribute makes it non-interactive (clicks fall through and the popup closes). z-index can't override inert.

What: Add a small QuickFilterDropdown built on the core Dropdown (react-aria) primitive from @openmetadata/ui-core-components. Its popover renders in the dialog's own top layer, so it stays interactive — no AntD-over-drawer workaround (getPopupContainer/ConfigProvider). ExploreQuickFilters renders it behind an untitledDropdown flag that only the Add Assets drawer passes (variant === 'drawer'); the Add Assets modal variant, the Explore page, the Glossary asset tab and Lineage controls keep the existing AntD SearchDropdown — zero change to those surfaces.

The library primitive provides the popover, the checkable items (showCheckbox), the counts (addon) and selection, so the component is ~30 lines. Per-filter in-popover search was intentionally left out to keep it minimal (a search box fights react-aria's menu typeahead, and the drawer already has its own asset searchbar); selection applies on click.

Note: no tracked GitHub issue — internal handoff. Happy to open one if required.

Type of change:

  • Bug fix

High-level design:

Minimal, additive, drawer-scoped. One new consumer-app component composed from the core Dropdown primitive (no core-component changes). ExploreQuickFilters gains an optional untitledDropdown prop (defaults to false), so the 4 other call sites are untouched. Rejected (per review): routing the AntD popup into the dialog via getPopupContainer / a ConfigProvider drawer provider — keeps an AntD overlay inside the Untitled drawer.

Tests:

Use cases covered

  • Add Assets drawer (Domain / Data Product / Input-Output Ports): each quick filter opens, selects (multi/single) with counts, fully interactive — the inert bug is gone because no AntD popup is rendered.
  • Modal variant (Glossary/Tags) and the Explore page behave exactly as before.

Unit tests

  • Existing ExploreQuickFilters.test.tsx / SearchDropdown.test.tsx Jest suites pass unchanged (the kept AntD paths). No new unit test in this minimal pass — the component is a thin wrapper over the library Dropdown.

Backend / Ingestion integration tests

  • Not applicable.

Playwright (UI) tests

  • The existing InputOutputPorts.spec.ts "Port drawers show Entity Type quick filter" test still covers the drawer trigger. A follow-up can extend it to open the popover and select an option (interactivity guard) — happy to add if wanted.

Manual testing performed

  • tsc --noEmit on the changed files — clean. UI checkstyle (organize-imports → eslint → prettier) — clean.

UI screen recording / screenshots:

⚠️ To be attached — short recording of the Add Assets drawer filters opening and selecting.

Checklist:

  • I have read the CONTRIBUTING document.
  • My PR is linked to a GitHub issue (no tracked issue — see note above).
  • For UI changes: I attached a screen recording and/or screenshots above (pending).

🤖 Generated with Claude Code

Greptile Summary

This PR fixes the non-interactive quick-filters in the Add Assets drawer by replacing the AntD SearchDropdown (whose popup portals to document.body, outside react-aria's inert-protected dialog subtree) with a new QuickFilterDropdown built on the core react-aria Dropdown primitive whose popover stays in the top layer and remains interactive.

  • QuickFilterDropdown is a ~80-line component wrapping Dropdown.Root/Popover/Menu/Item; it follows the existing Dropdown.Root + Button trigger pattern already used in OwnerReveal, OwnerTeamList, and others.
  • An untitledDropdown flag (default false) on ExploreQuickFilters gates the new path exclusively to the drawer variant; all four other call sites (Explore page, Glossary, Lineage, modal variant) keep the existing AntD SearchDropdown unchanged.
  • Selections apply immediately on click rather than behind an "Update" button; this is an intentional simplification noted in the PR description.

Confidence Score: 5/5

Safe to merge — the change is purely additive and drawer-scoped; all existing call sites are untouched.

The new QuickFilterDropdown follows the established Dropdown.Root + Button trigger pattern already proven across multiple components in the codebase. The untitledDropdown flag defaults to false, leaving every existing consumer (Explore, Glossary, Lineage, modal) on the unmodified AntD SearchDropdown path. No shared state, prop contracts, or API calls are changed.

No files require special attention.

Important Files Changed

Filename Overview
openmetadata-ui/src/main/resources/ui/src/components/Explore/QuickFilterDropdown.tsx New react-aria Dropdown-based filter component; follows the established Dropdown.Root pattern; selections apply immediately on click rather than via an Update button (intentional); defensive keys === 'all' guard is correct.
openmetadata-ui/src/main/resources/ui/src/components/Explore/ExploreQuickFilters.tsx Adds untitledDropdown flag (default false) gating the new component; existing AntD SearchDropdown path is fully unchanged; hasNullOption feature is omitted for the untitled path, consistent with the drawer call site not passing fieldsWithNullValues.
openmetadata-ui/src/main/resources/ui/src/components/DataAssets/AssetsSelectionModal/useAssetSelectionContent.tsx Passes untitledDropdown={variant === 'drawer'} to ExploreQuickFilters; correctly scopes the new component to the drawer variant only.
openmetadata-ui/src/main/resources/ui/src/components/Explore/QuickFilterDropdown.interface.ts Minimal interface; onChange carries a redundant searchKey second parameter (callers have it in closure), but this is a minor style point with no runtime impact.
openmetadata-ui/src/main/resources/ui/src/components/Explore/ExploreQuickFilters.interface.ts Adds optional untitledDropdown?: boolean prop; clean additive change.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A["ExploreQuickFilters\n(fields.map)"] --> B{untitledDropdown?}
    B -- "true\n(drawer variant)" --> C["QuickFilterDropdown\n(Dropdown.Root / react-aria)"]
    B -- "false\n(default)" --> D["SearchDropdown\n(Ant Design)"]
    C --> E["Dropdown.Popover\n→ react-aria top layer\n(stays interactive in SlideoutMenu)"]
    D --> F["AntD popup\n→ document.body\n(blocked by react-aria inert)"]
    G["useAssetSelectionContent\nvariant === 'drawer'"] -->|"untitledDropdown=true"| A
    H["ExplorePage / Glossary\n/ Lineage / Modal"] -->|"untitledDropdown=false (default)"| A
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
    A["ExploreQuickFilters\n(fields.map)"] --> B{untitledDropdown?}
    B -- "true\n(drawer variant)" --> C["QuickFilterDropdown\n(Dropdown.Root / react-aria)"]
    B -- "false\n(default)" --> D["SearchDropdown\n(Ant Design)"]
    C --> E["Dropdown.Popover\n→ react-aria top layer\n(stays interactive in SlideoutMenu)"]
    D --> F["AntD popup\n→ document.body\n(blocked by react-aria inert)"]
    G["useAssetSelectionContent\nvariant === 'drawer'"] -->|"untitledDropdown=true"| A
    H["ExplorePage / Glossary\n/ Lineage / Modal"] -->|"untitledDropdown=false (default)"| A
Loading

Reviews (4): Last reviewed commit: "fix(ui): use Untitled-UI dropdowns for A..." | Re-trigger Greptile

@siddhant1 siddhant1 requested a review from a team as a code owner June 18, 2026 06:12
Copilot AI review requested due to automatic review settings June 18, 2026 06:12

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@github-actions

github-actions Bot commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

❌ PR checklist incomplete

This PR cannot be merged until the following are addressed on its linked issue:

  • No GitHub issue is linked. Link an issue in the Development section of the PR (or add Fixes #12345 to the description). For a same-org cross-repo issue, add Fixes open-metadata/<repo>#123 to the description.

The fields live on the linked issue in the Shipping project (open the issue → right sidebar → Projects). After you set them, re-run this check (or push a commit) — issue/project changes do not re-trigger it automatically.

Maintainers can bypass this check by adding the skip-pr-checks label.

@github-actions

Copy link
Copy Markdown
Contributor

Hi there 👋 Thanks for your contribution!

The OpenMetadata team will review the PR shortly! Once it has been labeled as safe to test, the CI workflows
will start executing and we'll be able to make sure everything is working as expected.

Let us know if you need any help!

@siddhant1 siddhant1 closed this Jun 18, 2026
@siddhant1 siddhant1 reopened this Jun 18, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Hi there 👋 Thanks for your contribution!

The OpenMetadata team will review the PR shortly! Once it has been labeled as safe to test, the CI workflows
will start executing and we'll be able to make sure everything is working as expected.

Let us know if you need any help!

@github-actions

Copy link
Copy Markdown
Contributor

Hi there 👋 Thanks for your contribution!

The OpenMetadata team will review the PR shortly! Once it has been labeled as safe to test, the CI workflows
will start executing and we'll be able to make sure everything is working as expected.

Let us know if you need any help!

@siddhant1 siddhant1 changed the title fix(ui): enable quick-filter dropdowns in the Add Assets drawer fix(ui): use Untitled-UI dropdowns for Add Assets drawer quick-filters Jun 18, 2026
The Domains / Data Products "Add Assets" drawer is an Untitled-UI SlideoutMenu
(react-aria Modal/Dialog). Its quick-filter dropdowns used the Ant Design
SearchDropdown, whose popup portals to document.body — outside the dialog
subtree, where react-aria's `inert` attribute makes it non-interactive (clicks
fall through and the popup closes). z-index cannot fix `inert`.

Add a minimal QuickFilterDropdown built on the core `Dropdown` (react-aria)
primitive, whose popover renders in the dialog's top layer and stays
interactive without any AntD-over-drawer workaround. ExploreQuickFilters
renders it behind an `untitledDropdown` flag that only the Add Assets drawer
passes (variant === 'drawer'); the Modal variant, Explore page, Glossary tab
and Lineage controls keep the AntD SearchDropdown unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings June 18, 2026 08:20

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@github-actions

Copy link
Copy Markdown
Contributor

Hi there 👋 Thanks for your contribution!

The OpenMetadata team will review the PR shortly! Once it has been labeled as safe to test, the CI workflows
will start executing and we'll be able to make sure everything is working as expected.

Let us know if you need any help!

@siddhant1 siddhant1 added UI UI specific issues safe to test Add this label to run secure Github workflows on PRs labels Jun 18, 2026
@github-actions

Copy link
Copy Markdown
Contributor

❌ UI Checkstyle Failed

❌ I18n Sync

Translation locale files are out of sync with en-us.json.

Affected files
  • openmetadata-ui/src/main/resources/ui/src/locale/languages/sv-se.json

Fix locally (fast — only checks files changed in this branch):

make ui-checkstyle-changed

@siddhant1 siddhant1 closed this Jun 18, 2026
@gitar-bot

gitar-bot Bot commented Jun 18, 2026

Copy link
Copy Markdown
Code Review ✅ Approved 2 resolved / 2 findings

Replaces Ant Design dropdowns with Untitled-UI components in the Add Assets drawer to resolve react-aria interaction issues. Consider extending the selection logic to account for off-screen or unloaded options in the QuickFilterDropdown.

✅ 2 resolved
Quality: Debounced search is never cancelled on unmount

📄 openmetadata-ui/src/main/resources/ui/src/components/Explore/QuickFilterDropdown.tsx:62-65 📄 openmetadata-ui/src/main/resources/ui/src/components/Explore/QuickFilterDropdown.tsx:107-110
debouncedOnSearch is created with lodash.debounce but its pending invocation is never cancelled. If the popover/component unmounts (e.g. the drawer is closed) within 500ms of the last keystroke, the trailing call still fires onSearchgetFilterOptions, which triggers a setState in the parent on a component that may already be gone, producing a React "state update on an unmounted component" warning and a wasted/stale search request. The same applies when onSearch/searchKey change identity, leaving an orphaned timer. Add a cleanup effect that cancels the debounced function.

Edge Case: Selection rebuilt only from currently loaded options

📄 openmetadata-ui/src/main/resources/ui/src/components/Explore/QuickFilterDropdown.tsx:67-74
In QuickFilterDropdown.tsx the onSelectionChange handler reconstructs the selected values by filtering the local options array:

onChange(options.filter((option) => keys === 'all' || keys.has(option.key)), searchKey)

The react-aria Selection set (keys) reflects the full set of selected ids, but the resulting value is rebuilt purely from options (field.options ?? options ?? [], populated by onGetInitialOptions when the popover opens). If a previously selected option is not present in the currently loaded options list (e.g. the initial aggregation options differ from what was selected earlier, or the list is limited via optionPageSize), toggling any item will silently drop those previously selected values from the emitted value, because there is no option object to map the key back to.

The AntD SearchDropdown path keeps selected options independent of the visible option list. For the drawer's small, fixed quick-filters this is usually harmless, but for larger facets (Owners/Tags) it can lose selections. Consider merging the already-selected options into the lookup before filtering.

Options

Display: compact → Showing less information.

Comment with these commands to change:

Compact
gitar display:verbose         

Was this helpful? React with 👍 / 👎 | Gitar

@github-actions

Copy link
Copy Markdown
Contributor

Jest test Coverage

UI tests summary

Lines Statements Branches Functions
Coverage: 62%
62.25% (66568/106920) 44% (37229/84606) 45.35% (11181/24654)

@siddhant1

Copy link
Copy Markdown
Member Author

Superseded by #29168 — same goal (make the Add Assets drawer quick-filters interactive), implemented as the agreed final approach: a custom Untitled QuickFilterDropdown (react-aria PopoverTrigger/Popover + search + checkbox list) instead of the core Dropdown primitive. Closing in favor of #29168.

@sonarqubecloud

Copy link
Copy Markdown

@github-actions

Copy link
Copy Markdown
Contributor

🟡 Playwright Results — all passed (15 flaky)

✅ 4296 passed · ❌ 0 failed · 🟡 15 flaky · ⏭️ 88 skipped

Shard Passed Failed Flaky Skipped
🟡 Shard 1 300 0 2 4
🟡 Shard 2 809 0 3 9
🟡 Shard 3 812 0 1 8
🟡 Shard 4 854 0 3 12
🟡 Shard 5 732 0 1 47
🟡 Shard 6 789 0 5 8
🟡 15 flaky test(s) (passed on retry)
  • Features/TeamsHierarchy.spec.ts › Delete Parent Team (shard 1, 1 retry)
  • Pages/Roles.spec.ts › Roles page should work properly (shard 1, 1 retry)
  • Features/DataQuality/TestCaseImportExportE2eFlow.spec.ts › Admin: Complete export-import-validate flow (shard 2, 1 retry)
  • Features/DomainFilterQueryFilter.spec.ts › Multi-nested domain hierarchy: filters should scope correctly at every level (shard 2, 1 retry)
  • Features/ExploreQuickFilters.spec.ts › explore tree sidebar selection is not cleared when a top dropdown filter is applied (shard 2, 1 retry)
  • Features/Tasks/TaskNavigation.spec.ts › navigating to /table/TASK-XXXXX should show 404 (invalid URL pattern) (shard 3, 2 retries)
  • Flow/NotificationAlerts.spec.ts › Task source alert (shard 4, 1 retry)
  • Flow/NotificationAlerts.spec.ts › Conversation source alert (shard 4, 1 retry)
  • Pages/DataContractsSemanticRules.spec.ts › Validate Description Rule Is_Not_Set (shard 4, 1 retry)
  • Pages/ExplorePageRightPanel_KnowledgeCenter.spec.ts › Should remove user owner for knowledgeCenter (shard 5, 2 retries)
  • Pages/Lineage/LineageFilters.spec.ts › Verify lineage service type filter selection (shard 6, 1 retry)
  • Pages/Lineage/LineageFilters.spec.ts › Verify lineage schema filter selection (shard 6, 1 retry)
  • Pages/Lineage/LineageRightPanel.spec.ts › Verify custom properties tab IS visible for supported type: searchIndex (shard 6, 1 retry)
  • Pages/Lineage/PlatformLineage.spec.ts › Verify domain platform view (shard 6, 1 retry)
  • Pages/ServiceEntity.spec.ts › Tier Add, Update and Remove (shard 6, 1 retry)

📦 Download artifacts

How to debug locally
# Download playwright-test-results-<shard> artifact and unzip
npx playwright show-trace path/to/trace.zip    # view trace

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

Labels

safe to test Add this label to run secure Github workflows on PRs UI UI specific issues

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants