Skip to content

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

Open
chirag-madlani wants to merge 3 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 3 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 Drawer usage in the codebase by replacing it with SlideoutMenu from @openmetadata/ui-core-components, and replaces the antd Modal delete-edge confirmation dialog with the core-components ModalOverlay/Modal/Dialog/Button primitives. Two Playwright helpers are updated to target the new [data-testid="confirm-button"] instead of the now-removed .ant-btn-primary CSS class.

  • LineageProvider.tsx: MUI DrawerSlideoutMenu (preserving backdrop-click-to-close via isDismissable); antd ModalModalOverlay+Dialog with Button's isLoading/isDisabled props replacing the getLoadingStatusValue helper; the unused getLoadingStatusValue import is removed.
  • playwright/utils/lineage.ts: deleteEdge and removeColumnLineage now target [data-testid="delete-edge-confirmation-modal"] [data-testid="confirm-button"] instead of .ant-btn-primary.

Confidence Score: 5/5

Safe to merge — this is a pure component-library substitution with no logic changes, and all existing test IDs used by Playwright specs remain reachable in the new DOM structure.

Both replacements (SlideoutMenu for MUI Drawer, ModalOverlay/Dialog for antd Modal) are straightforward one-to-one substitutions that preserve open/close state, loading-disabled button behavior, and the z-index layering. The Playwright selector changes correctly target the new data-testid attributes. The getLoadingStatusValue import removal is clean. The lineage-entity-panel CSS class is now on the Dialog element rather than the old MUI Drawer root, matching how existing Playwright locators already target inner panel content.

No files require special attention.

Important Files Changed

Filename Overview
openmetadata-ui/src/main/resources/ui/src/context/LineageProvider/LineageProvider.tsx Replaces MUI Drawer and antd Modal with ui-core-components equivalents; removes the now-unused getLoadingStatusValue import; behavior is functionally equivalent for both the slide-out panel and confirmation dialog.
openmetadata-ui/src/main/resources/ui/playwright/utils/lineage.ts Two locators updated from framework-dependent .ant-btn-primary to stable data-testid selectors; change is minimal and correct.

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
    participant User
    participant LineageProvider
    participant SlideoutMenu
    participant ModalOverlay
    participant Dialog

    Note over LineageProvider: Node/Edge click
    User->>LineageProvider: click lineage node/edge
    LineageProvider->>SlideoutMenu: "isOpen=true"
    SlideoutMenu-->>User: slides in from right

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

    Note over LineageProvider: Delete edge flow
    User->>LineageProvider: click delete edge
    LineageProvider->>ModalOverlay: "isOpen=true"
    ModalOverlay->>Dialog: render confirmation
    Dialog-->>User: Remove Lineage Edge dialog

    User->>Dialog: click Confirm
    Dialog->>LineageProvider: onPress to onRemove
    LineageProvider->>LineageProvider: "deletionState.loading=true"
    Dialog-->>User: Button isLoading and isDisabled

    LineageProvider->>ModalOverlay: setShowDeleteModal(false)
    ModalOverlay-->>User: dialog 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
    participant Dialog

    Note over LineageProvider: Node/Edge click
    User->>LineageProvider: click lineage node/edge
    LineageProvider->>SlideoutMenu: "isOpen=true"
    SlideoutMenu-->>User: slides in from right

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

    Note over LineageProvider: Delete edge flow
    User->>LineageProvider: click delete edge
    LineageProvider->>ModalOverlay: "isOpen=true"
    ModalOverlay->>Dialog: render confirmation
    Dialog-->>User: Remove Lineage Edge dialog

    User->>Dialog: click Confirm
    Dialog->>LineageProvider: onPress to onRemove
    LineageProvider->>LineageProvider: "deletionState.loading=true"
    Dialog-->>User: Button isLoading and isDisabled

    LineageProvider->>ModalOverlay: setShowDeleteModal(false)
    ModalOverlay-->>User: dialog dismissed
Loading

Reviews (3): Last reviewed commit: "fix(lineage): drop unjustified zIndex ov..." | 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 on lines 191 to 195
await page
.locator('[data-testid="delete-edge-confirmation-modal"] .ant-btn-primary')
.locator(
'[data-testid="delete-edge-confirmation-modal"] [data-testid="confirm-button"]'
)
.dispatchEvent('click');

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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

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.)

Use a real Playwright click instead of dispatching a synthetic click event so react-aria's onPress fires reliably.:

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

Check the box to apply the fix or reply for a change | Was this helpful? React with 👍 / 👎

@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% (72719/114026) 46.91% (42298/90165) 48.2% (13013/26997)

@github-actions

github-actions Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

🟡 Playwright Results — all passed (15 flaky)

