fix(ui): shown children tab in storage container in case of schema empty (#13172)

* shown children tab in storage container in case of schema empty

* fix unit test

* fix unit test

---------

Co-authored-by: Chirag Madlani <12962843+chirag-madlani@users.noreply.github.com>
This commit is contained in:
Ashish Gupta 2023-09-19 19:40:55 +05:30 committed by GitHub
parent af6cd905e9
commit 64607c8869
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 89 additions and 43 deletions

View File

@ -15,6 +15,7 @@ import React from 'react';
import { BrowserRouter } from 'react-router-dom'; import { BrowserRouter } from 'react-router-dom';
import ContainerChildren from './ContainerChildren'; import ContainerChildren from './ContainerChildren';
const mockFetchChildren = jest.fn();
const mockChildrenList = [ const mockChildrenList = [
{ {
id: '1', id: '1',
@ -32,11 +33,26 @@ const mockChildrenList = [
}, },
]; ];
const mockDataProps = {
childrenList: mockChildrenList,
fetchChildren: mockFetchChildren,
};
describe('ContainerChildren', () => { describe('ContainerChildren', () => {
it('Should call fetch container function on load', () => {
render(
<BrowserRouter>
<ContainerChildren {...mockDataProps} />
</BrowserRouter>
);
expect(mockFetchChildren).toHaveBeenCalled();
});
it('Should render table with correct columns', () => { it('Should render table with correct columns', () => {
render( render(
<BrowserRouter> <BrowserRouter>
<ContainerChildren childrenList={mockChildrenList} /> <ContainerChildren {...mockDataProps} />
</BrowserRouter> </BrowserRouter>
); );
@ -48,7 +64,7 @@ describe('ContainerChildren', () => {
it('Should render container names as links', () => { it('Should render container names as links', () => {
render( render(
<BrowserRouter> <BrowserRouter>
<ContainerChildren childrenList={mockChildrenList} /> <ContainerChildren {...mockDataProps} />
</BrowserRouter> </BrowserRouter>
); );
@ -68,7 +84,7 @@ describe('ContainerChildren', () => {
it('Should render container descriptions as rich text', () => { it('Should render container descriptions as rich text', () => {
render( render(
<BrowserRouter> <BrowserRouter>
<ContainerChildren childrenList={mockChildrenList} /> <ContainerChildren {...mockDataProps} />
</BrowserRouter> </BrowserRouter>
); );

View File

@ -18,7 +18,7 @@ import Table from 'components/common/Table/Table';
import { getContainerDetailPath } from 'constants/constants'; import { getContainerDetailPath } from 'constants/constants';
import { Container } from 'generated/entity/data/container'; import { Container } from 'generated/entity/data/container';
import { EntityReference } from 'generated/type/entityReference'; import { EntityReference } from 'generated/type/entityReference';
import React, { FC, useMemo } from 'react'; import React, { FC, useEffect, useMemo } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
import { getEntityName } from 'utils/EntityUtils'; import { getEntityName } from 'utils/EntityUtils';
@ -26,11 +26,13 @@ import { getEntityName } from 'utils/EntityUtils';
interface ContainerChildrenProps { interface ContainerChildrenProps {
childrenList: Container['children']; childrenList: Container['children'];
isLoading?: boolean; isLoading?: boolean;
fetchChildren: () => void;
} }
const ContainerChildren: FC<ContainerChildrenProps> = ({ const ContainerChildren: FC<ContainerChildrenProps> = ({
childrenList, childrenList,
isLoading, isLoading,
fetchChildren,
}) => { }) => {
const { t } = useTranslation(); const { t } = useTranslation();
@ -72,6 +74,10 @@ const ContainerChildren: FC<ContainerChildrenProps> = ({
[] []
); );
useEffect(() => {
fetchChildren();
}, []);
return ( return (
<Table <Table
bordered bordered

View File

@ -45,7 +45,7 @@ import { CreateThread, ThreadType } from 'generated/api/feed/createThread';
import { Container } from 'generated/entity/data/container'; import { Container } from 'generated/entity/data/container';
import { Include } from 'generated/type/include'; import { Include } from 'generated/type/include';
import { LabelType, State, TagLabel, TagSource } from 'generated/type/tagLabel'; import { LabelType, State, TagLabel, TagSource } from 'generated/type/tagLabel';
import { isUndefined, omitBy, toString } from 'lodash'; import { isEmpty, isUndefined, omitBy, toString } from 'lodash';
import { observer } from 'mobx-react'; import { observer } from 'mobx-react';
import { EntityTags } from 'Models'; import { EntityTags } from 'Models';
import React, { useCallback, useEffect, useMemo, useState } from 'react'; import React, { useCallback, useEffect, useMemo, useState } from 'react';
@ -79,7 +79,7 @@ const ContainerPage = () => {
const { t } = useTranslation(); const { t } = useTranslation();
const { getEntityPermissionByFqn } = usePermissionProvider(); const { getEntityPermissionByFqn } = usePermissionProvider();
const { postFeed, deleteFeed, updateFeed } = useActivityFeedProvider(); const { postFeed, deleteFeed, updateFeed } = useActivityFeedProvider();
const { entityFQN: containerName, tab = EntityTabs.SCHEMA } = const { entityFQN: containerName, tab } =
useParams<{ entityFQN: string; tab: EntityTabs }>(); useParams<{ entityFQN: string; tab: EntityTabs }>();
// Local states // Local states
@ -130,10 +130,10 @@ const ContainerPage = () => {
} }
}; };
const fetchContainerChildren = async (containerFQN: string) => { const fetchContainerChildren = async () => {
setIsChildrenLoading(true); setIsChildrenLoading(true);
try { try {
const { children } = await getContainerByName(containerFQN, 'children'); const { children } = await getContainerByName(containerName, 'children');
setContainerChildrenData(children); setContainerChildrenData(children);
} catch (error) { } catch (error) {
showErrorToast(error as AxiosError); showErrorToast(error as AxiosError);
@ -218,6 +218,11 @@ const ContainerPage = () => {
[AppState.userDetails, AppState.nonSecureUserDetails] [AppState.userDetails, AppState.nonSecureUserDetails]
); );
const isDataModelEmpty = useMemo(
() => isEmpty(containerData?.dataModel),
[containerData]
);
const getEntityFeedCount = () => { const getEntityFeedCount = () => {
getFeedCounts(EntityType.CONTAINER, containerName, setFeedCount); getFeedCounts(EntityType.CONTAINER, containerName, setFeedCount);
}; };
@ -484,8 +489,13 @@ const ContainerPage = () => {
const tabs = useMemo( const tabs = useMemo(
() => [ () => [
{ {
label: <TabsLabel id={EntityTabs.SCHEMA} name={t('label.schema')} />, label: (
key: EntityTabs.SCHEMA, <TabsLabel
id={isDataModelEmpty ? EntityTabs.CHILDREN : EntityTabs.SCHEMA}
name={t(isDataModelEmpty ? 'label.children' : 'label.schema')}
/>
),
key: isDataModelEmpty ? EntityTabs.CHILDREN : EntityTabs.SCHEMA,
children: ( children: (
<Row gutter={[0, 16]} wrap={false}> <Row gutter={[0, 16]} wrap={false}>
<Col className="p-t-sm m-x-lg" flex="auto"> <Col className="p-t-sm m-x-lg" flex="auto">
@ -505,6 +515,13 @@ const ContainerPage = () => {
onThreadLinkSelect={onThreadLinkSelect} onThreadLinkSelect={onThreadLinkSelect}
/> />
{isDataModelEmpty ? (
<ContainerChildren
childrenList={containerChildrenData}
fetchChildren={fetchContainerChildren}
isLoading={isChildrenLoading}
/>
) : (
<ContainerDataModel <ContainerDataModel
dataModel={containerData?.dataModel} dataModel={containerData?.dataModel}
entityFqn={containerName} entityFqn={containerName}
@ -514,6 +531,7 @@ const ContainerPage = () => {
onThreadLinkSelect={onThreadLinkSelect} onThreadLinkSelect={onThreadLinkSelect}
onUpdate={handleUpdateDataModel} onUpdate={handleUpdateDataModel}
/> />
)}
</div> </div>
</Col> </Col>
<Col <Col
@ -550,6 +568,31 @@ const ContainerPage = () => {
</Row> </Row>
), ),
}, },
...(isDataModelEmpty
? []
: [
{
label: (
<TabsLabel
id={EntityTabs.CHILDREN}
name={t('label.children')}
/>
),
key: EntityTabs.CHILDREN,
children: (
<Row className="p-md" gutter={[0, 16]}>
<Col span={24}>
<ContainerChildren
childrenList={containerChildrenData}
fetchChildren={fetchContainerChildren}
isLoading={isChildrenLoading}
/>
</Col>
</Row>
),
},
]),
{ {
label: ( label: (
<TabsLabel <TabsLabel
@ -569,23 +612,6 @@ const ContainerPage = () => {
/> />
), ),
}, },
{
label: (
<TabsLabel id={EntityTabs.CHILDREN} name={t('label.children')} />
),
key: EntityTabs.CHILDREN,
children: (
<Row className="p-md" gutter={[0, 16]}>
<Col span={24}>
<ContainerChildren
childrenList={containerChildrenData}
isLoading={isChildrenLoading}
/>
</Col>
</Row>
),
},
{ {
label: <TabsLabel id={EntityTabs.LINEAGE} name={t('label.lineage')} />, label: <TabsLabel id={EntityTabs.LINEAGE} name={t('label.lineage')} />,
key: EntityTabs.LINEAGE, key: EntityTabs.LINEAGE,
@ -619,6 +645,7 @@ const ContainerPage = () => {
}, },
], ],
[ [
isDataModelEmpty,
containerData, containerData,
description, description,
containerName, containerName,
@ -667,12 +694,6 @@ const ContainerPage = () => {
fetchResourcePermission(containerName); fetchResourcePermission(containerName);
}, [containerName]); }, [containerName]);
useEffect(() => {
if (tab === EntityTabs.CHILDREN && hasViewPermission) {
fetchContainerChildren(containerName);
}
}, [tab, containerName, hasViewPermission]);
useEffect(() => { useEffect(() => {
if (hasViewPermission) { if (hasViewPermission) {
getEntityFeedCount(); getEntityFeedCount();
@ -723,7 +744,10 @@ const ContainerPage = () => {
</Col> </Col>
<Col span={24}> <Col span={24}>
<Tabs <Tabs
activeKey={tab ?? EntityTabs.DETAILS} activeKey={
tab ??
(isDataModelEmpty ? EntityTabs.CHILDREN : EntityTabs.SCHEMA)
}
className="entity-details-page-tabs" className="entity-details-page-tabs"
data-testid="tabs" data-testid="tabs"
items={tabs} items={tabs}