mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-09-02 05:33:49 +00:00
UI :- Added EmptyPlaceholder for no data Modal store (#8220)
* Added EmptyPlaceholder for no data Modal store * import fix for table * added unit test along * changes as per comments
This commit is contained in:
parent
38cd7eb6af
commit
6ad828ef98
@ -11,7 +11,12 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { findByTestId, findByText, render } from '@testing-library/react';
|
import {
|
||||||
|
findAllByText,
|
||||||
|
findByTestId,
|
||||||
|
findByText,
|
||||||
|
render,
|
||||||
|
} from '@testing-library/react';
|
||||||
import { LeafNodes } from 'Models';
|
import { LeafNodes } from 'Models';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { MemoryRouter } from 'react-router-dom';
|
import { MemoryRouter } from 'react-router-dom';
|
||||||
@ -205,6 +210,7 @@ jest.mock('../../utils/CommonUtils', () => {
|
|||||||
getEntityName: jest.fn().mockReturnValue('entityName'),
|
getEntityName: jest.fn().mockReturnValue('entityName'),
|
||||||
getEntityPlaceHolder: jest.fn().mockReturnValue('entityPlaceholder'),
|
getEntityPlaceHolder: jest.fn().mockReturnValue('entityPlaceholder'),
|
||||||
getOwnerValue: jest.fn().mockReturnValue('Owner'),
|
getOwnerValue: jest.fn().mockReturnValue('Owner'),
|
||||||
|
getEmptyPlaceholder: jest.fn().mockReturnValue(<p>ErrorPlaceHolder</p>),
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -244,6 +250,32 @@ describe('Test MlModel entity detail component', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('Should render hyper parameter and ml store table for details tab', async () => {
|
it('Should render hyper parameter and ml store table for details tab', async () => {
|
||||||
|
const mockPropDetails = {
|
||||||
|
...mockProp,
|
||||||
|
mlModelDetail: {
|
||||||
|
...mockProp.mlModelDetail,
|
||||||
|
mlHyperParameters: [],
|
||||||
|
mlStore: undefined,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const { container } = render(
|
||||||
|
<MlModelDetailComponent {...mockPropDetails} activeTab={3} />,
|
||||||
|
{
|
||||||
|
wrapper: MemoryRouter,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
const detailContainer = await findByTestId(container, 'mlmodel-details');
|
||||||
|
const emptyTablePlaceholder = await findAllByText(
|
||||||
|
container,
|
||||||
|
'ErrorPlaceHolder'
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(detailContainer).toBeInTheDocument();
|
||||||
|
expect(emptyTablePlaceholder).toHaveLength(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should render no data placeholder hyper parameter and ml store details tab', async () => {
|
||||||
const { container } = render(
|
const { container } = render(
|
||||||
<MlModelDetailComponent {...mockProp} activeTab={3} />,
|
<MlModelDetailComponent {...mockProp} activeTab={3} />,
|
||||||
{
|
{
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
import { Col, Row, Table } from 'antd';
|
import { Col, Row, Table } from 'antd';
|
||||||
import { ColumnsType } from 'antd/lib/table';
|
import { ColumnsType } from 'antd/lib/table';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { isUndefined, startCase, uniqueId } from 'lodash';
|
import { isEmpty, isUndefined, startCase, uniqueId } from 'lodash';
|
||||||
import { observer } from 'mobx-react';
|
import { observer } from 'mobx-react';
|
||||||
import { EntityTags, ExtraInfo } from 'Models';
|
import { EntityTags, ExtraInfo } from 'Models';
|
||||||
import React, {
|
import React, {
|
||||||
@ -26,6 +26,7 @@ import React, {
|
|||||||
useMemo,
|
useMemo,
|
||||||
useState,
|
useState,
|
||||||
} from 'react';
|
} from 'react';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
import AppState from '../../AppState';
|
import AppState from '../../AppState';
|
||||||
import { FQN_SEPARATOR_CHAR } from '../../constants/char.constants';
|
import { FQN_SEPARATOR_CHAR } from '../../constants/char.constants';
|
||||||
import {
|
import {
|
||||||
@ -46,6 +47,7 @@ import { LabelType, State, TagLabel } from '../../generated/type/tagLabel';
|
|||||||
import { useInfiniteScroll } from '../../hooks/useInfiniteScroll';
|
import { useInfiniteScroll } from '../../hooks/useInfiniteScroll';
|
||||||
import jsonData from '../../jsons/en';
|
import jsonData from '../../jsons/en';
|
||||||
import {
|
import {
|
||||||
|
getEmptyPlaceholder,
|
||||||
getEntityName,
|
getEntityName,
|
||||||
getEntityPlaceHolder,
|
getEntityPlaceHolder,
|
||||||
getOwnerValue,
|
getOwnerValue,
|
||||||
@ -95,6 +97,7 @@ const MlModelDetail: FC<MlModelDetailProp> = ({
|
|||||||
entityFieldTaskCount,
|
entityFieldTaskCount,
|
||||||
entityFieldThreadCount,
|
entityFieldThreadCount,
|
||||||
}) => {
|
}) => {
|
||||||
|
const { t } = useTranslation();
|
||||||
const [followersCount, setFollowersCount] = useState<number>(0);
|
const [followersCount, setFollowersCount] = useState<number>(0);
|
||||||
const [isFollowing, setIsFollowing] = useState<boolean>(false);
|
const [isFollowing, setIsFollowing] = useState<boolean>(false);
|
||||||
|
|
||||||
@ -379,12 +382,12 @@ const MlModelDetail: FC<MlModelDetailProp> = ({
|
|||||||
const getMlHyperParametersColumn: ColumnsType<MlHyperParameter> = useMemo(
|
const getMlHyperParametersColumn: ColumnsType<MlHyperParameter> = useMemo(
|
||||||
() => [
|
() => [
|
||||||
{
|
{
|
||||||
title: 'Name',
|
title: t('label.name'),
|
||||||
dataIndex: 'name',
|
dataIndex: 'name',
|
||||||
key: 'name',
|
key: 'name',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Value',
|
title: t('label.value'),
|
||||||
dataIndex: 'value',
|
dataIndex: 'value',
|
||||||
key: 'value',
|
key: 'value',
|
||||||
},
|
},
|
||||||
@ -395,16 +398,22 @@ const MlModelDetail: FC<MlModelDetailProp> = ({
|
|||||||
const getMlHyperParameters = () => {
|
const getMlHyperParameters = () => {
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col m-t-xs">
|
<div className="flex flex-col m-t-xs">
|
||||||
<h6 className="font-medium text-base">Hyper Parameters</h6>
|
<h6 className="font-medium text-base">
|
||||||
|
{t('label.hyper-parameters')}{' '}
|
||||||
|
</h6>
|
||||||
<div className="m-t-xs">
|
<div className="m-t-xs">
|
||||||
<Table
|
{isEmpty(mlModelDetail.mlHyperParameters) ? (
|
||||||
columns={getMlHyperParametersColumn}
|
getEmptyPlaceholder()
|
||||||
data-testid="hyperparameters-table"
|
) : (
|
||||||
dataSource={mlModelDetail.mlHyperParameters}
|
<Table
|
||||||
pagination={false}
|
columns={getMlHyperParametersColumn}
|
||||||
rowKey="name"
|
data-testid="hyperparameters-table"
|
||||||
size="small"
|
dataSource={mlModelDetail.mlHyperParameters}
|
||||||
/>
|
pagination={false}
|
||||||
|
rowKey="name"
|
||||||
|
size="small"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
@ -413,7 +422,7 @@ const MlModelDetail: FC<MlModelDetailProp> = ({
|
|||||||
const getMlModelStore = () => {
|
const getMlModelStore = () => {
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col m-t-xs">
|
<div className="flex flex-col m-t-xs">
|
||||||
<h6 className="font-medium text-base">Model Store</h6>
|
<h6 className="font-medium text-base">{t('label.model-store')}</h6>
|
||||||
{mlModelDetail.mlStore ? (
|
{mlModelDetail.mlStore ? (
|
||||||
<div className="m-t-xs tw-table-container">
|
<div className="m-t-xs tw-table-container">
|
||||||
<table
|
<table
|
||||||
@ -459,7 +468,7 @@ const MlModelDetail: FC<MlModelDetailProp> = ({
|
|||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<span className="tw-text-grey-muted tw-text-center">No Data</span>
|
getEmptyPlaceholder()
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -35,12 +35,15 @@
|
|||||||
"table-metrics-summary": "Table Metrics Summary",
|
"table-metrics-summary": "Table Metrics Summary",
|
||||||
"table-tests-summary": "Table Tests Summary",
|
"table-tests-summary": "Table Tests Summary",
|
||||||
"frequently-joined-columns": "Frequently joined columns",
|
"frequently-joined-columns": "Frequently joined columns",
|
||||||
"no-description": "No description",
|
|
||||||
"request-tags": "Request tags",
|
"request-tags": "Request tags",
|
||||||
"update-request-tags": "Update request tags",
|
"update-request-tags": "Update request tags",
|
||||||
"request-description": "Request description",
|
"request-description": "Request description",
|
||||||
"request-update-description": "Request update description",
|
"request-update-description": "Request update description",
|
||||||
"enter-column-description": "Enter Column Description"
|
"enter-column-description": "Enter Column Description",
|
||||||
|
"hyper-parameters": "Hyper Parameters",
|
||||||
|
"model-store": "Model Store",
|
||||||
|
"value": "Value",
|
||||||
|
"no-data-available": "No data available"
|
||||||
},
|
},
|
||||||
"message": {},
|
"message": {},
|
||||||
"server": {},
|
"server": {},
|
||||||
|
@ -11,10 +11,11 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Popover, Space, Tag } from 'antd';
|
import { Popover, Space, Tag, Typography } from 'antd';
|
||||||
import { ColumnsType } from 'antd/lib/table';
|
import { ColumnsType } from 'antd/lib/table';
|
||||||
import { AxiosError } from 'axios';
|
import { AxiosError } from 'axios';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
|
import i18n from 'i18next';
|
||||||
import {
|
import {
|
||||||
capitalize,
|
capitalize,
|
||||||
differenceWith,
|
differenceWith,
|
||||||
@ -43,6 +44,7 @@ import {
|
|||||||
getDayCron,
|
getDayCron,
|
||||||
getHourCron,
|
getHourCron,
|
||||||
} from '../components/common/CronEditor/CronEditor.constant';
|
} from '../components/common/CronEditor/CronEditor.constant';
|
||||||
|
import ErrorPlaceHolder from '../components/common/error-with-placeholder/ErrorPlaceHolder';
|
||||||
import PopOver from '../components/common/popover/PopOver';
|
import PopOver from '../components/common/popover/PopOver';
|
||||||
import { FQN_SEPARATOR_CHAR } from '../constants/char.constants';
|
import { FQN_SEPARATOR_CHAR } from '../constants/char.constants';
|
||||||
import {
|
import {
|
||||||
@ -57,6 +59,7 @@ import {
|
|||||||
UrlEntityCharRegEx,
|
UrlEntityCharRegEx,
|
||||||
validEmailRegEx,
|
validEmailRegEx,
|
||||||
} from '../constants/regex.constants';
|
} from '../constants/regex.constants';
|
||||||
|
import { SIZE } from '../enums/common.enum';
|
||||||
import { EntityType, FqnPart, TabSpecificField } from '../enums/entity.enum';
|
import { EntityType, FqnPart, TabSpecificField } from '../enums/entity.enum';
|
||||||
import { Ownership } from '../enums/mydata.enum';
|
import { Ownership } from '../enums/mydata.enum';
|
||||||
import { Bot } from '../generated/entity/bot';
|
import { Bot } from '../generated/entity/bot';
|
||||||
@ -1040,3 +1043,13 @@ export const getIngestionFrequency = (pipelineType: PipelineType) => {
|
|||||||
return getDayCron(value);
|
return getDayCron(value);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const getEmptyPlaceholder = () => {
|
||||||
|
return (
|
||||||
|
<ErrorPlaceHolder size={SIZE.MEDIUM}>
|
||||||
|
<Typography.Paragraph>
|
||||||
|
{i18n.t('label.no-data-available')}
|
||||||
|
</Typography.Paragraph>
|
||||||
|
</ErrorPlaceHolder>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user