Skip to content

Commit c57d612

Browse files
authored
feat: migrate drawer components from MUI to SlideoutMenu in untitled UI (#26518)
* feat: migrate drawer components from MUI to SlideoutMenu in untitled UI * addressed gitar comments * fixed drawer validation issue * fixed the form validation issue * fixed sonar issue * addressed PR comment * addressed PR comment * minor fix * fixed playwright test
1 parent 27de0fc commit c57d612

16 files changed

Lines changed: 96 additions & 485 deletions

File tree

openmetadata-ui-core-components/src/main/resources/ui/src/components/foundations/typography.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,13 +74,13 @@ export const Typography = (props: TypographyProps) => {
7474
quoteVariant = "default",
7575
className,
7676
children,
77-
size = "text-sm",
78-
weight = "regular",
77+
size,
78+
weight,
7979
...otherProps
8080
} = props;
8181

82-
const sizeClass = sizeClasses[size];
83-
const weightClass = weightClasses[weight];
82+
const sizeClass = size ? sizeClasses[size] : undefined;
83+
const weightClass = weight ? weightClasses[weight] : undefined;
8484

8585
const innerClassName = cx(sizeClass, weightClass, className);
8686

openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/DomainUIInteractions.spec.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
* limitations under the License.
1212
*/
1313

14-
import { expect, Page, test as base } from '@playwright/test';
14+
import { test as base, expect, Page } from '@playwright/test';
1515
import { SidebarItem } from '../../constant/sidebar';
1616
import { DataProduct } from '../../support/domain/DataProduct';
1717
import { Domain } from '../../support/domain/Domain';
@@ -26,8 +26,8 @@ import {
2626
selectDataProduct,
2727
selectDomain,
2828
} from '../../utils/domain';
29-
import { sidebarClick } from '../../utils/sidebar';
3029
import { waitForAllLoadersToDisappear } from '../../utils/entity';
30+
import { sidebarClick } from '../../utils/sidebar';
3131

3232
const test = base.extend<{
3333
page: Page;
@@ -577,7 +577,7 @@ test.describe('Domain Form Validation', () => {
577577
await sidebarClick(page, SidebarItem.DOMAIN);
578578

579579
await page.click('[data-testid="add-domain"]');
580-
await page.locator('h6:has-text("Add Domain")').waitFor();
580+
await page.getByTestId('form-heading').waitFor();
581581

582582
await page.locator('#root\\/name').fill('Invalid@Name#Test');
583583
await page.locator('#root\\/displayName').fill('Test Domain');
@@ -593,7 +593,7 @@ test.describe('Domain Form Validation', () => {
593593
await sidebarClick(page, SidebarItem.DOMAIN);
594594

595595
await page.click('[data-testid="add-domain"]');
596-
await page.locator('h6:has-text("Add Domain")').waitFor();
596+
await page.getByTestId('form-heading').waitFor();
597597

598598
const longName = 'a'.repeat(150);
599599
await page.locator('#root\\/name').fill(longName);
@@ -609,7 +609,7 @@ test.describe('Domain Form Validation', () => {
609609
await sidebarClick(page, SidebarItem.DOMAIN);
610610

611611
await page.click('[data-testid="add-domain"]');
612-
await page.locator('h6:has-text("Add Domain")').waitFor();
612+
await expect(page.getByTestId('form-heading')).toHaveText('Add Domain');
613613

614614
await page.locator('#root\\/name').fill('ValidName');
615615
await page.locator('#root\\/displayName').fill('Valid Display Name');

openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/Domains.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,10 +75,10 @@ import {
7575
deleteAnnouncement,
7676
editAnnouncement,
7777
followEntity,
78+
getEncodedFqn,
7879
replyAnnouncement,
7980
unFollowEntity,
8081
waitForAllLoadersToDisappear,
81-
getEncodedFqn,
8282
} from '../../utils/entity';
8383
import { selectActiveGlossaryTerm } from '../../utils/glossary';
8484
import {
@@ -1202,7 +1202,7 @@ test.describe('Domains', () => {
12021202
await sidebarClick(page, SidebarItem.DOMAIN);
12031203
await waitForAllLoadersToDisappear(page);
12041204
await page.click('[data-testid="add-domain"]');
1205-
await page.locator('h6:has-text("Add Domain")').waitFor({
1205+
await page.getByTestId('form-heading').waitFor({
12061206
state: 'visible',
12071207
});
12081208
});

openmetadata-ui/src/main/resources/ui/playwright/utils/domain.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -522,10 +522,9 @@ export const createDomain = async (
522522
validate = false
523523
) => {
524524
await page.click('[data-testid="add-domain"]');
525+
await page.getByTestId('form-heading').waitFor({ timeout: 5000 });
525526

526-
await page.locator('h6:has-text("Add Domain")').waitFor({ timeout: 5000 });
527-
528-
await expect(page.locator('h6:has-text("Add Domain")')).toBeVisible();
527+
await expect(page.getByTestId('form-heading')).toBeVisible();
529528

530529
const saveButton = page.getByRole('button', { name: 'Save' });
531530

openmetadata-ui/src/main/resources/ui/src/components/DataAssets/AssetsSelectionModal/useAssetSelectionDrawer.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,6 @@ export const useAssetSelectionDrawer = ({
6262

6363
// Create the drawer - always mounted but content conditionally rendered
6464
const assetDrawer = useCompositeDrawer({
65-
anchor: 'right',
6665
width: 670,
6766
closeOnEscape: false,
6867
testId: 'asset-selection-modal',

openmetadata-ui/src/main/resources/ui/src/components/DataProduct/DataProductListPage.tsx

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ import { useSnackbar } from 'notistack';
1818
import { useCallback, useMemo, useState } from 'react';
1919
import { useTranslation } from 'react-i18next';
2020
import { ReactComponent as FolderEmptyIcon } from '../../assets/svg/folder-empty.svg';
21-
import { DRAWER_HEADER_STYLING } from '../../constants/DomainsListPage.constants';
2221
import { LEARNING_PAGE_IDS } from '../../constants/Learning.constants';
2322
import { usePermissionProvider } from '../../context/PermissionProvider/PermissionProvider';
2423
import { ERROR_PLACEHOLDER_TYPE } from '../../enums/common.enum';
@@ -72,12 +71,8 @@ const DataProductListPage = () => {
7271

7372
const { formDrawer, openDrawer, closeDrawer } = useFormDrawerWithRef({
7473
title: t('label.add-entity', { entity: t('label.data-product') }),
75-
anchor: 'right',
7674
width: 670,
7775
closeOnEscape: false,
78-
header: {
79-
sx: DRAWER_HEADER_STYLING,
80-
},
8176
onCancel: () => {
8277
form.resetFields();
8378
},

openmetadata-ui/src/main/resources/ui/src/components/Domain/DomainDetails/DomainDetails.component.tsx

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,6 @@ import type { BreadcrumbItem } from '../../common/atoms/navigation/useBreadcrumb
105105
import { useBreadcrumbs } from '../../common/atoms/navigation/useBreadcrumbs';
106106

107107
import { Avatar } from '@openmetadata/ui-core-components';
108-
import { DRAWER_HEADER_STYLING } from '../../../constants/DomainsListPage.constants';
109108
import { LEARNING_PAGE_IDS } from '../../../constants/Learning.constants';
110109
import { FeedCounts } from '../../../interface/feed.interface';
111110
import { getEntityAvatarProps } from '../../../utils/IconUtils';
@@ -344,12 +343,8 @@ const DomainDetails = ({
344343
closeDrawer: closeDataProductDrawer,
345344
} = useFormDrawerWithRef({
346345
title: t('label.add-entity', { entity: t('label.data-product') }),
347-
anchor: 'right',
348346
width: 670,
349347
closeOnEscape: false,
350-
header: {
351-
sx: DRAWER_HEADER_STYLING,
352-
},
353348
onCancel: () => {
354349
dataProductForm.resetFields();
355350
},
@@ -491,12 +486,8 @@ const DomainDetails = ({
491486
closeDrawer: closeSubDomainDrawer,
492487
} = useFormDrawerWithRef({
493488
title: t('label.add-entity', { entity: t('label.sub-domain') }),
494-
anchor: 'right',
495489
width: 670,
496490
closeOnEscape: false,
497-
header: {
498-
sx: DRAWER_HEADER_STYLING,
499-
},
500491
onCancel: () => {
501492
subDomainForm.resetFields();
502493
},

openmetadata-ui/src/main/resources/ui/src/components/DomainListing/DomainListPage.tsx

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ import { useSnackbar } from 'notistack';
1818
import { useCallback, useEffect, useMemo, useState } from 'react';
1919
import { useTranslation } from 'react-i18next';
2020
import { ReactComponent as FolderEmptyIcon } from '../../assets/svg/folder-empty.svg';
21-
import { DRAWER_HEADER_STYLING } from '../../constants/DomainsListPage.constants';
2221
import { LEARNING_PAGE_IDS } from '../../constants/Learning.constants';
2322
import { usePermissionProvider } from '../../context/PermissionProvider/PermissionProvider';
2423
import { ERROR_PLACEHOLDER_TYPE } from '../../enums/common.enum';
@@ -74,12 +73,8 @@ const DomainListPage = () => {
7473

7574
const { formDrawer, openDrawer, closeDrawer } = useFormDrawerWithRef({
7675
title: t('label.add-entity', { entity: t('label.domain') }),
77-
anchor: 'right',
7876
width: 670,
7977
closeOnEscape: false,
80-
header: {
81-
sx: DRAWER_HEADER_STYLING,
82-
},
8378
onCancel: () => {
8479
form.resetFields();
8580
},

openmetadata-ui/src/main/resources/ui/src/components/common/atoms/drawer/useCompositeDrawer.tsx

Lines changed: 4 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
* limitations under the License.
1212
*/
1313

14-
import { Box } from '@mui/material';
1514
import { useCallback, useMemo } from 'react';
1615
import { DrawerConfig, useDrawer } from './useDrawer';
1716
import { DrawerBodyConfig, useDrawerBody } from './useDrawerBody';
@@ -25,48 +24,6 @@ export interface CompositeDrawerConfig extends DrawerConfig {
2524
onBeforeClose?: () => void;
2625
}
2726

28-
/**
29-
* Composite drawer hook that combines all drawer atoms
30-
*
31-
* @description
32-
* Higher-level hook that composes drawer atoms into a complete drawer.
33-
* Provides a fully configured drawer with header, body, and footer.
34-
*
35-
* @param config - Combined configuration for all drawer parts
36-
*
37-
* @example
38-
* ```typescript
39-
* const drawer = useCompositeDrawer({
40-
* anchor: 'right',
41-
* width: 600,
42-
* header: {
43-
* title: 'Edit User',
44-
* onClose: handleClose
45-
* },
46-
* body: {
47-
* children: <UserForm />,
48-
* loading: isLoading
49-
* },
50-
* footer: {
51-
* primaryButton: {
52-
* label: 'Save',
53-
* onClick: handleSave
54-
* },
55-
* secondaryButton: {
56-
* label: 'Cancel',
57-
* onClick: handleClose
58-
* }
59-
* }
60-
* });
61-
*
62-
* return (
63-
* <>
64-
* <Button onClick={drawer.openDrawer}>Open</Button>
65-
* {drawer.compositeDrawer}
66-
* </>
67-
* );
68-
* ```
69-
*/
7027
export const useCompositeDrawer = (config: CompositeDrawerConfig = {}) => {
7128
const {
7229
header = {},
@@ -78,7 +35,6 @@ export const useCompositeDrawer = (config: CompositeDrawerConfig = {}) => {
7835

7936
const baseDrawer = useDrawer(drawerConfig);
8037

81-
// Create a wrapped close function that calls onBeforeClose first
8238
const handleClose = useCallback(() => {
8339
onBeforeClose?.();
8440
if (header.onClose) {
@@ -97,11 +53,11 @@ export const useCompositeDrawer = (config: CompositeDrawerConfig = {}) => {
9753

9854
const drawerContent = useMemo(
9955
() => (
100-
<Box sx={{ height: '100%', display: 'flex', flexDirection: 'column' }}>
56+
<>
10157
{drawerHeader}
10258
{drawerBody}
10359
{drawerFooter}
104-
</Box>
60+
</>
10561
),
10662
[drawerHeader, drawerBody, drawerFooter]
10763
);
@@ -110,57 +66,24 @@ export const useCompositeDrawer = (config: CompositeDrawerConfig = {}) => {
11066
const DrawerComponent = baseDrawer.drawer;
11167
const Component = DrawerComponent.type;
11268

113-
return <Component {...DrawerComponent.props} children={drawerContent} />;
69+
return <Component {...DrawerComponent.props}>{drawerContent}</Component>;
11470
}, [baseDrawer.drawer, drawerContent]);
11571

116-
// Override closeDrawer to call onBeforeClose
11772
const closeDrawer = useCallback(() => {
11873
onBeforeClose?.();
11974
baseDrawer.closeDrawer();
12075
}, [onBeforeClose, baseDrawer.closeDrawer]);
12176

12277
return {
12378
...baseDrawer,
124-
closeDrawer, // Override with our version that calls onBeforeClose
79+
closeDrawer,
12580
compositeDrawer,
12681
drawerHeader,
12782
drawerBody,
12883
drawerFooter,
12984
};
13085
};
13186

132-
/**
133-
* Simplified composite drawer with render prop pattern
134-
*
135-
* @description
136-
* Alternative API using render props for more flexibility
137-
*
138-
* @example
139-
* ```typescript
140-
* const drawer = useCompositeDrawerWithRender({
141-
* anchor: 'right',
142-
* width: 500,
143-
* render: ({ closeDrawer }) => ({
144-
* header: {
145-
* title: 'Settings',
146-
* onClose: closeDrawer
147-
* },
148-
* body: {
149-
* children: <SettingsForm />
150-
* },
151-
* footer: {
152-
* primaryButton: {
153-
* label: 'Apply',
154-
* onClick: () => {
155-
* applySettings();
156-
* closeDrawer();
157-
* }
158-
* }
159-
* }
160-
* })
161-
* });
162-
* ```
163-
*/
16487
export const useCompositeDrawerWithRender = (
16588
config: Omit<CompositeDrawerConfig, 'header' | 'body' | 'footer'> & {
16689
render: (actions: {

0 commit comments

Comments
 (0)