Compare commits

..
Author SHA1 Message Date
ohif-bot 0b6e9cba76 chore(version): Update package versions [skip ci] 2025-04-10 02:48:32 +00:00
ohif-bot 963664cb63 chore(version): version.json [skip ci] 2025-04-10 02:48:27 +00:00
sedghi 12fe1e107d chore: release 3p10 2025-04-09 22:41:26 -04:00
ohif-bot e1e9b5ccb1 chore(version): Update package versions [skip ci] 2025-04-09 20:54:34 +00:00
ohif-bot 6b7e73b78a chore(version): version.json [skip ci] 2025-04-09 20:54:27 +00:00
AlirezaandJoe Boccanfuso 43bc142439 fix(ui): Enhance UI Components and Update CornerstoneJS Dependencies and resizable panels (#4938)
Co-authored-by: Joe Boccanfuso <joe.boccanfuso@radicalimaging.com>
2025-04-09 16:49:55 -04:00
ohif-bot c05ec1909f chore(version): Update package versions [skip ci] 2025-04-09 14:00:54 +00:00
ohif-bot c7529394ad chore(version): version.json [skip ci] 2025-04-09 14:00:48 +00:00
Pedro Köhler f6f60a63d2 fix: x-ray pixel spacing calibration (#4922) 2025-04-09 09:55:51 -04:00
ohif-bot 0d2ccc5830 chore(version): Update package versions [skip ci] 2025-04-09 03:01:36 +00:00
ohif-bot 08be5cc656 chore(version): version.json [skip ci] 2025-04-09 03:01:30 +00:00
Alireza c453c29449 docs: migration guides 3p10 (#4937) 2025-04-08 22:57:07 -04:00
ohif-bot a69dd8b1a0 chore(version): Update package versions [skip ci] 2025-04-08 22:38:59 +00:00
ohif-bot 17c5642a59 chore(version): version.json [skip ci] 2025-04-08 22:38:53 +00:00
Alireza bd2f843469 chore: update screenshopts for test (#4934) 2025-04-08 18:34:45 -04:00
ohif-bot 8b9b02d84c chore(version): Update package versions [skip ci] 2025-04-08 21:25:58 +00:00
ohif-bot c9958bafad chore(version): version.json [skip ci] 2025-04-08 21:25:52 +00:00
Dan Rukas 85f465968b ui(fix): small Create Report dialog fixes (#4935) 2025-04-08 17:21:08 -04:00
ohif-bot 47e491f1c8 chore(version): Update package versions [skip ci] 2025-04-08 16:10:38 +00:00
ohif-bot e56b53e897 chore(version): version.json [skip ci] 2025-04-08 16:10:32 +00:00
AlirezaandDan Rukas 2bdf4afa4d refactor(ui): Migrate components to ui-next (#4930)
Co-authored-by: Dan Rukas <dan.rukas@gmail.com>
2025-04-08 12:06:07 -04:00
Dan Rukas 1b8729dded ui(components): CinePlayer updated for ui-next (#4932) 2025-04-08 12:03:35 -04:00
ohif-bot f71d370969 chore(version): Update package versions [skip ci] 2025-04-08 13:48:32 +00:00
ohif-bot 033831ee72 chore(version): version.json [skip ci] 2025-04-08 13:48:24 +00:00
Dan Rukas 49c08298fc ui(colors): Adds neutral color variable and updates scrollbars (#4933) 2025-04-08 09:43:30 -04:00
elawendeandErnst Lawende cfa202e89a fix(OIDC): Use new access_token after refresh (#4853)
Co-authored-by: Ernst Lawende <ernstl@bastion365.nl>
2025-04-08 09:43:06 -04:00
ohif-bot 391a5f3bdd chore(version): Update package versions [skip ci] 2025-04-07 20:50:11 +00:00
ohif-bot 64d65a6830 chore(version): version.json [skip ci] 2025-04-07 20:50:05 +00:00
Alireza 3653de7487 fix(segmentation): Add segment jump for new segments and make panels scrollable (#4928) 2025-04-07 16:45:29 -04:00
Dan Rukas a8ac297e16 ui(components): Viewport components updated to ui-next with design updates (#4886) 2025-04-07 16:45:05 -04:00
ohif-bot 4e09f85d5d chore(version): Update package versions [skip ci] 2025-04-07 14:09:45 +00:00
ohif-bot d2f187153d chore(version): version.json [skip ci] 2025-04-07 14:09:39 +00:00
Pedro Köhler 62e5a62066 feat: allow saving to same SR series (#4889) 2025-04-07 10:05:22 -04:00
ohif-bot 7b40963997 chore(version): Update package versions [skip ci] 2025-04-04 17:38:08 +00:00
ohif-bot 75493334cf chore(version): version.json [skip ci] 2025-04-04 17:38:00 +00:00
Pedro Köhler 746f2524eb fix(cine): Resolve Cine Player Faults on DisplaySet Update (#4909) 2025-04-04 13:33:36 -04:00
ohif-bot 0eb9ff235c chore(version): Update package versions [skip ci] 2025-04-04 16:16:04 +00:00
ohif-bot e9b95afd4c chore(version): version.json [skip ci] 2025-04-04 16:15:57 +00:00
Alireza fc33bd0d59 feat(image capture): Enhance SEG and RTSS Support with Dependency Updates and Bug Fixes (#4924) 2025-04-04 12:11:29 -04:00
ohif-bot 479e280fdf chore(version): Update package versions [skip ci] 2025-04-04 16:07:02 +00:00
ohif-bot d4f81cd2b7 chore(version): version.json [skip ci] 2025-04-04 16:06:55 +00:00
nithin-trenserandDevu Jayalekshmi 54fded554e feat: Automate tracking prompts for a less disruptive annotation workflow (#4822)
Co-authored-by: Devu Jayalekshmi <devu.jayalekshmi@trenser.com>
2025-04-04 12:02:13 -04:00
370 changed files with 10417 additions and 2329 deletions

No files matched your search

+2 -2
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.
+2 -3
View File
@@ -28,9 +28,8 @@ jobs:
- name: Set up Git safe directory
run: git config --global --add safe.directory /__w/Viewers/Viewers
- name: Run Playwright tests
run:
export NODE_OPTIONS="--max_old_space_size=8192" && bun x playwright test --shard=${{
matrix.shardIndex }}/${{ matrix.shardTotal }}
run: |
NODE_OPTIONS="--max_old_space_size=8192" TEST_ENV=true bun x playwright test --shard=${{ matrix.shardIndex }}/${{ matrix.shardTotal }}
- name: Upload blob report to GitHub Actions Artifacts
if: ${{ !cancelled() }}
+1
View File
@@ -49,6 +49,7 @@ const defineValues = {
'process.env.LOCIZE_PROJECTID': JSON.stringify(process.env.LOCIZE_PROJECTID || ''),
'process.env.LOCIZE_API_KEY': JSON.stringify(process.env.LOCIZE_API_KEY || ''),
'process.env.REACT_APP_I18N_DEBUG': JSON.stringify(process.env.REACT_APP_I18N_DEBUG || ''),
'process.env.TEST_ENV': JSON.stringify(process.env.TEST_ENV || ''),
};
// Only redefine updated values. This avoids warning messages in the logs
+128
View File
@@ -3,6 +3,134 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [3.10.0](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.159...v3.10.0) (2025-04-10)
**Note:** Version bump only for package ohif-monorepo-root
# [3.10.0-beta.159](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.158...v3.10.0-beta.159) (2025-04-09)
### Bug Fixes
* **ui:** Enhance UI Components and Update CornerstoneJS Dependencies and resizable panels ([#4938](https://github.com/OHIF/Viewers/issues/4938)) ([43bc142](https://github.com/OHIF/Viewers/commit/43bc142439aab1a6514ba1711f86d64ac8bb1acb))
# [3.10.0-beta.158](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.157...v3.10.0-beta.158) (2025-04-09)
### Bug Fixes
* x-ray pixel spacing calibration ([#4922](https://github.com/OHIF/Viewers/issues/4922)) ([f6f60a6](https://github.com/OHIF/Viewers/commit/f6f60a63d2780cece8ade012a71b93cb3c7c4035))
# [3.10.0-beta.157](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.156...v3.10.0-beta.157) (2025-04-09)
**Note:** Version bump only for package ohif-monorepo-root
# [3.10.0-beta.156](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.155...v3.10.0-beta.156) (2025-04-08)
**Note:** Version bump only for package ohif-monorepo-root
# [3.10.0-beta.155](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.154...v3.10.0-beta.155) (2025-04-08)
**Note:** Version bump only for package ohif-monorepo-root
# [3.10.0-beta.154](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.153...v3.10.0-beta.154) (2025-04-08)
**Note:** Version bump only for package ohif-monorepo-root
# [3.10.0-beta.153](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.152...v3.10.0-beta.153) (2025-04-08)
### Bug Fixes
* **OIDC:** Use new access_token after refresh ([#4853](https://github.com/OHIF/Viewers/issues/4853)) ([cfa202e](https://github.com/OHIF/Viewers/commit/cfa202e89a51f8b2e81b29954bb3a211c583fe28))
# [3.10.0-beta.152](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.151...v3.10.0-beta.152) (2025-04-07)
### Bug Fixes
* **segmentation:** Add segment jump for new segments and make panels scrollable ([#4928](https://github.com/OHIF/Viewers/issues/4928)) ([3653de7](https://github.com/OHIF/Viewers/commit/3653de748731199d130f02200becde78c07d3303))
# [3.10.0-beta.151](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.150...v3.10.0-beta.151) (2025-04-07)
### Features
* allow saving to same SR series ([#4889](https://github.com/OHIF/Viewers/issues/4889)) ([62e5a62](https://github.com/OHIF/Viewers/commit/62e5a6206606ba7a16a56cf47456e52f892372da))
# [3.10.0-beta.150](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.149...v3.10.0-beta.150) (2025-04-04)
### Bug Fixes
* **cine:** Resolve Cine Player Faults on DisplaySet Update ([#4909](https://github.com/OHIF/Viewers/issues/4909)) ([746f252](https://github.com/OHIF/Viewers/commit/746f2524eb5e3ec1d36fbb35dc2cc5b55c7ba99f))
# [3.10.0-beta.149](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.148...v3.10.0-beta.149) (2025-04-04)
### Features
* **image capture:** Enhance SEG and RTSS Support with Dependency Updates and Bug Fixes ([#4924](https://github.com/OHIF/Viewers/issues/4924)) ([fc33bd0](https://github.com/OHIF/Viewers/commit/fc33bd0d594a1ac8de79b11080ead48630a8ca27))
# [3.10.0-beta.148](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.147...v3.10.0-beta.148) (2025-04-04)
### Features
* Automate tracking prompts for a less disruptive annotation workflow ([#4822](https://github.com/OHIF/Viewers/issues/4822)) ([54fded5](https://github.com/OHIF/Viewers/commit/54fded554e934f2f75e00d456ebad7692d561225))
# [3.10.0-beta.147](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.146...v3.10.0-beta.147) (2025-04-03)
**Note:** Version bump only for package ohif-monorepo-root
+107
View File
@@ -3,6 +3,113 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [3.10.0](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.159...v3.10.0) (2025-04-10)
**Note:** Version bump only for package @externals/devDependencies
# [3.10.0-beta.159](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.158...v3.10.0-beta.159) (2025-04-09)
**Note:** Version bump only for package @externals/devDependencies
# [3.10.0-beta.158](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.157...v3.10.0-beta.158) (2025-04-09)
**Note:** Version bump only for package @externals/devDependencies
# [3.10.0-beta.157](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.156...v3.10.0-beta.157) (2025-04-09)
**Note:** Version bump only for package @externals/devDependencies
# [3.10.0-beta.156](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.155...v3.10.0-beta.156) (2025-04-08)
**Note:** Version bump only for package @externals/devDependencies
# [3.10.0-beta.155](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.154...v3.10.0-beta.155) (2025-04-08)
**Note:** Version bump only for package @externals/devDependencies
# [3.10.0-beta.154](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.153...v3.10.0-beta.154) (2025-04-08)
**Note:** Version bump only for package @externals/devDependencies
# [3.10.0-beta.153](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.152...v3.10.0-beta.153) (2025-04-08)
**Note:** Version bump only for package @externals/devDependencies
# [3.10.0-beta.152](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.151...v3.10.0-beta.152) (2025-04-07)
### Bug Fixes
* **segmentation:** Add segment jump for new segments and make panels scrollable ([#4928](https://github.com/OHIF/Viewers/issues/4928)) ([3653de7](https://github.com/OHIF/Viewers/commit/3653de748731199d130f02200becde78c07d3303))
# [3.10.0-beta.151](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.150...v3.10.0-beta.151) (2025-04-07)
**Note:** Version bump only for package @externals/devDependencies
# [3.10.0-beta.150](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.149...v3.10.0-beta.150) (2025-04-04)
**Note:** Version bump only for package @externals/devDependencies
# [3.10.0-beta.149](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.148...v3.10.0-beta.149) (2025-04-04)
**Note:** Version bump only for package @externals/devDependencies
# [3.10.0-beta.148](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.147...v3.10.0-beta.148) (2025-04-04)
**Note:** Version bump only for package @externals/devDependencies
# [3.10.0-beta.147](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.146...v3.10.0-beta.147) (2025-04-03)
**Note:** Version bump only for package @externals/devDependencies
+2 -3
View File
@@ -1,7 +1,7 @@
{
"name": "@externals/devDependencies",
"description": "External dev dependencies - put dev build dependencies here",
"version": "3.10.0-beta.147",
"version": "3.10.0",
"license": "MIT",
"private": true,
"engines": {
@@ -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",
@@ -76,7 +76,6 @@
"shader-loader": "^1.3.1",
"shx": "^0.3.3",
"source-map-loader": "^4.0.1",
"start-server-and-test": "^1.10.0",
"style-loader": "^1.0.0",
"stylus": "^0.59.0",
"stylus-loader": "^7.1.3",
+104
View File
@@ -3,6 +3,110 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [3.10.0](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.159...v3.10.0) (2025-04-10)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.10.0-beta.159](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.158...v3.10.0-beta.159) (2025-04-09)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.10.0-beta.158](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.157...v3.10.0-beta.158) (2025-04-09)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.10.0-beta.157](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.156...v3.10.0-beta.157) (2025-04-09)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.10.0-beta.156](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.155...v3.10.0-beta.156) (2025-04-08)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.10.0-beta.155](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.154...v3.10.0-beta.155) (2025-04-08)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.10.0-beta.154](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.153...v3.10.0-beta.154) (2025-04-08)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.10.0-beta.153](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.152...v3.10.0-beta.153) (2025-04-08)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.10.0-beta.152](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.151...v3.10.0-beta.152) (2025-04-07)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.10.0-beta.151](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.150...v3.10.0-beta.151) (2025-04-07)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.10.0-beta.150](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.149...v3.10.0-beta.150) (2025-04-04)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.10.0-beta.149](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.148...v3.10.0-beta.149) (2025-04-04)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.10.0-beta.148](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.147...v3.10.0-beta.148) (2025-04-04)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.10.0-beta.147](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.146...v3.10.0-beta.147) (2025-04-03)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "@externals/dicom-microscopy-viewer",
"description": "External reference to dicom-microscopy-viewer",
"version": "3.10.0-beta.147",
"version": "3.10.0",
"license": "MIT",
"dependencies": {
"dicom-microscopy-viewer": "^0.46.1"
+297 -391
View File
File diff suppressed because it is too large. Load diff
+1 -1
View File
@@ -1 +1 @@
a52be6460b1cb462d9f9e826055662c473af6c43
12fe1e107deba3e804b822e0caa4a5ec058b6ee5
@@ -3,6 +3,122 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [3.10.0](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.159...v3.10.0) (2025-04-10)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.10.0-beta.159](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.158...v3.10.0-beta.159) (2025-04-09)
### Bug Fixes
* **ui:** Enhance UI Components and Update CornerstoneJS Dependencies and resizable panels ([#4938](https://github.com/OHIF/Viewers/issues/4938)) ([43bc142](https://github.com/OHIF/Viewers/commit/43bc142439aab1a6514ba1711f86d64ac8bb1acb))
# [3.10.0-beta.158](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.157...v3.10.0-beta.158) (2025-04-09)
### Bug Fixes
* x-ray pixel spacing calibration ([#4922](https://github.com/OHIF/Viewers/issues/4922)) ([f6f60a6](https://github.com/OHIF/Viewers/commit/f6f60a63d2780cece8ade012a71b93cb3c7c4035))
# [3.10.0-beta.157](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.156...v3.10.0-beta.157) (2025-04-09)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.10.0-beta.156](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.155...v3.10.0-beta.156) (2025-04-08)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.10.0-beta.155](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.154...v3.10.0-beta.155) (2025-04-08)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.10.0-beta.154](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.153...v3.10.0-beta.154) (2025-04-08)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.10.0-beta.153](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.152...v3.10.0-beta.153) (2025-04-08)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.10.0-beta.152](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.151...v3.10.0-beta.152) (2025-04-07)
### Bug Fixes
* **segmentation:** Add segment jump for new segments and make panels scrollable ([#4928](https://github.com/OHIF/Viewers/issues/4928)) ([3653de7](https://github.com/OHIF/Viewers/commit/3653de748731199d130f02200becde78c07d3303))
# [3.10.0-beta.151](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.150...v3.10.0-beta.151) (2025-04-07)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.10.0-beta.150](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.149...v3.10.0-beta.150) (2025-04-04)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.10.0-beta.149](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.148...v3.10.0-beta.149) (2025-04-04)
### Features
* **image capture:** Enhance SEG and RTSS Support with Dependency Updates and Bug Fixes ([#4924](https://github.com/OHIF/Viewers/issues/4924)) ([fc33bd0](https://github.com/OHIF/Viewers/commit/fc33bd0d594a1ac8de79b11080ead48630a8ca27))
# [3.10.0-beta.148](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.147...v3.10.0-beta.148) (2025-04-04)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.10.0-beta.147](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.146...v3.10.0-beta.147) (2025-04-03)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
@@ -1,6 +1,6 @@
{
"name": "@ohif/extension-cornerstone-dicom-pmap",
"version": "3.10.0-beta.147",
"version": "3.10.0",
"description": "DICOM Parametric Map read workflow",
"author": "OHIF",
"license": "MIT",
@@ -33,10 +33,10 @@
"start": "yarn run dev"
},
"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",
"@ohif/extension-cornerstone": "3.10.0",
"@ohif/extension-default": "3.10.0",
"@ohif/i18n": "3.10.0",
"prop-types": "^15.6.2",
"react": "^18.3.1",
"react-dom": "^18.3.1",
@@ -46,8 +46,8 @@
},
"dependencies": {
"@babel/runtime": "^7.20.13",
"@cornerstonejs/adapters": "^3.8.4",
"@cornerstonejs/core": "^3.8.4",
"@cornerstonejs/adapters": "^3.9.5",
"@cornerstonejs/core": "^3.9.5",
"@kitware/vtk.js": "32.12.0",
"react-color": "^2.19.3"
}
@@ -3,6 +3,113 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [3.10.0](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.159...v3.10.0) (2025-04-10)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.10.0-beta.159](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.158...v3.10.0-beta.159) (2025-04-09)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.10.0-beta.158](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.157...v3.10.0-beta.158) (2025-04-09)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.10.0-beta.157](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.156...v3.10.0-beta.157) (2025-04-09)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.10.0-beta.156](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.155...v3.10.0-beta.156) (2025-04-08)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.10.0-beta.155](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.154...v3.10.0-beta.155) (2025-04-08)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.10.0-beta.154](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.153...v3.10.0-beta.154) (2025-04-08)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.10.0-beta.153](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.152...v3.10.0-beta.153) (2025-04-08)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.10.0-beta.152](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.151...v3.10.0-beta.152) (2025-04-07)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.10.0-beta.151](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.150...v3.10.0-beta.151) (2025-04-07)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.10.0-beta.150](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.149...v3.10.0-beta.150) (2025-04-04)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.10.0-beta.149](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.148...v3.10.0-beta.149) (2025-04-04)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.10.0-beta.148](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.147...v3.10.0-beta.148) (2025-04-04)
### Features
* Automate tracking prompts for a less disruptive annotation workflow ([#4822](https://github.com/OHIF/Viewers/issues/4822)) ([54fded5](https://github.com/OHIF/Viewers/commit/54fded554e934f2f75e00d456ebad7692d561225))
# [3.10.0-beta.147](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.146...v3.10.0-beta.147) (2025-04-03)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
+5 -5
View File
@@ -1,6 +1,6 @@
{
"name": "@ohif/extension-cornerstone-dicom-rt",
"version": "3.10.0-beta.147",
"version": "3.10.0",
"description": "DICOM RT read workflow",
"author": "OHIF",
"license": "MIT",
@@ -33,10 +33,10 @@
"start": "yarn run dev"
},
"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",
"@ohif/extension-cornerstone": "3.10.0",
"@ohif/extension-default": "3.10.0",
"@ohif/i18n": "3.10.0",
"prop-types": "^15.6.2",
"react": "^18.3.1",
"react-dom": "^18.3.1",
@@ -1,5 +1,3 @@
import { ButtonEnums } from '@ohif/ui';
const RESPONSE = {
NO_NEVER: -1,
CANCEL: 0,
@@ -13,13 +11,13 @@ function promptHydrateRT({
preHydrateCallbacks,
hydrateRTDisplaySet,
}: withAppTypes) {
const { uiViewportDialogService } = servicesManager.services;
const { uiViewportDialogService, customizationService } = servicesManager.services;
const extensionManager = servicesManager._extensionManager;
const appConfig = extensionManager._appConfig;
return new Promise(async function (resolve, reject) {
const promptResult = appConfig?.disableConfirmationPrompts
? RESPONSE.HYDRATE_SEG
: await _askHydrate(uiViewportDialogService, viewportId);
: await _askHydrate(uiViewportDialogService, customizationService, viewportId);
if (promptResult === RESPONSE.HYDRATE_SEG) {
preHydrateCallbacks?.forEach(callback => {
@@ -37,19 +35,23 @@ function promptHydrateRT({
});
}
function _askHydrate(uiViewportDialogService: AppTypes.UIViewportDialogService, viewportId) {
function _askHydrate(
uiViewportDialogService: AppTypes.UIViewportDialogService,
customizationService: AppTypes.CustomizationService,
viewportId
) {
return new Promise(function (resolve, reject) {
const message = 'Do you want to open this Segmentation?';
const message = customizationService.getCustomization('viewportNotification.hydrateRTMessage');
const actions = [
{
id: 'no-hydrate',
type: ButtonEnums.type.secondary,
type: 'secondary',
text: 'No',
value: RESPONSE.CANCEL,
},
{
id: 'yes-hydrate',
type: ButtonEnums.type.primary,
type: 'primary',
text: 'Yes',
value: RESPONSE.HYDRATE_SEG,
},
@@ -1,6 +1,6 @@
import React, { useCallback, useEffect, useRef, useState } from 'react';
import PropTypes from 'prop-types';
import { ViewportActionArrows } from '@ohif/ui';
import { ViewportActionArrows } from '@ohif/ui-next';
import { useViewportGrid } from '@ohif/ui-next';
import { utils } from '@ohif/extension-cornerstone';
@@ -1,6 +1,6 @@
import React from 'react';
import { useTranslation } from 'react-i18next';
import { ViewportActionButton } from '@ohif/ui';
import { ViewportActionButton } from '@ohif/ui-next';
import { Icons, Tooltip, TooltipTrigger, TooltipContent } from '@ohif/ui-next';
export default function _getStatusComponent({ isHydrated, onStatusClick }) {
@@ -15,7 +15,7 @@ export default function _getStatusComponent({ isHydrated, onStatusClick }) {
case false:
StatusIcon = () => (
<Icons.ByName
className="text-aqua-pale"
className="text-muted-foreground h-4 w-4"
name="status-untracked"
/>
);
@@ -56,4 +56,4 @@ export default function _getStatusComponent({ isHydrated, onStatusClick }) {
{!ToolTipMessage && <StatusArea />}
</>
);
}
}
@@ -3,6 +3,125 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [3.10.0](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.159...v3.10.0) (2025-04-10)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.10.0-beta.159](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.158...v3.10.0-beta.159) (2025-04-09)
### Bug Fixes
* **ui:** Enhance UI Components and Update CornerstoneJS Dependencies and resizable panels ([#4938](https://github.com/OHIF/Viewers/issues/4938)) ([43bc142](https://github.com/OHIF/Viewers/commit/43bc142439aab1a6514ba1711f86d64ac8bb1acb))
# [3.10.0-beta.158](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.157...v3.10.0-beta.158) (2025-04-09)
### Bug Fixes
* x-ray pixel spacing calibration ([#4922](https://github.com/OHIF/Viewers/issues/4922)) ([f6f60a6](https://github.com/OHIF/Viewers/commit/f6f60a63d2780cece8ade012a71b93cb3c7c4035))
# [3.10.0-beta.157](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.156...v3.10.0-beta.157) (2025-04-09)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.10.0-beta.156](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.155...v3.10.0-beta.156) (2025-04-08)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.10.0-beta.155](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.154...v3.10.0-beta.155) (2025-04-08)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.10.0-beta.154](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.153...v3.10.0-beta.154) (2025-04-08)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.10.0-beta.153](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.152...v3.10.0-beta.153) (2025-04-08)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.10.0-beta.152](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.151...v3.10.0-beta.152) (2025-04-07)
### Bug Fixes
* **segmentation:** Add segment jump for new segments and make panels scrollable ([#4928](https://github.com/OHIF/Viewers/issues/4928)) ([3653de7](https://github.com/OHIF/Viewers/commit/3653de748731199d130f02200becde78c07d3303))
# [3.10.0-beta.151](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.150...v3.10.0-beta.151) (2025-04-07)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.10.0-beta.150](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.149...v3.10.0-beta.150) (2025-04-04)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.10.0-beta.149](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.148...v3.10.0-beta.149) (2025-04-04)
### Features
* **image capture:** Enhance SEG and RTSS Support with Dependency Updates and Bug Fixes ([#4924](https://github.com/OHIF/Viewers/issues/4924)) ([fc33bd0](https://github.com/OHIF/Viewers/commit/fc33bd0d594a1ac8de79b11080ead48630a8ca27))
# [3.10.0-beta.148](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.147...v3.10.0-beta.148) (2025-04-04)
### Features
* Automate tracking prompts for a less disruptive annotation workflow ([#4822](https://github.com/OHIF/Viewers/issues/4822)) ([54fded5](https://github.com/OHIF/Viewers/commit/54fded554e934f2f75e00d456ebad7692d561225))
# [3.10.0-beta.147](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.146...v3.10.0-beta.147) (2025-04-03)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
@@ -1,6 +1,6 @@
{
"name": "@ohif/extension-cornerstone-dicom-seg",
"version": "3.10.0-beta.147",
"version": "3.10.0",
"description": "DICOM SEG read workflow",
"author": "OHIF",
"license": "MIT",
@@ -33,10 +33,10 @@
"start": "yarn run dev"
},
"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",
"@ohif/extension-cornerstone": "3.10.0",
"@ohif/extension-default": "3.10.0",
"@ohif/i18n": "3.10.0",
"prop-types": "^15.6.2",
"react": "^18.3.1",
"react-dom": "^18.3.1",
@@ -46,8 +46,8 @@
},
"dependencies": {
"@babel/runtime": "^7.20.13",
"@cornerstonejs/adapters": "^3.8.4",
"@cornerstonejs/core": "^3.8.4",
"@cornerstonejs/adapters": "^3.9.5",
"@cornerstonejs/core": "^3.9.5",
"@kitware/vtk.js": "32.12.0",
"react-color": "^2.19.3"
}
@@ -305,9 +305,6 @@ const commandsModule = ({
};
const definitions = {
loadSegmentationDisplaySetsForViewport: {
commandFn: actions.loadSegmentationDisplaySetsForViewport,
},
loadSegmentationsForViewport: {
commandFn: actions.loadSegmentationsForViewport,
},
@@ -1,5 +1,3 @@
import { ButtonEnums } from '@ohif/ui';
const RESPONSE = {
NO_NEVER: -1,
CANCEL: 0,
@@ -13,14 +11,14 @@ function promptHydrateSEG({
preHydrateCallbacks,
hydrateCallback,
}: withAppTypes) {
const { uiViewportDialogService } = servicesManager.services;
const { uiViewportDialogService, customizationService } = servicesManager.services;
const extensionManager = servicesManager._extensionManager;
const appConfig = extensionManager._appConfig;
return new Promise(async function (resolve, reject) {
const promptResult = appConfig?.disableConfirmationPrompts
? RESPONSE.HYDRATE_SEG
: await _askHydrate(uiViewportDialogService, viewportId);
: await _askHydrate(uiViewportDialogService, customizationService, viewportId);
if (promptResult === RESPONSE.HYDRATE_SEG) {
preHydrateCallbacks?.forEach(callback => {
@@ -39,19 +37,23 @@ function promptHydrateSEG({
});
}
function _askHydrate(uiViewportDialogService, viewportId) {
function _askHydrate(
uiViewportDialogService: AppTypes.UIViewportDialogService,
customizationService: AppTypes.CustomizationService,
viewportId
) {
return new Promise(function (resolve, reject) {
const message = 'Do you want to open this Segmentation?';
const message = customizationService.getCustomization('viewportNotification.hydrateSEGMessage');
const actions = [
{
id: 'no-hydrate',
type: ButtonEnums.type.secondary,
type: 'secondary',
text: 'No',
value: RESPONSE.CANCEL,
},
{
id: 'yes-hydrate',
type: ButtonEnums.type.primary,
type: 'primary',
text: 'Yes',
value: RESPONSE.HYDRATE_SEG,
},
@@ -1,6 +1,6 @@
import React, { useCallback, useEffect, useRef, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { ViewportActionArrows } from '@ohif/ui';
import { ViewportActionArrows } from '@ohif/ui-next';
import { useViewportGrid } from '@ohif/ui-next';
import createSEGToolGroupAndAddTools from '../utils/initSEGToolGroup';
import promptHydrateSEG from '../utils/promptHydrateSEG';
@@ -47,7 +47,7 @@ function OHIFCornerstoneSEGViewport(props: withAppTypes) {
const [viewportGrid, viewportGridService] = useViewportGrid();
// States
let selectedSegmentObjectIndex: number = 0;
const selectedSegmentObjectIndex: number = 0;
const { setPositionPresentation } = usePositionPresentationStore();
// Hydration means that the SEG is opened and segments are loaded into the
@@ -160,7 +160,7 @@ function OHIFCornerstoneSEGViewport(props: withAppTypes) {
displaySetInstanceUID: referencedDisplaySet.displaySetInstanceUID,
});
viewportGridService.setDisplaySetsForViewport({
commandsManager.runCommand('loadSegmentationDisplaySetsForViewport', {
viewportId,
displaySetInstanceUIDs: [referencedDisplaySet.displaySetInstanceUID],
});
@@ -1,6 +1,6 @@
import React from 'react';
import { useTranslation } from 'react-i18next';
import { ViewportActionButton } from '@ohif/ui';
import { ViewportActionButton } from '@ohif/ui-next';
import { Icons, Tooltip, TooltipTrigger, TooltipContent } from '@ohif/ui-next';
export default function _getStatusComponent({ isHydrated, onStatusClick }) {
@@ -15,7 +15,7 @@ export default function _getStatusComponent({ isHydrated, onStatusClick }) {
case false:
StatusIcon = () => (
<Icons.ByName
className="text-aqua-pale"
className="text-muted-foreground h-4 w-4"
name="status-untracked"
/>
);
@@ -56,4 +56,4 @@ export default function _getStatusComponent({ isHydrated, onStatusClick }) {
{!ToolTipMessage && <StatusArea />}
</>
);
}
}
@@ -3,6 +3,128 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [3.10.0](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.159...v3.10.0) (2025-04-10)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.10.0-beta.159](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.158...v3.10.0-beta.159) (2025-04-09)
### Bug Fixes
* **ui:** Enhance UI Components and Update CornerstoneJS Dependencies and resizable panels ([#4938](https://github.com/OHIF/Viewers/issues/4938)) ([43bc142](https://github.com/OHIF/Viewers/commit/43bc142439aab1a6514ba1711f86d64ac8bb1acb))
# [3.10.0-beta.158](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.157...v3.10.0-beta.158) (2025-04-09)
### Bug Fixes
* x-ray pixel spacing calibration ([#4922](https://github.com/OHIF/Viewers/issues/4922)) ([f6f60a6](https://github.com/OHIF/Viewers/commit/f6f60a63d2780cece8ade012a71b93cb3c7c4035))
# [3.10.0-beta.157](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.156...v3.10.0-beta.157) (2025-04-09)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.10.0-beta.156](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.155...v3.10.0-beta.156) (2025-04-08)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.10.0-beta.155](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.154...v3.10.0-beta.155) (2025-04-08)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.10.0-beta.154](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.153...v3.10.0-beta.154) (2025-04-08)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.10.0-beta.153](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.152...v3.10.0-beta.153) (2025-04-08)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.10.0-beta.152](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.151...v3.10.0-beta.152) (2025-04-07)
### Bug Fixes
* **segmentation:** Add segment jump for new segments and make panels scrollable ([#4928](https://github.com/OHIF/Viewers/issues/4928)) ([3653de7](https://github.com/OHIF/Viewers/commit/3653de748731199d130f02200becde78c07d3303))
# [3.10.0-beta.151](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.150...v3.10.0-beta.151) (2025-04-07)
### Features
* allow saving to same SR series ([#4889](https://github.com/OHIF/Viewers/issues/4889)) ([62e5a62](https://github.com/OHIF/Viewers/commit/62e5a6206606ba7a16a56cf47456e52f892372da))
# [3.10.0-beta.150](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.149...v3.10.0-beta.150) (2025-04-04)
### Bug Fixes
* **cine:** Resolve Cine Player Faults on DisplaySet Update ([#4909](https://github.com/OHIF/Viewers/issues/4909)) ([746f252](https://github.com/OHIF/Viewers/commit/746f2524eb5e3ec1d36fbb35dc2cc5b55c7ba99f))
# [3.10.0-beta.149](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.148...v3.10.0-beta.149) (2025-04-04)
### Features
* **image capture:** Enhance SEG and RTSS Support with Dependency Updates and Bug Fixes ([#4924](https://github.com/OHIF/Viewers/issues/4924)) ([fc33bd0](https://github.com/OHIF/Viewers/commit/fc33bd0d594a1ac8de79b11080ead48630a8ca27))
# [3.10.0-beta.148](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.147...v3.10.0-beta.148) (2025-04-04)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.10.0-beta.147](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.146...v3.10.0-beta.147) (2025-04-03)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
+8 -8
View File
@@ -1,6 +1,6 @@
{
"name": "@ohif/extension-cornerstone-dicom-sr",
"version": "3.10.0-beta.147",
"version": "3.10.0",
"description": "OHIF extension for an SR Cornerstone Viewport",
"author": "OHIF",
"license": "MIT",
@@ -34,10 +34,10 @@
"test:unit:ci": "jest --ci --runInBand --collectCoverage --passWithNoTests"
},
"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",
"@ohif/extension-cornerstone": "3.10.0",
"@ohif/extension-measurement-tracking": "3.10.0",
"@ohif/ui": "3.10.0",
"dcmjs": "*",
"dicom-parser": "^1.8.9",
"hammerjs": "^2.0.8",
@@ -46,9 +46,9 @@
},
"dependencies": {
"@babel/runtime": "^7.20.13",
"@cornerstonejs/adapters": "^3.8.4",
"@cornerstonejs/core": "^3.8.4",
"@cornerstonejs/tools": "^3.8.4",
"@cornerstonejs/adapters": "^3.9.5",
"@cornerstonejs/core": "^3.9.5",
"@cornerstonejs/tools": "^3.9.5",
"classnames": "^2.3.2"
}
}
@@ -10,6 +10,15 @@ import hydrateStructuredReport from './utils/hydrateStructuredReport';
const { MeasurementReport } = adaptersSR.Cornerstone3D;
const { log } = OHIF;
interface Options {
SeriesDescription?: string;
SeriesInstanceUID?: string;
SeriesNumber?: number;
InstanceNumber?: number;
SeriesDate?: string;
SeriesTime?: string;
}
/**
* @param measurementData An array of measurements from the measurements service
* that you wish to serialize.
@@ -17,7 +26,7 @@ const { log } = OHIF;
* @param options Naturalized DICOM JSON headers to merge into the displaySet.
*
*/
const _generateReport = (measurementData, additionalFindingTypes, options = {}) => {
const _generateReport = (measurementData, additionalFindingTypes, options: Options = {}) => {
const filteredToolState = getFilteredCornerstoneToolState(
measurementData,
additionalFindingTypes
@@ -37,11 +46,14 @@ const _generateReport = (measurementData, additionalFindingTypes, options = {})
if (typeof dataset.SpecificCharacterSet === 'undefined') {
dataset.SpecificCharacterSet = 'ISO_IR 192';
}
dataset.InstanceNumber = options.InstanceNumber ?? 1;
return dataset;
};
const commandsModule = (props: withAppTypes) => {
const { servicesManager, extensionManager } = props;
const { servicesManager, extensionManager, commandsManager } = props;
const { customizationService, viewportGridService, displaySetService } = servicesManager.services;
const actions = {
@@ -156,12 +168,14 @@ const commandsModule = (props: withAppTypes) => {
const displaySets = displaySetService.getDisplaySetsForSeries(SeriesInstanceUIDs[0]);
if (displaySets.length) {
viewportGridService.setDisplaySetsForViewports([
{
viewportId: viewportGridService.getActiveViewportId(),
displaySetInstanceUIDs: [displaySets[0].displaySetInstanceUID],
},
]);
commandsManager.run('setDisplaySetsForViewports', {
viewportsToUpdate: [
{
viewportId: viewportGridService.getActiveViewportId(),
displaySetInstanceUIDs: [displaySets[0].displaySetInstanceUID],
},
],
});
}
},
};
@@ -5,7 +5,7 @@ import { ExtensionManager, useToolbar } from '@ohif/core';
import { setTrackingUniqueIdentifiersForElement } from '../tools/modules/dicomSRModule';
import { ViewportActionArrows } from '@ohif/ui';
import { ViewportActionArrows } from '@ohif/ui-next';
import createReferencedImageDisplaySet from '../utils/createReferencedImageDisplaySet';
import { usePositionPresentationStore } from '@ohif/extension-cornerstone';
import { useViewportGrid } from '@ohif/ui-next';
@@ -427,7 +427,7 @@ function _getStatusComponent({
case 3:
StatusIcon = () => (
<Icons.ByName
className="text-aqua-pale h-4 w-4"
className="text-muted-foreground h-4 w-4"
name="status-untracked"
/>
);
@@ -90,6 +90,7 @@ function _getDisplaySetsFromSeries(
SeriesDescription,
SeriesNumber,
SeriesDate,
SeriesTime,
ConceptNameCodeSequence,
SOPClassUID,
} = instance;
@@ -106,6 +107,7 @@ function _getDisplaySetsFromSeries(
SeriesDescription,
SeriesNumber,
SeriesDate,
SeriesTime,
SOPInstanceUID,
SeriesInstanceUID,
StudyInstanceUID,
@@ -1,7 +1,7 @@
import React from 'react';
import { SOPClassHandlerId, SOPClassHandlerId3D } from './id';
import { ViewportActionButton } from '@ohif/ui';
import { ViewportActionButton } from '@ohif/ui-next';
import i18n from '@ohif/i18n';
export default function onModeEnter({ servicesManager }) {
@@ -3,6 +3,125 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [3.10.0](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.159...v3.10.0) (2025-04-10)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.10.0-beta.159](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.158...v3.10.0-beta.159) (2025-04-09)
### Bug Fixes
* **ui:** Enhance UI Components and Update CornerstoneJS Dependencies and resizable panels ([#4938](https://github.com/OHIF/Viewers/issues/4938)) ([43bc142](https://github.com/OHIF/Viewers/commit/43bc142439aab1a6514ba1711f86d64ac8bb1acb))
# [3.10.0-beta.158](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.157...v3.10.0-beta.158) (2025-04-09)
### Bug Fixes
* x-ray pixel spacing calibration ([#4922](https://github.com/OHIF/Viewers/issues/4922)) ([f6f60a6](https://github.com/OHIF/Viewers/commit/f6f60a63d2780cece8ade012a71b93cb3c7c4035))
# [3.10.0-beta.157](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.156...v3.10.0-beta.157) (2025-04-09)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.10.0-beta.156](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.155...v3.10.0-beta.156) (2025-04-08)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.10.0-beta.155](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.154...v3.10.0-beta.155) (2025-04-08)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.10.0-beta.154](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.153...v3.10.0-beta.154) (2025-04-08)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.10.0-beta.153](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.152...v3.10.0-beta.153) (2025-04-08)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.10.0-beta.152](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.151...v3.10.0-beta.152) (2025-04-07)
### Bug Fixes
* **segmentation:** Add segment jump for new segments and make panels scrollable ([#4928](https://github.com/OHIF/Viewers/issues/4928)) ([3653de7](https://github.com/OHIF/Viewers/commit/3653de748731199d130f02200becde78c07d3303))
# [3.10.0-beta.151](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.150...v3.10.0-beta.151) (2025-04-07)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.10.0-beta.150](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.149...v3.10.0-beta.150) (2025-04-04)
### Bug Fixes
* **cine:** Resolve Cine Player Faults on DisplaySet Update ([#4909](https://github.com/OHIF/Viewers/issues/4909)) ([746f252](https://github.com/OHIF/Viewers/commit/746f2524eb5e3ec1d36fbb35dc2cc5b55c7ba99f))
# [3.10.0-beta.149](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.148...v3.10.0-beta.149) (2025-04-04)
### Features
* **image capture:** Enhance SEG and RTSS Support with Dependency Updates and Bug Fixes ([#4924](https://github.com/OHIF/Viewers/issues/4924)) ([fc33bd0](https://github.com/OHIF/Viewers/commit/fc33bd0d594a1ac8de79b11080ead48630a8ca27))
# [3.10.0-beta.148](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.147...v3.10.0-beta.148) (2025-04-04)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.10.0-beta.147](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.146...v3.10.0-beta.147) (2025-04-03)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
@@ -1,6 +1,6 @@
{
"name": "@ohif/extension-cornerstone-dynamic-volume",
"version": "3.10.0-beta.147",
"version": "3.10.0",
"description": "OHIF extension for 4D volumes data",
"author": "OHIF",
"license": "MIT",
@@ -29,11 +29,11 @@
"test:unit:ci": "jest --ci --runInBand --collectCoverage --passWithNoTests"
},
"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",
"@ohif/extension-cornerstone": "3.10.0",
"@ohif/extension-default": "3.10.0",
"@ohif/i18n": "3.10.0",
"@ohif/ui": "3.10.0",
"dcmjs": "*",
"dicom-parser": "^1.8.21",
"hammerjs": "^2.0.8",
@@ -42,8 +42,8 @@
},
"dependencies": {
"@babel/runtime": "^7.20.13",
"@cornerstonejs/core": "^3.8.4",
"@cornerstonejs/tools": "^3.8.4",
"@cornerstonejs/core": "^3.9.5",
"@cornerstonejs/tools": "^3.9.5",
"classnames": "^2.3.2"
}
}
@@ -263,7 +263,7 @@ const commandsModule = ({ commandsManager, servicesManager }: withAppTypes) => {
}
}
viewportGridService.setDisplaySetsForViewports(viewportsToUpdate);
commandsManager.run('setDisplaySetsForViewports', { viewportsToUpdate });
},
swapComputedWithDynamicDisplaySet: () => {
// Todo: this assumes there is only one dynamic display set in the viewer
@@ -313,7 +313,7 @@ const commandsModule = ({ commandsManager, servicesManager }: withAppTypes) => {
}
}
viewportGridService.setDisplaySetsForViewports(viewportsToUpdate);
commandsManager.run('setDisplaySetsForViewports', { viewportsToUpdate });
},
createNewLabelMapForDynamicVolume: async ({ label }) => {
const { viewports, activeViewportId } = viewportGridService.getState();
@@ -1,71 +0,0 @@
import React from 'react';
import { InputDoubleRange } from '@ohif/ui';
import { Select } from '@ohif/ui';
import { Button } from '@ohif/ui';
import PropTypes from 'prop-types';
const GenerateVolume = ({
rangeValues,
handleSliderChange,
operationsUI,
options,
handleGenerateOptionsChange,
onGenerateImage,
returnTo4D,
displayingComputedVolume,
}) => {
return (
<>
<div>
<div className="mb-2 text-white">Computed Image</div>
<Select
closeMenuOnSelect={true}
className="border-primary-main mr-2 bg-black text-white "
options={operationsUI}
placeholder={operationsUI.find(option => option.value === options.Operation).placeHolder}
value={options.Operation}
onChange={({ value }) => {
handleGenerateOptionsChange({
Operation: value,
});
}}
/>
<InputDoubleRange
values={rangeValues}
onChange={handleSliderChange}
minValue={rangeValues[0] || 1}
maxValue={rangeValues[1] || 2}
showLabel={true}
step={1}
/>
<div className="flex space-x-2">
<Button
onClick={onGenerateImage}
className="w-1/2"
>
Generate
</Button>
<Button
onClick={returnTo4D}
disabled={!displayingComputedVolume}
className="w-1/2"
>
Return To 4D
</Button>
</div>
</div>
</>
);
};
GenerateVolume.propTypes = {
rangeValues: PropTypes.array.isRequired,
handleSliderChange: PropTypes.func.isRequired,
operationsUI: PropTypes.array.isRequired,
options: PropTypes.object.isRequired,
handleGenerateOptionsChange: PropTypes.func.isRequired,
onGenerateImage: PropTypes.func.isRequired,
returnTo4D: PropTypes.func.isRequired,
};
export default GenerateVolume;
@@ -1,5 +1,5 @@
import React, { useEffect, useState, useRef } from 'react';
import { useCine } from '@ohif/ui';
import { useCine } from '@ohif/ui-next';
import { useViewportGrid } from '@ohif/ui-next';
import { utilities as csUtils, volumeLoader, eventTarget, Enums, cache } from '@cornerstonejs/core';
import { utilities as cstUtils } from '@cornerstonejs/tools';
+122
View File
@@ -3,6 +3,128 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [3.10.0](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.159...v3.10.0) (2025-04-10)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.10.0-beta.159](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.158...v3.10.0-beta.159) (2025-04-09)
### Bug Fixes
* **ui:** Enhance UI Components and Update CornerstoneJS Dependencies and resizable panels ([#4938](https://github.com/OHIF/Viewers/issues/4938)) ([43bc142](https://github.com/OHIF/Viewers/commit/43bc142439aab1a6514ba1711f86d64ac8bb1acb))
# [3.10.0-beta.158](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.157...v3.10.0-beta.158) (2025-04-09)
### Bug Fixes
* x-ray pixel spacing calibration ([#4922](https://github.com/OHIF/Viewers/issues/4922)) ([f6f60a6](https://github.com/OHIF/Viewers/commit/f6f60a63d2780cece8ade012a71b93cb3c7c4035))
# [3.10.0-beta.157](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.156...v3.10.0-beta.157) (2025-04-09)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.10.0-beta.156](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.155...v3.10.0-beta.156) (2025-04-08)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.10.0-beta.155](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.154...v3.10.0-beta.155) (2025-04-08)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.10.0-beta.154](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.153...v3.10.0-beta.154) (2025-04-08)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.10.0-beta.153](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.152...v3.10.0-beta.153) (2025-04-08)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.10.0-beta.152](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.151...v3.10.0-beta.152) (2025-04-07)
### Bug Fixes
* **segmentation:** Add segment jump for new segments and make panels scrollable ([#4928](https://github.com/OHIF/Viewers/issues/4928)) ([3653de7](https://github.com/OHIF/Viewers/commit/3653de748731199d130f02200becde78c07d3303))
# [3.10.0-beta.151](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.150...v3.10.0-beta.151) (2025-04-07)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.10.0-beta.150](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.149...v3.10.0-beta.150) (2025-04-04)
### Bug Fixes
* **cine:** Resolve Cine Player Faults on DisplaySet Update ([#4909](https://github.com/OHIF/Viewers/issues/4909)) ([746f252](https://github.com/OHIF/Viewers/commit/746f2524eb5e3ec1d36fbb35dc2cc5b55c7ba99f))
# [3.10.0-beta.149](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.148...v3.10.0-beta.149) (2025-04-04)
### Features
* **image capture:** Enhance SEG and RTSS Support with Dependency Updates and Bug Fixes ([#4924](https://github.com/OHIF/Viewers/issues/4924)) ([fc33bd0](https://github.com/OHIF/Viewers/commit/fc33bd0d594a1ac8de79b11080ead48630a8ca27))
# [3.10.0-beta.148](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.147...v3.10.0-beta.148) (2025-04-04)
### Features
* Automate tracking prompts for a less disruptive annotation workflow ([#4822](https://github.com/OHIF/Viewers/issues/4822)) ([54fded5](https://github.com/OHIF/Viewers/commit/54fded554e934f2f75e00d456ebad7692d561225))
# [3.10.0-beta.147](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.146...v3.10.0-beta.147) (2025-04-03)
**Note:** Version bump only for package @ohif/extension-cornerstone
+10 -10
View File
@@ -1,6 +1,6 @@
{
"name": "@ohif/extension-cornerstone",
"version": "3.10.0-beta.147",
"version": "3.10.0",
"description": "OHIF extension for Cornerstone",
"author": "OHIF",
"license": "MIT",
@@ -38,9 +38,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.4",
"@ohif/core": "3.10.0-beta.147",
"@ohif/ui": "3.10.0-beta.147",
"@cornerstonejs/dicom-image-loader": "^3.9.5",
"@ohif/core": "3.10.0",
"@ohif/ui": "3.10.0",
"dcmjs": "*",
"dicom-parser": "^1.8.21",
"hammerjs": "^2.0.8",
@@ -51,12 +51,12 @@
},
"dependencies": {
"@babel/runtime": "^7.20.13",
"@cornerstonejs/adapters": "^3.8.4",
"@cornerstonejs/ai": "^3.8.4",
"@cornerstonejs/core": "^3.8.4",
"@cornerstonejs/labelmap-interpolation": "^3.8.4",
"@cornerstonejs/polymorphic-segmentation": "^3.8.4",
"@cornerstonejs/tools": "^3.8.4",
"@cornerstonejs/adapters": "^3.9.5",
"@cornerstonejs/ai": "^3.9.5",
"@cornerstonejs/core": "^3.9.5",
"@cornerstonejs/labelmap-interpolation": "^3.9.5",
"@cornerstonejs/polymorphic-segmentation": "^3.9.5",
"@cornerstonejs/tools": "^3.9.5",
"@itk-wasm/morphological-contour-interpolation": "1.1.0",
"@kitware/vtk.js": "32.12.0",
"html2canvas": "^1.4.1",
@@ -3,7 +3,8 @@ import { useResizeDetector } from 'react-resize-detector';
import * as cs3DTools from '@cornerstonejs/tools';
import { Enums, eventTarget, getEnabledElement } from '@cornerstonejs/core';
import { MeasurementService } from '@ohif/core';
import { AllInOneMenu, useViewportDialog } from '@ohif/ui';
import { AllInOneMenu } from '@ohif/ui-next';
import { useViewportDialog } from '@ohif/ui-next';
import type { Types as csTypes } from '@cornerstonejs/core';
import { setEnabledElement } from '../state';
@@ -99,7 +100,7 @@ const OHIFCornerstoneViewport = React.memo(
const [viewportDialogState] = useViewportDialog();
// useCallback for scroll bar height calculation
const setImageScrollBarHeight = useCallback(() => {
const scrollbarHeight = `${elementRef.current.clientHeight - 40}px`;
const scrollbarHeight = `${elementRef.current.clientHeight - 10}px`;
setScrollbarHeight(scrollbarHeight);
}, [elementRef]);
@@ -3,7 +3,7 @@ import { vec3 } from 'gl-matrix';
import PropTypes from 'prop-types';
import { metaData, Enums, utilities } from '@cornerstonejs/core';
import type { ImageSliceData } from '@cornerstonejs/core/types';
import { ViewportOverlay } from '@ohif/ui';
import { ViewportOverlay } from '@ohif/ui-next';
import type { InstanceMetadata } from '@ohif/core/src/types';
import { formatDICOMDate, formatDICOMTime, formatNumberPrecision } from './utils';
import { utils } from '@ohif/core';
@@ -368,7 +368,7 @@ function OverlayItem(props) {
title={title}
>
{label ? <span className="mr-1 shrink-0">{label}</span> : null}
<span className="ml-1 mr-2 shrink-0">{value}</span>
<span className="ml-0 mr-2 shrink-0">{value}</span>
</div>
);
}
@@ -387,10 +387,10 @@ function VOIOverlayItem({ voi, customization }: OverlayItemProps) {
className="overlay-item flex flex-row"
style={{ color: customization?.color }}
>
<span className="mr-1 shrink-0">W:</span>
<span className="ml-1 mr-2 shrink-0">{windowWidth.toFixed(0)}</span>
<span className="mr-1 shrink-0">L:</span>
<span className="ml-1 shrink-0">{windowCenter.toFixed(0)}</span>
<span className="mr-0.5 shrink-0 opacity-[0.67]">W:</span>
<span className="mr-2.5 shrink-0">{windowWidth.toFixed(0)}</span>
<span className="mr-0.5 shrink-0 opacity-[0.67]">L:</span>
<span className="shrink-0">{windowCenter.toFixed(0)}</span>
</div>
);
}
@@ -404,7 +404,7 @@ function ZoomOverlayItem({ scale, customization }: OverlayItemProps) {
className="overlay-item flex flex-row"
style={{ color: (customization && customization.color) || undefined }}
>
<span className="mr-1 shrink-0">Zoom:</span>
<span className="mr-0.5 shrink-0 opacity-[0.67]">Zoom:</span>
<span>{scale.toFixed(2)}x</span>
</div>
);
@@ -428,7 +428,7 @@ function InstanceNumberOverlayItem({
<span>
{instanceNumber !== undefined && instanceNumber !== null ? (
<>
<span className="mr-1 shrink-0">I:</span>
<span className="mr-0.5 shrink-0 opacity-[0.67]">I:</span>
<span>{`${instanceNumber} (${imageIndex + 1}/${numberOfSlices})`}</span>
</>
) : (
@@ -1,7 +1,7 @@
import React, { useEffect } from 'react';
import PropTypes from 'prop-types';
import { Enums, VolumeViewport3D, utilities as csUtils } from '@cornerstonejs/core';
import { ImageScrollbar } from '@ohif/ui';
import { ImageScrollbar } from '@ohif/ui-next';
function CornerstoneImageScrollbar({
viewportData,
@@ -3,19 +3,18 @@
--marker-height: 100px;
--scrollbar-width: 20px;
pointer-events: none;
font-size: 15px;
line-height: 18px;
}
.ViewportOrientationMarkers .orientation-marker {
position: absolute;
}
.ViewportOrientationMarkers .top-mid {
top: 0.6rem;
top: 0.38rem;
left: 50%;
}
.ViewportOrientationMarkers .left-mid {
top: 47%;
left: 5px;
left: 0.38rem;
}
.ViewportOrientationMarkers .right-mid {
top: 47%;
@@ -119,8 +119,8 @@ function ViewportOrientationMarkers({
className={classNames(
'overlay-text',
`${m}-mid orientation-marker`,
'text-aqua-pale',
'text-[13px]',
'text-highlight/65',
'text-base',
'leading-5'
)}
key={`${m}-mid orientation-marker`}
+41 -5
View File
@@ -35,6 +35,7 @@ import { toolNames } from './initCornerstoneTools';
import CornerstoneViewportDownloadForm from './utils/CornerstoneViewportDownloadForm';
import { updateSegmentBidirectionalStats } from './utils/updateSegmentationStats';
import { generateSegmentationCSVReport } from './utils/generateSegmentationCSVReport';
import { getUpdatedViewportsForSegmentation } from './utils/hydrationUtils';
const { DefaultHistoryMemo } = csUtils.HistoryMemo;
const toggleSyncFunctions = {
@@ -495,7 +496,6 @@ function commandsModule({
downloadCSVSegmentationReport: ({ segmentationId }) => {
const segmentation = segmentationService.getSegmentation(segmentationId);
const cachedStats = segmentation.cachedStats;
const { representationData } = segmentation;
const { Labelmap } = representationData;
@@ -581,7 +581,6 @@ function commandsModule({
});
viewport.render();
},
toggleViewportColorbar: ({ viewportId, displaySetInstanceUIDs, options = {} }) => {
const hasColorbar = colorbarService.hasColorbar(viewportId);
if (hasColorbar) {
@@ -590,7 +589,6 @@ function commandsModule({
}
colorbarService.addColorbar(viewportId, displaySetInstanceUIDs, options);
},
setWindowLevel(props) {
const { toolGroupId } = props;
const { viewportId } = _getActiveViewportEnabledElement();
@@ -1021,6 +1019,10 @@ function commandsModule({
const toolGroup = toolGroupService.getToolGroupForViewport(viewportId);
if (!toolGroup.hasTool(toolName)) {
return;
}
const prevConfig = toolGroup?.getToolConfiguration(toolName);
toolGroup?.setToolConfiguration(
toolName,
@@ -1532,6 +1534,22 @@ function commandsModule({
measurementService.remove(activeAnnotationUID);
});
},
setDisplaySetsForViewports: ({ viewportsToUpdate }) => {
const { cineService, viewportGridService } = servicesManager.services;
// Stopping the cine of modified viewports before changing the viewports to
// avoid inconsistent state and lost references
viewportsToUpdate.forEach(viewport => {
const state = cineService.getState();
const currentCineState = state.cines?.[viewport.viewportId];
cineService.setCine({
id: viewport.viewportId,
frameRate: currentCineState?.frameRate ?? state.default?.frameRate ?? 24,
isPlaying: false,
});
});
viewportGridService.setDisplaySetsForViewports(viewportsToUpdate);
},
undo: () => {
DefaultHistoryMemo.undo();
},
@@ -1539,7 +1557,8 @@ function commandsModule({
DefaultHistoryMemo.redo();
},
toggleSegmentPreviewEdit: ({ toggle }) => {
const labelmapTools = getLabelmapTools({ toolGroupService });
let labelmapTools = getLabelmapTools({ toolGroupService });
labelmapTools = labelmapTools.filter(tool => !tool.toolName.includes('Eraser'));
labelmapTools.forEach(tool => {
tool.configuration = {
...tool.configuration,
@@ -1562,7 +1581,8 @@ function commandsModule({
});
},
toggleUseCenterSegmentIndex: ({ toggle }) => {
const labelmapTools = getLabelmapTools({ toolGroupService });
let labelmapTools = getLabelmapTools({ toolGroupService });
labelmapTools = labelmapTools.filter(tool => !tool.toolName.includes('Eraser'));
labelmapTools.forEach(tool => {
tool.configuration = {
...tool.configuration,
@@ -1707,6 +1727,20 @@ function commandsModule({
const activeSegmentation = segmentationService.getActiveSegmentation(activeViewportId);
segmentationService.addSegment(activeSegmentation.segmentationId);
},
loadSegmentationDisplaySetsForViewport: ({ viewportId, displaySetInstanceUIDs }) => {
const updatedViewports = getUpdatedViewportsForSegmentation({
viewportId,
servicesManager,
displaySetInstanceUIDs,
});
updatedViewports.forEach(viewport => {
viewportGridService.setDisplaySetsForViewport({
viewportId: viewport.viewportId,
displaySetInstanceUIDs: viewport.displaySetInstanceUIDs,
});
});
},
};
const definitions = {
@@ -1967,6 +2001,7 @@ function commandsModule({
deleteActiveAnnotation: {
commandFn: actions.deleteActiveAnnotation,
},
setDisplaySetsForViewports: actions.setDisplaySetsForViewports,
undo: actions.undo,
redo: actions.redo,
interpolateLabelmap: actions.interpolateLabelmap,
@@ -1985,6 +2020,7 @@ function commandsModule({
increaseBrushSize: actions.increaseBrushSize,
decreaseBrushSize: actions.decreaseBrushSize,
addNewSegment: actions.addNewSegment,
loadSegmentationDisplaySetsForViewport: actions.loadSegmentationDisplaySetsForViewport,
};
return {
@@ -179,7 +179,10 @@ function Trigger(props) {
>
<div>
{React.cloneElement(children, childProps)}
<ChevronDownIcon key="chevronDown" className="text-primary h-4 w-4 shrink-0 transition-transform duration-200" />
<ChevronDownIcon
key="chevronDown"
className="text-primary h-4 w-4 shrink-0 transition-transform duration-200"
/>
</div>
</AccordionTrigger>
);
@@ -1,5 +1,5 @@
import React, { useCallback, useEffect, useState, useRef } from 'react';
import { useCine } from '@ohif/ui';
import { useCine } from '@ohif/ui-next';
import { Enums, eventTarget, cache } from '@cornerstonejs/core';
import { useAppConfig } from '@state';
@@ -244,4 +244,4 @@ function RenderCinePlayer({
);
}
export default WrappedCinePlayer;
export default WrappedCinePlayer;
@@ -303,7 +303,7 @@ function DicomUploadProgress({
<span
className={classNames(
NO_WRAP_ELLIPSIS_CLASS_NAMES,
'text-primary-active hover:text-primary-light active:text-aqua-pale ml-auto cursor-pointer'
'text-primary hover:text-primary-light active:text-aqua-pale ml-auto cursor-pointer'
)}
onClick={cancelAllUploads}
>
@@ -89,7 +89,7 @@ const DicomUploadProgressItem = memo(
)}
<div className="ml-auto flex cursor-pointer">
<Icons.Close
className="text-primary-active self-center"
className="text-primary self-center"
onClick={cancelUpload}
/>
</div>
@@ -54,7 +54,7 @@ export const groupByNamedSets = (items, grouping) => {
};
export function MeasurementsOrAdditionalFindings(props): React.ReactNode {
const { items, children, grouping = {}, customHeader, group } = props;
const { items, children, grouping = {}, customHeader, group, actions } = props;
return (
<AccordionGroup
@@ -72,6 +72,7 @@ export function MeasurementsOrAdditionalFindings(props): React.ReactNode {
<MeasurementTableNested
customHeader={customHeader}
allItems={items}
actions={actions}
/>
</AccordionGroup.Accordion>
</AccordionGroup>
@@ -53,6 +53,10 @@ export function StudyMeasurementsActions({ items, StudyInstanceUID, measurementF
className="pl-0.5"
onClick={e => {
e.stopPropagation();
if (actions?.onDelete) {
actions.onDelete();
return;
}
commandsManager.runCommand('clearMeasurements', {
measurementFilter,
});
@@ -229,11 +229,6 @@ const ViewportWindowLevel = ({
No window level data available
</div>
)}
{isLoading && (
<div className="text-muted-foreground py-2 text-center text-sm">
Loading window level data...
</div>
)}
</PanelSection.Content>
</PanelSection>
);
@@ -1,5 +1,5 @@
import React, { ReactElement, useCallback, useEffect, useState } from 'react';
import { SwitchButton } from '@ohif/ui';
import { Switch } from '@ohif/ui-next';
import { StackViewport, VolumeViewport } from '@cornerstonejs/core';
import { ColorbarProps } from '../../types/Colorbar';
import { utilities } from '@cornerstonejs/core';
@@ -22,7 +22,7 @@ export function setViewportColorbar(
colorbarOptions.ticks = {
position: 'left',
style: {
font: '12px Arial',
font: '13px Inter',
color: '#000000',
maxNumTicks: 8,
tickSize: 5,
@@ -101,12 +101,20 @@ export function Colorbar({
}, [viewportId]);
return (
<div className="all-in-one-menu-item flex w-full justify-center">
<div className="mr-2 w-[28px]"></div>
<SwitchButton
label="Display Color bar"
<div
className="hover:bg-accent flex h-8 w-full flex-shrink-0 cursor-pointer items-center px-2 text-base hover:rounded"
onClick={e => {
e.stopPropagation();
onSetColorbar();
}}
>
<div className="flex w-7 flex-shrink-0 items-center justify-center"></div>
<span className="flex-grow">Display Color bar</span>
<Switch
className="ml-2 flex-shrink-0"
checked={showColorbar}
onChange={() => {
onClick={e => {
e.stopPropagation();
onSetColorbar();
}}
/>
@@ -1,5 +1,6 @@
import React, { ReactElement, useCallback, useEffect, useRef, useState, useMemo } from 'react';
import { AllInOneMenu, ButtonGroup, SwitchButton } from '@ohif/ui';
import React, { ReactElement, useCallback, useEffect, useRef, useState } from 'react';
import { AllInOneMenu, Switch, Tabs, TabsList, TabsTrigger } from '@ohif/ui-next';
import { StackViewport, Types } from '@cornerstonejs/core';
import { ColormapProps } from '../../types/Colormap';
@@ -64,20 +65,9 @@ export function Colormap({
return colormap;
};
const buttons = useMemo(() => {
return displaySets.map((displaySet, index) => ({
children: displaySet.Modality,
key: index,
style: {
minWidth: `calc(100% / ${displaySets.length})`,
fontSize: '0.8rem',
textAlign: 'center',
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
},
}));
}, [displaySets]);
const activeIndex = displaySets.findIndex(
ds => ds.displaySetInstanceUID === activeDisplaySetRef.current.displaySetInstanceUID
);
useEffect(() => {
setActiveDisplaySet(displaySets[displaySets.length - 1]);
@@ -85,46 +75,52 @@ export function Colormap({
return (
<>
{buttons.length > 1 && (
<div className="all-in-one-menu-item flex w-full justify-center">
<ButtonGroup
onActiveIndexChange={index => {
{displaySets.length > 1 && (
<div className="flex h-8 w-full flex-shrink-0 items-center justify-center px-2 text-base">
<Tabs
value={String(activeIndex)}
onValueChange={val => {
const index = parseInt(val, 10);
setActiveDisplaySet(displaySets[index]);
setPrePreviewColormap(null);
}}
activeIndex={
displaySets.findIndex(
ds => ds.displaySetInstanceUID === activeDisplaySetRef.current.displaySetInstanceUID
) || 1
}
className="w-[70%] text-[10px]"
>
{buttons.map(({ children, key, style }) => (
<div
key={key}
style={style}
>
{children}
</div>
))}
</ButtonGroup>
<TabsList>
{displaySets.map((ds, i) => (
<TabsTrigger
key={i}
value={String(i)}
>
{ds.Modality}
</TabsTrigger>
))}
</TabsList>
</Tabs>
</div>
)}
<div className="all-in-one-menu-item flex w-full justify-center">
<SwitchButton
label="Preview in viewport"
<div
className="hover:bg-accent flex h-8 w-full flex-shrink-0 cursor-pointer items-center px-2 text-base hover:rounded"
onClick={() => setShowPreview(!showPreview)}
>
<span className="flex-shrink-0">Preview in viewport</span>
<Switch
className="ml-auto flex-shrink-0"
checked={showPreview}
onChange={checked => {
onCheckedChange={checked => {
setShowPreview(checked);
}}
/>
</div>
<AllInOneMenu.DividerItem />
<AllInOneMenu.ItemPanel>
<AllInOneMenu.ItemPanel
maxHeight="calc(100vh - 250px)"
className="min-h-[200px] flex-grow"
>
{colormaps.map((colormap, index) => (
<AllInOneMenu.Item
key={index}
label={colormap.description}
useIconSpace={false}
onClick={() => {
onSetColorLUT({
viewportId,
@@ -1,5 +1,6 @@
import React, { ReactElement, useState, useEffect, useCallback } from 'react';
import { VolumeLightingProps } from '../../types/ViewportPresets';
import { Numeric } from '@ohif/ui-next';
export function VolumeLighting({
servicesManager,
@@ -8,135 +9,75 @@ export function VolumeLighting({
hasShade,
}: VolumeLightingProps): ReactElement {
const { cornerstoneViewportService } = servicesManager.services;
const [ambient, setAmbient] = useState(null);
const [diffuse, setDiffuse] = useState(null);
const [specular, setSpecular] = useState(null);
const [lightingValues, setLightingValues] = useState({
ambient: null,
diffuse: null,
specular: null,
});
const onAmbientChange = useCallback(() => {
commandsManager.runCommand('setVolumeLighting', { viewportId, options: { ambient } });
}, [ambient, commandsManager, viewportId]);
const onDiffuseChange = useCallback(() => {
commandsManager.runCommand('setVolumeLighting', { viewportId, options: { diffuse } });
}, [diffuse, commandsManager, viewportId]);
const onSpecularChange = useCallback(() => {
commandsManager.runCommand('setVolumeLighting', { viewportId, options: { specular } });
}, [specular, commandsManager, viewportId]);
const calculateBackground = value => {
const percentage = ((value - 0) / (1 - 0)) * 100;
return `linear-gradient(to right, #5acce6 0%, #5acce6 ${percentage}%, #3a3f99 ${percentage}%, #3a3f99 100%)`;
};
// Single callback to handle all lighting property changes
const onLightingChange = useCallback(
(property, value) => {
commandsManager.runCommand('setVolumeLighting', {
viewportId,
options: { [property]: value },
});
setLightingValues(prev => ({
...prev,
[property]: value,
}));
},
[commandsManager, viewportId]
);
useEffect(() => {
const viewport = cornerstoneViewportService.getCornerstoneViewport(viewportId);
const { actor } = viewport.getActors()[0];
const ambient = actor.getProperty().getAmbient();
const diffuse = actor.getProperty().getDiffuse();
const specular = actor.getProperty().getSpecular();
setAmbient(ambient);
setDiffuse(diffuse);
setSpecular(specular);
}, [viewportId, cornerstoneViewportService]);
const disableOption = hasShade ? '' : 'ohif-disabled !opacity-40';
const disableSlider = !hasShade;
return (
<>
<div
className={`all-in-one-menu-item flex w-full flex-row !items-center justify-between gap-[10px] ${disableOption}`}
>
<label
className="block text-white"
htmlFor="ambient"
>
Ambient
</label>
{ambient !== null && (
<input
className="bg-inputfield-main h-2 w-[120px] cursor-pointer appearance-none rounded-lg"
value={ambient}
onChange={e => {
setAmbient(e.target.value);
onAmbientChange();
}}
id="ambient"
disabled={disableSlider}
max={1}
min={0}
type="range"
step={0.1}
style={{
background: calculateBackground(ambient),
'--thumb-inner-color': '#5acce6',
'--thumb-outer-color': '#090c29',
}}
/>
)}
</div>
<div
className={`all-in-one-menu-item flex w-full flex-row !items-center justify-between gap-[10px] ${disableOption}`}
>
<label
className="block text-white"
htmlFor="diffuse"
>
Diffuse
</label>
{diffuse !== null && (
<input
className="bg-inputfield-main h-2 w-[120px] cursor-pointer appearance-none rounded-lg"
value={diffuse}
onChange={e => {
setDiffuse(e.target.value);
onDiffuseChange();
}}
disabled={disableSlider}
id="diffuse"
max={1}
min={0}
type="range"
step={0.1}
style={{
background: calculateBackground(diffuse),
'--thumb-inner-color': '#5acce6',
'--thumb-outer-color': '#090c29',
}}
/>
)}
</div>
const property = actor.getProperty();
<div
className={`all-in-one-menu-item flex w-full flex-row !items-center justify-between gap-[10px] ${disableOption}`}
>
<label
className="block text-white"
htmlFor="specular"
>
Specular
</label>
{specular !== null && (
<input
className="bg-inputfield-main h-2 w-[120px] cursor-pointer appearance-none rounded-lg"
value={specular}
disabled={disableSlider}
onChange={e => {
setSpecular(e.target.value);
onSpecularChange();
}}
id="specular"
max={1}
min={0}
type="range"
step={0.1}
style={{
background: calculateBackground(specular),
'--thumb-inner-color': '#5acce6',
'--thumb-outer-color': '#090c29',
}}
/>
)}
</div>
</>
const values = {
ambient: property.getAmbient(),
diffuse: property.getDiffuse(),
specular: property.getSpecular(),
};
setLightingValues(values);
}, [viewportId, cornerstoneViewportService]);
const disableOption = hasShade ? '' : 'ohif-disabled !opacity-40';
// Configuration for our lighting properties
const lightingProperties = [
{ key: 'ambient', label: 'Ambient' },
{ key: 'diffuse', label: 'Diffuse' },
{ key: 'specular', label: 'Specular' },
];
return (
<div className="my-1 mt-2 flex flex-col space-y-2">
{lightingProperties.map(
({ key, label }) =>
lightingValues[key] !== null && (
<div
key={key}
className={`w-full pl-2 pr-1 ${disableOption}`}
>
<Numeric.Container
mode="singleRange"
min={0}
max={1}
step={0.1}
value={lightingValues[key]}
onChange={value => onLightingChange(key, value)}
>
<div className="flex flex-row items-center">
<Numeric.Label className="w-16">{label}</Numeric.Label>
<Numeric.SingleRange sliderClassName="mx-2 flex-grow" />
</div>
</Numeric.Container>
</div>
)
)}
</div>
);
}
@@ -1,5 +1,5 @@
import React, { ReactElement, useState } from 'react';
import { AllInOneMenu } from '@ohif/ui';
import { AllInOneMenu } from '@ohif/ui-next';
import { VolumeRenderingOptionsProps } from '../../types/ViewportPresets';
import { VolumeRenderingQuality } from './VolumeRenderingQuality';
import { VolumeShift } from './VolumeShift';
@@ -26,11 +26,11 @@ export function VolumeRenderingOptions({
commandsManager={commandsManager}
servicesManager={servicesManager}
/>
<div className="all-in-one-menu-item mt-2 flex !h-[20px] w-full justify-start">
<div className="text-aqua-pale text-[13px]">LIGHTING</div>
<div className="mt-2 flex h-8 !h-[20px] w-full flex-shrink-0 items-center justify-start px-2 text-base">
<div className="text-muted-foreground text-sm">Lighting</div>
</div>
<div className="bg-primary-dark mt-1 mb-1 h-[2px] w-full"></div>
<div className="all-in-one-menu-item flex w-full justify-center">
<div className="bg-background mt-1 mb-1 h-px w-full"></div>
<div className="hover:bg-accent flex h-8 w-full flex-shrink-0 items-center px-2 text-base hover:rounded">
<VolumeShade
commandsManager={commandsManager}
servicesManager={servicesManager}
@@ -1,4 +1,4 @@
import { AllInOneMenu } from '@ohif/ui';
import { AllInOneMenu } from '@ohif/ui-next';
import { Icons } from '@ohif/ui-next';
import React, { ReactElement } from 'react';
import { VolumeRenderingPresetsProps } from '../../types/ViewportPresets';
@@ -1,5 +1,6 @@
import React, { ReactElement, useCallback, useState, useEffect } from 'react';
import { VolumeRenderingQualityProps } from '../../types/ViewportPresets';
import { Numeric } from '@ohif/ui-next';
export function VolumeRenderingQuality({
volumeRenderingQualityRange,
@@ -22,11 +23,6 @@ export function VolumeRenderingQuality({
[commandsManager, viewportId]
);
const calculateBackground = value => {
const percentage = ((value - 0) / (1 - 0)) * 100;
return `linear-gradient(to right, #5acce6 0%, #5acce6 ${percentage}%, #3a3f99 ${percentage}%, #3a3f99 100%)`;
};
useEffect(() => {
const viewport = cornerstoneViewportService.getCornerstoneViewport(viewportId);
const { actor } = viewport.getActors()[0];
@@ -41,33 +37,26 @@ export function VolumeRenderingQuality({
setQuality(Math.sqrt(averageSpacing / (sampleDistance * 0.5)));
}
}, [cornerstoneViewportService, viewportId]);
return (
<>
<div className="all-in-one-menu-item flex w-full flex-row !items-center justify-between gap-[10px]">
<label
className="block text-white"
htmlFor="volume"
>
Quality
</label>
{quality !== null && (
<input
className="bg-inputfield-main h-2 w-[120px] cursor-pointer appearance-none rounded-lg"
value={quality}
id="volume"
max={max}
<div className="my-1 mt-2 flex flex-col space-y-2">
{quality !== null && (
<div className="w-full pl-2 pr-1">
<Numeric.Container
mode="singleRange"
min={min}
type="range"
max={max}
step={step}
onChange={e => onChange(parseInt(e.target.value, 10))}
style={{
background: calculateBackground((quality - min) / (max - min)),
'--thumb-inner-color': '#5acce6',
'--thumb-outer-color': '#090c29',
}}
/>
)}
</div>
</>
value={quality}
onChange={onChange}
>
<div className="flex flex-row items-center">
<Numeric.Label className="w-16">Quality</Numeric.Label>
<Numeric.SingleRange sliderClassName="mx-2 flex-grow" />
</div>
</Numeric.Container>
</div>
)}
</div>
);
}
@@ -1,5 +1,5 @@
import React, { ReactElement, useCallback, useEffect, useState } from 'react';
import { SwitchButton } from '@ohif/ui';
import { Switch } from '@ohif/ui-next';
import { VolumeShadeProps } from '../../types/ViewportPresets';
export function VolumeShade({
@@ -28,15 +28,18 @@ export function VolumeShade({
}, [viewportId, cornerstoneViewportService]);
return (
<SwitchButton
key={key}
label="Shade"
checked={shade}
onChange={() => {
setShade(!shade);
onClickShade(!shade);
onShadeChange(!shade);
}}
/>
<>
<span className="flex-grow">Shade</span>
<Switch
className="ml-2 flex-shrink-0"
key={key}
checked={shade}
onCheckedChange={() => {
setShade(!shade);
onClickShade(!shade);
onShadeChange(!shade);
}}
/>
</>
);
}
@@ -1,5 +1,6 @@
import React, { ReactElement, useCallback, useEffect, useState, useRef } from 'react';
import { VolumeShiftProps } from '../../types/ViewportPresets';
import { Numeric } from '@ohif/ui-next';
export function VolumeShift({
viewportId,
@@ -46,48 +47,32 @@ export function VolumeShift({
viewportId,
shift: shiftDifference,
});
setShift(newShift);
},
[commandsManager, viewportId, viewport]
);
const calculateBackground = value => {
const percentage = ((value - 0) / (1 - 0)) * 100;
return `linear-gradient(to right, #5acce6 0%, #5acce6 ${percentage}%, #3a3f99 ${percentage}%, #3a3f99 100%)`;
};
return (
<>
<div className="all-in-one-menu-item flex w-full flex-row !items-center justify-between gap-[10px]">
<label
className="block text-white"
htmlFor="shift"
>
Shift
</label>
{step !== null && (
<input
className="bg-inputfield-main h-2 w-[120px] cursor-pointer appearance-none rounded-lg"
<div className="my-1 mt-2 flex flex-col space-y-2">
{step !== null && minShift !== null && maxShift !== null && (
<div className="w-full pl-2 pr-1">
<Numeric.Container
mode="singleRange"
min={minShift}
max={maxShift}
step={step}
value={shift}
onChange={e => {
const shiftValue = parseInt(e.target.value, 10);
setShift(shiftValue);
onChangeRange(shiftValue);
}}
id="shift"
onChange={onChangeRange}
onMouseDown={() => setIsBlocking(true)}
onMouseUp={() => setIsBlocking(false)}
max={maxShift}
min={minShift}
type="range"
step={step}
style={{
background: calculateBackground((shift - minShift) / (maxShift - minShift)),
'--thumb-inner-color': '#5acce6',
'--thumb-outer-color': '#090c29',
}}
/>
)}
</div>
</>
>
<div className="flex flex-row items-center">
<Numeric.Label className="w-16">Shift</Numeric.Label>
<Numeric.SingleRange sliderClassName="mx-2 flex-grow" />
</div>
</Numeric.Container>
</div>
)}
</div>
);
}
@@ -1,5 +1,5 @@
import React, { ReactElement, useCallback } from 'react';
import { AllInOneMenu } from '@ohif/ui';
import { AllInOneMenu } from '@ohif/ui-next';
import { WindowLevelPreset } from '../../types/WindowLevel';
import { CommandsManager } from '@ohif/core';
import { useTranslation } from 'react-i18next';
@@ -45,6 +45,7 @@ export function WindowLevel({
key={`${modality}-${index}`}
label={preset.description}
secondaryLabel={`${preset.window} / ${preset.level}`}
useIconSpace={false}
onClick={() => onSetWindowLevel(preset)}
/>
))}
@@ -1,7 +1,7 @@
import React, { ReactElement, useCallback, useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';
import classNames from 'classnames';
import { AllInOneMenu } from '@ohif/ui';
import { AllInOneMenu } from '@ohif/ui-next';
import { useViewportGrid } from '@ohif/ui-next';
import { Colormap } from './Colormap';
import { Colorbar } from './Colorbar';
@@ -119,8 +119,8 @@ export function WindowLevelActionMenu({
iconClassName={classNames(
// Visible on hover and for the active viewport
activeViewportId === viewportId ? 'visible' : 'invisible group-hover/pane:visible',
'flex shrink-0 cursor-pointer rounded active:text-white text-primary-light',
isLight ? ' hover:bg-secondary-dark' : 'hover:bg-secondary-light/60'
'flex shrink-0 cursor-pointer rounded active:text-foreground text-highlight',
isLight ? ' hover:bg-primary/30' : 'hover:bg-primary/30'
)}
menuStyle={{ maxHeight: vpHeight - 32, minWidth: 218 }}
onVisibilityChange={() => {
@@ -144,8 +144,10 @@ export function WindowLevelActionMenu({
key="colorLUTPresets"
itemLabel="Color LUT"
itemIcon="icon-color-lut"
className="flex h-[calc(100%-32px)] flex-col"
>
<Colormap
className="flex h-full w-full flex-col"
colormaps={colormaps}
viewportId={viewportId}
displaySets={displaySets.filter(ds => !nonWLModalities.includes(ds.Modality))}
@@ -8,7 +8,7 @@ import React, {
} from 'react';
import PropTypes from 'prop-types';
import { Types, ViewportActionCornersLocations } from '@ohif/ui';
import { Types, ViewportActionCornersLocations } from '@ohif/ui-next';
import ViewportActionCornersService, {
ActionComponentInfo,
} from '../services/ViewportActionCornersService/ViewportActionCornersService';
@@ -1,4 +1,4 @@
import { CinePlayer } from '@ohif/ui';
import { CinePlayer } from '@ohif/ui-next';
import DicomUpload from '../components/DicomUpload/DicomUpload';
export default {
@@ -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
@@ -67,7 +68,7 @@ export default function getSegmentationPanelCustomization({ commandsManager, ser
checked={useCenterAsSegmentIndex}
onCheckedChange={handleUseCenterAsSegmentIndexChange}
/>
<span className="text-base text-white">Use Center as Segment Index</span>
<span className="text-base text-white">Use center as segment index</span>
</div>
<div className="flex items-center gap-2">
+11 -2
View File
@@ -82,6 +82,7 @@ const stackRetrieveOptions = {
},
};
const unsubscriptions = [];
/**
*
*/
@@ -142,6 +143,8 @@ const cornerstoneExtension: Types.Extensions.Extension = {
useToggleOneUpViewportGridStore.getState().clearToggleOneUpViewportGridStore();
useSegmentationPresentationStore.getState().clearSegmentationPresentationStore();
segmentationService.removeAllSegmentations();
unsubscriptions.forEach(unsubscribe => unsubscribe());
},
/**
@@ -149,7 +152,7 @@ const cornerstoneExtension: Types.Extensions.Extension = {
*
* @param configuration.csToolsConfig - Passed directly to `initCornerstoneTools`
*/
preRegistration: function (props: Types.Extensions.ExtensionParams): Promise<void> {
preRegistration: async function (props: Types.Extensions.ExtensionParams): Promise<void> {
const { servicesManager, serviceProvidersManager } = props;
servicesManager.registerService(CornerstoneViewportService.REGISTRATION);
servicesManager.registerService(ToolGroupService.REGISTRATION);
@@ -167,7 +170,13 @@ const cornerstoneExtension: Types.Extensions.Extension = {
const { syncGroupService } = servicesManager.services;
syncGroupService.registerCustomSynchronizer('frameview', createFrameViewSynchronizer);
return init.call(this, props);
const initResult = await init.call(this, props);
unsubscriptions.push(...initResult.unsubscriptions);
return {
...initResult,
};
},
getToolbarModule,
getHangingProtocolModule,
+14 -6
View File
@@ -193,13 +193,14 @@ export default async function init({
});
// Setup segmentation event handlers
setupSegmentationDataModifiedHandler({
segmentationService,
customizationService,
commandsManager,
});
const { unsubscribe: unsubscribeSegmentationDataModifiedHandler } =
setupSegmentationDataModifiedHandler({
segmentationService,
customizationService,
commandsManager,
});
setupSegmentationModifiedHandler({
const { unsubscribe: unsubscribeSegmentationModifiedHandler } = setupSegmentationModifiedHandler({
segmentationService,
});
@@ -299,6 +300,13 @@ export default async function init({
// Call this function when initializing
initializeWebWorkerProgressHandler(servicesManager.services.uiNotificationService);
const unsubscriptions = [
unsubscribeSegmentationDataModifiedHandler,
unsubscribeSegmentationModifiedHandler,
];
return { unsubscriptions };
}
function initializeWebWorkerProgressHandler(uiNotificationService) {
@@ -7,7 +7,11 @@ import { toolNames } from './initCornerstoneTools';
import { onCompletedCalibrationLine } from './tools/CalibrationLineTool';
import measurementServiceMappingsFactory from './utils/measurementServiceMappings/measurementServiceMappingsFactory';
import getSOPInstanceAttributes from './utils/measurementServiceMappings/utils/getSOPInstanceAttributes';
import { triggerAnnotationRenderForViewportIds } from '@cornerstonejs/tools/utilities';
import {
setAnnotationLabel,
triggerAnnotationRenderForViewportIds,
} from '@cornerstonejs/tools/utilities';
import getActiveViewportEnabledElement from './utils/getActiveViewportEnabledElement';
const { CORNERSTONE_3D_TOOLS_SOURCE_NAME, CORNERSTONE_3D_TOOLS_SOURCE_VERSION } = CSExtensionEnums;
const { removeAnnotation } = annotation.state;
@@ -190,6 +194,7 @@ const connectToolsToMeasurementService = (servicesManager: AppTypes.ServicesMana
displaySetService,
cornerstoneViewportService,
customizationService,
viewportGridService,
} = servicesManager.services;
const csTools3DVer1MeasurementSource = initMeasurementService(
measurementService,
@@ -197,7 +202,11 @@ const connectToolsToMeasurementService = (servicesManager: AppTypes.ServicesMana
cornerstoneViewportService,
customizationService
);
connectMeasurementServiceToTools(measurementService, cornerstoneViewportService);
connectMeasurementServiceToTools(
measurementService,
cornerstoneViewportService,
viewportGridService
);
const { annotationToMeasurement, remove } = csTools3DVer1MeasurementSource;
//
@@ -323,7 +332,11 @@ const connectToolsToMeasurementService = (servicesManager: AppTypes.ServicesMana
return csTools3DVer1MeasurementSource;
};
const connectMeasurementServiceToTools = (measurementService, cornerstoneViewportService) => {
const connectMeasurementServiceToTools = (
measurementService,
cornerstoneViewportService,
viewportGridService
) => {
const { MEASUREMENT_REMOVED, MEASUREMENTS_CLEARED, MEASUREMENT_UPDATED, RAW_MEASUREMENT_ADDED } =
measurementService.EVENTS;
@@ -347,6 +360,10 @@ const connectMeasurementServiceToTools = (measurementService, cornerstoneViewpor
measurementService.subscribe(
MEASUREMENT_UPDATED,
({ source, measurement, notYetUpdatedAtSource }) => {
if (!source) {
return;
}
if (source.name !== CORNERSTONE_3D_TOOLS_SOURCE_NAME) {
return;
}
@@ -366,7 +383,8 @@ const connectMeasurementServiceToTools = (measurementService, cornerstoneViewpor
}
if (data.label !== label) {
data.label = label;
const element = getActiveViewportEnabledElement(viewportGridService)?.viewport.element;
setAnnotationLabel(sourceAnnotation, element, label);
}
if (metadata.toolName === 'ArrowAnnotate') {
@@ -2,12 +2,10 @@ import React from 'react';
import { SegmentationTable } from '@ohif/ui-next';
import { useActiveViewportSegmentationRepresentations } from '../hooks/useActiveViewportSegmentationRepresentations';
import { metaData } from '@cornerstonejs/core';
import { useSystem } from '@ohif/core/src';
export default function PanelSegmentation({
servicesManager,
commandsManager,
children,
}: withAppTypes) {
export default function PanelSegmentation({ children }: withAppTypes) {
const { commandsManager, servicesManager } = useSystem();
const { customizationService, displaySetService } = servicesManager.services;
const { segmentationsWithRepresentations, disabled } =
@@ -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;
@@ -427,6 +432,8 @@ class SegmentationService extends PubSubService {
...metaData.get('instance', image.referencedImageId),
}));
segDisplaySet.imageIds = derivedImageIds;
// We should parse the segmentation as separate slices to support overlapping segments.
// This parsing should occur in the CornerstoneJS library adapters.
// For now, we use the volume returned from the library and chop it here.
@@ -513,7 +520,7 @@ class SegmentationService extends PubSubService {
type: LABELMAP,
data: {
imageIds: derivedImageIds,
referencedVolumeId: this._getVolumeIdForDisplaySet(referencedDisplaySet),
// referencedVolumeId: this._getVolumeIdForDisplaySet(referencedDisplaySet),
referencedImageIds: imageIds as string[],
},
},
@@ -566,9 +573,10 @@ class SegmentationService extends PubSubService {
const referencedImageIds = referencedDisplaySet.imageIds;
// find the first image id that contains a referenced SOP instance UID
const firstSegmentedSliceImageId = referencedImageIds.find(imageId =>
referencedImageIdsWithGeometry.some(referencedId => imageId.includes(referencedId))
);
const firstSegmentedSliceImageId =
referencedImageIds?.find(imageId =>
referencedImageIdsWithGeometry.some(referencedId => imageId.includes(referencedId))
) || null;
rtDisplaySet.firstSegmentedSliceImageId = firstSegmentedSliceImageId;
// Map ROI contours to RT Struct Data
@@ -1248,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;
}
@@ -1763,6 +1772,12 @@ class SegmentationService extends PubSubService {
const { center } = cachedStats;
if (!center) {
return {
world: cachedStats.namedStats.center.value,
};
}
return center;
}
@@ -1,5 +1,5 @@
import { PubSubService } from '@ohif/core';
import { ViewportActionCornersLocations } from '@ohif/ui';
import { ViewportActionCornersLocations } from '@ohif/ui-next';
import { ReactNode } from 'react';
export type ActionComponentInfo = {
@@ -742,6 +742,7 @@ class CornerstoneViewportService extends PubSubService implements IViewportServi
// If you call loadStudyMetadata and it's not in the DicomMetadataStore cache, it should fire
// a request through the data source?
// (This call may or may not create sub-requests for series metadata)
const { displaySetService } = this.servicesManager.services;
const volumeInputArray = [];
const displaySetOptionsArray = viewportInfo.getDisplaySetOptions();
const { hangingProtocolService } = this.servicesManager.services;
@@ -750,7 +751,13 @@ class CornerstoneViewportService extends PubSubService implements IViewportServi
const displaySetInstanceUIDs = [];
for (const [index, data] of viewportData.data.entries()) {
const { volume, imageIds, displaySetInstanceUID } = data;
const { imageIds, displaySetInstanceUID } = data;
let volume = data.volume;
if (!volume) {
const displaySet = displaySetService.getDisplaySetByUID(displaySetInstanceUID);
volume = csToolsUtils.getOrCreateImageVolume(displaySet.images.map(image => image.imageId));
}
displaySetInstanceUIDs.push(displaySetInstanceUID);
@@ -1,7 +1,7 @@
import React, { useEffect, useState } from 'react';
import html2canvas from 'html2canvas';
import { getEnabledElement, StackViewport, BaseVolumeViewport } from '@cornerstonejs/core';
import { ToolGroupManager } from '@cornerstonejs/tools';
import { ToolGroupManager, segmentation, Enums } from '@cornerstonejs/tools';
import { getEnabledElement as OHIFgetEnabledElement } from '../state';
import { useSystem } from '@ohif/core/src';
@@ -103,6 +103,9 @@ const CornerstoneViewportDownloadForm = ({
return;
}
const segmentationRepresentations =
segmentation.state.getViewportSegmentationRepresentations(activeViewportId);
const { viewport } = activeViewportEnabledElement;
const downloadViewport = renderingEngine.getViewport(VIEWPORT_ID);
@@ -113,20 +116,48 @@ const CornerstoneViewportDownloadForm = ({
await downloadViewport.setStack([imageId]);
downloadViewport.setProperties(properties);
return {
width: Math.min(width || DEFAULT_SIZE, MAX_TEXTURE_SIZE),
height: Math.min(height || DEFAULT_SIZE, MAX_TEXTURE_SIZE),
};
} else if (downloadViewport instanceof BaseVolumeViewport) {
const volumeIds = viewport.getAllVolumeIds();
downloadViewport.setVolumes([{ volumeId: volumeIds[0] }]);
return {
width: Math.min(width || DEFAULT_SIZE, MAX_TEXTURE_SIZE),
height: Math.min(height || DEFAULT_SIZE, MAX_TEXTURE_SIZE),
};
}
if (segmentationRepresentations.length > 0) {
segmentationRepresentations.forEach(segRepresentation => {
const { segmentationId, colorLUTIndex, type } = segRepresentation;
if (type === Enums.SegmentationRepresentations.Labelmap) {
segmentation.addLabelmapRepresentationToViewportMap({
[downloadViewport.id]: [
{
segmentationId,
type: Enums.SegmentationRepresentations.Labelmap,
config: {
colorLUTOrIndex: colorLUTIndex,
},
},
],
});
}
if (type === Enums.SegmentationRepresentations.Contour) {
segmentation.addContourRepresentationToViewportMap({
[downloadViewport.id]: [
{
segmentationId,
type: Enums.SegmentationRepresentations.Contour,
config: {
colorLUTOrIndex: colorLUTIndex,
},
},
],
});
}
});
}
return {
width: Math.min(width || DEFAULT_SIZE, MAX_TEXTURE_SIZE),
height: Math.min(height || DEFAULT_SIZE, MAX_TEXTURE_SIZE),
};
} catch (error) {
console.error('Error loading image:', error);
}
@@ -167,6 +198,10 @@ const CornerstoneViewportDownloadForm = ({
setTimeout(() => {
handleLoadImage(viewportDimensions.width, viewportDimensions.height);
handleToggleAnnotations(showAnnotations);
// we need a resize here to make suer annotations world to canvas
// are properly calculated
renderingEngine.resize();
renderingEngine.render();
}, 100);
}
}, [viewportDimensions, showAnnotations]);
@@ -0,0 +1,31 @@
function getUpdatedViewportsForSegmentation({
viewportId,
servicesManager,
displaySetInstanceUIDs,
}: withAppTypes) {
const { hangingProtocolService, viewportGridService } = servicesManager.services;
const { isHangingProtocolLayout } = viewportGridService.getState();
const viewport = getTargetViewport({ viewportId, viewportGridService });
const targetViewportId = viewport.viewportOptions.viewportId;
const updatedViewports = hangingProtocolService.getViewportsRequireUpdate(
targetViewportId,
displaySetInstanceUIDs[0],
isHangingProtocolLayout
);
return updatedViewports.filter(v => v.viewportOptions?.viewportType !== 'volume3d');
}
const getTargetViewport = ({ viewportId, viewportGridService }) => {
const { viewports, activeViewportId } = viewportGridService.getState();
const targetViewportId = viewportId || activeViewportId;
const viewport = viewports.get(targetViewportId);
return viewport;
};
export { getUpdatedViewportsForSegmentation };
@@ -9,10 +9,15 @@ export function setupSegmentationDataModifiedHandler({
customizationService,
commandsManager,
}) {
segmentationService.subscribeDebounced(
const { unsubscribe } = segmentationService.subscribeDebounced(
segmentationService.EVENTS.SEGMENTATION_DATA_MODIFIED,
async ({ segmentationId }) => {
const segmentation = segmentationService.getSegmentation(segmentationId);
if (!segmentation) {
return;
}
const readableText = customizationService.getCustomization('panelSegmentation.readableText');
// Check for segments with bidirectional measurements and update them
@@ -46,17 +51,23 @@ export function setupSegmentationDataModifiedHandler({
},
1000
);
return { unsubscribe };
}
/**
* Sets up the handler for segmentation modification events
*/
export function setupSegmentationModifiedHandler({ segmentationService }) {
segmentationService.subscribe(
const { unsubscribe } = segmentationService.subscribe(
segmentationService.EVENTS.SEGMENTATION_MODIFIED,
async ({ segmentationId }) => {
const segmentation = segmentationService.getSegmentation(segmentationId);
if (!segmentation) {
return;
}
const annotationState = cornerstoneTools.annotation.state.getAllAnnotations();
const bidirectionalAnnotations = annotationState.filter(
annotation =>
@@ -90,4 +101,6 @@ export function setupSegmentationModifiedHandler({ segmentationService }) {
});
}
);
return { unsubscribe };
}
+122
View File
@@ -3,6 +3,128 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [3.10.0](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.159...v3.10.0) (2025-04-10)
**Note:** Version bump only for package @ohif/extension-default
# [3.10.0-beta.159](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.158...v3.10.0-beta.159) (2025-04-09)
### Bug Fixes
* **ui:** Enhance UI Components and Update CornerstoneJS Dependencies and resizable panels ([#4938](https://github.com/OHIF/Viewers/issues/4938)) ([43bc142](https://github.com/OHIF/Viewers/commit/43bc142439aab1a6514ba1711f86d64ac8bb1acb))
# [3.10.0-beta.158](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.157...v3.10.0-beta.158) (2025-04-09)
**Note:** Version bump only for package @ohif/extension-default
# [3.10.0-beta.157](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.156...v3.10.0-beta.157) (2025-04-09)
**Note:** Version bump only for package @ohif/extension-default
# [3.10.0-beta.156](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.155...v3.10.0-beta.156) (2025-04-08)
**Note:** Version bump only for package @ohif/extension-default
# [3.10.0-beta.155](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.154...v3.10.0-beta.155) (2025-04-08)
**Note:** Version bump only for package @ohif/extension-default
# [3.10.0-beta.154](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.153...v3.10.0-beta.154) (2025-04-08)
**Note:** Version bump only for package @ohif/extension-default
# [3.10.0-beta.153](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.152...v3.10.0-beta.153) (2025-04-08)
**Note:** Version bump only for package @ohif/extension-default
# [3.10.0-beta.152](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.151...v3.10.0-beta.152) (2025-04-07)
### Bug Fixes
* **segmentation:** Add segment jump for new segments and make panels scrollable ([#4928](https://github.com/OHIF/Viewers/issues/4928)) ([3653de7](https://github.com/OHIF/Viewers/commit/3653de748731199d130f02200becde78c07d3303))
# [3.10.0-beta.151](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.150...v3.10.0-beta.151) (2025-04-07)
### Features
* allow saving to same SR series ([#4889](https://github.com/OHIF/Viewers/issues/4889)) ([62e5a62](https://github.com/OHIF/Viewers/commit/62e5a6206606ba7a16a56cf47456e52f892372da))
# [3.10.0-beta.150](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.149...v3.10.0-beta.150) (2025-04-04)
### Bug Fixes
* **cine:** Resolve Cine Player Faults on DisplaySet Update ([#4909](https://github.com/OHIF/Viewers/issues/4909)) ([746f252](https://github.com/OHIF/Viewers/commit/746f2524eb5e3ec1d36fbb35dc2cc5b55c7ba99f))
# [3.10.0-beta.149](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.148...v3.10.0-beta.149) (2025-04-04)
### Features
* **image capture:** Enhance SEG and RTSS Support with Dependency Updates and Bug Fixes ([#4924](https://github.com/OHIF/Viewers/issues/4924)) ([fc33bd0](https://github.com/OHIF/Viewers/commit/fc33bd0d594a1ac8de79b11080ead48630a8ca27))
# [3.10.0-beta.148](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.147...v3.10.0-beta.148) (2025-04-04)
### Features
* Automate tracking prompts for a less disruptive annotation workflow ([#4822](https://github.com/OHIF/Viewers/issues/4822)) ([54fded5](https://github.com/OHIF/Viewers/commit/54fded554e934f2f75e00d456ebad7692d561225))
# [3.10.0-beta.147](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.146...v3.10.0-beta.147) (2025-04-03)
**Note:** Version bump only for package @ohif/extension-default
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@ohif/extension-default",
"version": "3.10.0-beta.147",
"version": "3.10.0",
"description": "Common/default features and functionality for basic image viewing",
"author": "OHIF Core Team",
"license": "MIT",
@@ -32,8 +32,8 @@
"start": "yarn run dev"
},
"peerDependencies": {
"@ohif/core": "3.10.0-beta.147",
"@ohif/i18n": "3.10.0-beta.147",
"@ohif/core": "3.10.0",
"@ohif/i18n": "3.10.0",
"dcmjs": "*",
"dicomweb-client": "^0.10.4",
"prop-types": "^15.6.2",
@@ -1,4 +1,3 @@
import React from 'react';
import { DicomMetadataStore } from '@ohif/core';
/**
@@ -113,7 +113,7 @@ function DataSourceConfigurationModalComponent({
: 'border border-dashed border-secondary-light';
const getSelectedItemTextClasses = itemIndex =>
itemIndex <= selectedItems.length ? 'text-primary-light' : 'text-primary-active';
itemIndex <= selectedItems.length ? 'text-primary-light' : 'text-primary';
const getErrorComponent = (): ReactElement => {
return (
@@ -1,5 +1,5 @@
import React from 'react';
import { LineChart } from '@ohif/ui';
import { LineChart } from '@ohif/ui-next';
const LineChartViewport = ({ displaySets }) => {
const displaySet = displaySets[0];
@@ -1,5 +1,5 @@
import React, { useEffect, useState, useCallback, ReactElement } from 'react';
import { ProgressDropdown } from '@ohif/ui';
import { ProgressDropdown } from '@ohif/ui-next';
const workflowStepsToDropdownOptions = (steps = []) =>
steps.map(step => ({
@@ -1,4 +1,4 @@
import { Types } from '@ohif/ui';
import { Types } from '@ohif/ui-next';
import { Menu, SelectorProps, MenuItem, ContextMenuProps } from './types';
type ContextMenuItem = Types.ContextMenuItem;
@@ -153,7 +153,7 @@ const DicomTagBrowser = ({
</Select>
</div>
{shouldShowInstanceList && (
<div className="mx-auto flex w-1/5 flex-col">
<div className="mx-auto mt-0.5 flex w-1/4 flex-col">
<span className="text-muted-foreground flex h-6 items-center text-xs">
Instance Number ({instanceNumber} of {activeDisplaySet?.images?.length})
</span>
@@ -169,7 +169,7 @@ const DicomTagBrowser = ({
/>
</div>
)}
<div className="ml-auto flex w-1/3 flex-col">
<div className="ml-auto mr-1 flex w-1/3 flex-col">
<span className="text-muted-foreground flex h-6 items-center text-xs">
Search metadata
</span>
@@ -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 { useImageViewer } 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';
@@ -34,8 +32,9 @@ function PanelStudyBrowser({
dataSource,
customMapDisplaySets,
onClickUntrack,
onDoubleClickThumbnailHandlerCallBack,
}) {
const { servicesManager, commandsManager } = useSystem();
const { servicesManager, commandsManager, extensionManager } = useSystem();
const { displaySetService, customizationService } = servicesManager.services;
const navigate = useNavigate();
const studyMode = customizationService.getCustomization('studyBrowser.studyMode') || 'all';
@@ -93,6 +92,7 @@ function PanelStudyBrowser({
commandsManager,
servicesManager,
isHangingProtocolLayout,
appConfig: extensionManager._appConfig,
};
const handlers = customHandler?.callbacks.map(callback => callback(setupArgs));
@@ -100,6 +100,7 @@ function PanelStudyBrowser({
for (const handler of handlers) {
await handler(displaySetInstanceUID);
}
onDoubleClickThumbnailHandlerCallBack?.(displaySetInstanceUID);
},
[
activeViewportId,
@@ -20,7 +20,7 @@ function PanelStudyBrowserHeader({
<div className={'flex h-[24px] w-full select-none justify-center self-center text-[14px]'}>
<div className="flex w-full items-center gap-[10px]">
<div className="flex items-center justify-center">
<div className="text-primary-active flex items-center space-x-1">
<div className="text-primary flex items-center space-x-1">
{actionIcons.map((icon: actionIcon, index) =>
React.createElement(Icons[icon.iconName] || Icons.MissingIcon, {
key: index,
@@ -7,6 +7,7 @@ export default function CreateReportDialogPrompt({
}): Promise<{
value: string;
dataSourceName: string;
series: string;
action: (typeof PROMPT_RESPONSES)[keyof typeof PROMPT_RESPONSES];
}> {
const { uiDialogService, customizationService } = servicesManager.services;
@@ -22,10 +23,11 @@ export default function CreateReportDialogPrompt({
content: ReportDialog,
contentProps: {
dataSources: allowMultipleDataSources ? dataSources : undefined,
onSave: async ({ reportName, dataSource: selectedDataSource }) => {
onSave: async ({ reportName, dataSource: selectedDataSource, series }) => {
resolve({
value: reportName,
dataSourceName: selectedDataSource,
series,
action: PROMPT_RESPONSES.CREATE_REPORT,
});
},
@@ -33,6 +35,7 @@ export default function CreateReportDialogPrompt({
resolve({
action: PROMPT_RESPONSES.CANCEL,
value: undefined,
series: undefined,
dataSourceName: undefined,
});
},
@@ -1,87 +0,0 @@
import React, { useEffect, useState, useCallback } from 'react';
import PropTypes from 'prop-types';
import { LayoutSelector as OHIFLayoutSelector, ToolbarButton } from '@ohif/ui';
function LegacyLayoutSelectorWithServices({
servicesManager,
rows = 3,
columns = 3,
onLayoutChange = () => {},
...props
}) {
const { toolbarService } = servicesManager.services;
const onSelection = useCallback(
props => {
toolbarService.recordInteraction({
interactionType: 'action',
commands: [
{
commandName: 'setViewportGridLayout',
commandOptions: { ...props },
context: 'DEFAULT',
},
],
});
},
[toolbarService]
);
return (
<LayoutSelector
{...props}
onSelection={onSelection}
/>
);
}
function LayoutSelector({ rows, columns, className, onSelection, ...rest }) {
const [isOpen, setIsOpen] = useState(false);
const closeOnOutsideClick = () => {
if (isOpen) {
setIsOpen(false);
}
};
useEffect(() => {
window.addEventListener('click', closeOnOutsideClick);
return () => {
window.removeEventListener('click', closeOnOutsideClick);
};
}, [isOpen]);
const onInteractionHandler = () => setIsOpen(!isOpen);
const DropdownContent = isOpen ? OHIFLayoutSelector : null;
return (
<ToolbarButton
id="Layout"
label="Grid Layout"
icon="tool-layout"
onInteraction={onInteractionHandler}
className={className}
rounded={rest.rounded}
dropdownContent={
DropdownContent !== null && (
<DropdownContent
rows={rows}
columns={columns}
onSelection={onSelection}
/>
)
}
isActive={isOpen}
type="toggle"
/>
);
}
LayoutSelector.propTypes = {
rows: PropTypes.number,
columns: PropTypes.number,
onLayoutChange: PropTypes.func,
servicesManager: PropTypes.object.isRequired,
};
export default LegacyLayoutSelectorWithServices;
@@ -44,9 +44,9 @@ function HeaderPatientInfo({ servicesManager, appConfig }: withAppTypes) {
onClick={handleOnClick}
>
{isMixedPatients ? (
<Icons.MultiplePatients className="text-primary-active" />
<Icons.MultiplePatients className="text-primary" />
) : (
<Icons.Patient className="text-primary-active" />
<Icons.Patient className="text-primary" />
)}
<div className="flex flex-col justify-center">
{expanded ? (
@@ -61,12 +61,12 @@ function HeaderPatientInfo({ servicesManager, appConfig }: withAppTypes) {
</div>
</>
) : (
<div className="text-primary-active self-center text-[13px]">
<div className="text-primary self-center text-[13px]">
{isMixedPatients ? 'Multiple Patients' : 'Patient'}
</div>
)}
</div>
<Icons.ArrowLeft className={`text-primary-active ${expanded ? 'rotate-180' : ''}`} />
<Icons.ArrowLeft className={`text-primary ${expanded ? 'rotate-180' : ''}`} />
</div>
);
}
@@ -28,7 +28,9 @@ const useResizablePanels = (
leftPanelClosed,
setLeftPanelClosed,
rightPanelClosed,
setRightPanelClosed
setRightPanelClosed,
hasLeftPanels,
hasRightPanels
) => {
const [leftPanelExpandedWidth, setLeftPanelExpandedWidth] = useState(
panelGroupDefinition.left.initialExpandedWidth
@@ -156,6 +158,8 @@ const useResizablePanels = (
rightPanelExpandedWidth,
leftResizablePanelMinimumSize,
rightResizablePanelMinimumSize,
hasLeftPanels,
hasRightPanels,
]);
/**
@@ -95,7 +95,7 @@ function ViewerHeader({ appConfig }: withAppTypes<{ appConfig: AppTypes.Config }
)
}
UndoRedo={
<div className="text-primary-active flex cursor-pointer items-center">
<div className="text-primary flex cursor-pointer items-center">
<Button
variant="ghost"
className="hover:bg-primary-dark"
@@ -4,7 +4,7 @@ const collapsedOutsideBorderSize = 4;
const collapsedWidth = 25;
const rightPanelInitialExpandedWidth = 280;
const leftPanelInitialExpandedWidth = 282;
const leftPanelInitialExpandedWidth = 292;
const panelGroupDefinition = {
groupId: 'viewerLayoutResizablePanelGroup',
@@ -1,7 +1,7 @@
import React, { useEffect, useState, useCallback, useRef } from 'react';
import React, { useEffect, useState, useCallback } from 'react';
import PropTypes from 'prop-types';
import { InvestigationalUseDialog } from '@ohif/ui';
import { InvestigationalUseDialog } from '@ohif/ui-next';
import { HangingProtocolService, CommandsManager } from '@ohif/core';
import { useAppConfig } from '@state';
import ViewerHeader from './ViewerHeader';
@@ -52,7 +52,9 @@ function ViewerLayout({
leftPanelClosed,
setLeftPanelClosed,
rightPanelClosed,
setRightPanelClosed
setRightPanelClosed,
hasLeftPanels,
hasRightPanels
);
const handleMouseEnter = () => {
+1 -1
View File
@@ -622,7 +622,7 @@ const commandsModule = ({
});
}
viewportGridService.setDisplaySetsForViewports(updatedViewports);
commandsManager.run('setDisplaySetsForViewports', { viewportsToUpdate: updatedViewports });
setTimeout(() => actions.scrollActiveThumbnailIntoView(), 0);
},
@@ -1,4 +1,4 @@
import { LabellingFlow } from '@ohif/ui';
import { LabellingFlow } from '@ohif/ui-next';
export default {
'ui.labellingComponent': LabellingFlow,
@@ -1,4 +1,4 @@
import { LoadingIndicatorProgress } from '@ohif/ui';
import { LoadingIndicatorProgress } from '@ohif/ui-next';
export default {
'ui.loadingIndicatorProgress': LoadingIndicatorProgress,
@@ -1,4 +1,4 @@
import { LoadingIndicatorTotalPercent } from '@ohif/ui';
import { LoadingIndicatorTotalPercent } from '@ohif/ui-next';
export default {
'ui.loadingIndicatorTotalPercent': LoadingIndicatorTotalPercent,
@@ -1,5 +1,29 @@
import { Notification } from '@ohif/ui';
import i18n from '@ohif/i18n';
import { ViewportDialog } from '@ohif/ui-next';
const beginTrackingMessage = i18n.t('MeasurementTable:Track measurements for this series?');
const trackNewSeriesMessage = i18n.t('Do you want to add this measurement to the existing report?');
const discardSeriesMessage = i18n.t(
'You have existing tracked measurements. What would you like to do with your existing tracked measurements?'
);
const trackNewStudyMessage = i18n.t('MeasurementTable:Track measurements for this series?');
const discardStudyMessage = i18n.t(
'Measurements cannot span across multiple studies. Do you want to save your tracked measurements?'
);
const hydrateSRMessage = i18n.t('Do you want to continue tracking measurements for this study?');
const hydrateRTMessage = i18n.t('Do you want to open this Segmentation?');
const hydrateSEGMessage = i18n.t('Do you want to open this Segmentation?');
const discardDirtyMessage = i18n.t('There are unsaved measurements. Do you want to save it?');
export default {
'ui.notificationComponent': Notification,
'ui.notificationComponent': ViewportDialog,
'viewportNotification.beginTrackingMessage': beginTrackingMessage,
'viewportNotification.trackNewSeriesMessage': trackNewSeriesMessage,
'viewportNotification.discardSeriesMessage': discardSeriesMessage,
'viewportNotification.trackNewStudyMessage': trackNewStudyMessage,
'viewportNotification.discardStudyMessage': discardStudyMessage,
'viewportNotification.hydrateSRMessage': hydrateSRMessage,
'viewportNotification.hydrateRTMessage': hydrateRTMessage,
'viewportNotification.hydrateSEGMessage': hydrateSEGMessage,
'viewportNotification.discardDirtyMessage': discardDirtyMessage,
};
@@ -1,4 +1,4 @@
import { ProgressLoadingBar } from '@ohif/ui';
import { ProgressLoadingBar } from '@ohif/ui-next';
export default {
'ui.progressLoadingBar': ProgressLoadingBar,
@@ -1,6 +1,7 @@
import React, { useState } from 'react';
import { InputDialog } from '@ohif/ui-next';
import React, { useEffect, useMemo, useState } from 'react';
import { InputDialog, cn } from '@ohif/ui-next';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@ohif/ui-next';
import { useSystem } from '@ohif/core';
type DataSource = {
value: string;
@@ -11,21 +12,53 @@ type DataSource = {
type ReportDialogProps = {
dataSources: DataSource[];
hide: () => void;
onSave: (data: { reportName: string; dataSource: string | null }) => void;
onSave: (data: { reportName: string; dataSource: string | null; series: string | null }) => void;
onCancel: () => void;
};
function ReportDialog({ dataSources, hide, onSave, onCancel }: ReportDialogProps) {
const { servicesManager } = useSystem();
const [selectedDataSource, setSelectedDataSource] = useState<string | null>(
dataSources?.[0]?.value ?? null
);
const [selectedSeries, setSelectedSeries] = useState<string | null>(null);
const [reportName, setReportName] = useState('');
const { displaySetService } = servicesManager.services;
const seriesOptions = useMemo(() => {
const displaySetsMap = displaySetService.getDisplaySetCache();
const displaySets = Array.from(displaySetsMap.values());
const options = displaySets
.filter(ds => ds.Modality === 'SR')
.map(ds => ({
value: ds.SeriesInstanceUID,
description: ds.SeriesDescription,
label: `${ds.SeriesDescription} ${ds.SeriesDate}/${ds.SeriesTime} ${ds.SeriesNumber}`,
}));
return [
{
value: null,
description: null,
label: 'Create new series',
},
...options,
];
}, [displaySetService]);
useEffect(() => {
const seriesOption = seriesOptions.find(s => s.value === selectedSeries);
const newReportName =
selectedSeries && seriesOption?.description ? seriesOption.description : '';
setReportName(newReportName);
}, [selectedSeries, seriesOptions]);
const handleSave = () => {
onSave({
reportName,
dataSource: selectedDataSource,
series: selectedSeries,
});
hide();
};
@@ -38,42 +71,93 @@ function ReportDialog({ dataSources, hide, onSave, onCancel }: ReportDialogProps
const showDataSourceSelect = dataSources?.length > 1;
return (
<div className="text-foreground mt-2 flex min-w-[400px] max-w-md flex-col gap-4">
<div className="flex flex-col gap-3">
<div className={showDataSourceSelect ? 'flex gap-4' : ''}>
<div className="text-foreground flex min-w-[400px] max-w-md flex-col">
<div className="flex flex-col gap-4">
<div className="flex gap-4">
{showDataSourceSelect && (
<div className="mt-1 w-1/3">
<>
<div className="mt-1 w-1/2">
<div className="mb-1 pl-1 text-base">Data source</div>
<Select
value={selectedDataSource}
onValueChange={setSelectedDataSource}
>
<SelectTrigger>
<SelectValue placeholder="Select a data source" />
</SelectTrigger>
<SelectContent>
{dataSources.map(source => (
<SelectItem
key={source.value}
value={source.value}
>
{source.label}
</SelectItem>
))}
</SelectContent>
</Select>
</div>
<div className={showDataSourceSelect ? 'mt-1 w-1/2' : 'mt-1 w-full'}>
<div className="mb-1 pl-1 text-base">Series</div>
<Select
value={selectedSeries}
onValueChange={setSelectedSeries}
>
<SelectTrigger>
<SelectValue placeholder="Select a series" />
</SelectTrigger>
<SelectContent>
{seriesOptions.map(series => (
<SelectItem
key={series.value}
value={series.value}
>
{series.label}
</SelectItem>
))}
</SelectContent>
</Select>
</div>
</>
)}
</div>
<div className="flex items-end gap-4">
{!showDataSourceSelect && (
<div className="w-1/3">
<div className="mb-1 pl-1 text-base">Series</div>
<Select
value={selectedDataSource}
onValueChange={setSelectedDataSource}
value={selectedSeries}
onValueChange={setSelectedSeries}
>
<SelectTrigger>
<SelectValue placeholder="Select a data source" />
<SelectValue placeholder="Select a series" />
</SelectTrigger>
<SelectContent>
{dataSources.map(source => (
{seriesOptions.map(series => (
<SelectItem
key={source.value}
value={source.value}
key={series.value}
value={series.value}
>
{source.label}
{series.label}
</SelectItem>
))}
</SelectContent>
</Select>
</div>
)}
<div className={showDataSourceSelect ? 'mt-1 w-2/3' : 'w-full'}>
<InputDialog
value={reportName}
onChange={setReportName}
submitOnEnter
>
<InputDialog.Field>
<InputDialog.Input placeholder="Report name" />
</InputDialog.Field>
</InputDialog>
</div>
<InputDialog
value={reportName}
onChange={setReportName}
submitOnEnter
className="flex-1"
>
<InputDialog.Field className="mb-0">
<InputDialog.Input
placeholder="Report name"
disabled={!!selectedSeries}
/>
</InputDialog.Field>
</InputDialog>
</div>
<div className="flex justify-end gap-2">
@@ -46,10 +46,9 @@ export default {
'studyBrowser.studyMode': 'all',
'studyBrowser.thumbnailDoubleClickCallback': {
callbacks: [
({ activeViewportId, servicesManager, isHangingProtocolLayout }) =>
({ activeViewportId, servicesManager, commandsManager, isHangingProtocolLayout }) =>
async displaySetInstanceUID => {
const { hangingProtocolService, viewportGridService, uiNotificationService } =
servicesManager.services;
const { hangingProtocolService, uiNotificationService } = servicesManager.services;
let updatedViewports = [];
const viewportId = activeViewportId;
@@ -69,7 +68,9 @@ export default {
});
}
viewportGridService.setDisplaySetsForViewports(updatedViewports);
commandsManager.run('setDisplaySetsForViewports', {
viewportsToUpdate: updatedViewports,
});
},
],
},
@@ -1,4 +1,4 @@
import { ViewportActionCorners } from '@ohif/ui';
import { ViewportActionCorners } from '@ohif/ui-next';
export default {
'ui.viewportActionCorner': ViewportActionCorners,
+6 -1
View File
@@ -33,7 +33,12 @@ export default function getToolbarModule({ commandsManager, servicesManager }: w
name: 'ohif.toolBoxButton',
defaultComponent: ToolBoxButtonWrapper,
},
// legacy
// legacy will get removed in the future
// legacy will get removed in the future
// legacy will get removed in the future
// legacy will get removed in the future
// legacy will get removed in the future
// legacy will get removed in the future
{
name: 'ohif.radioGroup',
defaultComponent: ToolbarButtonLegacy,
+1 -1
View File
@@ -85,7 +85,7 @@ export function Toolbox({ buttonSectionId, title }: { buttonSectionId: string; t
{CustomConfigComponent && (
<div className="ml-auto mr-2">
<Icons.Settings
className="text-primary-active h-4 w-4"
className="text-primary h-4 w-4"
onClick={e => {
e.stopPropagation();
setShowConfig(!showConfig);
Loaded 100 of 370 files, more files were not shown because too many files have changed in this diff. Show more