Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
# [0.36.0](https://github.com/ImagingDataCommons/slim/compare/v0.35.1...v0.36.0) (2024-12-06)


### Features

* update dmv version ([#257](https://github.com/ImagingDataCommons/slim/issues/257)) ([6feed17](https://github.com/ImagingDataCommons/slim/commit/6feed17845365a41fc48a991dc9d5f7e94d34c47))

## [0.35.1](https://github.com/ImagingDataCommons/slim/compare/v0.35.0...v0.35.1) (2024-11-22)


### Bug Fixes

* **DICOMTagBrowser:** Searched items should display all tree ([#255](https://github.com/ImagingDataCommons/slim/issues/255)) ([4633031](https://github.com/ImagingDataCommons/slim/commit/463303113ae9d4cb13b5aec8314947f21d39a725))

# [0.35.0](https://github.com/ImagingDataCommons/slim/compare/v0.34.0...v0.35.0) (2024-11-21)


Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "slim",
"version": "0.35.0",
"version": "0.36.0",
"homepage": "https://github.com/imagingdatacommons/slim",
"private": true,
"author": "ImagingDataCommons",
Expand Down Expand Up @@ -58,7 +58,7 @@
"craco-less": "^2.0.0",
"dcmjs": "^0.35.0",
"detect-browser": "^5.2.1",
"dicom-microscopy-viewer": "^0.47.2",
"dicom-microscopy-viewer": "^0.47.3",
"dicomweb-client": "^0.10.3",
"gh-pages": "^5.0.0",
"oidc-client": "^1.11.5",
Expand Down
100 changes: 64 additions & 36 deletions src/components/DicomTagBrowser/DicomTagBrowser.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,12 @@ const DicomTagBrowser = ({ clients, studyInstanceUID }: DicomTagBrowserProps): J
const debouncedSearchValue = useDebounce(searchInput, 300)

useEffect(() => {
setFilterValue(debouncedSearchValue)
if (debouncedSearchValue === '') {
setFilterValue('')
setExpandedKeys([])
} else {
setFilterValue(debouncedSearchValue)
}
}, [debouncedSearchValue])

useEffect(() => {
Expand Down Expand Up @@ -229,15 +234,11 @@ const DicomTagBrowser = ({ clients, studyInstanceUID }: DicomTagBrowserProps): J
return transformTagsToTableData(tags)
}, [instanceNumber, selectedDisplaySetInstanceUID, displaySets])

// Reset expanded keys when search value changes
useEffect(() => {
setExpandedKeys([])
}, [filterValue])

const filteredData = useMemo(() => {
if (filterValue === undefined || filterValue === '') return tableData

const searchLower = filterValue.toLowerCase()
const matchedKeys = new Set<string>()

const nodeMatches = (node: TableDataItem): boolean => {
return (
Expand All @@ -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 != null) {
node.children.forEach(child => {
const childPaths = findMatchingPaths(child, currentPath)
matchingPaths = [...matchingPaths, ...childPaths]
})
}

nodes.forEach(searchNode)
return results
return matchingPaths
}

// 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<string, {
node: TableDataItem
childPaths: TableDataItem[][]
}>()

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
})
}

return findMatchingNodes(tableData)
const filtered = reconstructTree(matchingPaths)
setExpandedKeys(Array.from(matchedKeys))

return filtered
}, [tableData, filterValue])

if (isLoading) {
Expand Down
8 changes: 4 additions & 4 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4982,10 +4982,10 @@ detective@^5.2.1:
defined "^1.0.0"
minimist "^1.2.6"

dicom-microscopy-viewer@^0.47.2:
version "0.47.2"
resolved "https://registry.yarnpkg.com/dicom-microscopy-viewer/-/dicom-microscopy-viewer-0.47.2.tgz#cc7b2ee5321872f14b3097480355385755831250"
integrity sha512-h+YaZwokxMFGNTdF4/YmiIaLyXA/Vn2A8ikS6JdSQOBkysHbolqzHelCCzZgpXO/ZPAF/p/hyrEjDuaE+LGDmw==
dicom-microscopy-viewer@^0.47.3:
version "0.47.3"
resolved "https://registry.yarnpkg.com/dicom-microscopy-viewer/-/dicom-microscopy-viewer-0.47.3.tgz#ff7b68ab6e8337818f1aea31257c283a444fa0a0"
integrity sha512-I/z8KikBnycPlS3dIFsyi6xhSrvOJmf0jhUo5juaxknl2tt094M8irhJ9VKHQJ4y4+/SrC7Z0gqR220cL5MIuA==
dependencies:
"@cornerstonejs/codec-charls" "^1.2.3"
"@cornerstonejs/codec-libjpeg-turbo-8bit" "^1.2.2"
Expand Down