mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-10-02 04:13:17 +00:00
fix(ui): terms got vanished for customised persona in glossary terms … (#22561)
* fix(ui): terms got vanished for customised persona in glossary terms page (cherry picked from commit 17341ec1cb17858067fb3869451342a71162be72) * fix the overview tab if it's placement changed on persona to next tabs * fix the version page tabs contains persona tab changes as well * fix tab change issue * remove the comment code as not needed * fix localisation issue for glossary terms page * add test * fix unit test * fix test * fix test * revert localisation changes --------- Co-authored-by: Ashish Gupta <ashish@getcollate.io> Co-authored-by: Pranita <pfulsundar8@gmail.com>
This commit is contained in:
parent
64c1fc15d3
commit
6c948e68bc
@ -529,4 +529,72 @@ test.describe('Persona customization', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('Validate Glossary Term details page after customization of tabs', async ({
|
||||||
|
adminPage,
|
||||||
|
userPage,
|
||||||
|
}) => {
|
||||||
|
test.slow();
|
||||||
|
|
||||||
|
await test.step('apply customization', async () => {
|
||||||
|
await settingClick(adminPage, GlobalSettingOptions.PERSONA);
|
||||||
|
await adminPage.waitForLoadState('networkidle');
|
||||||
|
await adminPage
|
||||||
|
.getByTestId(`persona-details-card-${persona.data.name}`)
|
||||||
|
.click();
|
||||||
|
await adminPage.getByRole('tab', { name: 'Customize UI' }).click();
|
||||||
|
await adminPage.waitForLoadState('networkidle');
|
||||||
|
await adminPage.getByText('Governance').click();
|
||||||
|
await adminPage.getByText('Glossary Term', { exact: true }).click();
|
||||||
|
|
||||||
|
await adminPage.waitForSelector('[data-testid="loader"]', {
|
||||||
|
state: 'detached',
|
||||||
|
});
|
||||||
|
|
||||||
|
const dragElement = adminPage.getByTestId('tab-Overview');
|
||||||
|
const dropTarget = adminPage.getByTestId('tab-Custom Properties');
|
||||||
|
|
||||||
|
await dragElement.dragTo(dropTarget);
|
||||||
|
|
||||||
|
expect(adminPage.getByTestId('save-button')).toBeEnabled();
|
||||||
|
|
||||||
|
await adminPage.getByTestId('save-button').click();
|
||||||
|
|
||||||
|
await toastNotification(
|
||||||
|
adminPage,
|
||||||
|
/^Page layout (created|updated) successfully\.$/
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
await test.step('Validate customization', async () => {
|
||||||
|
await redirectToHomePage(userPage);
|
||||||
|
|
||||||
|
const entity = getCustomizeDetailsEntity(
|
||||||
|
ECustomizedGovernance.GLOSSARY_TERM
|
||||||
|
);
|
||||||
|
await entity.visitEntityPage(userPage);
|
||||||
|
await userPage.waitForLoadState('networkidle');
|
||||||
|
await userPage.waitForSelector('[data-testid="loader"]', {
|
||||||
|
state: 'detached',
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(userPage.getByRole('tab', { name: 'Overview' })).toBeVisible();
|
||||||
|
expect(
|
||||||
|
userPage.getByRole('tab', { name: 'Glossary Terms' })
|
||||||
|
).toBeVisible();
|
||||||
|
expect(
|
||||||
|
userPage.getByTestId('create-error-placeholder-Glossary Term')
|
||||||
|
).toBeVisible();
|
||||||
|
|
||||||
|
await userPage.getByRole('tab', { name: 'Overview' }).click();
|
||||||
|
|
||||||
|
expect(userPage.getByTestId('asset-description-container')).toBeVisible();
|
||||||
|
|
||||||
|
await userPage.getByRole('tab', { name: 'Glossary Terms' }).click();
|
||||||
|
|
||||||
|
expect(
|
||||||
|
userPage.getByTestId('create-error-placeholder-Glossary Term')
|
||||||
|
).toBeVisible();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -98,7 +98,7 @@ export const GenericProvider = <T extends Omit<EntityReference, 'type'>>({
|
|||||||
const { tab } = useRequiredParams<{ tab: EntityTabs }>();
|
const { tab } = useRequiredParams<{ tab: EntityTabs }>();
|
||||||
const expandedLayout = useRef<WidgetConfig[]>([]);
|
const expandedLayout = useRef<WidgetConfig[]>([]);
|
||||||
const [layout, setLayout] = useState<WidgetConfig[]>(
|
const [layout, setLayout] = useState<WidgetConfig[]>(
|
||||||
getLayoutFromCustomizedPage(pageType, tab, customizedPage)
|
getLayoutFromCustomizedPage(pageType, tab, customizedPage, isVersionView)
|
||||||
);
|
);
|
||||||
const [filteredKeys, setFilteredKeys] = useState<string[]>([]);
|
const [filteredKeys, setFilteredKeys] = useState<string[]>([]);
|
||||||
const [activeTagDropdownKey, setActiveTagDropdownKey] = useState<
|
const [activeTagDropdownKey, setActiveTagDropdownKey] = useState<
|
||||||
@ -106,8 +106,10 @@ export const GenericProvider = <T extends Omit<EntityReference, 'type'>>({
|
|||||||
>(null);
|
>(null);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setLayout(getLayoutFromCustomizedPage(pageType, tab, customizedPage));
|
setLayout(
|
||||||
}, [customizedPage, tab, pageType]);
|
getLayoutFromCustomizedPage(pageType, tab, customizedPage, isVersionView)
|
||||||
|
);
|
||||||
|
}, [customizedPage, tab, pageType, isVersionView]);
|
||||||
|
|
||||||
const onThreadPanelClose = useCallback(() => {
|
const onThreadPanelClose = useCallback(() => {
|
||||||
setThreadLink('');
|
setThreadLink('');
|
||||||
|
@ -34,7 +34,7 @@
|
|||||||
&.custom-tab {
|
&.custom-tab {
|
||||||
background: @white;
|
background: @white;
|
||||||
border-radius: @border-rad-sm;
|
border-radius: @border-rad-sm;
|
||||||
margin-top: @padding-sm;
|
padding: @padding-sm;
|
||||||
}
|
}
|
||||||
|
|
||||||
> #KnowledgePanel\.LeftPanel {
|
> #KnowledgePanel\.LeftPanel {
|
||||||
|
@ -56,8 +56,7 @@ const GlossaryDetails = ({
|
|||||||
const { onAddGlossaryTerm } = useGlossaryStore();
|
const { onAddGlossaryTerm } = useGlossaryStore();
|
||||||
|
|
||||||
// Since we are rendering this component for all customized tabs we need tab ID to get layout form store
|
// Since we are rendering this component for all customized tabs we need tab ID to get layout form store
|
||||||
const { tab: activeTab = EntityTabs.TERMS } =
|
const { tab: activeTab } = useRequiredParams<{ tab: EntityTabs }>();
|
||||||
useRequiredParams<{ tab: EntityTabs }>();
|
|
||||||
const { customizedPage, isLoading } = useCustomPages(PageType.Glossary);
|
const { customizedPage, isLoading } = useCustomPages(PageType.Glossary);
|
||||||
|
|
||||||
const handleFeedCount = useCallback((data: FeedCounts) => {
|
const handleFeedCount = useCallback((data: FeedCounts) => {
|
||||||
|
@ -12,7 +12,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { Col, Row, Tabs } from 'antd';
|
import { Col, Row, Tabs } from 'antd';
|
||||||
|
|
||||||
import { isEmpty } from 'lodash';
|
import { isEmpty } from 'lodash';
|
||||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
@ -158,7 +157,7 @@ const GlossaryTermsV1 = ({
|
|||||||
const handleAssetSave = useCallback(() => {
|
const handleAssetSave = useCallback(() => {
|
||||||
fetchGlossaryTermAssets();
|
fetchGlossaryTermAssets();
|
||||||
assetTabRef.current?.refreshAssets();
|
assetTabRef.current?.refreshAssets();
|
||||||
activeTab !== 'assets' && activeTabHandler('assets');
|
activeTab !== EntityTabs.ASSETS && activeTabHandler(EntityTabs.ASSETS);
|
||||||
}, [assetTabRef, activeTab]);
|
}, [assetTabRef, activeTab]);
|
||||||
|
|
||||||
const onExtensionUpdate = useCallback(
|
const onExtensionUpdate = useCallback(
|
||||||
@ -204,12 +203,12 @@ const GlossaryTermsV1 = ({
|
|||||||
{getCountBadge(
|
{getCountBadge(
|
||||||
childGlossaryTerms.length,
|
childGlossaryTerms.length,
|
||||||
'',
|
'',
|
||||||
activeTab === EntityTabs.TERMS
|
activeTab === EntityTabs.GLOSSARY_TERMS
|
||||||
)}
|
)}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
),
|
),
|
||||||
key: EntityTabs.TERMS,
|
key: EntityTabs.GLOSSARY_TERMS,
|
||||||
children: (
|
children: (
|
||||||
<GlossaryTermTab
|
<GlossaryTermTab
|
||||||
className="p-md glossary-term-table-container"
|
className="p-md glossary-term-table-container"
|
||||||
@ -295,7 +294,8 @@ const GlossaryTermsV1 = ({
|
|||||||
return getDetailsTabWithNewLabel(
|
return getDetailsTabWithNewLabel(
|
||||||
items,
|
items,
|
||||||
customizedPage?.tabs,
|
customizedPage?.tabs,
|
||||||
EntityTabs.OVERVIEW
|
EntityTabs.OVERVIEW,
|
||||||
|
isVersionView
|
||||||
);
|
);
|
||||||
}, [
|
}, [
|
||||||
customizedPage?.tabs,
|
customizedPage?.tabs,
|
||||||
|
@ -13,21 +13,31 @@
|
|||||||
|
|
||||||
import { render, screen } from '@testing-library/react';
|
import { render, screen } from '@testing-library/react';
|
||||||
import { OperationPermission } from '../../../context/PermissionProvider/PermissionProvider.interface';
|
import { OperationPermission } from '../../../context/PermissionProvider/PermissionProvider.interface';
|
||||||
|
import { EntityTabs } from '../../../enums/entity.enum';
|
||||||
import {
|
import {
|
||||||
mockedGlossaryTerms,
|
mockedGlossaryTerms,
|
||||||
MOCK_ASSETS_DATA,
|
MOCK_ASSETS_DATA,
|
||||||
MOCK_PERMISSIONS,
|
MOCK_PERMISSIONS,
|
||||||
} from '../../../mocks/Glossary.mock';
|
} from '../../../mocks/Glossary.mock';
|
||||||
|
import { useRequiredParams } from '../../../utils/useRequiredParams';
|
||||||
import GlossaryTerms from './GlossaryTermsV1.component';
|
import GlossaryTerms from './GlossaryTermsV1.component';
|
||||||
|
|
||||||
|
const mockPush = jest.fn();
|
||||||
|
|
||||||
jest.mock('react-router-dom', () => ({
|
jest.mock('react-router-dom', () => ({
|
||||||
...jest.requireActual('react-router-dom'),
|
...jest.requireActual('react-router-dom'),
|
||||||
useParams: jest.fn().mockImplementation(() => ({
|
useNavigate: jest.fn().mockImplementation(() => mockPush),
|
||||||
glossaryName: 'glossary',
|
}));
|
||||||
tab: 'terms',
|
|
||||||
|
jest.mock('../../../utils/useRequiredParams', () => ({
|
||||||
|
useRequiredParams: jest.fn().mockReturnValue({
|
||||||
|
tab: undefined,
|
||||||
version: 'glossaryVersion',
|
version: 'glossaryVersion',
|
||||||
})),
|
}),
|
||||||
useNavigate: jest.fn().mockReturnValue(jest.fn()),
|
}));
|
||||||
|
|
||||||
|
jest.mock('../../../hooks/useFqn', () => ({
|
||||||
|
useFqn: jest.fn().mockReturnValue({ fqn: 'glossaryTerm' }),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
jest.mock(
|
jest.mock(
|
||||||
@ -54,9 +64,9 @@ jest.mock('../GlossaryTermTab/GlossaryTermTab.component', () =>
|
|||||||
jest.mock('../GlossaryHeader/GlossaryHeader.component', () =>
|
jest.mock('../GlossaryHeader/GlossaryHeader.component', () =>
|
||||||
jest.fn().mockReturnValue(<div>GlossaryHeader.component</div>)
|
jest.fn().mockReturnValue(<div>GlossaryHeader.component</div>)
|
||||||
);
|
);
|
||||||
jest.mock('../../Customization/GenericTab/GenericTab', () =>
|
jest.mock('../../Customization/GenericTab/GenericTab', () => ({
|
||||||
jest.fn().mockReturnValue(<div>GenericTab</div>)
|
GenericTab: jest.fn().mockImplementation(() => <div>GenericTab</div>),
|
||||||
);
|
}));
|
||||||
|
|
||||||
const mockProps = {
|
const mockProps = {
|
||||||
isSummaryPanelOpen: false,
|
isSummaryPanelOpen: false,
|
||||||
@ -103,7 +113,32 @@ jest.mock('../../../utils/TableColumn.util', () => ({
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
describe('Test Glossary-term component', () => {
|
describe('Test Glossary-term component', () => {
|
||||||
it('Should render GenericTab component', async () => {
|
it('Should render overview tab when activeTab is undefined', async () => {
|
||||||
|
render(<GlossaryTerms {...mockProps} />);
|
||||||
|
|
||||||
|
expect(screen.getByTestId('glossary-term')).toBeInTheDocument();
|
||||||
|
|
||||||
|
const tabs = await screen.findAllByRole('tab');
|
||||||
|
|
||||||
|
expect(tabs).toHaveLength(5);
|
||||||
|
expect(tabs[0].textContent).toBe('label.overview');
|
||||||
|
|
||||||
|
tabs
|
||||||
|
.filter((tab) => tab.textContent !== 'label.overview')
|
||||||
|
.forEach((tab) => {
|
||||||
|
expect(tab).not.toHaveAttribute('aria-selected', 'true');
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(mockPush).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should render GlossaryTermTab component', async () => {
|
||||||
|
const useRequiredParamsMock = useRequiredParams as jest.Mock;
|
||||||
|
useRequiredParamsMock.mockReturnValue({
|
||||||
|
tab: EntityTabs.GLOSSARY_TERMS,
|
||||||
|
version: 'glossaryVersion',
|
||||||
|
});
|
||||||
|
|
||||||
render(<GlossaryTerms {...mockProps} />);
|
render(<GlossaryTerms {...mockProps} />);
|
||||||
|
|
||||||
const tabs = await screen.findAllByRole('tab');
|
const tabs = await screen.findAllByRole('tab');
|
||||||
|
@ -227,11 +227,11 @@ const GlossaryV1 = ({
|
|||||||
setTermsLoading(true);
|
setTermsLoading(true);
|
||||||
// Update store with newly created term
|
// Update store with newly created term
|
||||||
insertNewGlossaryTermToChildTerms(term);
|
insertNewGlossaryTermToChildTerms(term);
|
||||||
if (!isGlossaryActive && tab !== 'terms') {
|
if (!isGlossaryActive && tab !== EntityTabs.GLOSSARY_TERMS) {
|
||||||
navigate(
|
navigate(
|
||||||
getGlossaryTermDetailsPath(
|
getGlossaryTermDetailsPath(
|
||||||
selectedData.fullyQualifiedName || '',
|
selectedData.fullyQualifiedName || '',
|
||||||
EntityTabs.TERMS
|
EntityTabs.GLOSSARY_TERMS
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -524,9 +524,10 @@ export const getDetailsTabWithNewLabel = (
|
|||||||
NonNullable<TabsProps['items']>[number] & { isHidden?: boolean }
|
NonNullable<TabsProps['items']>[number] & { isHidden?: boolean }
|
||||||
>,
|
>,
|
||||||
customizedTabs?: Tab[],
|
customizedTabs?: Tab[],
|
||||||
defaultTabId: EntityTabs = EntityTabs.OVERVIEW
|
defaultTabId: EntityTabs = EntityTabs.OVERVIEW,
|
||||||
|
isVersionView = false
|
||||||
) => {
|
) => {
|
||||||
if (!customizedTabs) {
|
if (!customizedTabs || isVersionView) {
|
||||||
return defaultTabs.filter((data) => !data.isHidden);
|
return defaultTabs.filter((data) => !data.isHidden);
|
||||||
}
|
}
|
||||||
const overviewTab = defaultTabs?.find((t) => t.key === defaultTabId);
|
const overviewTab = defaultTabs?.find((t) => t.key === defaultTabId);
|
||||||
@ -571,9 +572,10 @@ export const asyncNoop = async () => {
|
|||||||
export const getLayoutFromCustomizedPage = (
|
export const getLayoutFromCustomizedPage = (
|
||||||
pageType: PageType,
|
pageType: PageType,
|
||||||
tab: EntityTabs,
|
tab: EntityTabs,
|
||||||
customizedPage?: Page | null
|
customizedPage?: Page | null,
|
||||||
|
isVersionView = false
|
||||||
) => {
|
) => {
|
||||||
if (!customizedPage) {
|
if (!customizedPage || isVersionView) {
|
||||||
return getDefaultWidgetForTab(pageType, tab);
|
return getDefaultWidgetForTab(pageType, tab);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user