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:
Ashish Gupta 2022-10-20 17:45:42 +05:30 committed by GitHub
parent 38cd7eb6af
commit 6ad828ef98
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 75 additions and 18 deletions

View File

@ -11,7 +11,12 @@
* 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 React from 'react';
import { MemoryRouter } from 'react-router-dom';
@ -205,6 +210,7 @@ jest.mock('../../utils/CommonUtils', () => {
getEntityName: jest.fn().mockReturnValue('entityName'),
getEntityPlaceHolder: jest.fn().mockReturnValue('entityPlaceholder'),
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 () => {
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(
<MlModelDetailComponent {...mockProp} activeTab={3} />,
{

View File

@ -14,7 +14,7 @@
import { Col, Row, Table } from 'antd';
import { ColumnsType } from 'antd/lib/table';
import classNames from 'classnames';
import { isUndefined, startCase, uniqueId } from 'lodash';
import { isEmpty, isUndefined, startCase, uniqueId } from 'lodash';
import { observer } from 'mobx-react';
import { EntityTags, ExtraInfo } from 'Models';
import React, {
@ -26,6 +26,7 @@ import React, {
useMemo,
useState,
} from 'react';
import { useTranslation } from 'react-i18next';
import AppState from '../../AppState';
import { FQN_SEPARATOR_CHAR } from '../../constants/char.constants';
import {
@ -46,6 +47,7 @@ import { LabelType, State, TagLabel } from '../../generated/type/tagLabel';
import { useInfiniteScroll } from '../../hooks/useInfiniteScroll';
import jsonData from '../../jsons/en';
import {
getEmptyPlaceholder,
getEntityName,
getEntityPlaceHolder,
getOwnerValue,
@ -95,6 +97,7 @@ const MlModelDetail: FC<MlModelDetailProp> = ({
entityFieldTaskCount,
entityFieldThreadCount,
}) => {
const { t } = useTranslation();
const [followersCount, setFollowersCount] = useState<number>(0);
const [isFollowing, setIsFollowing] = useState<boolean>(false);
@ -379,12 +382,12 @@ const MlModelDetail: FC<MlModelDetailProp> = ({
const getMlHyperParametersColumn: ColumnsType<MlHyperParameter> = useMemo(
() => [
{
title: 'Name',
title: t('label.name'),
dataIndex: 'name',
key: 'name',
},
{
title: 'Value',
title: t('label.value'),
dataIndex: 'value',
key: 'value',
},
@ -395,16 +398,22 @@ const MlModelDetail: FC<MlModelDetailProp> = ({
const getMlHyperParameters = () => {
return (
<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">
<Table
columns={getMlHyperParametersColumn}
data-testid="hyperparameters-table"
dataSource={mlModelDetail.mlHyperParameters}
pagination={false}
rowKey="name"
size="small"
/>
{isEmpty(mlModelDetail.mlHyperParameters) ? (
getEmptyPlaceholder()
) : (
<Table
columns={getMlHyperParametersColumn}
data-testid="hyperparameters-table"
dataSource={mlModelDetail.mlHyperParameters}
pagination={false}
rowKey="name"
size="small"
/>
)}
</div>
</div>
);
@ -413,7 +422,7 @@ const MlModelDetail: FC<MlModelDetailProp> = ({
const getMlModelStore = () => {
return (
<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 ? (
<div className="m-t-xs tw-table-container">
<table
@ -459,7 +468,7 @@ const MlModelDetail: FC<MlModelDetailProp> = ({
</table>
</div>
) : (
<span className="tw-text-grey-muted tw-text-center">No Data</span>
getEmptyPlaceholder()
)}
</div>
);

View File

@ -35,12 +35,15 @@
"table-metrics-summary": "Table Metrics Summary",
"table-tests-summary": "Table Tests Summary",
"frequently-joined-columns": "Frequently joined columns",
"no-description": "No description",
"request-tags": "Request tags",
"update-request-tags": "Update request tags",
"request-description": "Request 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": {},
"server": {},

View File

@ -11,10 +11,11 @@
* limitations under the License.
*/
import { Popover, Space, Tag } from 'antd';
import { Popover, Space, Tag, Typography } from 'antd';
import { ColumnsType } from 'antd/lib/table';
import { AxiosError } from 'axios';
import classNames from 'classnames';
import i18n from 'i18next';
import {
capitalize,
differenceWith,
@ -43,6 +44,7 @@ import {
getDayCron,
getHourCron,
} from '../components/common/CronEditor/CronEditor.constant';
import ErrorPlaceHolder from '../components/common/error-with-placeholder/ErrorPlaceHolder';
import PopOver from '../components/common/popover/PopOver';
import { FQN_SEPARATOR_CHAR } from '../constants/char.constants';
import {
@ -57,6 +59,7 @@ import {
UrlEntityCharRegEx,
validEmailRegEx,
} from '../constants/regex.constants';
import { SIZE } from '../enums/common.enum';
import { EntityType, FqnPart, TabSpecificField } from '../enums/entity.enum';
import { Ownership } from '../enums/mydata.enum';
import { Bot } from '../generated/entity/bot';
@ -1040,3 +1043,13 @@ export const getIngestionFrequency = (pipelineType: PipelineType) => {
return getDayCron(value);
}
};
export const getEmptyPlaceholder = () => {
return (
<ErrorPlaceHolder size={SIZE.MEDIUM}>
<Typography.Paragraph>
{i18n.t('label.no-data-available')}
</Typography.Paragraph>
</ErrorPlaceHolder>
);
};