diff --git a/openmetadata-ui/src/main/resources/ui/src/axiosAPIs/mlModelAPI.ts b/openmetadata-ui/src/main/resources/ui/src/axiosAPIs/mlModelAPI.ts index 9894fdc8fb7..8463f74fc41 100644 --- a/openmetadata-ui/src/main/resources/ui/src/axiosAPIs/mlModelAPI.ts +++ b/openmetadata-ui/src/main/resources/ui/src/axiosAPIs/mlModelAPI.ts @@ -13,15 +13,25 @@ import { AxiosResponse } from 'axios'; import { Operation } from 'fast-json-patch'; +import { RestoreRequestType } from 'Models'; import { Mlmodel } from '../generated/entity/data/mlmodel'; import { EntityReference } from '../generated/type/entityReference'; +import { Include } from '../generated/type/include'; import { Paging } from '../generated/type/paging'; import { ServicePageData } from '../pages/service'; import { getURLWithQueryFields } from '../utils/APIUtils'; import APIClient from './index'; -export const getMlModelByFQN = async (fqn: string, arrQueryFields: string) => { - const url = getURLWithQueryFields(`mlmodels/name/${fqn}`, arrQueryFields); +export const getMlModelByFQN = async ( + fqn: string, + arrQueryFields: string, + include = Include.All +) => { + const url = getURLWithQueryFields( + `mlmodels/name/${fqn}`, + arrQueryFields, + `include=${include}` + ); const response = await APIClient.get(url); @@ -89,3 +99,12 @@ export const removeFollower = async (mlModelId: string, userId: string) => { return response.data; }; + +export const restoreMlmodel = async (id: string) => { + const response = await APIClient.put< + RestoreRequestType, + AxiosResponse + >('/mlmodels/restore', { id }); + + return response.data; +}; 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 76756b91561..3c7c80f1c82 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 @@ -323,4 +323,30 @@ describe('Test MlModel entity detail component', () => { expect(customProperties).toBeInTheDocument(); }); + + it('Soft deleted mlmodel should be visible', async () => { + const { container } = render( + , + { + wrapper: MemoryRouter, + } + ); + const detailContainer = await findByTestId(container, 'mlmodel-details'); + const entityInfo = await findByText(container, /EntityPageInfo/i); + const entityTabs = await findByTestId(container, 'tabs'); + const entityFeatureList = await findByText( + container, + /MlModelFeaturesList/i + ); + const entityDescription = await findByText(container, /Description/i); + + expect(detailContainer).toBeInTheDocument(); + expect(entityInfo).toBeInTheDocument(); + expect(entityTabs).toBeInTheDocument(); + expect(entityFeatureList).toBeInTheDocument(); + expect(entityDescription).toBeInTheDocument(); + }); }); 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 da73de7a145..d1156e910d4 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 @@ -13,6 +13,7 @@ import { Col, Row, Table } from 'antd'; import { ColumnsType } from 'antd/lib/table'; +import { AxiosError } from 'axios'; import classNames from 'classnames'; import { isEmpty, isUndefined, startCase, uniqueId } from 'lodash'; import { observer } from 'mobx-react'; @@ -29,6 +30,7 @@ import React, { import { useTranslation } from 'react-i18next'; import { useHistory } from 'react-router-dom'; import AppState from '../../AppState'; +import { restoreMlmodel } from '../../axiosAPIs/mlModelAPI'; import { FQN_SEPARATOR_CHAR } from '../../constants/char.constants'; import { getDashboardDetailsPath, @@ -52,13 +54,14 @@ import { getEntityName, getEntityPlaceHolder, getOwnerValue, + refreshPage, } from '../../utils/CommonUtils'; import { getEntityFieldThreadCounts } from '../../utils/FeedUtils'; import { DEFAULT_ENTITY_PERMISSION } from '../../utils/PermissionsUtils'; import { getLineageViewPath } from '../../utils/RouterUtils'; import { serviceTypeLogo } from '../../utils/ServiceUtils'; import { getTagsWithoutTier, getTierTags } from '../../utils/TableUtils'; -import { showErrorToast } from '../../utils/ToastUtils'; +import { showErrorToast, showSuccessToast } from '../../utils/ToastUtils'; import ActivityFeedList from '../ActivityFeed/ActivityFeedList/ActivityFeedList'; import ActivityThreadPanel from '../ActivityFeed/ActivityThreadPanel/ActivityThreadPanel'; import { CustomPropertyTable } from '../common/CustomPropertyTable/CustomPropertyTable'; @@ -376,6 +379,27 @@ const MlModelDetail: FC = ({ } }; + const handleRestoreMlmodel = async () => { + try { + await restoreMlmodel(mlModelDetail.id); + showSuccessToast( + t('message.restore-entities-success', { + entity: t('label.mlmodel'), + }), + // Autoclose timer + 2000 + ); + refreshPage(); + } catch (error) { + showErrorToast( + error as AxiosError, + t('message.restore-entities-error', { + entity: t('label.mlmodel'), + }) + ); + } + }; + const onFeaturesUpdate = async (features: Mlmodel['mlFeatures']) => { await updateMlModelFeatures({ ...mlModelDetail, mlFeatures: features }); }; @@ -567,6 +591,7 @@ const MlModelDetail: FC = ({ ? onTierUpdate : undefined } + onRestoreEntity={handleRestoreMlmodel} onThreadLinkSelect={handleThreadLinkSelect} /> 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 0b2f46bea5b..2dca5b60d98 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 @@ -498,6 +498,7 @@ "test-suite-status": "Test Suite Status", "last-run-result": "Last Run Result", "last-run": "Last Run", + "mlmodel": "ML Model", "search-entity": "Search {{entity}}", "more": "More", "update": "Update"