From a50bb3089802d08fecb0f70a672faa0c362942ed Mon Sep 17 00:00:00 2001 From: purnimagarg1 <139125209+purnimagarg1@users.noreply.github.com> Date: Thu, 18 Sep 2025 02:36:04 +0530 Subject: [PATCH] fix(ui/summary-tab): fix functionality on add assets button in assets module (#14801) Co-authored-by: Chris Collins --- .../summary/modules/assets/AddAssetsModal.tsx | 205 ++++++++++++++++++ .../summary/modules/assets/AssetsModule.tsx | 26 ++- .../summary/modules/assets/constants.ts | 3 + 3 files changed, 226 insertions(+), 8 deletions(-) create mode 100644 datahub-web-react/src/app/entityV2/summary/modules/assets/AddAssetsModal.tsx create mode 100644 datahub-web-react/src/app/entityV2/summary/modules/assets/constants.ts diff --git a/datahub-web-react/src/app/entityV2/summary/modules/assets/AddAssetsModal.tsx b/datahub-web-react/src/app/entityV2/summary/modules/assets/AddAssetsModal.tsx new file mode 100644 index 0000000000..35bef7e44e --- /dev/null +++ b/datahub-web-react/src/app/entityV2/summary/modules/assets/AddAssetsModal.tsx @@ -0,0 +1,205 @@ +import { message } from 'antd'; +import React, { useEffect, useState } from 'react'; + +import analytics, { EntityActionType, EventType } from '@app/analytics'; +import { useEntityContext, useEntityData, useRefetch } from '@app/entity/shared/EntityContext'; +import { EntityCapabilityType } from '@app/entityV2/Entity'; +import { SearchSelectModal } from '@app/entityV2/shared/components/styled/search/SearchSelectModal'; +import { handleBatchError } from '@app/entityV2/shared/utils'; +import { useEntityRegistryV2 } from '@app/useEntityRegistry'; + +import { useBatchSetDataProductMutation } from '@graphql/dataProduct.generated'; +import { useBatchAddTermsMutation, useBatchSetDomainMutation } from '@graphql/mutations.generated'; +import { EntityType } from '@types'; + +interface Props { + setShowAddAssetsModal: React.Dispatch>; +} + +export default function AddAssetsModal({ setShowAddAssetsModal }: Props) { + const { entityType, urn } = useEntityData(); + const entityRegistry = useEntityRegistryV2(); + const { setShouldRefetchEmbeddedListSearch, entityState } = useEntityContext(); + const refetch = useRefetch(); + + const [isBatchAddGlossaryTermModalVisible, setIsBatchAddGlossaryTermModalVisible] = useState(false); + const [isBatchSetDomainModalVisible, setIsBatchSetDomainModalVisible] = useState(false); + const [isBatchSetDataProductModalVisible, setIsBatchSetDataProductModalVisible] = useState(false); + const [batchAddTermsMutation] = useBatchAddTermsMutation(); + const [batchSetDomainMutation] = useBatchSetDomainMutation(); + const [batchSetDataProductMutation] = useBatchSetDataProductMutation(); + + useEffect(() => { + if (entityType === EntityType.DataProduct) { + setIsBatchSetDataProductModalVisible(true); + } else if (entityType === EntityType.Domain) { + setIsBatchSetDomainModalVisible(true); + } else if (entityType === EntityType.GlossaryTerm) { + setIsBatchAddGlossaryTermModalVisible(true); + } + }, [entityType]); + + const batchAddGlossaryTerms = (entityUrns: Array) => { + batchAddTermsMutation({ + variables: { + input: { + termUrns: [urn], + resources: entityUrns.map((entityUrn) => ({ + resourceUrn: entityUrn, + })), + }, + }, + }) + .then(({ errors }) => { + if (!errors) { + setIsBatchAddGlossaryTermModalVisible(false); + message.loading({ content: 'Updating...', duration: 3 }); + setTimeout(() => { + message.success({ + content: `Added Glossary Term to entities!`, + duration: 2, + }); + refetch?.(); + setShouldRefetchEmbeddedListSearch?.(true); + }, 3000); + } + }) + .catch((e) => { + message.destroy(); + message.error( + handleBatchError(entityUrns, e, { + content: `Failed to add glossary term: \n ${e.message || ''}`, + duration: 3, + }), + ); + }) + .finally(() => { + setShowAddAssetsModal(false); + }); + }; + + const batchSetDomain = (entityUrns: Array) => { + batchSetDomainMutation({ + variables: { + input: { + domainUrn: urn, + resources: entityUrns.map((entityUrn) => ({ + resourceUrn: entityUrn, + })), + }, + }, + }) + .then(({ errors }) => { + if (!errors) { + setIsBatchSetDomainModalVisible(false); + message.loading({ content: 'Updating...', duration: 3 }); + setTimeout(() => { + message.success({ + content: `Added assets to Domain!`, + duration: 3, + }); + refetch?.(); + setShouldRefetchEmbeddedListSearch?.(true); + entityState?.setShouldRefetchContents(true); + }, 3000); + analytics.event({ + type: EventType.BatchEntityActionEvent, + actionType: EntityActionType.SetDomain, + entityUrns, + }); + } + }) + .catch((e) => { + message.destroy(); + message.error( + handleBatchError(entityUrns, e, { + content: `Failed to add assets to Domain: \n ${e.message || ''}`, + duration: 3, + }), + ); + }) + .finally(() => { + setShowAddAssetsModal(false); + }); + }; + + const batchSetDataProduct = (entityUrns: Array) => { + batchSetDataProductMutation({ + variables: { + input: { + dataProductUrn: urn, + resourceUrns: entityUrns, + }, + }, + }) + .then(({ errors }) => { + if (!errors) { + setIsBatchSetDataProductModalVisible(false); + message.loading({ content: 'Updating...', duration: 3 }); + setTimeout(() => { + message.success({ + content: `Added assets to Data Product!`, + duration: 3, + }); + refetch?.(); + setShouldRefetchEmbeddedListSearch?.(true); + }, 3000); + analytics.event({ + type: EventType.BatchEntityActionEvent, + actionType: EntityActionType.SetDataProduct, + entityUrns, + }); + } + }) + .catch((e) => { + message.destroy(); + message.error( + handleBatchError(entityUrns, e, { + content: `Failed to add assets to Data Product. An unknown error occurred.`, + duration: 3, + }), + ); + }) + .finally(() => { + setShowAddAssetsModal(false); + }); + }; + + return ( + <> + {isBatchAddGlossaryTermModalVisible && ( + setIsBatchAddGlossaryTermModalVisible(false)} + fixedEntityTypes={Array.from( + entityRegistry.getTypesWithSupportedCapabilities(EntityCapabilityType.GLOSSARY_TERMS), + )} + /> + )} + {isBatchSetDomainModalVisible && ( + setIsBatchSetDomainModalVisible(false)} + fixedEntityTypes={Array.from( + entityRegistry.getTypesWithSupportedCapabilities(EntityCapabilityType.DOMAINS), + )} + /> + )} + {isBatchSetDataProductModalVisible && ( + setIsBatchSetDataProductModalVisible(false)} + fixedEntityTypes={Array.from( + entityRegistry.getTypesWithSupportedCapabilities(EntityCapabilityType.DATA_PRODUCTS), + )} + /> + )} + + ); +} diff --git a/datahub-web-react/src/app/entityV2/summary/modules/assets/AssetsModule.tsx b/datahub-web-react/src/app/entityV2/summary/modules/assets/AssetsModule.tsx index 1e8f8e0da1..df0ffde4b8 100644 --- a/datahub-web-react/src/app/entityV2/summary/modules/assets/AssetsModule.tsx +++ b/datahub-web-react/src/app/entityV2/summary/modules/assets/AssetsModule.tsx @@ -1,6 +1,9 @@ import { InfiniteScrollList } from '@components'; -import React from 'react'; +import React, { useState } from 'react'; +import { useEntityData } from '@app/entity/shared/EntityContext'; +import AddAssetsModal from '@app/entityV2/summary/modules/assets/AddAssetsModal'; +import { ENTITIES_TO_ADD_TO_ASSETS } from '@app/entityV2/summary/modules/assets/constants'; import { useGetAssets } from '@app/entityV2/summary/modules/assets/useGetAssets'; import EmptyContent from '@app/homeV3/module/components/EmptyContent'; import EntityItem from '@app/homeV3/module/components/EntityItem'; @@ -13,6 +16,10 @@ const DEFAULT_PAGE_SIZE = 10; export default function AssetsModule(props: ModuleProps) { const { loading, fetchAssets, total, navigateToAssetsTab } = useGetAssets(); + const { entityType } = useEntityData(); + + const canAddToAssets = ENTITIES_TO_ADD_TO_ASSETS.includes(entityType); + const [showAddAssetsModal, setShowAddAssetsModal] = useState(false); return ( @@ -24,16 +31,19 @@ export default function AssetsModule(props: ModuleProps) { )} pageSize={DEFAULT_PAGE_SIZE} emptyState={ - + canAddToAssets ? ( + setShowAddAssetsModal(true)} + /> + ) : null } totalItemCount={total} /> + {showAddAssetsModal && } ); diff --git a/datahub-web-react/src/app/entityV2/summary/modules/assets/constants.ts b/datahub-web-react/src/app/entityV2/summary/modules/assets/constants.ts new file mode 100644 index 0000000000..c11c8dc5c7 --- /dev/null +++ b/datahub-web-react/src/app/entityV2/summary/modules/assets/constants.ts @@ -0,0 +1,3 @@ +import { EntityType } from '@types'; + +export const ENTITIES_TO_ADD_TO_ASSETS = [EntityType.DataProduct, EntityType.Domain, EntityType.GlossaryTerm];