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:
Chirag Madlani 2025-08-12 15:28:49 +05:30 committed by GitHub
parent 64c1fc15d3
commit 6c948e68bc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 132 additions and 26 deletions

View File

@ -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();
});
});
});

View File

@ -98,7 +98,7 @@ export const GenericProvider = <T extends Omit<EntityReference, 'type'>>({
const { tab } = useRequiredParams<{ tab: EntityTabs }>();
const expandedLayout = useRef<WidgetConfig[]>([]);
const [layout, setLayout] = useState<WidgetConfig[]>(
getLayoutFromCustomizedPage(pageType, tab, customizedPage)
getLayoutFromCustomizedPage(pageType, tab, customizedPage, isVersionView)
);
const [filteredKeys, setFilteredKeys] = useState<string[]>([]);
const [activeTagDropdownKey, setActiveTagDropdownKey] = useState<
@ -106,8 +106,10 @@ export const GenericProvider = <T extends Omit<EntityReference, 'type'>>({
>(null);
useEffect(() => {
setLayout(getLayoutFromCustomizedPage(pageType, tab, customizedPage));
}, [customizedPage, tab, pageType]);
setLayout(
getLayoutFromCustomizedPage(pageType, tab, customizedPage, isVersionView)
);
}, [customizedPage, tab, pageType, isVersionView]);
const onThreadPanelClose = useCallback(() => {
setThreadLink('');

View File

@ -34,7 +34,7 @@
&.custom-tab {
background: @white;
border-radius: @border-rad-sm;
margin-top: @padding-sm;
padding: @padding-sm;
}
> #KnowledgePanel\.LeftPanel {

View File

@ -56,8 +56,7 @@ const GlossaryDetails = ({
const { onAddGlossaryTerm } = useGlossaryStore();
// Since we are rendering this component for all customized tabs we need tab ID to get layout form store
const { tab: activeTab = EntityTabs.TERMS } =
useRequiredParams<{ tab: EntityTabs }>();
const { tab: activeTab } = useRequiredParams<{ tab: EntityTabs }>();
const { customizedPage, isLoading } = useCustomPages(PageType.Glossary);
const handleFeedCount = useCallback((data: FeedCounts) => {

View File

@ -12,7 +12,6 @@
*/
import { Col, Row, Tabs } from 'antd';
import { isEmpty } from 'lodash';
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { useTranslation } from 'react-i18next';
@ -158,7 +157,7 @@ const GlossaryTermsV1 = ({
const handleAssetSave = useCallback(() => {
fetchGlossaryTermAssets();
assetTabRef.current?.refreshAssets();
activeTab !== 'assets' && activeTabHandler('assets');
activeTab !== EntityTabs.ASSETS && activeTabHandler(EntityTabs.ASSETS);
}, [assetTabRef, activeTab]);
const onExtensionUpdate = useCallback(
@ -204,12 +203,12 @@ const GlossaryTermsV1 = ({
{getCountBadge(
childGlossaryTerms.length,
'',
activeTab === EntityTabs.TERMS
activeTab === EntityTabs.GLOSSARY_TERMS
)}
</span>
</div>
),
key: EntityTabs.TERMS,
key: EntityTabs.GLOSSARY_TERMS,
children: (
<GlossaryTermTab
className="p-md glossary-term-table-container"
@ -295,7 +294,8 @@ const GlossaryTermsV1 = ({
return getDetailsTabWithNewLabel(
items,
customizedPage?.tabs,
EntityTabs.OVERVIEW
EntityTabs.OVERVIEW,
isVersionView
);
}, [
customizedPage?.tabs,

View File

@ -13,21 +13,31 @@
import { render, screen } from '@testing-library/react';
import { OperationPermission } from '../../../context/PermissionProvider/PermissionProvider.interface';
import { EntityTabs } from '../../../enums/entity.enum';
import {
mockedGlossaryTerms,
MOCK_ASSETS_DATA,
MOCK_PERMISSIONS,
} from '../../../mocks/Glossary.mock';
import { useRequiredParams } from '../../../utils/useRequiredParams';
import GlossaryTerms from './GlossaryTermsV1.component';
const mockPush = jest.fn();
jest.mock('react-router-dom', () => ({
...jest.requireActual('react-router-dom'),
useParams: jest.fn().mockImplementation(() => ({
glossaryName: 'glossary',
tab: 'terms',
useNavigate: jest.fn().mockImplementation(() => mockPush),
}));
jest.mock('../../../utils/useRequiredParams', () => ({
useRequiredParams: jest.fn().mockReturnValue({
tab: undefined,
version: 'glossaryVersion',
})),
useNavigate: jest.fn().mockReturnValue(jest.fn()),
}),
}));
jest.mock('../../../hooks/useFqn', () => ({
useFqn: jest.fn().mockReturnValue({ fqn: 'glossaryTerm' }),
}));
jest.mock(
@ -54,9 +64,9 @@ jest.mock('../GlossaryTermTab/GlossaryTermTab.component', () =>
jest.mock('../GlossaryHeader/GlossaryHeader.component', () =>
jest.fn().mockReturnValue(<div>GlossaryHeader.component</div>)
);
jest.mock('../../Customization/GenericTab/GenericTab', () =>
jest.fn().mockReturnValue(<div>GenericTab</div>)
);
jest.mock('../../Customization/GenericTab/GenericTab', () => ({
GenericTab: jest.fn().mockImplementation(() => <div>GenericTab</div>),
}));
const mockProps = {
isSummaryPanelOpen: false,
@ -103,7 +113,32 @@ jest.mock('../../../utils/TableColumn.util', () => ({
}));
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} />);
const tabs = await screen.findAllByRole('tab');

View File

@ -227,11 +227,11 @@ const GlossaryV1 = ({
setTermsLoading(true);
// Update store with newly created term
insertNewGlossaryTermToChildTerms(term);
if (!isGlossaryActive && tab !== 'terms') {
if (!isGlossaryActive && tab !== EntityTabs.GLOSSARY_TERMS) {
navigate(
getGlossaryTermDetailsPath(
selectedData.fullyQualifiedName || '',
EntityTabs.TERMS
EntityTabs.GLOSSARY_TERMS
)
);
}

View File

@ -524,9 +524,10 @@ export const getDetailsTabWithNewLabel = (
NonNullable<TabsProps['items']>[number] & { isHidden?: boolean }
>,
customizedTabs?: Tab[],
defaultTabId: EntityTabs = EntityTabs.OVERVIEW
defaultTabId: EntityTabs = EntityTabs.OVERVIEW,
isVersionView = false
) => {
if (!customizedTabs) {
if (!customizedTabs || isVersionView) {
return defaultTabs.filter((data) => !data.isHidden);
}
const overviewTab = defaultTabs?.find((t) => t.key === defaultTabId);
@ -571,9 +572,10 @@ export const asyncNoop = async () => {
export const getLayoutFromCustomizedPage = (
pageType: PageType,
tab: EntityTabs,
customizedPage?: Page | null
customizedPage?: Page | null,
isVersionView = false
) => {
if (!customizedPage) {
if (!customizedPage || isVersionView) {
return getDefaultWidgetForTab(pageType, tab);
}