From b78c8dc4e6afc817743b2cb02776132ff7f53b3a Mon Sep 17 00:00:00 2001 From: Igor Octaviano Date: Thu, 21 Nov 2024 16:44:29 -0300 Subject: [PATCH] Address search issues --- .../DicomTagBrowser/DicomTagBrowser.tsx | 88 ++++++++++++------- 1 file changed, 58 insertions(+), 30 deletions(-) diff --git a/src/components/DicomTagBrowser/DicomTagBrowser.tsx b/src/components/DicomTagBrowser/DicomTagBrowser.tsx index abcb31f..1a115fc 100644 --- a/src/components/DicomTagBrowser/DicomTagBrowser.tsx +++ b/src/components/DicomTagBrowser/DicomTagBrowser.tsx @@ -238,6 +238,7 @@ const DicomTagBrowser = ({ clients, studyInstanceUID }: DicomTagBrowserProps): J if (filterValue === undefined || filterValue === '') return tableData const searchLower = filterValue.toLowerCase() + const matchedKeys = new Set() const nodeMatches = (node: TableDataItem): boolean => { return ( @@ -248,42 +249,69 @@ const DicomTagBrowser = ({ clients, studyInstanceUID }: DicomTagBrowserProps): J ) } - const findMatchingNodes = (nodes: TableDataItem[]): TableDataItem[] => { - const results: TableDataItem[] = [] - - const searchNode = (node: TableDataItem): void => { - if (nodeMatches(node)) { - // Create a new matching node with its original structure - const matchingNode: TableDataItem = { - key: node.key, - tag: node.tag, - vr: node.vr, - keyword: node.keyword, - value: node.value - } + // First pass: find all matching nodes and their parent paths + const findMatchingPaths = ( + node: TableDataItem, + parentPath: TableDataItem[] = [] + ): TableDataItem[][] => { + const currentPath = [...parentPath, node] + let matchingPaths: TableDataItem[][] = [] - // If the node has children, preserve them for expansion - matchingNode.children = node?.children?.map((child): TableDataItem => ({ - key: child.key, - tag: child.tag, - vr: child.vr, - keyword: child.keyword, - value: child.value, - children: child.children - })) - - results.push(matchingNode) - } + if (nodeMatches(node)) { + matchingPaths.push(currentPath) + } - // Continue searching through children - node?.children?.forEach(searchNode) + if (node.children) { + node.children.forEach(child => { + const childPaths = findMatchingPaths(child, currentPath) + matchingPaths = [...matchingPaths, ...childPaths] + }) } - nodes.forEach(searchNode) - return results + return matchingPaths } - return findMatchingNodes(tableData) + // Find all paths that contain matches + const matchingPaths = tableData.flatMap(node => findMatchingPaths(node)) + + // Second pass: reconstruct the tree with matching paths + const reconstructTree = ( + paths: TableDataItem[][], + level = 0 + ): TableDataItem[] => { + if (paths.length === 0 || level >= paths[0].length) return [] + + const nodesAtLevel = new Map() + + paths.forEach(path => { + if (level < path.length) { + const node = path[level] + if (!nodesAtLevel.has(node.key)) { + nodesAtLevel.set(node.key, { + node: { ...node }, + childPaths: [] + }) + } + if (level + 1 < path.length) { + nodesAtLevel.get(node.key)?.childPaths.push(path) + } + } + }) + + return Array.from(nodesAtLevel.values()).map(({ node, childPaths }) => { + matchedKeys.add(node.key) + const children = reconstructTree(childPaths, level + 1) + return children.length > 0 ? { ...node, children } : node + }) + } + + const filtered = reconstructTree(matchingPaths) + setExpandedKeys(Array.from(matchedKeys)) + + return filtered }, [tableData, filterValue]) if (isLoading) {