Skip to content

refactor(lineage): replace MUI Drawer and antd Modal with ui-core-components#29758

Open
chirag-madlani wants to merge 6 commits into
mainfrom
lineage-mui-to-core-components
Open

refactor(lineage): replace MUI Drawer and antd Modal with ui-core-components#29758
chirag-madlani wants to merge 6 commits into
mainfrom
lineage-mui-to-core-components

Conversation

@chirag-madlani

@chirag-madlani chirag-madlani commented Jul 6, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • LineageProvider.tsx was the last remaining MUI (@mui/material) usage in the codebase; replaced its Drawer (entity/edge side panel) with SlideoutMenu from @openmetadata/ui-core-components.
  • Also replaced the antd Modal (delete-lineage-edge confirmation) with the core-components ModalOverlay/Modal/Dialog primitives, preserving the loading/disabled button behavior via Button's isLoading/isDisabled props.
  • Added isDismissable to the SlideoutMenu to preserve the original Drawer's backdrop-click-to-close behavior (matches the existing OntologyEntityPanel pattern).
  • Updated the two Playwright helpers (deleteEdge, removeColumnLineage in playwright/utils/lineage.ts) that clicked the antd .ant-btn-primary class inside the confirmation modal — that class no longer exists, so they now target [data-testid="confirm-button"].

Test plan

  • tsc --noEmit clean (only a pre-existing, unrelated error in LineageProvider.test.tsx remains — confirmed present before this change via git stash)
  • LineageProvider.test.tsx — 11/11 pass
  • Lineage.test.tsx, PlatformLineage.test.tsx, ContainerPage.test.tsx, LineageTable.test.tsx — all pass
  • Full EntityLineage Jest suite — 18 suites / 249 tests pass
  • Scanned Playwright specs referencing the lineage side panel/modal (LineageRightPanel.spec.ts, LineageFilters.spec.ts, PlatformLineage.spec.ts, DataAssetLineage.spec.ts) — all use stable data-testids preserved in the new markup
  • ui-checkstyle sequence (organize-imports → eslint --fix → prettier) run on changed files — no residual diff
image Screenshot 2026-07-06 at 7 37 39 PM

🤖 Generated with Claude Code

Greptile Summary

This PR removes the last @mui/material usage in the codebase by replacing the MUI Drawer (entity/edge side panel) with SlideoutMenu from @openmetadata/ui-core-components, and replaces the antd Modal (delete-edge confirmation) with the core-components ModalOverlay/Modal/Dialog primitives. Two Playwright helpers are updated to use stable [data-testid="confirm-button"] instead of the now-absent .ant-btn-primary class.

  • The SlideoutMenu is correctly driven by ModalOverlay/Modal/Dialog from slideout-menus/slideout-menu.tsx, while the delete confirmation modal correctly uses the separate centered-modal components from modals/modal.tsx — both sourced through @openmetadata/ui-core-components's index.
  • The getLoadingStatusValue utility import is cleanly removed since button loading state is now expressed through Button's isLoading/isDisabled props.
  • Playwright click helpers are upgraded from dispatchEvent('click') (raw DOM event, no actionability checks) to .click() (proper Playwright interaction), which is a correctness improvement in addition to the selector fix.

Confidence Score: 5/5

Safe to merge — the component swaps are mechanically correct, the delete modal correctly uses centered-modal primitives, and the Playwright helpers now target stable testids.

Both component replacements resolve to the right implementations via the package's index (centered modal vs slideout panel are separate exports). Existing Playwright tests that query children of [data-testid="lineage-entity-panel"] remain valid because the testid moves from the MUI Drawer wrapper to the React Aria ModalOverlay wrapper — both are the outermost container element and all child elements remain nested within. No behavioral regressions were identified.

No files require special attention.

Important Files Changed

