mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2026-01-06 04:26:57 +00:00
UI: Added expand/collapse button for single nodes and increase zoom out default value (#9977)
This commit is contained in:
parent
5650ae35df
commit
da224c090d
@ -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<EntityLineageProp> = ({
|
||||
hasEditAccess,
|
||||
onExitFullScreenViewClick,
|
||||
}: EntityLineageProp) => {
|
||||
const { t } = useTranslation();
|
||||
const reactFlowWrapper = useRef<HTMLDivElement>(null);
|
||||
const [reactFlowInstance, setReactFlowInstance] =
|
||||
useState<ReactFlowInstance>();
|
||||
@ -479,6 +480,88 @@ const EntityLineageComponent: FunctionComponent<EntityLineageProp> = ({
|
||||
[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 = (
|
||||
<LineageNodeLabel
|
||||
isExpanded
|
||||
node={node}
|
||||
onNodeExpand={handleNodeExpand}
|
||||
/>
|
||||
);
|
||||
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 = (
|
||||
<LineageNodeLabel
|
||||
isExpanded={false}
|
||||
node={node}
|
||||
onNodeExpand={handleNodeExpand}
|
||||
/>
|
||||
);
|
||||
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<EntityLineageProp> = ({
|
||||
tableColumnsRef.current,
|
||||
addPipelineClick,
|
||||
handleColumnClick,
|
||||
expandAllColumns
|
||||
expandAllColumns,
|
||||
handleNodeExpand
|
||||
) as CustomElement;
|
||||
|
||||
const uniqueElements: CustomElement = {
|
||||
@ -951,31 +1035,6 @@ const EntityLineageComponent: FunctionComponent<EntityLineageProp> = ({
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 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<EntityLineageProp> = ({
|
||||
isEditMode,
|
||||
label: (
|
||||
<Fragment>
|
||||
<LineageNodeLabel node={selectedEntity} />
|
||||
<LineageNodeLabel
|
||||
node={selectedEntity}
|
||||
onNodeExpand={handleNodeExpand}
|
||||
/>
|
||||
{getNodeRemoveButton(() => {
|
||||
removeNodeHandler({
|
||||
...el,
|
||||
@ -1139,6 +1201,13 @@ const EntityLineageComponent: FunctionComponent<EntityLineageProp> = ({
|
||||
setNodes((prevNodes) => {
|
||||
const updatedNode = prevNodes.map((node) => {
|
||||
node.data.isExpanded = value;
|
||||
node.data.label = (
|
||||
<LineageNodeLabel
|
||||
isExpanded={value}
|
||||
node={node.data.node}
|
||||
onNodeExpand={handleNodeExpand}
|
||||
/>
|
||||
);
|
||||
|
||||
return node;
|
||||
});
|
||||
@ -1236,7 +1305,12 @@ const EntityLineageComponent: FunctionComponent<EntityLineageProp> = ({
|
||||
...el,
|
||||
data: {
|
||||
...el.data,
|
||||
label: <LineageNodeLabel node={newlyAddedNode} />,
|
||||
label: (
|
||||
<LineageNodeLabel
|
||||
node={newlyAddedNode}
|
||||
onNodeExpand={handleNodeExpand}
|
||||
/>
|
||||
),
|
||||
},
|
||||
};
|
||||
} else {
|
||||
|
||||
@ -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 (
|
||||
<p className="tw-flex tw-items-center tw-m-0 tw-py-3">
|
||||
<span className="tw-mr-2">{getEntityIcon(node.type)}</span>
|
||||
{getDataLabel(
|
||||
node.displayName,
|
||||
node.fullyQualifiedName,
|
||||
false,
|
||||
node.type
|
||||
)}
|
||||
</p>
|
||||
<>
|
||||
{node.type === 'table' ? (
|
||||
<Button
|
||||
ghost
|
||||
className="custom-node-expand-button p-0"
|
||||
icon={
|
||||
<SVGIcons
|
||||
alt="plus"
|
||||
icon={isExpanded ? Icons.ICON_MINUS : Icons.ICON_PLUS}
|
||||
width="16px"
|
||||
/>
|
||||
}
|
||||
size="small"
|
||||
type="text"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
onNodeExpand && onNodeExpand(!isExpanded, node);
|
||||
}}
|
||||
/>
|
||||
) : null}
|
||||
<p className="flex items-center m-0 p-y-sm">
|
||||
<span className="m-r-xs">{getEntityIcon(node.type)}</span>
|
||||
{getDataLabel(
|
||||
node.displayName,
|
||||
node.fullyQualifiedName,
|
||||
false,
|
||||
node.type
|
||||
)}
|
||||
</p>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@ -115,3 +115,10 @@
|
||||
column-gap: 8px;
|
||||
height: 32px;
|
||||
}
|
||||
.custom-node-expand-button {
|
||||
position: absolute;
|
||||
top: -14px;
|
||||
left: -12px;
|
||||
cursor: pointer;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
@ -16,8 +16,8 @@ import { capitalize } from 'lodash';
|
||||
import { EntityType } from '../enums/entity.enum';
|
||||
|
||||
export const FOREIGN_OBJECT_SIZE = 40;
|
||||
export const ZOOM_VALUE = 1;
|
||||
export const MIN_ZOOM_VALUE = 0.5;
|
||||
export const ZOOM_VALUE = 0.5;
|
||||
export const MIN_ZOOM_VALUE = 0.1;
|
||||
export const MAX_ZOOM_VALUE = 2.5;
|
||||
export const ZOOM_SLIDER_STEP = 0.1;
|
||||
export const ZOOM_BUTTON_STEP = 0.25;
|
||||
|
||||
@ -50,9 +50,9 @@ import { FQN_SEPARATOR_CHAR } from '../constants/char.constants';
|
||||
import { SECONDARY_COLOR } from '../constants/constants';
|
||||
import {
|
||||
EXPANDED_NODE_HEIGHT,
|
||||
MIN_ZOOM_VALUE,
|
||||
NODE_HEIGHT,
|
||||
NODE_WIDTH,
|
||||
ZOOM_VALUE,
|
||||
} from '../constants/Lineage.constants';
|
||||
import {
|
||||
EntityLineageDirection,
|
||||
@ -109,7 +109,7 @@ export const getHeaderLabel = (
|
||||
|
||||
export const onLoad = (reactFlowInstance: ReactFlowInstance) => {
|
||||
reactFlowInstance.fitView();
|
||||
reactFlowInstance.zoomTo(MIN_ZOOM_VALUE);
|
||||
reactFlowInstance.zoomTo(ZOOM_VALUE);
|
||||
};
|
||||
/* eslint-disable-next-line */
|
||||
export const onNodeMouseEnter = (_event: ReactMouseEvent, _node: Node) => {
|
||||
@ -193,7 +193,8 @@ export const getLineageData = (
|
||||
data: CustomEdgeData
|
||||
) => void,
|
||||
handleColumnClick?: (value: string) => void,
|
||||
isExpanded?: boolean
|
||||
isExpanded?: boolean,
|
||||
onNodeExpand?: (isExpanded: boolean, node: EntityReference) => void
|
||||
) => {
|
||||
const [x, y] = [0, 0];
|
||||
const nodes = [...(entityLineage['nodes'] || []), entityLineage['entity']];
|
||||
@ -324,7 +325,11 @@ export const getLineageData = (
|
||||
</div>
|
||||
)}
|
||||
|
||||
<LineageNodeLabel node={node} />
|
||||
<LineageNodeLabel
|
||||
isExpanded={isExpanded}
|
||||
node={node}
|
||||
onNodeExpand={onNodeExpand}
|
||||
/>
|
||||
|
||||
{type === EntityLineageNodeType.OUTPUT && (
|
||||
<div
|
||||
@ -392,7 +397,13 @@ export const getLineageData = (
|
||||
type: getNodeType(entityLineage, mainNode.id),
|
||||
className: `leaf-node core`,
|
||||
data: {
|
||||
label: <LineageNodeLabel node={mainNode} />,
|
||||
label: (
|
||||
<LineageNodeLabel
|
||||
isExpanded={isExpanded}
|
||||
node={mainNode}
|
||||
onNodeExpand={onNodeExpand}
|
||||
/>
|
||||
),
|
||||
isEditMode,
|
||||
removeNodeHandler,
|
||||
handleColumnClick,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user