diff --git a/openmetadata-ui/src/main/resources/ui/src/components/MlModelDetail/MlModelDetail.component.test.tsx b/openmetadata-ui/src/main/resources/ui/src/components/MlModelDetail/MlModelDetail.component.test.tsx
index 23b63bed87c..76756b91561 100644
--- a/openmetadata-ui/src/main/resources/ui/src/components/MlModelDetail/MlModelDetail.component.test.tsx
+++ b/openmetadata-ui/src/main/resources/ui/src/components/MlModelDetail/MlModelDetail.component.test.tsx
@@ -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(
ErrorPlaceHolder
),
};
});
@@ -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(
+ ,
+ {
+ 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(
,
{
diff --git a/openmetadata-ui/src/main/resources/ui/src/components/MlModelDetail/MlModelDetail.component.tsx b/openmetadata-ui/src/main/resources/ui/src/components/MlModelDetail/MlModelDetail.component.tsx
index aaad9b9be5b..6fd4f67fd65 100644
--- a/openmetadata-ui/src/main/resources/ui/src/components/MlModelDetail/MlModelDetail.component.tsx
+++ b/openmetadata-ui/src/main/resources/ui/src/components/MlModelDetail/MlModelDetail.component.tsx
@@ -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 = ({
entityFieldTaskCount,
entityFieldThreadCount,
}) => {
+ const { t } = useTranslation();
const [followersCount, setFollowersCount] = useState(0);
const [isFollowing, setIsFollowing] = useState(false);
@@ -379,12 +382,12 @@ const MlModelDetail: FC = ({
const getMlHyperParametersColumn: ColumnsType = 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 = ({
const getMlHyperParameters = () => {
return (
-
Hyper Parameters
+
+ {t('label.hyper-parameters')}{' '}
+
-
+ {isEmpty(mlModelDetail.mlHyperParameters) ? (
+ getEmptyPlaceholder()
+ ) : (
+
+ )}
);
@@ -413,7 +422,7 @@ const MlModelDetail: FC = ({
const getMlModelStore = () => {
return (
-
Model Store
+
{t('label.model-store')}
{mlModelDetail.mlStore ? (
) : (
-
No Data
+ getEmptyPlaceholder()
)}
);
diff --git a/openmetadata-ui/src/main/resources/ui/src/locale/languages/en-us.json b/openmetadata-ui/src/main/resources/ui/src/locale/languages/en-us.json
index b114fdeea95..35822789ed8 100644
--- a/openmetadata-ui/src/main/resources/ui/src/locale/languages/en-us.json
+++ b/openmetadata-ui/src/main/resources/ui/src/locale/languages/en-us.json
@@ -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": {},
diff --git a/openmetadata-ui/src/main/resources/ui/src/utils/CommonUtils.tsx b/openmetadata-ui/src/main/resources/ui/src/utils/CommonUtils.tsx
index 0bba49b68bd..402e503c313 100644
--- a/openmetadata-ui/src/main/resources/ui/src/utils/CommonUtils.tsx
+++ b/openmetadata-ui/src/main/resources/ui/src/utils/CommonUtils.tsx
@@ -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 (
+
+
+ {i18n.t('label.no-data-available')}
+
+
+ );
+};