Filename Overview
openmetadata-ui/src/main/resources/ui/src/context/LineageProvider/LineageProvider.tsx Replaces MUI Drawer with SlideoutMenu and antd Modal with ModalOverlay/Modal/Dialog; the correct centered-modal primitives (from modals/modal.tsx) are resolved at the package index level, so the delete dialog renders centered as expected.
openmetadata-ui/src/main/resources/ui/playwright/utils/lineage.ts Updates two Playwright helpers to use the stable data-testid selector instead of the antd class, and upgrades from dispatchEvent to .click() for proper actionability checks.

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
    participant User
    participant LineageProvider
    participant SlideoutMenu
    participant ModalOverlay as ModalOverlay (centered)
    participant onRemove

    User->>LineageProvider: click lineage node/edge
    LineageProvider->>SlideoutMenu: "isOpen=true (entity/edge panel)"
    SlideoutMenu-->>User: slides in from right

    User->>SlideoutMenu: click backdrop (isDismissable)
    SlideoutMenu->>LineageProvider: onOpenChange(false)
    LineageProvider->>SlideoutMenu: "isOpen=false"
    SlideoutMenu-->>User: slides out

    User->>LineageProvider: click delete edge
    LineageProvider->>ModalOverlay: "isOpen=true (delete confirmation)"
    ModalOverlay-->>User: centered modal with Confirm / Cancel

    User->>ModalOverlay: "click Confirm (isLoading=true)"
    ModalOverlay->>onRemove: invoke
    onRemove-->>LineageProvider: success - setShowDeleteModal(false)
    LineageProvider->>ModalOverlay: "isOpen=false"
    ModalOverlay-->>User: modal dismissed
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"}}}%%
sequenceDiagram
    participant User
    participant LineageProvider
    participant SlideoutMenu
    participant ModalOverlay as ModalOverlay (centered)
    participant onRemove

    User->>LineageProvider: click lineage node/edge
    LineageProvider->>SlideoutMenu: "isOpen=true (entity/edge panel)"
    SlideoutMenu-->>User: slides in from right

    User->>SlideoutMenu: click backdrop (isDismissable)
    SlideoutMenu->>LineageProvider: onOpenChange(false)
    LineageProvider->>SlideoutMenu: "isOpen=false"
    SlideoutMenu-->>User: slides out

    User->>LineageProvider: click delete edge
    LineageProvider->>ModalOverlay: "isOpen=true (delete confirmation)"
    ModalOverlay-->>User: centered modal with Confirm / Cancel

    User->>ModalOverlay: "click Confirm (isLoading=true)"
    ModalOverlay->>onRemove: invoke
    onRemove-->>LineageProvider: success - setShowDeleteModal(false)
    LineageProvider->>ModalOverlay: "isOpen=false"
    ModalOverlay-->>User: modal dismissed
Loading

Reviews (5): Last reviewed commit: "Merge remote-tracking branch 'origin/mai..." | Re-trigger Greptile

…ponents

LineageProvider.tsx was the last remaining MUI usage; swap the entity/edge
side panel to SlideoutMenu and the delete-edge confirmation to
Modal/Dialog, matching the SlideoutMenu pattern already used by
OntologyEntityPanel. Update the two Playwright helpers that clicked the
antd .ant-btn-primary class inside the confirmation modal.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@chirag-madlani chirag-madlani requested a review from a team as a code owner July 6, 2026 07:46
Copilot AI review requested due to automatic review settings July 6, 2026 07:46

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 Jul 6, 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 github-actions Bot added safe to test Add this label to run secure Github workflows on PRs UI UI specific issues labels Jul 6, 2026
Comment thread openmetadata-ui/src/main/resources/ui/playwright/utils/lineage.ts Outdated
@github-actions

github-actions Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Jest test Coverage

UI tests summary

Lines Statements Branches Functions
Coverage: 63%
63.77% (72752/114070) 46.92% (42353/90260) 48.21% (13025/27015)

@github-actions

github-actions Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

🟡 Playwright Results — all passed (23 flaky)

✅ 4087 passed · ❌ 0 failed · 🟡 23 flaky · ⏭️ 22 skipped

