Compare commits
42
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0b6e9cba76 | ||
|
|
963664cb63 | ||
|
|
12fe1e107d | ||
|
|
e1e9b5ccb1 | ||
|
|
6b7e73b78a | ||
|
|
43bc142439 | ||
|
|
c05ec1909f | ||
|
|
c7529394ad | ||
|
|
f6f60a63d2 | ||
|
|
0d2ccc5830 | ||
|
|
08be5cc656 | ||
|
|
c453c29449 | ||
|
|
a69dd8b1a0 | ||
|
|
17c5642a59 | ||
|
|
bd2f843469 | ||
|
|
8b9b02d84c | ||
|
|
c9958bafad | ||
|
|
85f465968b | ||
|
|
47e491f1c8 | ||
|
|
e56b53e897 | ||
|
|
2bdf4afa4d | ||
|
|
1b8729dded | ||
|
|
f71d370969 | ||
|
|
033831ee72 | ||
|
|
49c08298fc | ||
|
|
cfa202e89a | ||
|
|
391a5f3bdd | ||
|
|
64d65a6830 | ||
|
|
3653de7487 | ||
|
|
a8ac297e16 | ||
|
|
4e09f85d5d | ||
|
|
d2f187153d | ||
|
|
62e5a62066 | ||
|
|
7b40963997 | ||
|
|
75493334cf | ||
|
|
746f2524eb | ||
|
|
0eb9ff235c | ||
|
|
e9b95afd4c | ||
|
|
fc33bd0d59 | ||
|
|
479e280fdf | ||
|
|
d4f81cd2b7 | ||
|
|
54fded554e |
No files matched your search
@@ -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.
|
||||
|
||||
@@ -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() }}
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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",
|
||||
|
||||
@@ -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
@@ -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"
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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],
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
+2
-2
@@ -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';
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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`}
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
}
|
||||
+5
-5
@@ -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
-1
@@ -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';
|
||||
|
||||
+19
-30
@@ -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)}
|
||||
/>
|
||||
))}
|
||||
|
||||
+5
-3
@@ -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">
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
-1
@@ -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 };
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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 = () => {
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
Reference in new issue
Block a user