From 83a1d4bb31d4bc183b55c2d1a61bfe024caf0b53 Mon Sep 17 00:00:00 2001 From: mgorsk1 Date: Sat, 6 Jan 2024 10:24:41 +0100 Subject: [PATCH] fix: rendering of more complex pipelines tree view (#14595) --- .../TreeView/TreeViewTab.component.tsx | 4 +- .../resources/ui/src/utils/executionUtils.tsx | 164 ++++++++---------- 2 files changed, 77 insertions(+), 91 deletions(-) diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Execution/TreeView/TreeViewTab.component.tsx b/openmetadata-ui/src/main/resources/ui/src/components/Execution/TreeView/TreeViewTab.component.tsx index 8c05c5eb882..2648cca21fe 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/Execution/TreeView/TreeViewTab.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/Execution/TreeView/TreeViewTab.component.tsx @@ -78,7 +78,7 @@ const TreeViewTab = ({ /> ) : ( - + - + taskData.downstreamTasks?.includes(currentTask.name) ); +// Function to build a tree for all nodes +export const buildCompleteTree = ( + data: Task[], + viewElements: { + key: string; + value: any; + }[], + icon: any, + key: string, + parentKey: string +) => { + let node: DataNode; + + const nodeKey: string = parentKey + '-' + key; + + if (icon != null) { + node = { + key: nodeKey, + title: viewElements.find((item) => item.key === key)?.value ?? null, + children: [], + icon, + }; + } else { + node = { + key: nodeKey, + title: viewElements.find((item) => item.key === key)?.value ?? null, + children: [], + }; + } + const entry = data.find((item) => item.name === key); + + if (entry) { + const childrenKeys = entry.downstreamTasks ?? []; + + for (const childKey of childrenKeys) { + const childNode = buildCompleteTree( + data, + viewElements, + icon, + childKey, + parentKey + '-' + entry.name + ); + node.children?.push(childNode); + } + } + + if (node.children?.length === 0) { + delete node.children; + } + + return node; +}; + export const getTreeData = ( tasks: Task[], viewData: Record ) => { const icon =
; - let treeDataList: DataNode[] = []; - let treeLabelList: DataNode[] = []; + const treeDataList: DataNode[] = []; + const treeLabelList: DataNode[] = []; // map execution element to task name const viewElements = map(viewData, (value, key) => ({ @@ -161,96 +214,29 @@ export const getTreeData = ( ), })); + const labelElements: { key: string; value: string }[] = []; + + viewElements.forEach((value) => { + const object = { key: value.key, value: value.key }; + labelElements.push(object); + }); + + const roots: string[] = []; + for (const task of tasks) { - const taskName = task.name; - - // list of downstream tasks - const downstreamTasks = task.downstreamTasks ?? []; - - // check has downstream tasks or not - const hasDownStream = Boolean(downstreamTasks.length); - - // check if current task is downstream task - const isDownStreamTask = checkIsDownStreamTask(task, tasks); - - // check if it's an existing tree data - const existingData = treeDataList.find((tData) => tData.key === taskName); - - // check if it's an existing label data - const existingLabel = treeLabelList.find((lData) => lData.key === taskName); - - // get the execution element for current task - const currentViewElement = getExecutionElementByKey(taskName, viewElements); - const currentTreeData = { - key: taskName, - title: currentViewElement?.value ?? null, - }; - - const currentLabelData = { - key: taskName, - title: taskName, - icon, - }; - - // skip the down stream node as it will be render by the parent task - if (isDownStreamTask) { - continue; - } else if (hasDownStream) { - const dataChildren: DataNode[] = []; - const labelChildren: DataNode[] = []; - // get execution list of downstream tasks - - for (const downstreamTask of downstreamTasks) { - const taskElement = getExecutionElementByKey( - downstreamTask, - viewElements - ); - - dataChildren.push({ - key: downstreamTask, - title: taskElement?.value ?? null, - }); - - labelChildren.push({ - key: downstreamTask, - title: downstreamTask, - icon, - }); - } - - /** - * if not existing data then push current tree data to tree data list - * else modified the existing data - */ - treeDataList = isUndefined(existingData) - ? [...treeDataList, { ...currentTreeData, children: dataChildren }] - : treeDataList.map((currentData) => { - if (currentData.key === existingData.key) { - return { ...existingData, children: dataChildren }; - } else { - return currentData; - } - }); - - treeLabelList = isUndefined(existingLabel) - ? [...treeLabelList, { ...currentLabelData, children: labelChildren }] - : treeLabelList.map((currentData) => { - if (currentData.key === existingLabel.key) { - return { ...existingLabel, children: labelChildren }; - } else { - return currentData; - } - }); - } else { - treeDataList = isUndefined(existingData) - ? [...treeDataList, currentTreeData] - : treeDataList; - - treeLabelList = isUndefined(existingLabel) - ? [...treeLabelList, currentLabelData] - : treeLabelList; + if (!checkIsDownStreamTask(task, tasks)) { + roots.push(task.name); } } + roots.forEach((taskName) => { + treeDataList.push( + buildCompleteTree(tasks, viewElements, null, taskName, 'root') + ); + treeLabelList.push( + buildCompleteTree(tasks, labelElements, icon, taskName, 'root') + ); + }); + return { treeDataList, treeLabelList }; };