Shard Passed Failed Flaky Skipped
🟡 Shard 2 809 0 14 4
🟡 Shard 3 816 0 1 12
🟡 Shard 4 818 0 1 5
🟡 Shard 5 829 0 1 0
🟡 Shard 6 815 0 6 1
🟡 23 flaky test(s) (passed on retry)
  • Features/BulkEditEntity.spec.ts › Database (shard 2, 1 retry)
  • Features/BulkEditEntity.spec.ts › Database Schema (shard 2, 1 retry)
  • Features/BulkEditEntity.spec.ts › Table (shard 2, 1 retry)
  • Features/BulkImport.spec.ts › Database service (shard 2, 2 retries)
  • Features/BulkImport.spec.ts › Database (shard 2, 1 retry)
  • Features/BulkImport.spec.ts › Database Schema (shard 2, 1 retry)
  • Features/ContextCenterArticles.spec.ts › Article listing search filters, clears, and shows empty state (shard 2, 2 retries)
  • Features/ContextCenterArticles.spec.ts › Article list cards, recently viewed widget, and pagination work (shard 2, 1 retry)
  • Features/ContextCenterMemories.spec.ts › Shared memory shows the shared-with-specific-people description (shard 2, 1 retry)
  • Features/ContextCenterPermission.spec.ts › user with view-only permission cannot see restore or delete actions on an archived document (shard 2, 1 retry)
  • Features/ContextCenterPermission.spec.ts › user with view-only permission sees no Add Memory button, no row actions, and no modal action buttons (shard 2, 1 retry)
  • Features/ContextCenterPermission.spec.ts › user with createAll permission sees Add Memory button but no row edit/delete actions or modal action buttons, and can create a memory (shard 2, 1 retry)
  • Features/DataProductRenameConsolidation.spec.ts › Multiple rename + update cycles - assets should be preserved (shard 2, 1 retry)
  • Features/Glossary/GlossaryCRUDOperations.spec.ts › should create glossary with mutually exclusive enabled (shard 2, 1 retry)
  • Features/SearchExport.spec.ts › Export queues a background job and downloads from the jobs tray (shard 3, 1 retry)
  • Pages/DataContracts.spec.ts › Contract Status badge should be visible on condition if Contract Tab is present/hidden by Persona (shard 4, 1 retry)
  • Pages/ExplorePageRightPanel_KnowledgeCenter.spec.ts › Should remove user owner for knowledgeCenter (shard 5, 1 retry)
  • Pages/ExplorePageRightPanel.spec.ts › Should allow Data Steward to view all tabs for searchIndex (shard 6, 1 retry)
  • Pages/GlossaryFormValidation.spec.ts › should show error when glossary description is empty (shard 6, 1 retry)
  • Pages/Lineage/LineageFilters.spec.ts › Verify Impact Analysis service filter selection (shard 6, 1 retry)
  • Pages/Lineage/LineageRightPanel.spec.ts › Verify custom properties tab is NOT visible for pipelineService in platform lineage (shard 6, 1 retry)
  • Pages/TagPageRightPanel.spec.ts › Should open right panel when clicking asset in tag assets page (shard 6, 1 retry)
  • Pages/Teams.spec.ts › Teams Page Flow (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

… swap

SlideoutMenu applies its className prop to both the outer ModalOverlay
and the inner Modal, so passing "lineage-entity-panel" via className
duplicated it onto two elements — Playwright's `.locator('.lineage-entity-panel')`
then hit strict-mode violations (2 elements matched) across every
DataAssetLineage/LineageFilters spec that opens and closes the panel.
Move the selector-class onto dialogClassName, which only targets the
single Dialog element.

Also give ModalWithFunctionEditor (antd Modal opened from within the
lineage edge drawer) an explicit zIndex so its Save button always
stacks above the new SlideoutMenu overlay — it was being intercepted by
the panel's backdrop in LineageInteraction.spec.ts.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
open={visible}
title={<Typography.Text data-testid="header">{header}</Typography.Text>}
width="700px"
zIndex={1050}

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.

Any reason we need zindex ?
Since Toast is having zIndex of 1000, so confirm this thing once

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Good catch, and you're right to question it — I dug back in and there's no justification for it.

Verified concretely:

  • tw:z-999 on the SlideoutMenu compiles to z-index: 999 (checked via the Tailwind v4 compiler directly).
  • antd's default .ant-modal-wrap/.ant-modal-mask z-index is 1000 (checked in the compiled antd.css).

So antd's modal already stacks above our panel by default (1000 > 999) — no override needed, and bumping to 1050 would've also incorrectly outranked Toast (also z-index 1000), exactly as you flagged.

The Save-button interception this was band-aiding was almost certainly a side effect of the actual bug: SlideoutMenu applies its className prop to both the outer ModalOverlay and inner Modal, so passing lineage-entity-panel via className duplicated that class onto two elements, which is what caused the bulk of the CI failures (Playwright strict-mode violations). I've since moved that class to dialogClassName (single element only) in a follow-up commit, and removed the zIndex override here — pushed in f49e20c.

…itor

Verified antd's default z-index for .ant-modal-wrap/.ant-modal-mask is
1000 (compiled antd.css) and our SlideoutMenu overlay's tw:z-999
compiles to z-index:999 (verified via the Tailwind v4 compiler), so
antd's modal already stacks above the lineage panel without an
override. The zIndex={1050} bump was an unjustified band-aid from the
earlier fix and would incorrectly outrank Toast notifications (also
z-index 1000). The Save-button interception seen in
LineageInteraction.spec.ts was almost certainly a symptom of the
duplicate lineage-entity-panel class fixed in the previous commit.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 6, 2026 14:27

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.

chirag-madlani and others added 3 commits July 6, 2026 23:41
…se prop

- playwright/utils/lineage.ts: use a real .click() instead of
  .dispatchEvent('click') for the confirm-button — it's a react-aria
  Button (usePress/onPress), and a synthetic dispatched click isn't
  guaranteed to trigger onPress the way a trusted Playwright click does.
  Matches the .click() convention already used for this same testid
  elsewhere in the suite (glossary.ts, testCases.ts, etc.).
- LineageProvider.tsx: drop the onClose prop passed to Dialog in the
  delete-edge confirmation — ui-core-components' Dialog only wires
  onClose to its CloseButton, which never renders here since
  showCloseButton isn't set, so it was dead code. Dismissal is already
  handled by ModalOverlay's onOpenChange and the footer buttons.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Now that MUI is gone, nothing else pulls in reactflow's base/style CSS
transitively — import them directly.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…omponents

# Conflicts:
#	openmetadata-ui/src/main/resources/ui/src/styles/index.ts
Copilot AI review requested due to automatic review settings July 6, 2026 18: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.

@gitar-bot

gitar-bot Bot commented Jul 6, 2026

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

Replaces the last MUI Drawer and antd Modal in the codebase with ui-core-components primitives to unify the UI design language. Playwright tests were updated to use stable data-testids, and all previous modal and drawer functionality remains preserved.

✅ 3 resolved
Quality: Dialog onClose prop is a no-op (not part of react-aria Dialog API)

📄 openmetadata-ui/src/main/resources/ui/src/context/LineageProvider/LineageProvider.tsx:2228-2231
Dialog from @openmetadata/ui-core-components wraps react-aria's AriaDialog, whose props (DialogProps extends AriaDialogProps) do not include an onClose callback — closing is done via the render-prop close() or the parent overlay's onOpenChange. The onClose={() => setShowDeleteModal(false)} passed to <Dialog> here is therefore dead code that never fires (and could be forwarded to the DOM as an unknown attribute). Since the Dialog has no close (X) button in its header and the Cancel/Confirm buttons handle closing directly, this is harmless but misleading; remove it to avoid implying a close affordance that doesn't exist.

Bug: dispatchEvent('click') may not trigger react-aria onPress

📄 openmetadata-ui/src/main/resources/ui/playwright/utils/lineage.ts:191-195 📄 openmetadata-ui/src/main/resources/ui/playwright/utils/lineage.ts:615-619
The new confirm button ([data-testid="confirm-button"]) is a Button from @openmetadata/ui-core-components, which is built on react-aria's usePress/onPress rather than a native DOM onClick. The Playwright helpers deleteEdge and removeColumnLineage still trigger it via .dispatchEvent('click'). A programmatically dispatched (untrusted) click event does not reliably fire react-aria's onPress, since press handling is driven by the pointer/keyboard interaction sequence. This can make these helpers silently fail to confirm the deletion, causing flaky or broken lineage e2e tests. Prefer Playwright's .click(), which performs a full trusted interaction that react-aria recognizes:

await page
  .locator('[data-testid="delete-edge-confirmation-modal"] [data-testid="confirm-button"]')
  .click();

(This is speculative on the exact react-aria version behavior — worth verifying the helpers still confirm deletion when running the affected specs.)

Quality: Dialog onClose prop is dead code in delete-edge modal

📄 openmetadata-ui/src/main/resources/ui/src/context/LineageProvider/LineageProvider.tsx:2228-2231
The Dialog in the delete-edge confirmation passes onClose={() => setShowDeleteModal(false)}, but in the ui-core-components Dialog implementation onClose is only wired to the CloseButton, which is rendered exclusively when showCloseButton is true. Since showCloseButton is not set here, this onClose handler is never invoked — it is dead code. Actual dismissal is handled correctly by the parent ModalOverlay's onOpenChange and the footer's cancel/confirm Buttons. This is harmless but misleading, since it suggests the Dialog participates in close logic when it does not. Consider removing the prop to avoid confusion (dismissal is already fully handled by ModalOverlay and the footer buttons).

Options

Display: compact → Showing less information.

Comment with these commands to change the behavior for this request:

Compact
gitar display:verbose         

Was this helpful? React with 👍 / 👎 | Gitar

@sonarqubecloud

sonarqubecloud Bot commented Jul 6, 2026

Copy link
Copy Markdown

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.

3 participants