diff --git a/openmetadata-ui/src/main/resources/ui/src/components/EntityLineage/EntityLineage.component.tsx b/openmetadata-ui/src/main/resources/ui/src/components/EntityLineage/EntityLineage.component.tsx index 2a0554f4b4d..d0ba5a718d0 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/EntityLineage/EntityLineage.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/EntityLineage/EntityLineage.component.tsx @@ -33,6 +33,7 @@ import React, { useRef, useState, } from 'react'; +import { useTranslation } from 'react-i18next'; import ReactFlow, { addEdge, Background, @@ -57,7 +58,7 @@ import { ZOOM_TRANSITION_DURATION, ZOOM_VALUE, } from '../../constants/Lineage.constants'; -import { EntityType } from '../../enums/entity.enum'; +import { EntityLineageNodeType, EntityType } from '../../enums/entity.enum'; import { SearchIndex } from '../../enums/search.enum'; import { AddLineage, @@ -80,7 +81,6 @@ import { getAllTracedNodes, getClassifiedEdge, getColumnType, - getDataLabel, getDeletedLineagePlaceholder, getEdgeStyle, getEdgeType, @@ -145,6 +145,7 @@ const EntityLineageComponent: FunctionComponent = ({ hasEditAccess, onExitFullScreenViewClick, }: EntityLineageProp) => { + const { t } = useTranslation(); const reactFlowWrapper = useRef(null); const [reactFlowInstance, setReactFlowInstance] = useState(); @@ -479,6 +480,88 @@ const EntityLineageComponent: FunctionComponent = ({ [nodes, updatedLineageData] ); + /** + * take node and get the columns for that node + * @param expandNode + */ + const getTableColumns = async (expandNode?: EntityReference) => { + if (expandNode) { + try { + const res = await getTableDetails(expandNode.id, ['columns']); + const tableId = expandNode.id; + const { columns } = res; + tableColumnsRef.current[tableId] = columns; + updateColumnsToNode(columns, tableId); + } catch (error) { + showErrorToast( + error as AxiosError, + t('server.entity-details-fetch-error', { + entityName: expandNode.displayName ?? expandNode.name, + entityType: t('label.column-plural'), + }) + ); + } + } + }; + + const handleNodeExpand = (isExpanded: boolean, node: EntityReference) => { + if (isExpanded) { + setNodes((prevState) => { + const newNodes = prevState.map((prevNode) => { + if (prevNode.id === node.id) { + const nodeId = node.id; + prevNode.data.label = ( + + ); + prevNode.data.isExpanded = true; + if (isUndefined(tableColumnsRef.current[nodeId])) { + getTableColumns(node); + } else { + const cols: { [key: string]: ModifiedColumn } = {}; + tableColumnsRef.current[nodeId]?.forEach((col) => { + cols[col.fullyQualifiedName || col.name] = { + ...col, + type: isEditMode + ? EntityLineageNodeType.DEFAULT + : getColumnType(edges, col.fullyQualifiedName || col.name), + }; + }); + prevNode.data.columns = cols; + } + } + + return prevNode; + }); + + return newNodes; + }); + } else { + setNodes((prevState) => { + const newNodes = prevState.map((n) => { + if (n.id === node.id) { + n.data.label = ( + + ); + n.data.isExpanded = false; + n.data.columns = undefined; + } + + return n; + }); + + return newNodes; + }); + } + }; + const setElementsHandle = (data: EntityLineage) => { if (!isEmpty(data)) { const graphElements = getLineageData( @@ -494,7 +577,8 @@ const EntityLineageComponent: FunctionComponent = ({ tableColumnsRef.current, addPipelineClick, handleColumnClick, - expandAllColumns + expandAllColumns, + handleNodeExpand ) as CustomElement; const uniqueElements: CustomElement = { @@ -951,31 +1035,6 @@ const EntityLineageComponent: FunctionComponent = ({ }); }; - /** - * take node and get the columns for that node - * @param expandNode - */ - const getTableColumns = async (expandNode?: EntityReference) => { - if (expandNode) { - try { - const res = await getTableDetails(expandNode.id, ['columns']); - const tableId = expandNode.id; - const { columns } = res; - tableColumnsRef.current[tableId] = columns; - updateColumnsToNode(columns, tableId); - } catch (error) { - showErrorToast( - error as AxiosError, - `Error while fetching ${getDataLabel( - expandNode.displayName, - expandNode.name, - true - )} columns` - ); - } - } - }; - /** * handle node drag event * @param event @@ -1078,7 +1137,10 @@ const EntityLineageComponent: FunctionComponent = ({ isEditMode, label: ( - + {getNodeRemoveButton(() => { removeNodeHandler({ ...el, @@ -1139,6 +1201,13 @@ const EntityLineageComponent: FunctionComponent = ({ setNodes((prevNodes) => { const updatedNode = prevNodes.map((node) => { node.data.isExpanded = value; + node.data.label = ( + + ); return node; }); @@ -1236,7 +1305,12 @@ const EntityLineageComponent: FunctionComponent = ({ ...el, data: { ...el.data, - label: , + label: ( + + ), }, }; } else { diff --git a/openmetadata-ui/src/main/resources/ui/src/components/EntityLineage/LineageNodeLabel.tsx b/openmetadata-ui/src/main/resources/ui/src/components/EntityLineage/LineageNodeLabel.tsx index 64b7cba9c92..63832a28323 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/EntityLineage/LineageNodeLabel.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/EntityLineage/LineageNodeLabel.tsx @@ -11,22 +11,55 @@ * limitations under the License. */ +import { Button } from 'antd'; import React from 'react'; +import SVGIcons, { Icons } from 'utils/SvgUtils'; import { EntityReference } from '../../generated/type/entityReference'; import { getDataLabel } from '../../utils/EntityLineageUtils'; import { getEntityIcon } from '../../utils/TableUtils'; -const LineageNodeLabel = ({ node }: { node: EntityReference }) => { +interface LineageNodeLabelProps { + node: EntityReference; + onNodeExpand?: (isExpanded: boolean, node: EntityReference) => void; + isExpanded?: boolean; +} + +const LineageNodeLabel = ({ + node, + onNodeExpand, + isExpanded = false, +}: LineageNodeLabelProps) => { return ( -

- {getEntityIcon(node.type)} - {getDataLabel( - node.displayName, - node.fullyQualifiedName, - false, - node.type - )} -

+ <> + {node.type === 'table' ? ( +