✅ 4062 passed · ❌ 0 failed · 🟡 15 flaky · ⏭️ 21 skipped

Shard Passed Failed Flaky Skipped
🟡 Shard 2 821 0 3 8
🟡 Shard 3 800 0 1 7
🟡 Shard 4 813 0 2 5
🟡 Shard 5 861 0 2 0
🟡 Shard 6 767 0 7 1
🟡 15 flaky test(s) (passed on retry)
  • Features/BulkImport.spec.ts › Database Schema (shard 2, 1 retry)
  • Features/ContextCenterDocumentPage.spec.ts › moving document to folder shows folder on card; re-opening menu shows current folder selected; clicking it again removes document from folder (shard 2, 1 retry)
  • Features/ContextCenterPermission.spec.ts › user with editAll permission can see restore action but not delete action on an archived document, and can restore it (shard 2, 1 retry)
  • Features/KnowledgeCenterList.spec.ts › Knowledge Center List - Verify Recently Viewed widget (shard 3, 1 retry)
  • Pages/CustomProperties.spec.ts › Integer (shard 4, 1 retry)
  • Pages/CustomProperties.spec.ts › Should display custom properties for apiCollection in right panel (shard 4, 1 retry)
  • Pages/EntityDataConsumer.spec.ts › Tier Add, Update and Remove (shard 5, 1 retry)
  • Pages/ExplorePageRightPanel.spec.ts › Should display and verify schema fields for dashboardDataModel (shard 5, 1 retry)
  • Pages/ExplorePageRightPanel.spec.ts › Should allow Data Steward to edit tier for searchIndex (shard 6, 1 retry)
  • Pages/GlossaryImportExport.spec.ts › Import validation - missing required fields (shard 6, 1 retry)
  • Pages/GlossaryImportExport.spec.ts › Import partial success - some terms pass, some fail (shard 6, 1 retry)
  • Pages/GlossaryImportExport.spec.ts › Glossary CSV import preserves typed relations (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/Lineage/LineageRightPanel.spec.ts › Verify custom properties tab is NOT visible for apiService in platform lineage (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.

Comment on lines +2228 to +2231
<Dialog
data-testid="delete-edge-confirmation-modal"
width={400}
onClose={() => setShowDeleteModal(false)}>

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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

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).

Remove the no-op onClose prop from Dialog; dismissal is handled by ModalOverlay's onOpenChange and the footer buttons.:

<Modal>
  <Dialog
    data-testid="delete-edge-confirmation-modal"
    width={400}>
    <Dialog.Header title={t('message.remove-lineage-edge')} />
  • Apply fix

Check the box to apply the fix or reply for a change | Was this helpful? React with 👍 / 👎

@gitar-bot

gitar-bot Bot commented Jul 6, 2026

Copy link
Copy Markdown
Code Review 👍 Approved with suggestions 1 resolved / 3 findings

Refactors Lineage UI by replacing MUI and antd components with core-components primitives, while updating Playwright selectors to maintain test stability. Note that the new confirm button may require simulating pointer events instead of generic clicks, and ensure the Dialog's onClose usage aligns with the component API.

💡 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.)

Use a real Playwright click instead of dispatching a synthetic click event so react-aria's onPress fires reliably.
await page
  .locator(
    '[data-testid="delete-edge-confirmation-modal"] [data-testid="confirm-button"]'
  )
  .click();
💡 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).

Remove the no-op onClose prop from Dialog; dismissal is handled by ModalOverlay's onOpenChange and the footer buttons.
<Modal>
  <Dialog
    data-testid="delete-edge-confirmation-modal"
    width={400}>
    <Dialog.Header title={t('message.remove-lineage-edge')} />
✅ 1 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.

🤖 Prompt for agents
Code Review: Refactors Lineage UI by replacing MUI and antd components with core-components primitives, while updating Playwright selectors to maintain test stability. Note that the new confirm button may require simulating pointer events instead of generic clicks, and ensure the Dialog's `onClose` usage aligns with the component API.

1. 💡 Bug: dispatchEvent('click') may not trigger react-aria onPress
   Files: 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.)

   Fix (Use a real Playwright click instead of dispatching a synthetic click event so react-aria's onPress fires reliably.):
   await page
     .locator(
       '[data-testid="delete-edge-confirmation-modal"] [data-testid="confirm-button"]'
     )
     .click();

2. 💡 Quality: Dialog onClose prop is dead code in delete-edge modal
   Files: 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 `Button`s. 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).

   Fix (Remove the no-op onClose prop from Dialog; dismissal is handled by ModalOverlay's onOpenChange and the footer buttons.):
   <Modal>
     <Dialog
       data-testid="delete-edge-confirmation-modal"
       width={400}>
       <Dialog.Header title={t('message.remove-lineage-edge')} />

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