fix(segmentation): Add segment jump for new segments and make panels scrollable (#4928)

This commit is contained in:
Alireza 2025-04-07 16:45:29 -04:00 committed by GitHub
parent a8ac297e16
commit 3653de7487
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
23 changed files with 491 additions and 368 deletions

View File

@ -242,7 +242,7 @@ jobs:
- setup_remote_docker:
docker_layer_caching: false
- run:
name: Build Docker image for arm64
name: Build Docker image for arm64 (Release)
command: |
# This file will exist if a new version was published by
# our command in the previous job.
@ -369,7 +369,7 @@ jobs:
- setup_remote_docker:
docker_layer_caching: false
- run:
name: Create and push multi-architecture manifest
name: Create and push multi-architecture manifest (Release)
command: |
# This file will exist if a new version was published by
# our command in the previous job.

View File

@ -13,7 +13,7 @@
"@kitware/vtk.js": "32.12.0",
"clsx": "^2.1.1",
"core-js": "^3.2.1",
"moment": "^2.9.4"
"moment": "^2.30.1"
},
"peerDependencies": {
"react": "^18.3.1",

284
bun.lock
View File

@ -33,13 +33,13 @@
},
"addOns/externals/devDependencies": {
"name": "@externals/devDependencies",
"version": "3.10.0-beta.147",
"version": "3.10.0-beta.150",
"dependencies": {
"@babel/runtime": "^7.20.13",
"@kitware/vtk.js": "32.12.0",
"clsx": "^2.1.1",
"core-js": "^3.2.1",
"moment": "^2.9.4",
"moment": "^2.30.1",
},
"devDependencies": {
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.15",
@ -121,22 +121,22 @@
},
"addOns/externals/dicom-microscopy-viewer": {
"name": "@externals/dicom-microscopy-viewer",
"version": "3.10.0-beta.147",
"version": "3.10.0-beta.150",
"dependencies": {
"dicom-microscopy-viewer": "^0.46.1",
},
},
"extensions/cornerstone": {
"name": "@ohif/extension-cornerstone",
"version": "3.10.0-beta.147",
"version": "3.10.0-beta.150",
"dependencies": {
"@babel/runtime": "^7.20.13",
"@cornerstonejs/adapters": "^3.8.5",
"@cornerstonejs/ai": "^3.8.5",
"@cornerstonejs/core": "^3.8.5",
"@cornerstonejs/labelmap-interpolation": "^3.8.5",
"@cornerstonejs/polymorphic-segmentation": "^3.8.5",
"@cornerstonejs/tools": "^3.8.5",
"@cornerstonejs/adapters": "^3.9.1",
"@cornerstonejs/ai": "^3.9.1",
"@cornerstonejs/core": "^3.9.1",
"@cornerstonejs/labelmap-interpolation": "^3.9.1",
"@cornerstonejs/polymorphic-segmentation": "^3.9.1",
"@cornerstonejs/tools": "^3.9.1",
"@itk-wasm/morphological-contour-interpolation": "1.1.0",
"@kitware/vtk.js": "32.12.0",
"html2canvas": "^1.4.1",
@ -153,9 +153,9 @@
"@cornerstonejs/codec-libjpeg-turbo-8bit": "^1.2.2",
"@cornerstonejs/codec-openjpeg": "^1.2.4",
"@cornerstonejs/codec-openjph": "^2.4.5",
"@cornerstonejs/dicom-image-loader": "^3.8.5",
"@ohif/core": "3.10.0-beta.147",
"@ohif/ui": "3.10.0-beta.147",
"@cornerstonejs/dicom-image-loader": "^3.9.1",
"@ohif/core": "3.10.0-beta.150",
"@ohif/ui": "3.10.0-beta.150",
"dcmjs": "*",
"dicom-parser": "^1.8.21",
"hammerjs": "^2.0.8",
@ -167,19 +167,19 @@
},
"extensions/cornerstone-dicom-pmap": {
"name": "@ohif/extension-cornerstone-dicom-pmap",
"version": "3.10.0-beta.147",
"version": "3.10.0-beta.150",
"dependencies": {
"@babel/runtime": "^7.20.13",
"@cornerstonejs/adapters": "^3.8.5",
"@cornerstonejs/core": "^3.8.5",
"@cornerstonejs/adapters": "^3.9.1",
"@cornerstonejs/core": "^3.9.1",
"@kitware/vtk.js": "32.12.0",
"react-color": "^2.19.3",
},
"peerDependencies": {
"@ohif/core": "3.10.0-beta.147",
"@ohif/extension-cornerstone": "3.10.0-beta.147",
"@ohif/extension-default": "3.10.0-beta.147",
"@ohif/i18n": "3.10.0-beta.147",
"@ohif/core": "3.10.0-beta.150",
"@ohif/extension-cornerstone": "3.10.0-beta.150",
"@ohif/extension-default": "3.10.0-beta.150",
"@ohif/i18n": "3.10.0-beta.150",
"prop-types": "^15.6.2",
"react": "^18.3.1",
"react-dom": "^18.3.1",
@ -190,16 +190,16 @@
},
"extensions/cornerstone-dicom-rt": {
"name": "@ohif/extension-cornerstone-dicom-rt",
"version": "3.10.0-beta.147",
"version": "3.10.0-beta.150",
"dependencies": {
"@babel/runtime": "^7.20.13",
"react-color": "^2.19.3",
},
"peerDependencies": {
"@ohif/core": "3.10.0-beta.147",
"@ohif/extension-cornerstone": "3.10.0-beta.147",
"@ohif/extension-default": "3.10.0-beta.147",
"@ohif/i18n": "3.10.0-beta.147",
"@ohif/core": "3.10.0-beta.150",
"@ohif/extension-cornerstone": "3.10.0-beta.150",
"@ohif/extension-default": "3.10.0-beta.150",
"@ohif/i18n": "3.10.0-beta.150",
"prop-types": "^15.6.2",
"react": "^18.3.1",
"react-dom": "^18.3.1",
@ -210,19 +210,19 @@
},
"extensions/cornerstone-dicom-seg": {
"name": "@ohif/extension-cornerstone-dicom-seg",
"version": "3.10.0-beta.147",
"version": "3.10.0-beta.150",
"dependencies": {
"@babel/runtime": "^7.20.13",
"@cornerstonejs/adapters": "^3.8.5",
"@cornerstonejs/core": "^3.8.5",
"@cornerstonejs/adapters": "^3.9.1",
"@cornerstonejs/core": "^3.9.1",
"@kitware/vtk.js": "32.12.0",
"react-color": "^2.19.3",
},
"peerDependencies": {
"@ohif/core": "3.10.0-beta.147",
"@ohif/extension-cornerstone": "3.10.0-beta.147",
"@ohif/extension-default": "3.10.0-beta.147",
"@ohif/i18n": "3.10.0-beta.147",
"@ohif/core": "3.10.0-beta.150",
"@ohif/extension-cornerstone": "3.10.0-beta.150",
"@ohif/extension-default": "3.10.0-beta.150",
"@ohif/i18n": "3.10.0-beta.150",
"prop-types": "^15.6.2",
"react": "^18.3.1",
"react-dom": "^18.3.1",
@ -233,19 +233,19 @@
},
"extensions/cornerstone-dicom-sr": {
"name": "@ohif/extension-cornerstone-dicom-sr",
"version": "3.10.0-beta.147",
"version": "3.10.0-beta.150",
"dependencies": {
"@babel/runtime": "^7.20.13",
"@cornerstonejs/adapters": "^3.8.5",
"@cornerstonejs/core": "^3.8.5",
"@cornerstonejs/tools": "^3.8.5",
"@cornerstonejs/adapters": "^3.9.1",
"@cornerstonejs/core": "^3.9.1",
"@cornerstonejs/tools": "^3.9.1",
"classnames": "^2.3.2",
},
"peerDependencies": {
"@ohif/core": "3.10.0-beta.147",
"@ohif/extension-cornerstone": "3.10.0-beta.147",
"@ohif/extension-measurement-tracking": "3.10.0-beta.147",
"@ohif/ui": "3.10.0-beta.147",
"@ohif/core": "3.10.0-beta.150",
"@ohif/extension-cornerstone": "3.10.0-beta.150",
"@ohif/extension-measurement-tracking": "3.10.0-beta.150",
"@ohif/ui": "3.10.0-beta.150",
"dcmjs": "*",
"dicom-parser": "^1.8.9",
"hammerjs": "^2.0.8",
@ -255,19 +255,19 @@
},
"extensions/cornerstone-dynamic-volume": {
"name": "@ohif/extension-cornerstone-dynamic-volume",
"version": "3.10.0-beta.147",
"version": "3.10.0-beta.150",
"dependencies": {
"@babel/runtime": "^7.20.13",
"@cornerstonejs/core": "^3.8.5",
"@cornerstonejs/tools": "^3.8.5",
"@cornerstonejs/core": "^3.9.1",
"@cornerstonejs/tools": "^3.9.1",
"classnames": "^2.3.2",
},
"peerDependencies": {
"@ohif/core": "3.10.0-beta.147",
"@ohif/extension-cornerstone": "3.10.0-beta.147",
"@ohif/extension-default": "3.10.0-beta.147",
"@ohif/i18n": "3.10.0-beta.147",
"@ohif/ui": "3.10.0-beta.147",
"@ohif/core": "3.10.0-beta.150",
"@ohif/extension-cornerstone": "3.10.0-beta.150",
"@ohif/extension-default": "3.10.0-beta.150",
"@ohif/i18n": "3.10.0-beta.150",
"@ohif/ui": "3.10.0-beta.150",
"dcmjs": "*",
"dicom-parser": "^1.8.21",
"hammerjs": "^2.0.8",
@ -277,7 +277,7 @@
},
"extensions/default": {
"name": "@ohif/extension-default",
"version": "3.10.0-beta.147",
"version": "3.10.0-beta.150",
"dependencies": {
"@babel/runtime": "^7.20.13",
"@cornerstonejs/calculate-suv": "^1.1.0",
@ -285,8 +285,8 @@
"lodash.uniqby": "^4.7.0",
},
"peerDependencies": {
"@ohif/core": "3.10.0-beta.147",
"@ohif/i18n": "3.10.0-beta.147",
"@ohif/core": "3.10.0-beta.150",
"@ohif/i18n": "3.10.0-beta.150",
"dcmjs": "*",
"dicomweb-client": "^0.10.4",
"prop-types": "^15.6.2",
@ -300,7 +300,7 @@
},
"extensions/dicom-microscopy": {
"name": "@ohif/extension-dicom-microscopy",
"version": "3.10.0-beta.147",
"version": "3.10.0-beta.150",
"dependencies": {
"@babel/runtime": "^7.20.13",
"@cornerstonejs/codec-charls": "^1.2.3",
@ -311,10 +311,10 @@
"mathjs": "^12.4.2",
},
"peerDependencies": {
"@ohif/core": "3.10.0-beta.147",
"@ohif/extension-default": "3.10.0-beta.147",
"@ohif/i18n": "3.10.0-beta.147",
"@ohif/ui": "3.10.0-beta.147",
"@ohif/core": "3.10.0-beta.150",
"@ohif/extension-default": "3.10.0-beta.150",
"@ohif/i18n": "3.10.0-beta.150",
"@ohif/ui": "3.10.0-beta.150",
"prop-types": "^15.6.2",
"react": "^18.3.1",
"react-dom": "^18.3.1",
@ -325,14 +325,14 @@
},
"extensions/dicom-pdf": {
"name": "@ohif/extension-dicom-pdf",
"version": "3.10.0-beta.147",
"version": "3.10.0-beta.150",
"dependencies": {
"@babel/runtime": "^7.20.13",
"classnames": "^2.3.2",
},
"peerDependencies": {
"@ohif/core": "3.10.0-beta.147",
"@ohif/ui": "3.10.0-beta.147",
"@ohif/core": "3.10.0-beta.150",
"@ohif/ui": "3.10.0-beta.150",
"dcmjs": "*",
"dicom-parser": "^1.8.9",
"hammerjs": "^2.0.8",
@ -342,14 +342,14 @@
},
"extensions/dicom-video": {
"name": "@ohif/extension-dicom-video",
"version": "3.10.0-beta.147",
"version": "3.10.0-beta.150",
"dependencies": {
"@babel/runtime": "^7.20.13",
"classnames": "^2.3.2",
},
"peerDependencies": {
"@ohif/core": "3.10.0-beta.147",
"@ohif/ui": "3.10.0-beta.147",
"@ohif/core": "3.10.0-beta.150",
"@ohif/ui": "3.10.0-beta.150",
"dcmjs": "*",
"dicom-parser": "^1.8.9",
"hammerjs": "^2.0.8",
@ -359,20 +359,20 @@
},
"extensions/measurement-tracking": {
"name": "@ohif/extension-measurement-tracking",
"version": "3.10.0-beta.147",
"version": "3.10.0-beta.150",
"dependencies": {
"@babel/runtime": "^7.20.13",
"@ohif/ui": "3.10.0-beta.147",
"@ohif/ui": "3.10.0-beta.150",
"@xstate/react": "^3.2.2",
"xstate": "^4.10.0",
},
"peerDependencies": {
"@cornerstonejs/core": "^3.8.5",
"@cornerstonejs/tools": "^3.8.5",
"@ohif/core": "3.10.0-beta.147",
"@ohif/extension-cornerstone-dicom-sr": "3.10.0-beta.147",
"@ohif/extension-default": "3.10.0-beta.147",
"@ohif/ui": "3.10.0-beta.147",
"@cornerstonejs/core": "^3.9.1",
"@cornerstonejs/tools": "^3.9.1",
"@ohif/core": "3.10.0-beta.150",
"@ohif/extension-cornerstone-dicom-sr": "3.10.0-beta.150",
"@ohif/extension-default": "3.10.0-beta.150",
"@ohif/ui": "3.10.0-beta.150",
"classnames": "^2.3.2",
"dcmjs": "*",
"lodash.debounce": "^4.0.8",
@ -385,14 +385,14 @@
},
"extensions/test-extension": {
"name": "@ohif/extension-test",
"version": "3.10.0-beta.147",
"version": "3.10.0-beta.150",
"dependencies": {
"@babel/runtime": "^7.20.13",
"classnames": "^2.3.2",
},
"peerDependencies": {
"@ohif/core": "3.10.0-beta.147",
"@ohif/ui": "3.10.0-beta.147",
"@ohif/core": "3.10.0-beta.150",
"@ohif/ui": "3.10.0-beta.150",
"dcmjs": "0.38.0",
"dicom-parser": "^1.8.9",
"hammerjs": "^2.0.8",
@ -402,7 +402,7 @@
},
"extensions/tmtv": {
"name": "@ohif/extension-tmtv",
"version": "3.10.0-beta.147",
"version": "3.10.0-beta.150",
"dependencies": {
"@babel/runtime": "^7.20.13",
"classnames": "^2.3.2",
@ -419,7 +419,7 @@
},
"modes/basic-dev-mode": {
"name": "@ohif/mode-basic-dev-mode",
"version": "3.10.0-beta.147",
"version": "3.10.0-beta.150",
"dependencies": {
"@babel/runtime": "^7.20.13",
"i18next": "^17.0.3",
@ -429,17 +429,17 @@
"webpack-merge": "^5.7.3",
},
"peerDependencies": {
"@ohif/core": "3.10.0-beta.147",
"@ohif/extension-cornerstone": "3.10.0-beta.147",
"@ohif/extension-cornerstone-dicom-sr": "3.10.0-beta.147",
"@ohif/extension-default": "3.10.0-beta.147",
"@ohif/extension-dicom-pdf": "3.10.0-beta.147",
"@ohif/extension-dicom-video": "3.10.0-beta.147",
"@ohif/core": "3.10.0-beta.150",
"@ohif/extension-cornerstone": "3.10.0-beta.150",
"@ohif/extension-cornerstone-dicom-sr": "3.10.0-beta.150",
"@ohif/extension-default": "3.10.0-beta.150",
"@ohif/extension-dicom-pdf": "3.10.0-beta.150",
"@ohif/extension-dicom-video": "3.10.0-beta.150",
},
},
"modes/basic-test-mode": {
"name": "@ohif/mode-test",
"version": "3.10.0-beta.147",
"version": "3.10.0-beta.150",
"dependencies": {
"@babel/runtime": "^7.20.13",
"i18next": "^17.0.3",
@ -449,19 +449,19 @@
"webpack-merge": "^5.7.3",
},
"peerDependencies": {
"@ohif/core": "3.10.0-beta.147",
"@ohif/extension-cornerstone": "3.10.0-beta.147",
"@ohif/extension-cornerstone-dicom-sr": "3.10.0-beta.147",
"@ohif/extension-default": "3.10.0-beta.147",
"@ohif/extension-dicom-pdf": "3.10.0-beta.147",
"@ohif/extension-dicom-video": "3.10.0-beta.147",
"@ohif/extension-measurement-tracking": "3.10.0-beta.147",
"@ohif/extension-test": "3.10.0-beta.147",
"@ohif/core": "3.10.0-beta.150",
"@ohif/extension-cornerstone": "3.10.0-beta.150",
"@ohif/extension-cornerstone-dicom-sr": "3.10.0-beta.150",
"@ohif/extension-default": "3.10.0-beta.150",
"@ohif/extension-dicom-pdf": "3.10.0-beta.150",
"@ohif/extension-dicom-video": "3.10.0-beta.150",
"@ohif/extension-measurement-tracking": "3.10.0-beta.150",
"@ohif/extension-test": "3.10.0-beta.150",
},
},
"modes/longitudinal": {
"name": "@ohif/mode-longitudinal",
"version": "3.10.0-beta.147",
"version": "3.10.0-beta.150",
"dependencies": {
"@babel/runtime": "^7.20.13",
"i18next": "^17.0.3",
@ -471,32 +471,32 @@
"webpack-merge": "^5.7.3",
},
"peerDependencies": {
"@ohif/core": "3.10.0-beta.147",
"@ohif/extension-cornerstone": "3.10.0-beta.147",
"@ohif/extension-cornerstone-dicom-rt": "3.10.0-beta.147",
"@ohif/extension-cornerstone-dicom-seg": "3.10.0-beta.147",
"@ohif/extension-cornerstone-dicom-sr": "3.10.0-beta.147",
"@ohif/extension-default": "3.10.0-beta.147",
"@ohif/extension-dicom-pdf": "3.10.0-beta.147",
"@ohif/extension-dicom-video": "3.10.0-beta.147",
"@ohif/extension-measurement-tracking": "3.10.0-beta.147",
"@ohif/core": "3.10.0-beta.150",
"@ohif/extension-cornerstone": "3.10.0-beta.150",
"@ohif/extension-cornerstone-dicom-rt": "3.10.0-beta.150",
"@ohif/extension-cornerstone-dicom-seg": "3.10.0-beta.150",
"@ohif/extension-cornerstone-dicom-sr": "3.10.0-beta.150",
"@ohif/extension-default": "3.10.0-beta.150",
"@ohif/extension-dicom-pdf": "3.10.0-beta.150",
"@ohif/extension-dicom-video": "3.10.0-beta.150",
"@ohif/extension-measurement-tracking": "3.10.0-beta.150",
},
},
"modes/microscopy": {
"name": "@ohif/mode-microscopy",
"version": "3.10.0-beta.147",
"version": "3.10.0-beta.150",
"dependencies": {
"@babel/runtime": "^7.20.13",
"i18next": "^17.0.3",
},
"peerDependencies": {
"@ohif/core": "3.10.0-beta.147",
"@ohif/extension-dicom-microscopy": "3.10.0-beta.147",
"@ohif/core": "3.10.0-beta.150",
"@ohif/extension-dicom-microscopy": "3.10.0-beta.150",
},
},
"modes/preclinical-4d": {
"name": "@ohif/mode-preclinical-4d",
"version": "3.10.0-beta.147",
"version": "3.10.0-beta.150",
"dependencies": {
"@babel/runtime": "^7.20.13",
},
@ -515,7 +515,7 @@
},
"modes/segmentation": {
"name": "@ohif/mode-segmentation",
"version": "3.10.0-beta.147",
"version": "3.10.0-beta.150",
"dependencies": {
"@babel/runtime": "^7.20.13",
"i18next": "^17.0.3",
@ -559,7 +559,7 @@
},
"modes/tmtv": {
"name": "@ohif/mode-tmtv",
"version": "3.10.0-beta.147",
"version": "3.10.0-beta.150",
"dependencies": {
"@babel/runtime": "^7.20.13",
"i18next": "^17.0.3",
@ -580,32 +580,32 @@
},
"platform/app": {
"name": "@ohif/app",
"version": "3.10.0-beta.147",
"version": "3.10.0-beta.150",
"dependencies": {
"@babel/runtime": "^7.20.13",
"@cornerstonejs/codec-charls": "^1.2.3",
"@cornerstonejs/codec-libjpeg-turbo-8bit": "^1.2.2",
"@cornerstonejs/codec-openjpeg": "^1.2.4",
"@cornerstonejs/codec-openjph": "^2.4.5",
"@cornerstonejs/dicom-image-loader": "^3.8.5",
"@cornerstonejs/dicom-image-loader": "^3.9.1",
"@emotion/serialize": "^1.1.3",
"@ohif/core": "3.10.0-beta.147",
"@ohif/extension-cornerstone": "3.10.0-beta.147",
"@ohif/extension-cornerstone-dicom-rt": "3.10.0-beta.147",
"@ohif/extension-cornerstone-dicom-seg": "3.10.0-beta.147",
"@ohif/extension-cornerstone-dicom-sr": "3.10.0-beta.147",
"@ohif/extension-default": "3.10.0-beta.147",
"@ohif/extension-dicom-microscopy": "3.10.0-beta.147",
"@ohif/extension-dicom-pdf": "3.10.0-beta.147",
"@ohif/extension-dicom-video": "3.10.0-beta.147",
"@ohif/extension-test": "3.10.0-beta.147",
"@ohif/i18n": "3.10.0-beta.147",
"@ohif/mode-basic-dev-mode": "3.10.0-beta.147",
"@ohif/mode-longitudinal": "3.10.0-beta.147",
"@ohif/mode-microscopy": "3.10.0-beta.147",
"@ohif/mode-test": "3.10.0-beta.147",
"@ohif/ui": "3.10.0-beta.147",
"@ohif/ui-next": "3.10.0-beta.147",
"@ohif/core": "3.10.0-beta.150",
"@ohif/extension-cornerstone": "3.10.0-beta.150",
"@ohif/extension-cornerstone-dicom-rt": "3.10.0-beta.150",
"@ohif/extension-cornerstone-dicom-seg": "3.10.0-beta.150",
"@ohif/extension-cornerstone-dicom-sr": "3.10.0-beta.150",
"@ohif/extension-default": "3.10.0-beta.150",
"@ohif/extension-dicom-microscopy": "3.10.0-beta.150",
"@ohif/extension-dicom-pdf": "3.10.0-beta.150",
"@ohif/extension-dicom-video": "3.10.0-beta.150",
"@ohif/extension-test": "3.10.0-beta.150",
"@ohif/i18n": "3.10.0-beta.150",
"@ohif/mode-basic-dev-mode": "3.10.0-beta.150",
"@ohif/mode-longitudinal": "3.10.0-beta.150",
"@ohif/mode-microscopy": "3.10.0-beta.150",
"@ohif/mode-test": "3.10.0-beta.150",
"@ohif/ui": "3.10.0-beta.150",
"@ohif/ui-next": "3.10.0-beta.150",
"@svgr/webpack": "^8.1.0",
"@types/react": "^18.3.3",
"classnames": "^2.3.2",
@ -646,13 +646,13 @@
},
"platform/cli": {
"name": "@ohif/cli",
"version": "3.10.0-beta.147",
"version": "3.10.0-beta.150",
"bin": {
"ohif-cli": "src/index.js",
},
"dependencies": {
"@babel/core": "7.24.7",
"axios": "^1.8.2",
"axios": "^1.8.4",
"chalk": "^5.0.0",
"execa": "^8.0.1",
"gitignore": "^0.7.0",
@ -670,7 +670,7 @@
},
"platform/core": {
"name": "@ohif/core",
"version": "3.10.0-beta.147",
"version": "3.10.0-beta.150",
"dependencies": {
"@babel/runtime": "^7.20.13",
"dcmjs": "*",
@ -680,7 +680,7 @@
"isomorphic-base64": "^1.0.2",
"lodash.clonedeep": "^4.5.0",
"lodash.isequal": "^4.5.0",
"moment": "*",
"moment": "^2.30.1",
"object-hash": "2.1.1",
"query-string": "^6.14.0",
"react-shepherd": "6.1.1",
@ -695,15 +695,15 @@
"@cornerstonejs/codec-libjpeg-turbo-8bit": "^1.2.2",
"@cornerstonejs/codec-openjpeg": "^1.2.4",
"@cornerstonejs/codec-openjph": "^2.4.5",
"@cornerstonejs/dicom-image-loader": "^3.8.5",
"@ohif/ui": "3.10.0-beta.147",
"@cornerstonejs/dicom-image-loader": "^3.9.1",
"@ohif/ui": "3.10.0-beta.150",
"cornerstone-math": "0.1.9",
"dicom-parser": "^1.8.21",
},
},
"platform/i18n": {
"name": "@ohif/i18n",
"version": "3.10.0-beta.147",
"version": "3.10.0-beta.150",
"dependencies": {
"@babel/runtime": "^7.20.13",
"i18next-locize-backend": "^2.0.0",
@ -728,7 +728,7 @@
},
"platform/ui": {
"name": "@ohif/ui",
"version": "3.10.0-beta.147",
"version": "3.10.0-beta.150",
"dependencies": {
"@testing-library/react": "^13.1.0",
"browser-detect": "^0.2.28",
@ -743,7 +743,7 @@
"lodash.clonedeep": "^4.5.0",
"lodash.debounce": "^4.0.8",
"lodash.merge": "^4.6.1",
"moment": "*",
"moment": "^2.30.1",
"mousetrap": "^1.6.5",
"react": "^18.3.1",
"react-dates": "^21.8.0",
@ -788,7 +788,7 @@
},
"platform/ui-next": {
"name": "@ohif/ui-next",
"version": "3.10.0-beta.147",
"version": "3.10.0-beta.150",
"dependencies": {
"@radix-ui/react-accordion": "^1.2.0",
"@radix-ui/react-checkbox": "^1.1.1",
@ -1099,9 +1099,9 @@
"@colors/colors": ["@colors/colors@1.5.0", "", {}, "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ=="],
"@cornerstonejs/adapters": ["@cornerstonejs/adapters@3.8.5", "", { "dependencies": { "@babel/runtime-corejs2": "^7.17.8", "buffer": "^6.0.3", "dcmjs": "^0.29.8", "gl-matrix": "^3.4.3", "ndarray": "^1.0.19" }, "peerDependencies": { "@cornerstonejs/core": "^3.8.5", "@cornerstonejs/tools": "^3.8.5" } }, "sha512-dQlKKSCbV6V3QpivDdZZiI7N792l1VqsOj8H+e8iiarpy6MvwiEvck2u50/GBhto9D/U9QvRkZVs9TH0ewUs5w=="],
"@cornerstonejs/adapters": ["@cornerstonejs/adapters@3.9.1", "", { "dependencies": { "@babel/runtime-corejs2": "^7.17.8", "buffer": "^6.0.3", "dcmjs": "^0.29.8", "gl-matrix": "^3.4.3", "ndarray": "^1.0.19" }, "peerDependencies": { "@cornerstonejs/core": "^3.9.1", "@cornerstonejs/tools": "^3.9.1" } }, "sha512-Wkbh3+oj+9TQOnwYACj8w8IqEaCFdIVL2F3TaQKvsPC7/sP/WLKDiRVtAV951NI1/AJiiWd2UFze0kKU8DrsvQ=="],
"@cornerstonejs/ai": ["@cornerstonejs/ai@3.8.5", "", { "dependencies": { "@babel/runtime-corejs2": "^7.17.8", "buffer": "^6.0.3", "dcmjs": "^0.29.8", "gl-matrix": "^3.4.3", "lodash.clonedeep": "^4.5.0", "ndarray": "^1.0.19", "onnxruntime-common": "1.17.1", "onnxruntime-web": "1.17.1" }, "peerDependencies": { "@cornerstonejs/core": "^3.8.5", "@cornerstonejs/tools": "^3.8.5" } }, "sha512-9QR7PmTtkeXZOjDFh9WulLJGnraWLaM/g/qNB0ZaPKDMo1PLT7/tHn1F6wsyT2cmpEb3/G5towdxtEvhvlpm/w=="],
"@cornerstonejs/ai": ["@cornerstonejs/ai@3.9.1", "", { "dependencies": { "@babel/runtime-corejs2": "^7.17.8", "buffer": "^6.0.3", "dcmjs": "^0.29.8", "gl-matrix": "^3.4.3", "lodash.clonedeep": "^4.5.0", "ndarray": "^1.0.19", "onnxruntime-common": "1.17.1", "onnxruntime-web": "1.17.1" }, "peerDependencies": { "@cornerstonejs/core": "^3.9.1", "@cornerstonejs/tools": "^3.9.1" } }, "sha512-wa//BGNEaiTbZXBFZWoNSzBrWW6FgF3cmD+So+V40k7m0AZGuhJwIDamtV1nsS3iUwEvBDWghzpgAD7OqMNLhA=="],
"@cornerstonejs/calculate-suv": ["@cornerstonejs/calculate-suv@1.1.0", "", {}, "sha512-Q9XraiDJif9aMFArD2iEuDO/HXbcRVCqB7KfaHgDrdTTjgDFovS91Psbdim7crypRSvE6dh/+HKeFNHdvNkA6w=="],
@ -1113,15 +1113,15 @@
"@cornerstonejs/codec-openjph": ["@cornerstonejs/codec-openjph@2.4.7", "", {}, "sha512-qvP4q4JDib7mi9r7LqKOwqz7YZ8gjtDX4ZCezeYf8+eb7MBXCz5uXAMeVF3yz9Axw4XiIMdB/pqXkm8tqCl13w=="],
"@cornerstonejs/core": ["@cornerstonejs/core@3.8.5", "", { "dependencies": { "@kitware/vtk.js": "32.12.1", "comlink": "^4.4.1", "gl-matrix": "^3.4.3", "loglevel": "^1.9.2" } }, "sha512-x3LZwZUqhVldChpwtLqNwUWx8eXq9q1ndwrx5lVpnX4ZUT9qQIAro01Ih8DPiXlLb1NXbN3sG4e/x/TxuQ+5bw=="],
"@cornerstonejs/core": ["@cornerstonejs/core@3.9.1", "", { "dependencies": { "@kitware/vtk.js": "32.12.1", "comlink": "^4.4.1", "gl-matrix": "^3.4.3", "loglevel": "^1.9.2" } }, "sha512-1R6plBRfKX3hYzeIisXmYquqpRLCnF51abl49vfKVu48TEB+cD8zvQO0xCQWC6QfcuxmFfw9BQmtIXLvDoo38A=="],
"@cornerstonejs/dicom-image-loader": ["@cornerstonejs/dicom-image-loader@3.8.5", "", { "dependencies": { "@cornerstonejs/codec-charls": "^1.2.3", "@cornerstonejs/codec-libjpeg-turbo-8bit": "^1.2.2", "@cornerstonejs/codec-openjpeg": "^1.2.2", "@cornerstonejs/codec-openjph": "^2.4.5", "comlink": "^4.4.1", "dicom-parser": "^1.8.9", "jpeg-lossless-decoder-js": "^2.1.0", "pako": "^2.0.4", "uuid": "^9.0.0" }, "peerDependencies": { "@cornerstonejs/core": "^3.8.5" } }, "sha512-yuLLU2sbtFWueNKVbeYBddPoJnfhrUQ+rRnXJb+y9iczwZMQLy4tYyk3Q5INo+/nIdwCVeZg7P9qORZERsBivw=="],
"@cornerstonejs/dicom-image-loader": ["@cornerstonejs/dicom-image-loader@3.9.1", "", { "dependencies": { "@cornerstonejs/codec-charls": "^1.2.3", "@cornerstonejs/codec-libjpeg-turbo-8bit": "^1.2.2", "@cornerstonejs/codec-openjpeg": "^1.2.2", "@cornerstonejs/codec-openjph": "^2.4.5", "comlink": "^4.4.1", "dicom-parser": "^1.8.9", "jpeg-lossless-decoder-js": "^2.1.0", "pako": "^2.0.4", "uuid": "^9.0.0" }, "peerDependencies": { "@cornerstonejs/core": "^3.9.1" } }, "sha512-FHhFJTzrF2+CIfjDiHYWRqquInuxCYP8F16gTBDWT9FxNEMNjHqkTo7qVYhB/mG2nIV+sKcTMs4OSx3hBDqikQ=="],
"@cornerstonejs/labelmap-interpolation": ["@cornerstonejs/labelmap-interpolation@3.8.5", "", { "dependencies": { "@itk-wasm/morphological-contour-interpolation": "1.1.0", "itk-wasm": "1.0.0-b.165" }, "peerDependencies": { "@cornerstonejs/core": "^3.8.5", "@cornerstonejs/tools": "^3.8.5", "@kitware/vtk.js": "32.12.1" } }, "sha512-u80OTJE8eju+tZ+S/N1b/HTIw2mPjEE2o5u3T/7/w90FX7OaxJJiMYjPPfnSZWXjE2HhRu0gEAKHOU3dr8pL4w=="],
"@cornerstonejs/labelmap-interpolation": ["@cornerstonejs/labelmap-interpolation@3.9.1", "", { "dependencies": { "@itk-wasm/morphological-contour-interpolation": "1.1.0", "itk-wasm": "1.0.0-b.165" }, "peerDependencies": { "@cornerstonejs/core": "^3.9.1", "@cornerstonejs/tools": "^3.9.1", "@kitware/vtk.js": "32.12.1" } }, "sha512-todwKvOCxnQsc5X9KNjAOjC74bop8UYgA/Mnhl+fCagGaVxS5t+GlnV2PG29Yw9Klw+S4vJkd0XiMCgO2BevLw=="],
"@cornerstonejs/polymorphic-segmentation": ["@cornerstonejs/polymorphic-segmentation@3.8.5", "", { "dependencies": { "@icr/polyseg-wasm": "0.4.0" }, "peerDependencies": { "@cornerstonejs/core": "^3.8.5", "@cornerstonejs/tools": "^3.8.5", "@kitware/vtk.js": "32.12.1" } }, "sha512-6L9a9f36CnUIuGsydA8kkkC0z1Gjid4KfclCQoYYaxcsLWLDpba5usFERmxCLIm9VyBsA3POqesIGDqWTgJmFg=="],
"@cornerstonejs/polymorphic-segmentation": ["@cornerstonejs/polymorphic-segmentation@3.9.1", "", { "dependencies": { "@icr/polyseg-wasm": "0.4.0" }, "peerDependencies": { "@cornerstonejs/core": "^3.9.1", "@cornerstonejs/tools": "^3.9.1", "@kitware/vtk.js": "32.12.1" } }, "sha512-QAJYYBtXNpHSKFiN4kVuCOlQB2Cnl6UrnTgAgBKw1sE00wrmbjyF/z1x1qBR34IkAe1ggMbF1QmhQpR90s1M6A=="],
"@cornerstonejs/tools": ["@cornerstonejs/tools@3.8.5", "", { "dependencies": { "@types/offscreencanvas": "2019.7.3", "comlink": "^4.4.1", "lodash.get": "^4.4.2" }, "peerDependencies": { "@cornerstonejs/core": "^3.8.5", "@kitware/vtk.js": "32.12.1", "@types/d3-array": "^3.0.4", "@types/d3-interpolate": "^3.0.1", "d3-array": "^3.2.3", "d3-interpolate": "^3.0.1", "gl-matrix": "^3.4.3" } }, "sha512-aTaziRHJakCCxvbHhbrSkEuiamURGakcK83KXGJPjSdStWC/2cVpkCzPxc8V7FZBIstsvo5pgciXSpNc6Yt7Og=="],
"@cornerstonejs/tools": ["@cornerstonejs/tools@3.9.1", "", { "dependencies": { "@types/offscreencanvas": "2019.7.3", "comlink": "^4.4.1", "lodash.get": "^4.4.2" }, "peerDependencies": { "@cornerstonejs/core": "^3.9.1", "@kitware/vtk.js": "32.12.1", "@types/d3-array": "^3.0.4", "@types/d3-interpolate": "^3.0.1", "d3-array": "^3.2.3", "d3-interpolate": "^3.0.1", "gl-matrix": "^3.4.3" } }, "sha512-OP3oZ+Af3ax3Kdo7DLaRs74XlRHTpBuePZvUuYb21VsWBVr50E9nRV5zyCo/4klRb+/zEKlWGQbQogmQxv9+NA=="],
"@csstools/postcss-cascade-layers": ["@csstools/postcss-cascade-layers@1.1.1", "", { "dependencies": { "@csstools/selector-specificity": "^2.0.2", "postcss-selector-parser": "^6.0.10" }, "peerDependencies": { "postcss": "^8.2" } }, "sha512-+KdYrpKC5TgomQr2DlZF4lDEpHcoxnj5IGddYYfBWJAKfj1JtuHUIqMa+E1pJJ+z3kvDViWMqyqPlG4Ja7amQA=="],

View File

@ -46,8 +46,8 @@
},
"dependencies": {
"@babel/runtime": "^7.20.13",
"@cornerstonejs/adapters": "^3.8.5",
"@cornerstonejs/core": "^3.8.5",
"@cornerstonejs/adapters": "^3.9.1",
"@cornerstonejs/core": "^3.9.1",
"@kitware/vtk.js": "32.12.0",
"react-color": "^2.19.3"
}

View File

@ -46,8 +46,8 @@
},
"dependencies": {
"@babel/runtime": "^7.20.13",
"@cornerstonejs/adapters": "^3.8.5",
"@cornerstonejs/core": "^3.8.5",
"@cornerstonejs/adapters": "^3.9.1",
"@cornerstonejs/core": "^3.9.1",
"@kitware/vtk.js": "32.12.0",
"react-color": "^2.19.3"
}

View File

@ -46,9 +46,9 @@
},
"dependencies": {
"@babel/runtime": "^7.20.13",
"@cornerstonejs/adapters": "^3.8.5",
"@cornerstonejs/core": "^3.8.5",
"@cornerstonejs/tools": "^3.8.5",
"@cornerstonejs/adapters": "^3.9.1",
"@cornerstonejs/core": "^3.9.1",
"@cornerstonejs/tools": "^3.9.1",
"classnames": "^2.3.2"
}
}

View File

@ -42,8 +42,8 @@
},
"dependencies": {
"@babel/runtime": "^7.20.13",
"@cornerstonejs/core": "^3.8.5",
"@cornerstonejs/tools": "^3.8.5",
"@cornerstonejs/core": "^3.9.1",
"@cornerstonejs/tools": "^3.9.1",
"classnames": "^2.3.2"
}
}

View File

@ -38,7 +38,7 @@
"@cornerstonejs/codec-libjpeg-turbo-8bit": "^1.2.2",
"@cornerstonejs/codec-openjpeg": "^1.2.4",
"@cornerstonejs/codec-openjph": "^2.4.5",
"@cornerstonejs/dicom-image-loader": "^3.8.5",
"@cornerstonejs/dicom-image-loader": "^3.9.1",
"@ohif/core": "3.10.0-beta.151",
"@ohif/ui": "3.10.0-beta.151",
"dcmjs": "*",
@ -51,12 +51,12 @@
},
"dependencies": {
"@babel/runtime": "^7.20.13",
"@cornerstonejs/adapters": "^3.8.5",
"@cornerstonejs/ai": "^3.8.5",
"@cornerstonejs/core": "^3.8.5",
"@cornerstonejs/labelmap-interpolation": "^3.8.5",
"@cornerstonejs/polymorphic-segmentation": "^3.8.5",
"@cornerstonejs/tools": "^3.8.5",
"@cornerstonejs/adapters": "^3.9.1",
"@cornerstonejs/ai": "^3.9.1",
"@cornerstonejs/core": "^3.9.1",
"@cornerstonejs/labelmap-interpolation": "^3.9.1",
"@cornerstonejs/polymorphic-segmentation": "^3.9.1",
"@cornerstonejs/tools": "^3.9.1",
"@itk-wasm/morphological-contour-interpolation": "1.1.0",
"@kitware/vtk.js": "32.12.0",
"html2canvas": "^1.4.1",

View File

@ -31,6 +31,7 @@ export default function getSegmentationPanelCustomization({ commandsManager, ser
peakLPS: 'Peak Coord',
volume: 'Volume',
lesionGlycolysis: 'Lesion Glycolysis',
center: 'Center',
},
'segmentationToolbox.config': () => {
// Get initial states based on current configuration

View File

@ -277,6 +277,11 @@ class SegmentationService extends PubSubService {
): Promise<void> {
const segmentation = this.getSegmentation(segmentationId);
const csViewport = this.getAndValidateViewport(viewportId);
if (!csViewport) {
return;
}
const colorLUTIndex = this._segmentationIdToColorLUTIndexMap.get(segmentationId);
const defaultRepresentationType = csToolsEnums.SegmentationRepresentations.Labelmap;
@ -1251,7 +1256,8 @@ class SegmentationService extends PubSubService {
const csViewport =
this.servicesManager.services.cornerstoneViewportService.getCornerstoneViewport(viewportId);
if (!csViewport) {
throw new Error(`Viewport with id ${viewportId} not found.`);
console.warn(`Viewport with id ${viewportId} not found.`);
return null;
}
return csViewport;
}
@ -1766,6 +1772,12 @@ class SegmentationService extends PubSubService {
const { center } = cachedStats;
if (!center) {
return {
world: cachedStats.namedStats.center.value,
};
}
return center;
}

View File

@ -1,10 +1,8 @@
import React, { useState, useEffect, useCallback } from 'react';
import { useImageViewer } from '@ohif/ui';
import { useViewportGrid } from '@ohif/ui-next';
import { StudyBrowser } from '@ohif/ui-next';
import { useSystem, utils } from '@ohif/core';
import { useNavigate } from 'react-router-dom';
import { Separator } from '@ohif/ui-next';
import { useViewportGrid, StudyBrowser, Separator } from '@ohif/ui-next';
import { PanelStudyBrowserHeader } from './PanelStudyBrowserHeader';
import { defaultActionIcons } from './constants';
import MoreDropdownMenu from '../../Components/MoreDropdownMenu';

View File

@ -4,7 +4,7 @@ const collapsedOutsideBorderSize = 4;
const collapsedWidth = 25;
const rightPanelInitialExpandedWidth = 280;
const leftPanelInitialExpandedWidth = 282;
const leftPanelInitialExpandedWidth = 292;
const panelGroupDefinition = {
groupId: 'viewerLayoutResizablePanelGroup',

View File

@ -32,8 +32,8 @@
"start": "yarn run dev"
},
"peerDependencies": {
"@cornerstonejs/core": "^3.8.5",
"@cornerstonejs/tools": "^3.8.5",
"@cornerstonejs/core": "^3.9.1",
"@cornerstonejs/tools": "^3.9.1",
"@ohif/core": "3.10.0-beta.151",
"@ohif/extension-cornerstone-dicom-sr": "3.10.0-beta.151",
"@ohif/extension-default": "3.10.0-beta.151",

View File

@ -3,6 +3,7 @@ import { useActiveViewportSegmentationRepresentations } from '@ohif/extension-co
import { handleROIThresholding } from '../../utils/handleROIThresholding';
import { debounce } from '@ohif/core/src/utils';
import { useSystem } from '@ohif/core/src';
import { Button } from '@ohif/ui-next';
export default function PanelRoiThresholdSegmentation() {
const { commandsManager, servicesManager } = useSystem();
@ -11,6 +12,7 @@ export default function PanelRoiThresholdSegmentation() {
useActiveViewportSegmentationRepresentations({ servicesManager });
const segmentationIds = segmentationsInfo?.map(info => info.segmentation.segmentationId) || [];
const segmentations = segmentationsInfo?.map(info => info.segmentation) || [];
useEffect(() => {
const initialRun = async () => {
@ -54,17 +56,37 @@ export default function PanelRoiThresholdSegmentation() {
const stats = segmentationService.getSegmentationGroupStats(segmentationIds);
const tmtvValue = stats?.tmtv;
const handleExportCSV = () => {
if (!segmentations.length) {
return;
}
commandsManager.runCommand('exportTMTVReportCSV', {
segmentations,
tmtv: tmtvValue,
config: {},
});
};
return (
<div className="mt-2 mb-10 flex flex-col">
<div className="mb-1 flex flex-col">
<div className="invisible-scrollbar overflow-y-auto overflow-x-hidden">
{tmtvValue !== null && tmtvValue !== undefined ? (
<div className="bg-secondary-dark flex items-baseline justify-between px-2 py-1">
<span className="text-base font-bold uppercase tracking-widest text-white">
{'TMTV:'}
</span>
<div className="text-white">{`${tmtvValue?.toFixed(3)} mL`}</div>
<div className="py-1">
<span className="text-muted-foreground text-base font-bold uppercase">{'TMTV: '}</span>
<span className="text-foreground">{tmtvValue ? `${tmtvValue.toFixed(3)} mL` : ''}</span>
</div>
<div className="flex items-center">
<Button
size="sm"
variant="ghost"
className="text-blue-500"
onClick={handleExportCSV}
>
<span className="pl-1">CSV</span>
</Button>
</div>
</div>
) : null}
</div>
</div>
);

View File

@ -54,7 +54,7 @@
"@cornerstonejs/codec-libjpeg-turbo-8bit": "^1.2.2",
"@cornerstonejs/codec-openjpeg": "^1.2.4",
"@cornerstonejs/codec-openjph": "^2.4.5",
"@cornerstonejs/dicom-image-loader": "^3.8.5",
"@cornerstonejs/dicom-image-loader": "^3.9.1",
"@emotion/serialize": "^1.1.3",
"@ohif/core": "3.10.0-beta.151",
"@ohif/extension-cornerstone": "3.10.0-beta.151",

View File

@ -21,7 +21,7 @@
"license": "MIT",
"dependencies": {
"@babel/core": "7.24.7",
"axios": "^1.8.2",
"axios": "^1.8.4",
"chalk": "^5.0.0",
"execa": "^8.0.1",
"gitignore": "^0.7.0",

View File

@ -37,7 +37,7 @@
"@cornerstonejs/codec-libjpeg-turbo-8bit": "^1.2.2",
"@cornerstonejs/codec-openjpeg": "^1.2.4",
"@cornerstonejs/codec-openjph": "^2.4.5",
"@cornerstonejs/dicom-image-loader": "^3.8.5",
"@cornerstonejs/dicom-image-loader": "^3.9.1",
"@ohif/ui": "3.10.0-beta.151",
"cornerstone-math": "0.1.9",
"dicom-parser": "^1.8.21"
@ -51,7 +51,7 @@
"isomorphic-base64": "^1.0.2",
"lodash.clonedeep": "^4.5.0",
"lodash.isequal": "^4.5.0",
"moment": "*",
"moment": "^2.30.1",
"object-hash": "2.1.1",
"query-string": "^6.14.0",
"react-shepherd": "6.1.1",

View File

@ -9,6 +9,8 @@ import { Button } from '../Button';
import { Icons } from '../Icons/Icons';
import { DropdownMenu, DropdownMenuTrigger } from '../DropdownMenu';
import { Tooltip, TooltipTrigger, TooltipContent } from '../Tooltip/Tooltip';
import { ScrollArea } from '../../components';
import { useDynamicMaxHeight } from '../../hooks/useDynamicMaxHeight';
// The Header container component
const SegmentationExpandedHeader = ({ children }: { children: React.ReactNode }) => {
@ -94,13 +96,23 @@ const SegmentationExpandedRoot = ({ children }) => {
const { data, activeSegmentationId, onSegmentationClick, mode } =
useSegmentationTableContext('SegmentationExpanded');
const { ref: scrollableContainerRef, maxHeight } = useDynamicMaxHeight(data);
// Check if we should render based on mode
if (mode !== 'expanded' || !data || data.length === 0) {
return null;
}
return (
<div className={`space-y-0 pl-0.5`}>
<ScrollArea
className={`bg-bkg-low space-y-px`}
showArrows={true}
>
<div
ref={scrollableContainerRef}
style={{ maxHeight: maxHeight }}
className={`space-y-0 pl-0.5`}
>
{data.map(segmentationInfo => {
const isActive = segmentationInfo.segmentation.segmentationId === activeSegmentationId;
@ -121,6 +133,7 @@ const SegmentationExpandedRoot = ({ children }) => {
);
})}
</div>
</ScrollArea>
);
};

View File

@ -3,6 +3,7 @@ import { ScrollArea, DataRow } from '../../components';
import { HoverCard, HoverCardTrigger, HoverCardContent } from '../../components/HoverCard';
import { useSegmentationTableContext, useSegmentationExpanded } from './contexts';
import { SegmentStatistics } from './SegmentStatistics';
import { useDynamicMaxHeight } from '../../hooks/useDynamicMaxHeight';
export const SegmentationSegments = ({ children = null }: { children?: React.ReactNode }) => {
const {
@ -35,17 +36,23 @@ export const SegmentationSegments = ({ children = null }: { children?: React.Rea
representation = segmentationInfo?.representation;
}
const segments = Object.values(representation.segments);
const isActiveSegmentation = segmentation.segmentationId === activeSegmentationId;
const { ref: scrollableContainerRef, maxHeight } = useDynamicMaxHeight(segments);
if (!representation || !segmentation) {
return null;
}
const segments = Object.values(representation.segments);
const isActiveSegmentation = segmentation.segmentationId === activeSegmentationId;
return (
<ScrollArea
className={`ohif-scrollbar invisible-scrollbar bg-bkg-low max-h-80 space-y-px`}
className={`bg-bkg-low space-y-px`}
showArrows={true}
>
<div
ref={scrollableContainerRef}
style={{ maxHeight: maxHeight }}
>
{segments.map(segment => {
if (!segment) {
@ -71,7 +78,7 @@ export const SegmentationSegments = ({ children = null }: { children?: React.Rea
key={segmentIndex}
number={segmentIndex}
title={label}
details={displayText}
// details={displayText}
description={displayText}
colorHex={cssColor}
isSelected={active}
@ -130,6 +137,7 @@ export const SegmentationSegments = ({ children = null }: { children?: React.Rea
DataRowComponent
);
})}
</div>
</ScrollArea>
);
};

View File

@ -2,6 +2,8 @@ import React from 'react';
import PropTypes from 'prop-types';
import { Thumbnail } from '../Thumbnail';
import { useDynamicMaxHeight } from '../../hooks/useDynamicMaxHeight';
import { ScrollArea } from '../ScrollArea';
const ThumbnailList = ({
thumbnails,
@ -12,6 +14,9 @@ const ThumbnailList = ({
viewPreset,
ThumbnailMenuItems,
}) => {
// Use the dynamic height hook on the parent container
const { ref, maxHeight } = useDynamicMaxHeight(thumbnails);
// Filter thumbnails into list items and thumbnail items
const listItems = thumbnails?.filter(
({ componentType }) => componentType === 'thumbnailNoImage' || viewPreset === 'list'
@ -22,12 +27,16 @@ const ThumbnailList = ({
);
return (
<div className="flex flex-col gap-[4px] pt-[4px] pr-[2.5px] pl-[5px] pb-[4px]">
{/* Thumbnail Items */}
<ScrollArea className="flex flex-col gap-[4px] pt-[4px] pr-[2.5px] pl-[5px] pb-[4px]">
<div
ref={ref}
style={{ maxHeight: maxHeight, minHeight: '300px' }}
className="flex flex-col gap-[4px] pt-[4px] pr-[2.5px] pl-[5px] pb-[4px]"
>
{thumbnailItems.length > 0 && (
<div
id="ohif-thumbnail-list"
className="ohif-scrollbar bg-bkg-low grid grid-cols-[repeat(auto-fit,_minmax(0,135px))] place-items-start gap-[4px] overflow-y-hidden"
className="bg-bkg-low grid grid-cols-[repeat(auto-fit,_minmax(0,135px))] place-items-start gap-[4px]"
>
{thumbnailItems.map(item => {
const { displaySetInstanceUID, componentType, numInstances, ...rest } = item;
@ -55,7 +64,7 @@ const ThumbnailList = ({
{listItems.length > 0 && (
<div
id="ohif-thumbnail-list"
className="ohif-scrollbar bg-bkg-low grid grid-cols-[repeat(auto-fit,_minmax(0,275px))] place-items-start gap-[2px] overflow-y-hidden"
className="bg-bkg-low grid grid-cols-[repeat(auto-fit,_minmax(0,275px))] place-items-start gap-[2px]"
>
{listItems.map(item => {
const { displaySetInstanceUID, componentType, numInstances, ...rest } = item;
@ -79,6 +88,7 @@ const ThumbnailList = ({
</div>
)}
</div>
</ScrollArea>
);
};

View File

@ -0,0 +1,50 @@
import { useRef, useState, useEffect, RefObject } from 'react';
/**
* Calculates the maximum height for an element based on its position
* relative to the bottom of the viewport.
*
* @param data The data that, when changed, should trigger a recalculation.
* @param buffer Optional buffer space (in pixels) to leave below the element. Defaults to 20.
* @param minHeight Optional minimum height (in pixels) for the element. Defaults to 100.
* @returns An object containing:
* - `ref`: A RefObject to attach to the target DOM element.
* - `maxHeight`: The calculated maximum height string (e.g., "500px").
*/
export function useDynamicMaxHeight(
data: any,
buffer = 20,
minHeight = 100
): {
ref: RefObject<HTMLDivElement>;
maxHeight: string;
} {
const ref = useRef<HTMLDivElement>(null);
const [maxHeight, setMaxHeight] = useState<string>('100vh'); // Start with full viewport height initially
useEffect(() => {
const calculateMaxHeight = () => {
if (ref.current) {
const rect = ref.current.getBoundingClientRect();
const availableHeight = window.innerHeight - rect.top - buffer;
setMaxHeight(`${Math.max(minHeight, availableHeight)}px`);
}
};
// Calculate initially
// Use requestAnimationFrame to ensure layout is stable after initial render
const rafId = requestAnimationFrame(calculateMaxHeight);
// Recalculate on window resize
window.addEventListener('resize', calculateMaxHeight);
// Cleanup listener and requestAnimationFrame on component unmount
return () => {
window.removeEventListener('resize', calculateMaxHeight);
cancelAnimationFrame(rafId);
};
// Dependencies: buffer, minHeight, and data.
}, [data, buffer, minHeight]);
return { ref, maxHeight };
}

View File

@ -46,7 +46,7 @@
"lodash.clonedeep": "^4.5.0",
"lodash.debounce": "^4.0.8",
"lodash.merge": "^4.6.1",
"moment": "*",
"moment": "^2.30.1",
"mousetrap": "^1.6.5",
"react": "^18.3.1",
"react-dates": "^21.8.0",

View File

@ -1393,10 +1393,10 @@
resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.5.0.tgz#bb504579c1cae923e6576a4f5da43d25f97bdbd9"
integrity sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==
"@cornerstonejs/adapters@^3.8.5":
version "3.8.5"
resolved "https://registry.yarnpkg.com/@cornerstonejs/adapters/-/adapters-3.8.5.tgz#d516a8fba29d200b47d77fe0ef586ed8962506de"
integrity sha512-dQlKKSCbV6V3QpivDdZZiI7N792l1VqsOj8H+e8iiarpy6MvwiEvck2u50/GBhto9D/U9QvRkZVs9TH0ewUs5w==
"@cornerstonejs/adapters@^3.9.1":
version "3.9.1"
resolved "https://registry.yarnpkg.com/@cornerstonejs/adapters/-/adapters-3.9.1.tgz#94c2806c9bc55d3f6d25c4f8e888f766c396d6bc"
integrity sha512-Wkbh3+oj+9TQOnwYACj8w8IqEaCFdIVL2F3TaQKvsPC7/sP/WLKDiRVtAV951NI1/AJiiWd2UFze0kKU8DrsvQ==
dependencies:
"@babel/runtime-corejs2" "^7.17.8"
buffer "^6.0.3"
@ -1404,10 +1404,10 @@
gl-matrix "^3.4.3"
ndarray "^1.0.19"
"@cornerstonejs/ai@^3.8.5":
version "3.8.5"
resolved "https://registry.yarnpkg.com/@cornerstonejs/ai/-/ai-3.8.5.tgz#8f6be57b7bc660afacd52b34ce56a71c696419ed"
integrity sha512-9QR7PmTtkeXZOjDFh9WulLJGnraWLaM/g/qNB0ZaPKDMo1PLT7/tHn1F6wsyT2cmpEb3/G5towdxtEvhvlpm/w==
"@cornerstonejs/ai@^3.9.1":
version "3.9.1"
resolved "https://registry.yarnpkg.com/@cornerstonejs/ai/-/ai-3.9.1.tgz#94a69937b0c46e0c4156ddab022b408f4452b5a2"
integrity sha512-wa//BGNEaiTbZXBFZWoNSzBrWW6FgF3cmD+So+V40k7m0AZGuhJwIDamtV1nsS3iUwEvBDWghzpgAD7OqMNLhA==
dependencies:
"@babel/runtime-corejs2" "^7.17.8"
buffer "^6.0.3"
@ -1443,20 +1443,20 @@
resolved "https://registry.yarnpkg.com/@cornerstonejs/codec-openjph/-/codec-openjph-2.4.5.tgz#8690b61a86fa53ef38a70eee9d665a79229517c0"
integrity sha512-MZCUy8VG0VG5Nl1l58+g+kH3LujAzLYTfJqkwpWI2gjSrGXnP6lgwyy4GmPRZWVoS40/B1LDNALK905cNWm+sg==
"@cornerstonejs/core@^3.8.5":
version "3.8.5"
resolved "https://registry.yarnpkg.com/@cornerstonejs/core/-/core-3.8.5.tgz#577bd32f0a3da36f895bf89c821b02a4cf97e225"
integrity sha512-x3LZwZUqhVldChpwtLqNwUWx8eXq9q1ndwrx5lVpnX4ZUT9qQIAro01Ih8DPiXlLb1NXbN3sG4e/x/TxuQ+5bw==
"@cornerstonejs/core@^3.9.1":
version "3.9.1"
resolved "https://registry.yarnpkg.com/@cornerstonejs/core/-/core-3.9.1.tgz#88619a436013a34bd04c6e5304d89aeec1c51804"
integrity sha512-1R6plBRfKX3hYzeIisXmYquqpRLCnF51abl49vfKVu48TEB+cD8zvQO0xCQWC6QfcuxmFfw9BQmtIXLvDoo38A==
dependencies:
"@kitware/vtk.js" "32.12.1"
comlink "^4.4.1"
gl-matrix "^3.4.3"
loglevel "^1.9.2"
"@cornerstonejs/dicom-image-loader@^3.8.5":
version "3.8.5"
resolved "https://registry.yarnpkg.com/@cornerstonejs/dicom-image-loader/-/dicom-image-loader-3.8.5.tgz#963a3174af3603e4beb096d448671442a0d5f10a"
integrity sha512-yuLLU2sbtFWueNKVbeYBddPoJnfhrUQ+rRnXJb+y9iczwZMQLy4tYyk3Q5INo+/nIdwCVeZg7P9qORZERsBivw==
"@cornerstonejs/dicom-image-loader@^3.9.1":
version "3.9.1"
resolved "https://registry.yarnpkg.com/@cornerstonejs/dicom-image-loader/-/dicom-image-loader-3.9.1.tgz#37ce24da222271b0363d9c762674d322c56104ce"
integrity sha512-FHhFJTzrF2+CIfjDiHYWRqquInuxCYP8F16gTBDWT9FxNEMNjHqkTo7qVYhB/mG2nIV+sKcTMs4OSx3hBDqikQ==
dependencies:
"@cornerstonejs/codec-charls" "^1.2.3"
"@cornerstonejs/codec-libjpeg-turbo-8bit" "^1.2.2"
@ -1468,25 +1468,25 @@
pako "^2.0.4"
uuid "^9.0.0"
"@cornerstonejs/labelmap-interpolation@^3.8.5":
version "3.8.5"
resolved "https://registry.yarnpkg.com/@cornerstonejs/labelmap-interpolation/-/labelmap-interpolation-3.8.5.tgz#19e8142362d5b83540bcb764306cd6bdf277c9ce"
integrity sha512-u80OTJE8eju+tZ+S/N1b/HTIw2mPjEE2o5u3T/7/w90FX7OaxJJiMYjPPfnSZWXjE2HhRu0gEAKHOU3dr8pL4w==
"@cornerstonejs/labelmap-interpolation@^3.9.1":
version "3.9.1"
resolved "https://registry.yarnpkg.com/@cornerstonejs/labelmap-interpolation/-/labelmap-interpolation-3.9.1.tgz#41fc327da444136139ed046df663ad43b0a68e47"
integrity sha512-todwKvOCxnQsc5X9KNjAOjC74bop8UYgA/Mnhl+fCagGaVxS5t+GlnV2PG29Yw9Klw+S4vJkd0XiMCgO2BevLw==
dependencies:
"@itk-wasm/morphological-contour-interpolation" "1.1.0"
itk-wasm "1.0.0-b.165"
"@cornerstonejs/polymorphic-segmentation@^3.8.5":
version "3.8.5"
resolved "https://registry.yarnpkg.com/@cornerstonejs/polymorphic-segmentation/-/polymorphic-segmentation-3.8.5.tgz#5289f1b9d7f8fdbf3164330c4d30dd03fffa16be"
integrity sha512-6L9a9f36CnUIuGsydA8kkkC0z1Gjid4KfclCQoYYaxcsLWLDpba5usFERmxCLIm9VyBsA3POqesIGDqWTgJmFg==
"@cornerstonejs/polymorphic-segmentation@^3.9.1":
version "3.9.1"
resolved "https://registry.yarnpkg.com/@cornerstonejs/polymorphic-segmentation/-/polymorphic-segmentation-3.9.1.tgz#599307c3e606d6199d3cf9351a17be9dbc028029"
integrity sha512-QAJYYBtXNpHSKFiN4kVuCOlQB2Cnl6UrnTgAgBKw1sE00wrmbjyF/z1x1qBR34IkAe1ggMbF1QmhQpR90s1M6A==
dependencies:
"@icr/polyseg-wasm" "0.4.0"
"@cornerstonejs/tools@^3.8.5":
version "3.8.5"
resolved "https://registry.yarnpkg.com/@cornerstonejs/tools/-/tools-3.8.5.tgz#15fe20fa051dc12084141515c2a715a4f0a9a858"
integrity sha512-aTaziRHJakCCxvbHhbrSkEuiamURGakcK83KXGJPjSdStWC/2cVpkCzPxc8V7FZBIstsvo5pgciXSpNc6Yt7Og==
"@cornerstonejs/tools@^3.9.1":
version "3.9.1"
resolved "https://registry.yarnpkg.com/@cornerstonejs/tools/-/tools-3.9.1.tgz#e821057de4eb773337380c7f4143bebe25281a8c"
integrity sha512-OP3oZ+Af3ax3Kdo7DLaRs74XlRHTpBuePZvUuYb21VsWBVr50E9nRV5zyCo/4klRb+/zEKlWGQbQogmQxv9+NA==
dependencies:
"@types/offscreencanvas" "2019.7.3"
comlink "^4.4.1"
@ -6729,7 +6729,7 @@ axios@^0.27.2:
follow-redirects "^1.14.9"
form-data "^4.0.0"
axios@^1.0.0, axios@^1.4.0, axios@^1.6.2, axios@^1.8.2:
axios@^1.0.0, axios@^1.4.0, axios@^1.6.2:
version "1.8.3"
resolved "https://registry.yarnpkg.com/axios/-/axios-1.8.3.tgz#9ebccd71c98651d547162a018a1a95a4b4ed4de8"
integrity sha512-iP4DebzoNlP/YN2dpwCgb8zoCmhtkajzS48JvwmkSkXvPI3DHc7m+XYL5tGnSlJtR6nImXZmdCuN5aP8dh1d8A==
@ -6738,6 +6738,15 @@ axios@^1.0.0, axios@^1.4.0, axios@^1.6.2, axios@^1.8.2:
form-data "^4.0.0"
proxy-from-env "^1.1.0"
axios@^1.8.4:
version "1.8.4"
resolved "https://registry.yarnpkg.com/axios/-/axios-1.8.4.tgz#78990bb4bc63d2cae072952d374835950a82f447"
integrity sha512-eBSYY4Y68NNlHbHBMdeDmKNtDgXWhQsJcGqzO3iLUM0GraQFSS9cVgPX5I9b3lbdFKyYoAEGAZF1DwhTaljNAw==
dependencies:
follow-redirects "^1.15.6"
form-data "^4.0.0"
proxy-from-env "^1.1.0"
axobject-query@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-4.1.0.tgz#28768c76d0e3cff21bc62a9e2d0b6ac30042a1ee"
@ -15313,7 +15322,7 @@ modify-values@^1.0.1:
resolved "https://registry.yarnpkg.com/modify-values/-/modify-values-1.0.1.tgz#b3939fa605546474e3e3e3c63d64bd43b4ee6022"
integrity sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw==
moment@*, moment@>=1.6.0, moment@^2.9.4:
moment@>=1.6.0, moment@^2.30.1:
version "2.30.1"
resolved "https://registry.yarnpkg.com/moment/-/moment-2.30.1.tgz#f8c91c07b7a786e30c59926df530b4eac96974ae"
integrity sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==