diff --git a/openmetadata-ui/src/main/resources/ui/src/components/DashboardDetails/DashboardDetails.component.tsx b/openmetadata-ui/src/main/resources/ui/src/components/DashboardDetails/DashboardDetails.component.tsx index f21c7d8bc9d..7e4f26971f6 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/DashboardDetails/DashboardDetails.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/DashboardDetails/DashboardDetails.component.tsx @@ -53,6 +53,8 @@ import { getTagsWithoutTier } from '../../utils/TableUtils'; import { getTagCategories, getTaglist } from '../../utils/TagsUtils'; import ActivityFeedList from '../ActivityFeed/ActivityFeedList/ActivityFeedList'; import ActivityThreadPanel from '../ActivityFeed/ActivityThreadPanel/ActivityThreadPanel'; +import { CustomPropertyTable } from '../common/CustomPropertyTable/CustomPropertyTable'; +import { CustomPropertyProps } from '../common/CustomPropertyTable/CustomPropertyTable.interface'; import Description from '../common/description/Description'; import EntityPageInfo from '../common/entityPageInfo/EntityPageInfo'; import NonAdminAction from '../common/non-admin-action/NonAdminAction'; @@ -112,6 +114,7 @@ const DashboardDetails = ({ fetchFeedHandler, updateThreadHandler, entityFieldTaskCount, + onExtensionUpdate, }: DashboardDetailsProps) => { const [isEdit, setIsEdit] = useState(false); const [followersCount, setFollowersCount] = useState(0); @@ -192,6 +195,11 @@ const DashboardDetails = ({ isProtected: false, position: 3, }, + { + name: 'Custom Properties', + isProtected: false, + position: 4, + }, { name: 'Manage', icon: { @@ -202,7 +210,7 @@ const DashboardDetails = ({ }, isProtected: true, protectedState: !owner || hasEditAccess(), - position: 4, + position: 5, }, ]; @@ -739,6 +747,15 @@ const DashboardDetails = ({ )} {activeTab === 4 && ( + + )} + {activeTab === 5 && (
void; deletePostHandler: (threadId: string, postId: string) => void; updateThreadHandler: ThreadUpdatedFunc; + onExtensionUpdate: (updatedDashboard: Dashboard) => void; } diff --git a/openmetadata-ui/src/main/resources/ui/src/components/DashboardDetails/DashboardDetails.test.tsx b/openmetadata-ui/src/main/resources/ui/src/components/DashboardDetails/DashboardDetails.test.tsx index a88c07326e7..f385e9637a6 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/DashboardDetails/DashboardDetails.test.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/DashboardDetails/DashboardDetails.test.tsx @@ -118,6 +118,7 @@ const DashboardDetailsProps = { paging: {} as Paging, fetchFeedHandler: jest.fn(), updateThreadHandler: jest.fn(), + onExtensionUpdate: jest.fn(), }; const mockObserve = jest.fn(); @@ -336,7 +337,7 @@ describe('Test DashboardDetails component', () => { it('Check if active tab is manage', async () => { const { container } = render( - , + , { wrapper: MemoryRouter, } @@ -346,6 +347,21 @@ describe('Test DashboardDetails component', () => { expect(manage).toBeInTheDocument(); }); + it('Check if active tab is custom properties', async () => { + const { container } = render( + , + { + wrapper: MemoryRouter, + } + ); + const customProperties = await findByTestId( + container, + 'custom-properties-table' + ); + + expect(customProperties).toBeInTheDocument(); + }); + it('Should create an observer if IntersectionObserver is available', async () => { const { container } = render( , diff --git a/openmetadata-ui/src/main/resources/ui/src/components/DatasetDetails/DatasetDetails.component.tsx b/openmetadata-ui/src/main/resources/ui/src/components/DatasetDetails/DatasetDetails.component.tsx index fb3b0ce2573..b579d590a17 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/DatasetDetails/DatasetDetails.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/DatasetDetails/DatasetDetails.component.tsx @@ -57,6 +57,8 @@ import { } from '../../utils/TableUtils'; import ActivityFeedList from '../ActivityFeed/ActivityFeedList/ActivityFeedList'; import ActivityThreadPanel from '../ActivityFeed/ActivityThreadPanel/ActivityThreadPanel'; +import { CustomPropertyTable } from '../common/CustomPropertyTable/CustomPropertyTable'; +import { CustomPropertyProps } from '../common/CustomPropertyTable/CustomPropertyTable.interface'; import Description from '../common/description/Description'; import EntityPageInfo from '../common/entityPageInfo/EntityPageInfo'; import TabsPane from '../common/TabsPane/TabsPane'; @@ -75,7 +77,6 @@ import SchemaTab from '../SchemaTab/SchemaTab.component'; import TableProfiler from '../TableProfiler/TableProfiler.component'; import TableProfilerGraph from '../TableProfiler/TableProfilerGraph.component'; import TableQueries from '../TableQueries/TableQueries'; -import { CustomPropertyTable } from './CustomPropertyTable/CustomPropertyTable'; import { DatasetDetailsProps } from './DatasetDetails.interface'; const DatasetDetails: React.FC = ({ @@ -295,12 +296,6 @@ const DatasetDetails: React.FC = ({ }, { name: 'Custom Properties', - icon: { - alt: 'custom_properties', - name: 'custom_properties-light-grey', - title: 'custom_properties', - selectedName: 'custom_properties-primery', - }, isProtected: false, position: 9, }, @@ -842,8 +837,11 @@ const DatasetDetails: React.FC = ({ )} {activeTab === 9 && ( )} {activeTab === 10 && ( diff --git a/openmetadata-ui/src/main/resources/ui/src/components/DatasetDetails/DatasetDetails.test.tsx b/openmetadata-ui/src/main/resources/ui/src/components/DatasetDetails/DatasetDetails.test.tsx index 98da700e460..a1de1767abf 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/DatasetDetails/DatasetDetails.test.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/DatasetDetails/DatasetDetails.test.tsx @@ -350,6 +350,21 @@ describe('Test MyDataDetailsPage page', () => { expect(manage).toBeInTheDocument(); }); + it('Check if active tab is custom properties', async () => { + const { container } = render( + , + { + wrapper: MemoryRouter, + } + ); + const customProperties = await findByTestId( + container, + 'custom-properties-table' + ); + + expect(customProperties).toBeInTheDocument(); + }); + it('Should create an observer if IntersectionObserver is available', async () => { const { container } = render( , 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 f80dea65635..4e4992e4f4a 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 @@ -152,6 +152,7 @@ const mockProp = { lineageLeafNodes: {} as LeafNodes, isNodeLoading: { id: undefined, state: false }, }, + onExtensionUpdate: jest.fn(), }; jest.mock('../ManageTab/ManageTab.component', () => { @@ -254,7 +255,7 @@ describe('Test MlModel entity detail component', () => { it('Should render manage component for manage tab', async () => { const { container } = render( - , + , { wrapper: MemoryRouter, } @@ -266,4 +267,19 @@ describe('Test MlModel entity detail component', () => { expect(detailContainer).toBeInTheDocument(); expect(manageTab).toBeInTheDocument(); }); + + it('Check if active tab is custom properties', async () => { + const { container } = render( + , + { + wrapper: MemoryRouter, + } + ); + const customProperties = await findByTestId( + container, + 'custom-properties-table' + ); + + expect(customProperties).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 a66707c5fe4..4a4ccd195f9 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 @@ -45,6 +45,8 @@ import { LabelType, State, TagLabel } from '../../generated/type/tagLabel'; import { getEntityName, getEntityPlaceHolder } from '../../utils/CommonUtils'; import { serviceTypeLogo } from '../../utils/ServiceUtils'; import { getTagsWithoutTier, getTierTags } from '../../utils/TableUtils'; +import { CustomPropertyTable } from '../common/CustomPropertyTable/CustomPropertyTable'; +import { CustomPropertyProps } from '../common/CustomPropertyTable/CustomPropertyTable.interface'; import Description from '../common/description/Description'; import EntityPageInfo from '../common/entityPageInfo/EntityPageInfo'; import TabsPane from '../common/TabsPane/TabsPane'; @@ -75,6 +77,7 @@ interface MlModelDetailProp extends HTMLAttributes { lineageLeafNodes: LeafNodes; isNodeLoading: LoadingNodeState; }; + onExtensionUpdate: (updatedMlModel: Mlmodel) => void; } const MlModelDetail: FC = ({ @@ -88,6 +91,7 @@ const MlModelDetail: FC = ({ settingsUpdateHandler, updateMlModelFeatures, lineageTabData, + onExtensionUpdate, }) => { const [followersCount, setFollowersCount] = useState(0); const [isFollowing, setIsFollowing] = useState(false); @@ -213,6 +217,11 @@ const MlModelDetail: FC = ({ isProtected: false, position: 3, }, + { + name: 'Custom Properties', + isProtected: false, + position: 4, + }, { name: 'Manage', icon: { @@ -223,7 +232,7 @@ const MlModelDetail: FC = ({ }, isProtected: false, protectedState: !mlModelDetail.owner || hasEditAccess(), - position: 4, + position: 5, }, ]; @@ -536,6 +545,15 @@ const MlModelDetail: FC = ({
)} {activeTab === 4 && ( + + )} + {activeTab === 5 && (
{ const [isEdit, setIsEdit] = useState(false); const [followersCount, setFollowersCount] = useState(0); @@ -186,6 +189,11 @@ const PipelineDetails = ({ isProtected: false, position: 3, }, + { + name: 'Custom Properties', + isProtected: false, + position: 4, + }, { name: 'Manage', icon: { @@ -196,7 +204,7 @@ const PipelineDetails = ({ }, isProtected: true, protectedState: !owner || hasEditAccess(), - position: 4, + position: 5, }, ]; @@ -524,6 +532,15 @@ const PipelineDetails = ({
)} {activeTab === 4 && ( + + )} + {activeTab === 5 && (
void; deletePostHandler: (threadId: string, postId: string) => void; updateThreadHandler: ThreadUpdatedFunc; + onExtensionUpdate: (updatedPipeline: Pipeline) => void; } diff --git a/openmetadata-ui/src/main/resources/ui/src/components/PipelineDetails/PipelineDetails.test.tsx b/openmetadata-ui/src/main/resources/ui/src/components/PipelineDetails/PipelineDetails.test.tsx index 52e8510a2cc..b5d4a1a8081 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/PipelineDetails/PipelineDetails.test.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/PipelineDetails/PipelineDetails.test.tsx @@ -125,6 +125,7 @@ const PipelineDetailsProps = { pipelineStatus: [], isPipelineStatusLoading: false, updateThreadHandler: jest.fn(), + onExtensionUpdate: jest.fn(), }; const mockObserve = jest.fn(); @@ -274,7 +275,7 @@ describe('Test PipelineDetails component', () => { it('Check if active tab is manage', async () => { const { container } = render( - , + , { wrapper: MemoryRouter, } @@ -284,6 +285,21 @@ describe('Test PipelineDetails component', () => { expect(manage).toBeInTheDocument(); }); + it('Check if active tab is custom properties', async () => { + const { container } = render( + , + { + wrapper: MemoryRouter, + } + ); + const customProperties = await findByTestId( + container, + 'custom-properties-table' + ); + + expect(customProperties).toBeInTheDocument(); + }); + it('Should create an observer if IntersectionObserver is available', async () => { const { container } = render( , diff --git a/openmetadata-ui/src/main/resources/ui/src/components/TopicDetails/TopicDetails.component.tsx b/openmetadata-ui/src/main/resources/ui/src/components/TopicDetails/TopicDetails.component.tsx index 7b77cc4d084..f94177691a3 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/TopicDetails/TopicDetails.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/TopicDetails/TopicDetails.component.tsx @@ -44,6 +44,8 @@ import { bytesToSize } from '../../utils/StringsUtils'; import { getTagsWithoutTier } from '../../utils/TableUtils'; import ActivityFeedList from '../ActivityFeed/ActivityFeedList/ActivityFeedList'; import ActivityThreadPanel from '../ActivityFeed/ActivityThreadPanel/ActivityThreadPanel'; +import { CustomPropertyTable } from '../common/CustomPropertyTable/CustomPropertyTable'; +import { CustomPropertyProps } from '../common/CustomPropertyTable/CustomPropertyTable.interface'; import Description from '../common/description/Description'; import EntityPageInfo from '../common/entityPageInfo/EntityPageInfo'; import TabsPane from '../common/TabsPane/TabsPane'; @@ -97,6 +99,7 @@ const TopicDetails: React.FC = ({ updateThreadHandler, entityFieldTaskCount, lineageTabData, + onExtensionUpdate, }: TopicDetailsProps) => { const [isEdit, setIsEdit] = useState(false); const [followersCount, setFollowersCount] = useState(0); @@ -221,6 +224,11 @@ const TopicDetails: React.FC = ({ isProtected: false, position: 5, }, + { + name: 'Custom Properties', + isProtected: false, + position: 6, + }, { name: 'Manage', icon: { @@ -231,7 +239,7 @@ const TopicDetails: React.FC = ({ }, isProtected: true, protectedState: !owner || hasEditAccess(), - position: 6, + position: 7, }, ]; const extraInfo: Array = [ @@ -557,6 +565,15 @@ const TopicDetails: React.FC = ({
)} {activeTab === 6 && ( + + )} + {activeTab === 7 && (
void; } diff --git a/openmetadata-ui/src/main/resources/ui/src/components/TopicDetails/TopicDetails.test.tsx b/openmetadata-ui/src/main/resources/ui/src/components/TopicDetails/TopicDetails.test.tsx index 77a35cefd7d..c4d20992135 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/TopicDetails/TopicDetails.test.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/TopicDetails/TopicDetails.test.tsx @@ -111,6 +111,7 @@ const TopicDetailsProps = { lineageLeafNodes: {} as LeafNodes, isNodeLoading: { id: undefined, state: false }, }, + onExtensionUpdate: jest.fn(), }; const mockObserve = jest.fn(); @@ -240,7 +241,7 @@ describe('Test TopicDetails component', () => { it('Check if active tab is manage', async () => { const { container } = render( - , + , { wrapper: MemoryRouter, } @@ -263,6 +264,21 @@ describe('Test TopicDetails component', () => { expect(detailContainer).toBeInTheDocument(); }); + it('Check if active tab is custom properties', async () => { + const { container } = render( + , + { + wrapper: MemoryRouter, + } + ); + const customProperties = await findByTestId( + container, + 'custom-properties-table' + ); + + expect(customProperties).toBeInTheDocument(); + }); + it('Should create an observer if IntersectionObserver is available', async () => { const { container } = render( , diff --git a/openmetadata-ui/src/main/resources/ui/src/components/common/CustomPropertyTable/CustomPropertyTable.interface.ts b/openmetadata-ui/src/main/resources/ui/src/components/common/CustomPropertyTable/CustomPropertyTable.interface.ts new file mode 100644 index 00000000000..72f3797f813 --- /dev/null +++ b/openmetadata-ui/src/main/resources/ui/src/components/common/CustomPropertyTable/CustomPropertyTable.interface.ts @@ -0,0 +1,27 @@ +/* + * Copyright 2021 Collate + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { EntityType } from '../../../enums/entity.enum'; +import { Dashboard } from '../../../generated/entity/data/dashboard'; +import { Mlmodel } from '../../../generated/entity/data/mlmodel'; +import { Pipeline } from '../../../generated/entity/data/pipeline'; +import { Table } from '../../../generated/entity/data/table'; +import { Topic } from '../../../generated/entity/data/topic'; + +export type EntityDetails = Table & Topic & Dashboard & Pipeline & Mlmodel; + +export interface CustomPropertyProps { + entityDetails: EntityDetails; + entityType: EntityType; + handleExtentionUpdate: (updatedTable: EntityDetails) => void; +} diff --git a/openmetadata-ui/src/main/resources/ui/src/components/DatasetDetails/CustomPropertyTable/CustomPropertyTable.test.tsx b/openmetadata-ui/src/main/resources/ui/src/components/common/CustomPropertyTable/CustomPropertyTable.test.tsx similarity index 87% rename from openmetadata-ui/src/main/resources/ui/src/components/DatasetDetails/CustomPropertyTable/CustomPropertyTable.test.tsx rename to openmetadata-ui/src/main/resources/ui/src/components/common/CustomPropertyTable/CustomPropertyTable.test.tsx index f9ed2969d09..564917efb04 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/DatasetDetails/CustomPropertyTable/CustomPropertyTable.test.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/common/CustomPropertyTable/CustomPropertyTable.test.tsx @@ -14,7 +14,12 @@ import { render } from '@testing-library/react'; import React from 'react'; import { getTypeByFQN } from '../../../axiosAPIs/metadataTypeAPI'; +import { EntityType } from '../../../enums/entity.enum'; +import { Dashboard } from '../../../generated/entity/data/dashboard'; +import { Mlmodel } from '../../../generated/entity/data/mlmodel'; +import { Pipeline } from '../../../generated/entity/data/pipeline'; import { Table } from '../../../generated/entity/data/table'; +import { Topic } from '../../../generated/entity/data/topic'; import { CustomPropertyTable } from './CustomPropertyTable'; const mockCustomProperties = [ @@ -53,12 +58,13 @@ jest.mock('../../../axiosAPIs/metadataTypeAPI', () => ({ ), })); -const mockTableDetails = {} as Table; +const mockTableDetails = {} as Table & Topic & Dashboard & Pipeline & Mlmodel; const handleExtentionUpdate = jest.fn(); const mockProp = { - tableDetails: mockTableDetails, + entityDetails: mockTableDetails, handleExtentionUpdate, + entityType: EntityType.TABLE, }; describe('Test CustomProperty Table Component', () => { diff --git a/openmetadata-ui/src/main/resources/ui/src/components/DatasetDetails/CustomPropertyTable/CustomPropertyTable.tsx b/openmetadata-ui/src/main/resources/ui/src/components/common/CustomPropertyTable/CustomPropertyTable.tsx similarity index 88% rename from openmetadata-ui/src/main/resources/ui/src/components/DatasetDetails/CustomPropertyTable/CustomPropertyTable.tsx rename to openmetadata-ui/src/main/resources/ui/src/components/common/CustomPropertyTable/CustomPropertyTable.tsx index 38916d3429c..008f8b97ced 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/DatasetDetails/CustomPropertyTable/CustomPropertyTable.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/common/CustomPropertyTable/CustomPropertyTable.tsx @@ -16,25 +16,21 @@ import classNames from 'classnames'; import { uniqueId } from 'lodash'; import React, { FC, useEffect, useState } from 'react'; import { getTypeByFQN } from '../../../axiosAPIs/metadataTypeAPI'; -import { Table } from '../../../generated/entity/data/table'; import { Type } from '../../../generated/entity/type'; import { isEven } from '../../../utils/CommonUtils'; import { showErrorToast } from '../../../utils/ToastUtils'; +import { CustomPropertyProps } from './CustomPropertyTable.interface'; import { PropertyValue } from './PropertyValue'; -interface Props { - tableDetails: Table; - handleExtentionUpdate: (updatedTable: Table) => void; -} - -export const CustomPropertyTable: FC = ({ - tableDetails, +export const CustomPropertyTable: FC = ({ + entityDetails, handleExtentionUpdate, + entityType, }) => { const [entityTypeDetail, setEntityTypeDetail] = useState({} as Type); const fetchTypeDetail = () => { - getTypeByFQN('table') + getTypeByFQN(entityType) .then((res: AxiosResponse) => { setEntityTypeDetail(res.data); }) @@ -43,10 +39,12 @@ export const CustomPropertyTable: FC = ({ const customProperties = entityTypeDetail.customProperties || []; - const extension = tableDetails.extension; + const extension = entityDetails.extension; - const onExtensionUpdate = (updatedExtension: Table['extension']) => { - handleExtentionUpdate({ ...tableDetails, extension: updatedExtension }); + const onExtensionUpdate = ( + updatedExtension: CustomPropertyProps['entityDetails']['extension'] + ) => { + handleExtentionUpdate({ ...entityDetails, extension: updatedExtension }); }; useEffect(() => { diff --git a/openmetadata-ui/src/main/resources/ui/src/components/DatasetDetails/CustomPropertyTable/PropertyInput.test.tsx b/openmetadata-ui/src/main/resources/ui/src/components/common/CustomPropertyTable/PropertyInput.test.tsx similarity index 100% rename from openmetadata-ui/src/main/resources/ui/src/components/DatasetDetails/CustomPropertyTable/PropertyInput.test.tsx rename to openmetadata-ui/src/main/resources/ui/src/components/common/CustomPropertyTable/PropertyInput.test.tsx diff --git a/openmetadata-ui/src/main/resources/ui/src/components/DatasetDetails/CustomPropertyTable/PropertyInput.tsx b/openmetadata-ui/src/main/resources/ui/src/components/common/CustomPropertyTable/PropertyInput.tsx similarity index 100% rename from openmetadata-ui/src/main/resources/ui/src/components/DatasetDetails/CustomPropertyTable/PropertyInput.tsx rename to openmetadata-ui/src/main/resources/ui/src/components/common/CustomPropertyTable/PropertyInput.tsx diff --git a/openmetadata-ui/src/main/resources/ui/src/components/DatasetDetails/CustomPropertyTable/PropertyValue.test.tsx b/openmetadata-ui/src/main/resources/ui/src/components/common/CustomPropertyTable/PropertyValue.test.tsx similarity index 100% rename from openmetadata-ui/src/main/resources/ui/src/components/DatasetDetails/CustomPropertyTable/PropertyValue.test.tsx rename to openmetadata-ui/src/main/resources/ui/src/components/common/CustomPropertyTable/PropertyValue.test.tsx diff --git a/openmetadata-ui/src/main/resources/ui/src/components/DatasetDetails/CustomPropertyTable/PropertyValue.tsx b/openmetadata-ui/src/main/resources/ui/src/components/common/CustomPropertyTable/PropertyValue.tsx similarity index 97% rename from openmetadata-ui/src/main/resources/ui/src/components/DatasetDetails/CustomPropertyTable/PropertyValue.tsx rename to openmetadata-ui/src/main/resources/ui/src/components/common/CustomPropertyTable/PropertyValue.tsx index ac004be5a6d..a6278787622 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/DatasetDetails/CustomPropertyTable/PropertyValue.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/common/CustomPropertyTable/PropertyValue.tsx @@ -16,8 +16,8 @@ import React, { FC, Fragment, useState } from 'react'; import { Table } from '../../../generated/entity/data/table'; import { EntityReference } from '../../../generated/type/entityReference'; import SVGIcons, { Icons } from '../../../utils/SvgUtils'; -import RichTextEditorPreviewer from '../../common/rich-text-editor/RichTextEditorPreviewer'; import { ModalWithMarkdownEditor } from '../../Modals/ModalWithMarkdownEditor/ModalWithMarkdownEditor'; +import RichTextEditorPreviewer from '../rich-text-editor/RichTextEditorPreviewer'; import { PropertyInput } from './PropertyInput'; interface Props { diff --git a/openmetadata-ui/src/main/resources/ui/src/pages/DashboardDetailsPage/DashboardDetailsPage.component.tsx b/openmetadata-ui/src/main/resources/ui/src/pages/DashboardDetailsPage/DashboardDetailsPage.component.tsx index d895d23536e..9735d0cc7cf 100644 --- a/openmetadata-ui/src/main/resources/ui/src/pages/DashboardDetailsPage/DashboardDetailsPage.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/pages/DashboardDetailsPage/DashboardDetailsPage.component.tsx @@ -746,6 +746,27 @@ const DashboardDetailsPage = () => { updateThreadData(threadId, postId, isThread, data, setEntityThread); }; + const handleExtentionUpdate = async (updatedDashboard: Dashboard) => { + try { + const { data } = await saveUpdatedDashboardData(updatedDashboard); + + if (data) { + const { version, owner: ownerValue, tags } = data; + setCurrentVersion(version); + setDashboardDetails(data); + setOwner(ownerValue); + setTier(getTierTags(tags)); + } else { + throw jsonData['api-error-messages']['update-entity-error']; + } + } catch (error) { + showErrorToast( + error as AxiosError, + jsonData['api-error-messages']['update-entity-error'] + ); + } + }; + useEffect(() => { fetchTabSpecificData(dashboardDetailsTabs[activeTab - 1].field); }, [activeTab]); @@ -816,6 +837,7 @@ const DashboardDetailsPage = () => { updateThreadHandler={updateThreadHandler} version={currentVersion as string} versionHandler={versionHandler} + onExtensionUpdate={handleExtentionUpdate} /> )} diff --git a/openmetadata-ui/src/main/resources/ui/src/pages/MlModelPage/MlModelPage.component.tsx b/openmetadata-ui/src/main/resources/ui/src/pages/MlModelPage/MlModelPage.component.tsx index b36d17f3c29..65eb22a39a9 100644 --- a/openmetadata-ui/src/main/resources/ui/src/pages/MlModelPage/MlModelPage.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/pages/MlModelPage/MlModelPage.component.tsx @@ -356,6 +356,23 @@ const MlModelPage = () => { }); }; + const handleExtentionUpdate = async (updatedMlModel: Mlmodel) => { + try { + const { data } = await saveUpdatedMlModelData(updatedMlModel); + + if (data) { + setMlModelDetail(data); + } else { + throw jsonData['api-error-messages']['update-entity-error']; + } + } catch (error) { + showErrorToast( + error as AxiosError, + jsonData['api-error-messages']['update-entity-error'] + ); + } + }; + const getMlModelDetail = () => { if (!isNil(mlModelDetail) && !isEmpty(mlModelDetail)) { return ( @@ -379,6 +396,7 @@ const MlModelPage = () => { tagUpdateHandler={onTagUpdate} unfollowMlModelHandler={unfollowMlModel} updateMlModelFeatures={updateMlModelFeatures} + onExtensionUpdate={handleExtentionUpdate} /> ); } else { diff --git a/openmetadata-ui/src/main/resources/ui/src/pages/PipelineDetails/PipelineDetailsPage.component.tsx b/openmetadata-ui/src/main/resources/ui/src/pages/PipelineDetails/PipelineDetailsPage.component.tsx index 1e8fe25e4f9..716b4a2409a 100644 --- a/openmetadata-ui/src/main/resources/ui/src/pages/PipelineDetails/PipelineDetailsPage.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/pages/PipelineDetails/PipelineDetailsPage.component.tsx @@ -687,6 +687,27 @@ const PipelineDetailsPage = () => { updateThreadData(threadId, postId, isThread, data, setEntityThread); }; + const handleExtentionUpdate = async (updatedPipeline: Pipeline) => { + try { + const { data } = await saveUpdatedPipelineData(updatedPipeline); + + if (data) { + const { version, owner: ownerValue, tags } = data; + setCurrentVersion(version); + setPipelineDetails(data); + setOwner(ownerValue); + setTier(getTierTags(tags)); + } else { + throw jsonData['api-error-messages']['update-entity-error']; + } + } catch (error) { + showErrorToast( + error as AxiosError, + jsonData['api-error-messages']['update-entity-error'] + ); + } + }; + useEffect(() => { fetchTabSpecificData(pipelineDetailsTabs[activeTab - 1].field); }, [activeTab]); @@ -757,6 +778,7 @@ const PipelineDetailsPage = () => { updateThreadHandler={updateThreadHandler} version={currentVersion as string} versionHandler={versionHandler} + onExtensionUpdate={handleExtentionUpdate} /> )} diff --git a/openmetadata-ui/src/main/resources/ui/src/pages/TopicDetails/TopicDetailsPage.component.tsx b/openmetadata-ui/src/main/resources/ui/src/pages/TopicDetails/TopicDetailsPage.component.tsx index ba6847dadbf..90c8d1bcc48 100644 --- a/openmetadata-ui/src/main/resources/ui/src/pages/TopicDetails/TopicDetailsPage.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/pages/TopicDetails/TopicDetailsPage.component.tsx @@ -359,7 +359,12 @@ const TopicDetailsPage: FunctionComponent = () => { const fetchTopicDetail = (topicFQN: string) => { setLoading(true); - getTopicByFqn(topicFQN, ['owner', 'followers', 'tags']) + getTopicByFqn(topicFQN, [ + TabSpecificField.OWNER, + TabSpecificField.FOLLOWERS, + TabSpecificField.TAGS, + TabSpecificField.EXTENSION, + ]) .then((res: AxiosResponse) => { if (res.data) { const { @@ -668,6 +673,27 @@ const TopicDetailsPage: FunctionComponent = () => { updateThreadData(threadId, postId, isThread, data, setEntityThread); }; + const handleExtentionUpdate = async (updatedTopic: Topic) => { + try { + const { data } = await saveUpdatedTopicData(updatedTopic); + + if (data) { + const { version, owner: ownerValue, tags } = data; + setCurrentVersion(version); + setTopicDetails(data); + setOwner(ownerValue); + setTier(getTierTags(tags)); + } else { + throw jsonData['api-error-messages']['update-entity-error']; + } + } catch (error) { + showErrorToast( + error as AxiosError, + jsonData['api-error-messages']['update-entity-error'] + ); + } + }; + useEffect(() => { if (topicDetailsTabs[activeTab - 1].path !== tab) { setActiveTab(getCurrentTopicTab(tab)); @@ -743,6 +769,7 @@ const TopicDetailsPage: FunctionComponent = () => { updateThreadHandler={updateThreadHandler} version={currentVersion} versionHandler={versionHandler} + onExtensionUpdate={handleExtentionUpdate} /> )} diff --git a/openmetadata-ui/src/main/resources/ui/src/utils/DashboardDetailsUtils.ts b/openmetadata-ui/src/main/resources/ui/src/utils/DashboardDetailsUtils.ts index a9686e1e364..09771dee32f 100644 --- a/openmetadata-ui/src/main/resources/ui/src/utils/DashboardDetailsUtils.ts +++ b/openmetadata-ui/src/main/resources/ui/src/utils/DashboardDetailsUtils.ts @@ -14,7 +14,7 @@ import { TabSpecificField } from '../enums/entity.enum'; export const defaultFields = `${TabSpecificField.OWNER}, ${TabSpecificField.FOLLOWERS}, ${TabSpecificField.TAGS}, -${TabSpecificField.USAGE_SUMMARY}, ${TabSpecificField.CHARTS}`; +${TabSpecificField.USAGE_SUMMARY}, ${TabSpecificField.CHARTS},${TabSpecificField.EXTENSION}`; export const dashboardDetailsTabs = [ { @@ -31,6 +31,10 @@ export const dashboardDetailsTabs = [ path: 'lineage', field: TabSpecificField.LINEAGE, }, + { + name: 'Custom Properties', + path: 'custom_properties', + }, { name: 'Manage', path: 'manage', @@ -50,11 +54,16 @@ export const getCurrentDashboardTab = (tab: string) => { break; - case 'manage': + case 'custom_properties': currentTab = 4; break; + case 'manage': + currentTab = 5; + + break; + case 'details': default: currentTab = 1; diff --git a/openmetadata-ui/src/main/resources/ui/src/utils/MlModelDetailsUtils.ts b/openmetadata-ui/src/main/resources/ui/src/utils/MlModelDetailsUtils.ts index a4a3ee65463..ccd0fe1cefe 100644 --- a/openmetadata-ui/src/main/resources/ui/src/utils/MlModelDetailsUtils.ts +++ b/openmetadata-ui/src/main/resources/ui/src/utils/MlModelDetailsUtils.ts @@ -14,7 +14,7 @@ import { TabSpecificField } from '../enums/entity.enum'; export const defaultFields = `${TabSpecificField.USAGE_SUMMARY}, -${TabSpecificField.FOLLOWERS}, ${TabSpecificField.TAGS}, ${TabSpecificField.OWNER}, ${TabSpecificField.DASHBOARD} `; +${TabSpecificField.FOLLOWERS}, ${TabSpecificField.TAGS}, ${TabSpecificField.OWNER}, ${TabSpecificField.DASHBOARD} ,${TabSpecificField.EXTENSION}`; export const mlModelTabs = [ { @@ -30,6 +30,10 @@ export const mlModelTabs = [ path: 'lineage', field: TabSpecificField.LINEAGE, }, + { + name: 'Custom Properties', + path: 'custom_properties', + }, { name: 'Manage', path: 'manage', @@ -47,9 +51,13 @@ export const getCurrentMlModelTab = (tab: string) => { currentTab = 3; break; - case 'manage': + case 'custom_properties': currentTab = 4; + break; + case 'manage': + currentTab = 5; + break; case 'features': currentTab = 1; diff --git a/openmetadata-ui/src/main/resources/ui/src/utils/PipelineDetailsUtils.ts b/openmetadata-ui/src/main/resources/ui/src/utils/PipelineDetailsUtils.ts index f980bef5565..a82d5a87602 100644 --- a/openmetadata-ui/src/main/resources/ui/src/utils/PipelineDetailsUtils.ts +++ b/openmetadata-ui/src/main/resources/ui/src/utils/PipelineDetailsUtils.ts @@ -20,7 +20,7 @@ import { import { Icons } from './SvgUtils'; export const defaultFields = `${TabSpecificField.FOLLOWERS}, ${TabSpecificField.TAGS}, ${TabSpecificField.OWNER}, -${TabSpecificField.TASKS}, ${TabSpecificField.PIPELINE_STATUS}`; +${TabSpecificField.TASKS}, ${TabSpecificField.PIPELINE_STATUS},${TabSpecificField.EXTENSION}`; export const pipelineDetailsTabs = [ { @@ -37,6 +37,10 @@ export const pipelineDetailsTabs = [ path: 'lineage', field: TabSpecificField.LINEAGE, }, + { + name: 'Custom Properties', + path: 'custom_properties', + }, { name: 'Manage', path: 'manage', @@ -54,10 +58,14 @@ export const getCurrentPipelineTab = (tab: string) => { case 'lineage': currentTab = 3; + break; + case 'custom_properties': + currentTab = 4; + break; case 'manage': - currentTab = 4; + currentTab = 5; break; diff --git a/openmetadata-ui/src/main/resources/ui/src/utils/TopicDetailsUtils.ts b/openmetadata-ui/src/main/resources/ui/src/utils/TopicDetailsUtils.ts index 6f844aeb616..c39056bce0f 100644 --- a/openmetadata-ui/src/main/resources/ui/src/utils/TopicDetailsUtils.ts +++ b/openmetadata-ui/src/main/resources/ui/src/utils/TopicDetailsUtils.ts @@ -37,6 +37,10 @@ export const topicDetailsTabs = [ path: 'lineage', field: TabSpecificField.LINEAGE, }, + { + name: 'Custom Properties', + path: 'custom_properties', + }, { name: 'Manage', path: 'manage', @@ -62,9 +66,13 @@ export const getCurrentTopicTab = (tab: string) => { currentTab = 5; break; - case 'manage': + case 'custom_properties': currentTab = 6; + break; + case 'manage': + currentTab = 7; + break; case 'schema':