UI: Added expand/collapse button for single nodes and increase zoom out default value (#9977)

This commit is contained in:
Shailesh Parmar 2023-01-29 00:01:10 +05:30 committed by GitHub
parent 5650ae35df
commit da224c090d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 172 additions and 47 deletions

View File

@ -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 {

View File

@ -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>
</>
);
};

View File

@ -115,3 +115,10 @@
column-gap: 8px;
height: 32px;
}
.custom-node-expand-button {
position: absolute;
top: -14px;
left: -12px;
cursor: pointer;
z-index: 1;
}

View File

@ -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;

View File

@ -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,