diff --git a/packages/react-components/package.json b/packages/react-components/package.json index 7cd634b0..5f966dee 100644 --- a/packages/react-components/package.json +++ b/packages/react-components/package.json @@ -37,7 +37,7 @@ "react-virtualized": "^9.21.0", "semantic-ui-css": "^2.4.1", "semantic-ui-react": "^0.86.0", - "timeline-chart": "^0.4.0", + "timeline-chart": "^0.4.1", "traceviewer-base": "0.3.0", "tsp-typescript-client": "^0.4.3" }, diff --git a/packages/react-components/src/components/timegraph-output-component.tsx b/packages/react-components/src/components/timegraph-output-component.tsx index a9451d35..8145d219 100644 --- a/packages/react-components/src/components/timegraph-output-component.tsx +++ b/packages/react-components/src/components/timegraph-output-component.tsx @@ -1056,9 +1056,6 @@ export class TimegraphOutputComponent extends AbstractTreeOutputComponent !emptyNodes.includes(rowId)) + ); + } this.setState({ emptyNodes }); // Apply the pending selection here since the row provider had been called before this method. @@ -1475,7 +1478,8 @@ export class TimegraphOutputComponent extends AbstractTreeOutputComponent { const tree = listToTree(this.state.timegraphTree, this.state.columns); - const rowIndex = getIndexOfNode(id, tree, this.state.collapsedNodes); + const rowIndex = getIndexOfNode(id, tree, this.state.collapsedNodes, this.state.emptyNodes); if (isShiftClicked) { // Perform shift action based on selectedRow value if (this.state.selectedRow !== undefined) { - const treeNodeIds = getAllExpandedNodeIds(tree, this.state.collapsedNodes); - const lastSelectedRowIndex = getIndexOfNode(this.state.selectedRow, tree, this.state.collapsedNodes); + const treeNodeIds = getAllExpandedNodeIds(tree, this.state.collapsedNodes, this.state.emptyNodes); + const lastSelectedRowIndex = getIndexOfNode( + this.state.selectedRow, + tree, + this.state.collapsedNodes, + this.state.emptyNodes + ); this.handleShiftClick(rowIndex, lastSelectedRowIndex, treeNodeIds); } else { // Do not have a previous selection therefore treat this as a normal row click @@ -1514,7 +1523,12 @@ export class TimegraphOutputComponent extends AbstractTreeOutputComponent { if (!this.props.nodes) { return undefined; } - return {this.renderRows()}; } } diff --git a/packages/react-components/src/components/utils/filter-tree/table.tsx b/packages/react-components/src/components/utils/filter-tree/table.tsx index bdbd9f70..5100d516 100644 --- a/packages/react-components/src/components/utils/filter-tree/table.tsx +++ b/packages/react-components/src/components/utils/filter-tree/table.tsx @@ -80,7 +80,7 @@ export class Table extends React.Component { let nodes = sortNodes(this.props.nodes, this.props.sortConfig); if (this.props.hideEmptyNodes) { - nodes = filterEmptyNodes(nodes, this.props.emptyNodes); + nodes = filterEmptyNodes(nodes, this.props.emptyNodes, this.props.collapsedNodes); } return ( diff --git a/packages/react-components/src/components/utils/filter-tree/tree.tsx b/packages/react-components/src/components/utils/filter-tree/tree.tsx index fc9fae4f..0c17b724 100644 --- a/packages/react-components/src/components/utils/filter-tree/tree.tsx +++ b/packages/react-components/src/components/utils/filter-tree/tree.tsx @@ -3,7 +3,7 @@ import { TreeNode } from './tree-node'; import { Message } from './message'; import { Filter } from './filter'; import { Table } from './table'; -import { getAllExpandedNodeIds, filterEmptyNodes } from './utils'; +import { getAllExpandedNodeIds } from './utils'; import { SortConfig, sortNodes } from './sort'; import ColumnHeader from './column-header'; import { isEqual } from 'lodash'; @@ -96,7 +96,7 @@ export class FilterTree extends React.Component { - const ids = getAllExpandedNodeIds(nodes, this.props.collapsedNodes); + const ids = getAllExpandedNodeIds(nodes, this.props.collapsedNodes, this.props.emptyNodes); this.props.onOrderChange(ids); }; diff --git a/packages/react-components/src/components/utils/filter-tree/utils.tsx b/packages/react-components/src/components/utils/filter-tree/utils.tsx index a7222a1b..3be0bd1a 100644 --- a/packages/react-components/src/components/utils/filter-tree/utils.tsx +++ b/packages/react-components/src/components/utils/filter-tree/utils.tsx @@ -47,19 +47,26 @@ export const listToTree = (list: Entry[], headers: ColumnHeader[]): TreeNode[] = return rootNodes; }; -export const getAllExpandedNodeIds = (nodes: TreeNode[], collapsedNodes: number[]): number[] => { +export const getAllExpandedNodeIds = (nodes: TreeNode[], collapsedNodes: number[], emptyNodes?: number[]): number[] => { const visibleIds: number[] = []; nodes.forEach((node: TreeNode) => { - visibleIds.push(node.id); + if (!emptyNodes?.includes(node.id)) { + visibleIds.push(node.id); + } if (node.children.length && !collapsedNodes.includes(node.id)) { - visibleIds.push(...getAllExpandedNodeIds(node.children, collapsedNodes)); + visibleIds.push(...getAllExpandedNodeIds(node.children, collapsedNodes, emptyNodes)); } }); return visibleIds; }; -export const getIndexOfNode = (id: number, nodes: TreeNode[], collapsedNodes: number[]): number => { - const ids = getAllExpandedNodeIds(nodes, collapsedNodes); +export const getIndexOfNode = ( + id: number, + nodes: TreeNode[], + collapsedNodes: number[], + emptyNodes: number[] +): number => { + const ids = getAllExpandedNodeIds(nodes, collapsedNodes, emptyNodes); return ids.findIndex(eId => eId === id); }; @@ -75,26 +82,31 @@ export const validateNumArray = (arr: any | undefined): boolean => { * Removes specified nodes from the tree structure. * @param nodes The array of root nodes of the tree. * @param nodesToRemove An array of node IDs to be removed. + * @param collapsedNodes The array of collapsed node IDs. * @returns A new array of root nodes with specified nodes removed. */ -export function filterEmptyNodes(nodes: TreeNode[], nodesToRemove: number[]): TreeNode[] { +export function filterEmptyNodes(nodes: TreeNode[], nodesToRemove: number[], collapsedNodes: number[]): TreeNode[] { // return nodes; return nodes.reduce((acc: TreeNode[], node) => { - // If the current node is in the removal list, don't add it to the accumulator - if (nodesToRemove.includes(node.id)) { - return acc; - } - // Create a new node object with the same properties const newNode: TreeNode = { ...node }; // Recursively remove nodes from children if (newNode.children.length > 0) { - newNode.children = filterEmptyNodes(newNode.children, nodesToRemove); + newNode.children = filterEmptyNodes(newNode.children, nodesToRemove, collapsedNodes); + } + + if (!nodesToRemove.includes(node.id)) { + // If the new node is not in the removal list, add it to the accumulator + acc.push(newNode); + } else if (!collapsedNodes.includes(node.id)) { + // If the new node is in the removal list and expanded, add its filtered children to the accumulator + newNode.children.forEach(child => { + child.parentId = newNode.parentId; + acc.push(child); + }); } - // Add the new node to the accumulator - acc.push(newNode); return acc; }, []); } diff --git a/yarn.lock b/yarn.lock index 98e503f2..74e8ae85 100644 --- a/yarn.lock +++ b/yarn.lock @@ -13633,10 +13633,10 @@ through@2, "through@>=2.2.7 <3", through@^2.3.4, through@^2.3.6, through@^2.3.8: resolved "https://registry.npmjs.org/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg== -timeline-chart@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/timeline-chart/-/timeline-chart-0.4.0.tgz#c96301ce89b1306e4f69aa366b44e87bfcd4bffd" - integrity sha512-Pmsr+fLVBERWyKO3P9UJRIVWY3Sj+rqvzP4yg/RjCslqdQvl9qpQ+n8Tg7G9bxSvZ/NBKG+EpVpJGPDunPO84Q== +timeline-chart@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/timeline-chart/-/timeline-chart-0.4.1.tgz#57cefac6cfa928cd84842cfb5031a157d8bb716e" + integrity sha512-f5lNTaY4438ml6x4bHdh29/FTXZgMOvunM5FDA1fWocxlq5PCBWvndwSh/HiqOHT0HLuom7jz9juxFtjyFCZmg== dependencies: "@types/lodash.throttle" "^4.1.4" glob "^7.1.6"