Compare commits
8
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
72ec0bffb5 | ||
|
|
82c6c3c353 | ||
|
|
1d38fe30a4 | ||
|
|
666964b6d7 | ||
|
|
fa4ee5c559 | ||
|
|
cd58560e9c | ||
|
|
16afa740b6 | ||
|
|
6715ad9bd6 |
No files matched your search
@@ -1,6 +1,5 @@
|
||||
server {
|
||||
listen ${PORT} default_server;
|
||||
listen [::]:${PORT} default_server;
|
||||
listen ${PORT};
|
||||
location / {
|
||||
root /usr/share/nginx/html;
|
||||
index index.html index.htm;
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
server {
|
||||
listen ${SSL_PORT} ssl http2 default_server;
|
||||
listen [::]:${SSL_PORT} ssl http2 default_server;
|
||||
ssl_certificate /etc/ssl/certs/ssl-certificate.crt;
|
||||
ssl_certificate_key /etc/ssl/private/ssl-private-key.key;
|
||||
location / {
|
||||
root /usr/share/nginx/html;
|
||||
index index.html index.htm;
|
||||
try_files $uri $uri/ /index.html;
|
||||
add_header Cross-Origin-Opener-Policy same-origin;
|
||||
add_header Cross-Origin-Embedder-Policy require-corp;
|
||||
add_header Cross-Origin-Resource-Policy same-origin;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto;
|
||||
}
|
||||
error_page 500 502 503 504 /50x.html;
|
||||
location = /50x.html {
|
||||
root /usr/share/nginx/html;
|
||||
}
|
||||
}
|
||||
@@ -1,16 +1,6 @@
|
||||
#!/bin/sh
|
||||
|
||||
if [ -n "$SSL_PORT" ]
|
||||
then
|
||||
envsubst '${SSL_PORT}:${PORT}' < /usr/src/default.ssl.conf.template > /etc/nginx/conf.d/default.conf
|
||||
else
|
||||
envsubst '${PORT}' < /usr/src/default.conf.template > /etc/nginx/conf.d/default.conf
|
||||
fi
|
||||
|
||||
if [ -n "$APP_CONFIG" ]
|
||||
then
|
||||
echo "$APP_CONFIG" > /usr/share/nginx/html/app-config.js
|
||||
fi
|
||||
envsubst '${PORT}' < /usr/src/default.conf.template > /etc/nginx/conf.d/default.conf
|
||||
|
||||
if [ -n "$CLIENT_ID" ] || [ -n "$HEALTHCARE_API_ENDPOINT" ]
|
||||
then
|
||||
|
||||
@@ -73,6 +73,15 @@ module.exports = (env, argv, { SRC_DIR, ENTRY }) => {
|
||||
children: false,
|
||||
warnings: true,
|
||||
},
|
||||
devServer: {
|
||||
open: true,
|
||||
port: 3000,
|
||||
historyApiFallback: true,
|
||||
headers: {
|
||||
'Cross-Origin-Embedder-Policy': 'require-corp',
|
||||
'Cross-Origin-Opener-Policy': 'same-origin',
|
||||
},
|
||||
},
|
||||
cache: {
|
||||
type: 'filesystem',
|
||||
},
|
||||
|
||||
+1
-6
@@ -61,7 +61,7 @@ RUN yarn run build
|
||||
|
||||
# Stage 3: Bundle the built application into a Docker container
|
||||
# which runs Nginx using Alpine Linux
|
||||
FROM nginxinc/nginx-unprivileged:1.25-alpine as final
|
||||
FROM nginxinc/nginx-unprivileged:1.23.1-alpine as final
|
||||
#RUN apk add --no-cache bash
|
||||
ENV PORT=80
|
||||
RUN rm /etc/nginx/conf.d/default.conf
|
||||
@@ -69,10 +69,5 @@ USER nginx
|
||||
COPY --chown=nginx:nginx .docker/Viewer-v3.x /usr/src
|
||||
RUN chmod 777 /usr/src/entrypoint.sh
|
||||
COPY --from=builder /usr/src/app/platform/app/dist /usr/share/nginx/html
|
||||
# In entrypoint.sh, app-config.js might be overwritten, so chmod it to be writeable.
|
||||
# The nginx user cannot chmod it, so change to root.
|
||||
USER root
|
||||
RUN chmod 666 /usr/share/nginx/html/app-config.js
|
||||
USER nginx
|
||||
ENTRYPOINT ["/usr/src/entrypoint.sh"]
|
||||
CMD ["nginx", "-g", "daemon off;"]
|
||||
@@ -17,6 +17,10 @@ provided by the <a href="https://ohif.org/">Open Health Imaging Foundation (OHIF
|
||||
<div align="center">
|
||||
📰 <a href="https://ohif.org/news/"><strong>Join OHIF Newsletter</strong></a> 📰
|
||||
</div>
|
||||
<div align="center">
|
||||
📰 <a href="https://ohif.org/news/"><strong>Join OHIF Newsletter</strong></a> 📰
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<hr />
|
||||
@@ -34,16 +38,7 @@ provided by the <a href="https://ohif.org/">Open Health Imaging Foundation (OHIF
|
||||
<!-- [](#contributors) -->
|
||||
<!-- prettier-ignore-end -->
|
||||
|
||||
|
||||
| | | |
|
||||
| :-: | :--- | :--- |
|
||||
| <img src="platform/docs/docs/assets/img/demo-measurements.jpg" alt="Measurement tracking" width="350"/> | Measurement Tracking | [Demo](https://viewer.ohif.org/viewer?StudyInstanceUIDs=1.3.6.1.4.1.25403.345050719074.3824.20170125095438.5) |
|
||||
| <img src="platform/docs/docs/assets/img/demo-segmentation.png" alt="Segmentations" width="350"/> | Labelmap Segmentations | [Demo](https://viewer.ohif.org/viewer?StudyInstanceUIDs=1.3.12.2.1107.5.2.32.35162.30000015050317233592200000046) |
|
||||
| <img src="platform/docs/docs/assets/img/demo-ptct.png" alt="Hanging Protocols" width="350"/> | Fusion and Custom Hanging protocols | [Demo](https://viewer.ohif.org/tmtv?StudyInstanceUIDs=1.3.6.1.4.1.14519.5.2.1.7009.2403.334240657131972136850343327463) |
|
||||
| <img src="platform/docs/docs/assets/img/demo-microscopy.png" alt="Microscopy" width="350"/> | Slide Microscopy | [Demo](https://viewer.ohif.org/microscopy?StudyInstanceUIDs=2.25.275741864483510678566144889372061815320) |
|
||||
| <img src="platform/docs/docs/assets/img/demo-volumeRendering.png" alt="Volume Rendering" width="350"/> | Volume Rendering | [Demo](https://viewer.ohif.org/viewer?StudyInstanceUIDs=1.3.6.1.4.1.25403.345050719074.3824.20170125095438.5&hangingprotocolId=mprAnd3DVolumeViewport) |
|
||||
|
||||
|
||||

|
||||
|
||||
## About
|
||||
|
||||
@@ -90,14 +85,17 @@ forking).
|
||||
|
||||
### Support
|
||||
|
||||
We offer support through
|
||||
[GitHub Issues](https://github.com/OHIF/Viewers/issues/new/choose). You can:
|
||||
|
||||
- [Report a Bug 🐛](https://github.com/OHIF/Viewers/issues/new?assignees=&labels=Community%3A+Report+%3Abug%3A%2CAwaiting+Reproduction&projects=&template=bug-report.yml&title=%5BBug%5D+)
|
||||
- [Request a Feature 🚀](https://github.com/OHIF/Viewers/issues/new?assignees=&labels=Community%3A+Request+%3Ahand%3A&projects=&template=feature-request.yml&title=%5BFeature+Request%5D+)
|
||||
- [Ask a Question 🤗](community.ohif.org)
|
||||
- [Slack Channel](https://join.slack.com/t/cornerstonejs/shared_invite/zt-1r8xb2zau-dOxlD6jit3TN0Uwf928w9Q)
|
||||
|
||||
For commercial support, academic collaborations, and answers to common
|
||||
questions; please use [Get Support](https://ohif.org/get-support/) to contact
|
||||
us.
|
||||
questions; please read our
|
||||
[documented FAQ](https://docs.ohif.org/faq/index.html#does-ohif-offer-commercial-support).
|
||||
|
||||
|
||||
## Developing
|
||||
@@ -130,6 +128,9 @@ Here is a schematic representation of our development workflow:
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### Requirements
|
||||
|
||||
- [Yarn 1.17.3+](https://yarnpkg.com/en/docs/install)
|
||||
@@ -221,6 +222,15 @@ you'll see the following:
|
||||
└── README.md # This file
|
||||
```
|
||||
|
||||
Want to better understand why and how we've structured this repository? Read
|
||||
more about it in our [Architecture Documentation][ohif-architecture].
|
||||
|
||||
|
||||
|
||||
| Name | Description | Links |
|
||||
| ---------------------------------------------------- | ----------------------------------------------------- | ---------------------- |
|
||||
| [@ohif/extension-cornerstone][extension-cornerstone] | 2D image viewing, annotation, and segementation tools | [NPM][cornerstone-npm] |
|
||||
|
||||
## Acknowledgments
|
||||
|
||||
To acknowledge the OHIF Viewer in an academic publication, please cite
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
7d286a07f2141bf8b8b85ca9d9b5eb3c0d7fc996
|
||||
1d38fe30a490010c7de487c7a0b1a5bfe3bc75a4
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ohif/extension-cornerstone-dicom-rt",
|
||||
"version": "3.7.0-beta.32",
|
||||
"version": "3.6.0",
|
||||
"description": "DICOM RT read workflow",
|
||||
"author": "OHIF",
|
||||
"license": "MIT",
|
||||
@@ -31,10 +31,10 @@
|
||||
"start": "yarn run dev"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@ohif/core": "3.7.0-beta.32",
|
||||
"@ohif/extension-cornerstone": "3.7.0-beta.32",
|
||||
"@ohif/extension-default": "3.7.0-beta.32",
|
||||
"@ohif/i18n": "3.7.0-beta.32",
|
||||
"@ohif/core": "3.6.0",
|
||||
"@ohif/extension-cornerstone": "3.6.0",
|
||||
"@ohif/extension-default": "3.6.0",
|
||||
"@ohif/i18n": "3.6.0",
|
||||
"prop-types": "^15.6.2",
|
||||
"react": "^17.0.2",
|
||||
"react-dom": "^17.0.2",
|
||||
|
||||
@@ -181,6 +181,12 @@ export default async function loadRTStruct(
|
||||
ContourGeometricType,
|
||||
} = ContourSequenceArray[c];
|
||||
|
||||
const sopInstanceUID = ContourImageSequence.ReferencedSOPInstanceUID;
|
||||
const imageId = _getImageId(imageIdSopInstanceUidPairs, sopInstanceUID);
|
||||
|
||||
if (!imageId) {
|
||||
continue;
|
||||
}
|
||||
let isSupported = false;
|
||||
|
||||
const points = [];
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { ButtonEnums } from '@ohif/ui';
|
||||
import hydrateRTDisplaySet from './_hydrateRT';
|
||||
|
||||
const RESPONSE = {
|
||||
@@ -39,12 +38,12 @@ function _askHydrate(uiViewportDialogService, viewportIndex) {
|
||||
const message = 'Do you want to open this Segmentation?';
|
||||
const actions = [
|
||||
{
|
||||
type: ButtonEnums.type.secondary,
|
||||
type: 'secondary',
|
||||
text: 'No',
|
||||
value: RESPONSE.CANCEL,
|
||||
},
|
||||
{
|
||||
type: ButtonEnums.type.primary,
|
||||
type: 'primary',
|
||||
text: 'Yes',
|
||||
value: RESPONSE.HYDRATE_SEG,
|
||||
},
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ohif/extension-cornerstone-dicom-seg",
|
||||
"version": "3.7.0-beta.32",
|
||||
"version": "3.6.0",
|
||||
"description": "DICOM SEG read workflow",
|
||||
"author": "OHIF",
|
||||
"license": "MIT",
|
||||
@@ -31,10 +31,10 @@
|
||||
"start": "yarn run dev"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@ohif/core": "3.7.0-beta.32",
|
||||
"@ohif/extension-cornerstone": "3.7.0-beta.32",
|
||||
"@ohif/extension-default": "3.7.0-beta.32",
|
||||
"@ohif/i18n": "3.7.0-beta.32",
|
||||
"@ohif/core": "3.6.0",
|
||||
"@ohif/extension-cornerstone": "3.6.0",
|
||||
"@ohif/extension-default": "3.6.0",
|
||||
"@ohif/i18n": "3.6.0",
|
||||
"prop-types": "^15.6.2",
|
||||
"react": "^17.0.2",
|
||||
"react-dom": "^17.0.2",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React from 'react';
|
||||
import { Input, Dialog, ButtonEnums } from '@ohif/ui';
|
||||
import { Input, Dialog } from '@ohif/ui';
|
||||
|
||||
function callInputDialog(uiDialogService, label, callback) {
|
||||
const dialogId = 'enter-segment-label';
|
||||
@@ -29,8 +29,8 @@ function callInputDialog(uiDialogService, label, callback) {
|
||||
noCloseButton: true,
|
||||
onClose: () => uiDialogService.dismiss({ id: dialogId }),
|
||||
actions: [
|
||||
{ id: 'cancel', text: 'Cancel', type: ButtonEnums.type.secondary },
|
||||
{ id: 'save', text: 'Confirm', type: ButtonEnums.type.primary },
|
||||
{ id: 'cancel', text: 'Cancel', type: 'primary' },
|
||||
{ id: 'save', text: 'Confirm', type: 'secondary' },
|
||||
],
|
||||
onSubmit: onSubmitHandler,
|
||||
body: ({ value, setValue }) => {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { ButtonEnums } from '@ohif/ui';
|
||||
import hydrateSEGDisplaySet from './_hydrateSEG';
|
||||
|
||||
const RESPONSE = {
|
||||
@@ -7,7 +6,11 @@ const RESPONSE = {
|
||||
HYDRATE_SEG: 5,
|
||||
};
|
||||
|
||||
function promptHydrateSEG({ servicesManager, segDisplaySet, viewportIndex }) {
|
||||
function promptHydrateSEG({
|
||||
servicesManager,
|
||||
segDisplaySet,
|
||||
viewportIndex,
|
||||
}) {
|
||||
const { uiViewportDialogService } = servicesManager.services;
|
||||
|
||||
return new Promise(async function(resolve, reject) {
|
||||
@@ -33,12 +36,12 @@ function _askHydrate(uiViewportDialogService, viewportIndex) {
|
||||
const message = 'Do you want to open this Segmentation?';
|
||||
const actions = [
|
||||
{
|
||||
type: ButtonEnums.type.secondary,
|
||||
type: 'secondary',
|
||||
text: 'No',
|
||||
value: RESPONSE.CANCEL,
|
||||
},
|
||||
{
|
||||
type: ButtonEnums.type.primary,
|
||||
type: 'primary',
|
||||
text: 'Yes',
|
||||
value: RESPONSE.HYDRATE_SEG,
|
||||
},
|
||||
|
||||
@@ -71,8 +71,7 @@ function OHIFCornerstoneSEGViewport(props) {
|
||||
|
||||
const referencedDisplaySet = segDisplaySet.getReferenceDisplaySet();
|
||||
const referencedDisplaySetMetadata = _getReferencedDisplaySetMetadata(
|
||||
referencedDisplaySet,
|
||||
segDisplaySet
|
||||
referencedDisplaySet
|
||||
);
|
||||
|
||||
referencedDisplaySetRef.current = {
|
||||
@@ -344,10 +343,10 @@ function OHIFCornerstoneSEGViewport(props) {
|
||||
patientSex: PatientSex || '',
|
||||
patientAge: PatientAge || '',
|
||||
MRN: PatientID || '',
|
||||
thickness: SliceThickness ? `${parseFloat(SliceThickness).toFixed(2)}mm` : '',
|
||||
thickness: SliceThickness ? `${SliceThickness.toFixed(2)}mm` : '',
|
||||
spacing:
|
||||
SpacingBetweenSlices !== undefined
|
||||
? `${parseFloat(SpacingBetweenSlices).toFixed(2)}mm`
|
||||
? `${SpacingBetweenSlices.toFixed(2)}mm`
|
||||
: '',
|
||||
scanner: ManufacturerModelName || '',
|
||||
},
|
||||
@@ -382,28 +381,20 @@ OHIFCornerstoneSEGViewport.defaultProps = {
|
||||
customProps: {},
|
||||
};
|
||||
|
||||
function _getReferencedDisplaySetMetadata(referencedDisplaySet, segDisplaySet) {
|
||||
const {
|
||||
SharedFunctionalGroupsSequence: [SharedFunctionalGroup],
|
||||
} = segDisplaySet.instance;
|
||||
const {
|
||||
PixelMeasuresSequence: [PixelMeasures],
|
||||
} = SharedFunctionalGroup;
|
||||
const { SpacingBetweenSlices, SliceThickness } = PixelMeasures;
|
||||
|
||||
function _getReferencedDisplaySetMetadata(referencedDisplaySet) {
|
||||
const image0 = referencedDisplaySet.images[0];
|
||||
const referencedDisplaySetMetadata = {
|
||||
PatientID: image0.PatientID,
|
||||
PatientName: image0.PatientName,
|
||||
PatientSex: image0.PatientSex,
|
||||
PatientAge: image0.PatientAge,
|
||||
SliceThickness: image0.SliceThickness || SliceThickness,
|
||||
SliceThickness: image0.SliceThickness,
|
||||
StudyDate: image0.StudyDate,
|
||||
SeriesDescription: image0.SeriesDescription,
|
||||
SeriesInstanceUID: image0.SeriesInstanceUID,
|
||||
SeriesNumber: image0.SeriesNumber,
|
||||
ManufacturerModelName: image0.ManufacturerModelName,
|
||||
SpacingBetweenSlices: image0.SpacingBetweenSlices || SpacingBetweenSlices,
|
||||
SpacingBetweenSlices: image0.SpacingBetweenSlices,
|
||||
};
|
||||
|
||||
return referencedDisplaySetMetadata;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ohif/extension-cornerstone-dicom-sr",
|
||||
"version": "3.7.0-beta.32",
|
||||
"version": "3.6.0",
|
||||
"description": "OHIF extension for an SR Cornerstone Viewport",
|
||||
"author": "OHIF",
|
||||
"license": "MIT",
|
||||
@@ -32,10 +32,10 @@
|
||||
"test:unit:ci": "jest --ci --runInBand --collectCoverage --passWithNoTests"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@ohif/core": "3.7.0-beta.32",
|
||||
"@ohif/extension-cornerstone": "3.7.0-beta.32",
|
||||
"@ohif/extension-measurement-tracking": "3.7.0-beta.32",
|
||||
"@ohif/ui": "3.7.0-beta.32",
|
||||
"@ohif/core": "3.6.0",
|
||||
"@ohif/extension-cornerstone": "3.6.0",
|
||||
"@ohif/extension-measurement-tracking": "3.6.0",
|
||||
"@ohif/ui": "3.6.0",
|
||||
"dcmjs": "^0.29.5",
|
||||
"dicom-parser": "^1.8.9",
|
||||
"hammerjs": "^2.0.8",
|
||||
@@ -44,9 +44,9 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.20.13",
|
||||
"@cornerstonejs/adapters": "^1.4.1",
|
||||
"@cornerstonejs/core": "^1.4.1",
|
||||
"@cornerstonejs/tools": "^1.4.1",
|
||||
"@cornerstonejs/adapters": "^1.1.0",
|
||||
"@cornerstonejs/core": "^1.1.0",
|
||||
"@cornerstonejs/tools": "^1.1.0",
|
||||
"classnames": "^2.3.2"
|
||||
}
|
||||
}
|
||||
@@ -225,7 +225,6 @@ function OHIFCornerstoneSRViewport(props) {
|
||||
}}
|
||||
onElementEnabled={onElementEnabled}
|
||||
initialImageIndex={initialImageIndex}
|
||||
isJumpToMeasurementDisabled={true}
|
||||
></Component>
|
||||
);
|
||||
}, [activeImageDisplaySetData, viewportIndex, measurementSelected]);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ohif/extension-cornerstone",
|
||||
"version": "3.7.0-beta.32",
|
||||
"version": "3.6.0",
|
||||
"description": "OHIF extension for Cornerstone",
|
||||
"author": "OHIF",
|
||||
"license": "MIT",
|
||||
@@ -36,9 +36,9 @@
|
||||
"@cornerstonejs/codec-libjpeg-turbo-8bit": "^1.2.2",
|
||||
"@cornerstonejs/codec-openjpeg": "^1.2.2",
|
||||
"@cornerstonejs/codec-openjph": "^2.4.2",
|
||||
"@cornerstonejs/dicom-image-loader": "^1.4.1",
|
||||
"@ohif/core": "3.7.0-beta.32",
|
||||
"@ohif/ui": "3.7.0-beta.32",
|
||||
"@cornerstonejs/dicom-image-loader": "^0.6.8",
|
||||
"@ohif/core": "3.6.0",
|
||||
"@ohif/ui": "3.6.0",
|
||||
"dcmjs": "^0.29.6",
|
||||
"dicom-parser": "^1.8.21",
|
||||
"hammerjs": "^2.0.8",
|
||||
@@ -52,10 +52,10 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.20.13",
|
||||
"@cornerstonejs/adapters": "^1.4.1",
|
||||
"@cornerstonejs/core": "^1.4.1",
|
||||
"@cornerstonejs/streaming-image-volume-loader": "^1.4.1",
|
||||
"@cornerstonejs/tools": "^1.4.1",
|
||||
"@cornerstonejs/adapters": "^1.1.0",
|
||||
"@cornerstonejs/core": "^1.1.0",
|
||||
"@cornerstonejs/streaming-image-volume-loader": "^1.1.0",
|
||||
"@cornerstonejs/tools": "^1.1.0",
|
||||
"@kitware/vtk.js": "27.3.1",
|
||||
"html2canvas": "^1.4.1",
|
||||
"lodash.debounce": "4.0.8",
|
||||
|
||||
@@ -119,7 +119,6 @@ const OHIFCornerstoneViewport = React.memo(props => {
|
||||
servicesManager,
|
||||
onElementEnabled,
|
||||
onElementDisabled,
|
||||
isJumpToMeasurementDisabled,
|
||||
// Note: you SHOULD NOT use the initialImageIdOrIndex for manipulation
|
||||
// of the imageData in the OHIFCornerstoneViewport. This prop is used
|
||||
// to set the initial state of the viewport's first image to render
|
||||
@@ -455,10 +454,6 @@ const OHIFCornerstoneViewport = React.memo(props => {
|
||||
* the cache for jumping to see if there is any jump queued, then we jump to the correct slice.
|
||||
*/
|
||||
useEffect(() => {
|
||||
if (isJumpToMeasurementDisabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
const unsubscribeFromJumpToMeasurementEvents = _subscribeToJumpToMeasurementEvents(
|
||||
measurementService,
|
||||
displaySetService,
|
||||
@@ -721,10 +716,6 @@ function _jumpToMeasurement(
|
||||
// Component displayName
|
||||
OHIFCornerstoneViewport.displayName = 'OHIFCornerstoneViewport';
|
||||
|
||||
OHIFCornerstoneViewport.defaultProps = {
|
||||
isJumpToMeasurementDisabled: false,
|
||||
};
|
||||
|
||||
OHIFCornerstoneViewport.propTypes = {
|
||||
viewportIndex: PropTypes.number.isRequired,
|
||||
displaySets: PropTypes.array.isRequired,
|
||||
@@ -733,7 +724,6 @@ OHIFCornerstoneViewport.propTypes = {
|
||||
displaySetOptions: PropTypes.arrayOf(PropTypes.any),
|
||||
servicesManager: PropTypes.object.isRequired,
|
||||
onElementEnabled: PropTypes.func,
|
||||
isJumpToMeasurementDisabled: PropTypes.bool,
|
||||
// Note: you SHOULD NOT use the initialImageIdOrIndex for manipulation
|
||||
// of the imageData in the OHIFCornerstoneViewport. This prop is used
|
||||
// to set the initial state of the viewport's first image to render
|
||||
|
||||
@@ -379,7 +379,7 @@ function _getViewportInstance(viewportData, imageIndex) {
|
||||
if (viewportData.viewportType === Enums.ViewportType.STACK) {
|
||||
imageId = viewportData.data.imageIds[imageIndex];
|
||||
} else if (viewportData.viewportType === Enums.ViewportType.ORTHOGRAPHIC) {
|
||||
const volumes = viewportData.data;
|
||||
const volumes = viewportData.volumes;
|
||||
if (volumes && volumes.length == 1) {
|
||||
const volume = volumes[0];
|
||||
imageId = volume.imageIds[imageIndex];
|
||||
|
||||
@@ -457,9 +457,11 @@ function commandsModule({
|
||||
|
||||
const { viewport } = enabledElement;
|
||||
|
||||
const { invert } = viewport.getProperties();
|
||||
viewport.setProperties({ invert: !invert });
|
||||
viewport.render();
|
||||
if (viewport instanceof StackViewport) {
|
||||
const { invert } = viewport.getProperties();
|
||||
viewport.setProperties({ invert: !invert });
|
||||
viewport.render();
|
||||
}
|
||||
},
|
||||
resetViewport: () => {
|
||||
const enabledElement = _getActiveViewportEnabledElement();
|
||||
|
||||
@@ -5,7 +5,7 @@ import PropTypes from 'prop-types';
|
||||
import classNames from 'classnames';
|
||||
import DicomFileUploader from '../../utils/DicomFileUploader';
|
||||
import DicomUploadProgress from './DicomUploadProgress';
|
||||
import { Button, ButtonEnums } from '@ohif/ui';
|
||||
import { Button } from '@ohif/ui';
|
||||
import './DicomUpload.css';
|
||||
|
||||
type DicomUploadProps = {
|
||||
@@ -46,7 +46,12 @@ function DicomUpload({
|
||||
<Dropzone onDrop={onDrop} noDrag>
|
||||
{({ getRootProps, getInputProps }) => (
|
||||
<div {...getRootProps()}>
|
||||
<Button disabled={false} onClick={() => {}}>
|
||||
<Button
|
||||
variant="contained"
|
||||
color="primary"
|
||||
disabled={false}
|
||||
onClick={() => {}}
|
||||
>
|
||||
{'Add files'}
|
||||
<input {...getInputProps()} />
|
||||
</Button>
|
||||
@@ -57,7 +62,9 @@ function DicomUpload({
|
||||
{({ getRootProps, getInputProps }) => (
|
||||
<div {...getRootProps()}>
|
||||
<Button
|
||||
type={ButtonEnums.type.secondary}
|
||||
variant="contained"
|
||||
color="primaryDark"
|
||||
border="primaryActive"
|
||||
disabled={false}
|
||||
onClick={() => {}}
|
||||
>
|
||||
|
||||
@@ -308,7 +308,13 @@ function DicomUploadProgress({
|
||||
} ${
|
||||
dicomFileUploaderArr.length > 1 ? 'files' : 'file'
|
||||
} completed.`}</span>
|
||||
<Button disabled={false} className="ml-auto" onClick={onComplete}>
|
||||
<Button
|
||||
variant="contained"
|
||||
color="primary"
|
||||
disabled={false}
|
||||
className="ml-auto"
|
||||
onClick={onComplete}
|
||||
>
|
||||
{'Close'}
|
||||
</Button>
|
||||
</>
|
||||
|
||||
@@ -27,6 +27,7 @@ const DicomUploadProgressItem = memo(
|
||||
const [failedReason, setFailedReason] = useState('');
|
||||
const [status, setStatus] = useState(dicomFileUploader.getStatus());
|
||||
|
||||
console.info(`${dicomFileUploader.getFileId()}`);
|
||||
const isComplete = useCallback(() => {
|
||||
return (
|
||||
status === UploadStatus.Failed ||
|
||||
|
||||
@@ -24,6 +24,7 @@ import { toolNames } from './initCornerstoneTools';
|
||||
import { getEnabledElement, reset as enabledElementReset } from './state';
|
||||
import dicomLoaderService from './utils/dicomLoaderService';
|
||||
import getActiveViewportEnabledElement from './utils/getActiveViewportEnabledElement';
|
||||
import { registerColormap } from './utils/colormap/transferFunctionHelpers';
|
||||
|
||||
import { id } from './id';
|
||||
import * as csWADOImageLoader from './initWADOImageLoader.js';
|
||||
|
||||
@@ -26,7 +26,6 @@ import nthLoader from './utils/nthLoader';
|
||||
import interleaveTopToBottom from './utils/interleaveTopToBottom';
|
||||
import initContextMenu from './initContextMenu';
|
||||
import initDoubleClick from './initDoubleClick';
|
||||
import { CornerstoneServices } from './types';
|
||||
|
||||
// TODO: Cypress tests are currently grabbing this from the window?
|
||||
window.cornerstone = cornerstone;
|
||||
@@ -70,7 +69,10 @@ export default async function init({
|
||||
|
||||
const {
|
||||
userAuthenticationService,
|
||||
measurementService,
|
||||
customizationService,
|
||||
displaySetService,
|
||||
uiDialogService,
|
||||
uiModalService,
|
||||
uiNotificationService,
|
||||
cineService,
|
||||
@@ -79,7 +81,7 @@ export default async function init({
|
||||
toolGroupService,
|
||||
viewportGridService,
|
||||
stateSyncService,
|
||||
} = servicesManager.services as CornerstoneServices;
|
||||
} = servicesManager.services;
|
||||
|
||||
window.services = servicesManager.services;
|
||||
window.extensionManager = extensionManager;
|
||||
@@ -164,7 +166,7 @@ export default async function init({
|
||||
prefetch: appConfig?.maxNumRequests?.prefetch || 10,
|
||||
};
|
||||
|
||||
initWADOImageLoader(userAuthenticationService, appConfig, extensionManager);
|
||||
initWADOImageLoader(userAuthenticationService, appConfig);
|
||||
|
||||
/* Measurement Service */
|
||||
this.measurementServiceSource = connectToolsToMeasurementService(
|
||||
|
||||
@@ -5,7 +5,7 @@ import dicomImageLoader, {
|
||||
webWorkerManager,
|
||||
} from '@cornerstonejs/dicom-image-loader';
|
||||
import dicomParser from 'dicom-parser';
|
||||
import { errorHandler, utils } from '@ohif/core';
|
||||
import { errorHandler } from '@ohif/core';
|
||||
|
||||
const { registerVolumeLoader } = volumeLoader;
|
||||
|
||||
@@ -35,8 +35,7 @@ function initWebWorkers(appConfig) {
|
||||
|
||||
export default function initWADOImageLoader(
|
||||
userAuthenticationService,
|
||||
appConfig,
|
||||
extensionManager
|
||||
appConfig
|
||||
) {
|
||||
dicomImageLoader.external.cornerstone = cornerstone;
|
||||
dicomImageLoader.external.dicomParser = dicomParser;
|
||||
@@ -56,18 +55,18 @@ export default function initWADOImageLoader(
|
||||
convertFloatPixelDataToInt: false,
|
||||
},
|
||||
beforeSend: function(xhr) {
|
||||
//TODO should be removed in the future and request emitted by DicomWebDataSource
|
||||
const sourceConfig =
|
||||
extensionManager.getActiveDataSource()?.[0].getConfig() ?? {};
|
||||
const headers = userAuthenticationService.getAuthorizationHeader();
|
||||
const acceptHeader = utils.generateAcceptHeader(
|
||||
sourceConfig.acceptHeader,
|
||||
sourceConfig.requestTransferSyntaxUID,
|
||||
sourceConfig.omitQuotationForMultipartRequest
|
||||
);
|
||||
|
||||
// Request:
|
||||
// JPEG-LS Lossless (1.2.840.10008.1.2.4.80) if available, otherwise accept
|
||||
// whatever transfer-syntax the origin server provides.
|
||||
// For now we use image/jls and image/x-jls because some servers still use the old type
|
||||
// http://dicom.nema.org/medical/dicom/current/output/html/part18.html
|
||||
const xhrRequestHeaders = {
|
||||
Accept: acceptHeader,
|
||||
Accept: appConfig.omitQuotationForMultipartRequest
|
||||
? 'multipart/related; type=application/octet-stream'
|
||||
: 'multipart/related; type="application/octet-stream"',
|
||||
// 'multipart/related; type="image/x-jls", multipart/related; type="image/jls"; transfer-syntax="1.2.840.10008.1.2.4.80", multipart/related; type="image/x-jls", multipart/related; type="application/octet-stream"; transfer-syntax=*',
|
||||
};
|
||||
|
||||
if (headers) {
|
||||
|
||||
@@ -117,7 +117,7 @@ class SegmentationService extends PubSubService {
|
||||
* -- opacity: the opacity of the segment
|
||||
* -- visibility: the visibility of the segment (boolean)
|
||||
* -- isLocked: whether the segment is locked for editing
|
||||
* -- active: whether the segment is currently the active segment to be edited
|
||||
* -- active: whether the segment is currently the active segment to be edited or not
|
||||
*/
|
||||
public addSegment(
|
||||
segmentationId: string,
|
||||
@@ -542,7 +542,6 @@ class SegmentationService extends PubSubService {
|
||||
id: segmentationId,
|
||||
displaySetInstanceUID: segDisplaySet.displaySetInstanceUID,
|
||||
type: representationType,
|
||||
label: segDisplaySet.SeriesDescription,
|
||||
representationData: {
|
||||
[LABELMAP]: {
|
||||
volumeId: segmentationId,
|
||||
@@ -790,7 +789,6 @@ class SegmentationService extends PubSubService {
|
||||
id: segmentationId,
|
||||
displaySetInstanceUID: rtDisplaySetUID,
|
||||
type: representationType,
|
||||
label: rtDisplaySet.SeriesDescription,
|
||||
representationData: {
|
||||
[CONTOUR]: {
|
||||
geometryIds,
|
||||
@@ -818,54 +816,45 @@ class SegmentationService extends PubSubService {
|
||||
const segmentsCachedStats = {};
|
||||
const initializeContour = async rtStructData => {
|
||||
const { data, id, color, segmentIndex, geometryId } = rtStructData;
|
||||
|
||||
// catch error instead of failing to allow loading to continue
|
||||
try {
|
||||
const geometry = await geometryLoader.createAndCacheGeometry(
|
||||
geometryId,
|
||||
{
|
||||
geometryData: {
|
||||
data,
|
||||
id,
|
||||
color,
|
||||
frameOfReferenceUID: structureSet.frameOfReferenceUID,
|
||||
segmentIndex,
|
||||
},
|
||||
type: csEnums.GeometryType.CONTOUR,
|
||||
}
|
||||
);
|
||||
|
||||
const contourSet = geometry.data;
|
||||
const centroid = contourSet.getCentroid();
|
||||
|
||||
segmentsCachedStats[segmentIndex] = {
|
||||
center: { world: centroid },
|
||||
modifiedTime: rtDisplaySet.SeriesDate, // we use the SeriesDate as the modifiedTime since this is the first time we are creating the segmentation
|
||||
};
|
||||
|
||||
segmentation.segments[segmentIndex] = {
|
||||
label: id,
|
||||
segmentIndex,
|
||||
const geometry = await geometryLoader.createAndCacheGeometry(geometryId, {
|
||||
geometryData: {
|
||||
data,
|
||||
id,
|
||||
color,
|
||||
...SEGMENT_CONSTANT,
|
||||
};
|
||||
frameOfReferenceUID: structureSet.frameOfReferenceUID,
|
||||
segmentIndex,
|
||||
},
|
||||
type: csEnums.GeometryType.CONTOUR,
|
||||
});
|
||||
|
||||
const numInitialized = Object.keys(segmentsCachedStats).length;
|
||||
const contourSet = geometry.data;
|
||||
const centroid = contourSet.getCentroid();
|
||||
|
||||
// Calculate percentage completed
|
||||
const percentComplete = Math.round(
|
||||
(numInitialized / allRTStructData.length) * 100
|
||||
);
|
||||
segmentsCachedStats[segmentIndex] = {
|
||||
center: { world: centroid },
|
||||
modifiedTime: rtDisplaySet.SeriesDate, // we use the SeriesDate as the modifiedTime since this is the first time we are creating the segmentation
|
||||
};
|
||||
|
||||
this._broadcastEvent(EVENTS.SEGMENT_LOADING_COMPLETE, {
|
||||
percentComplete,
|
||||
// Note: this is not the geometryIds length since there might be
|
||||
// some missing ROINumbers
|
||||
numSegments: allRTStructData.length,
|
||||
});
|
||||
} catch (e) {
|
||||
console.warn(e);
|
||||
}
|
||||
segmentation.segments[segmentIndex] = {
|
||||
label: id,
|
||||
segmentIndex,
|
||||
color,
|
||||
...SEGMENT_CONSTANT,
|
||||
};
|
||||
|
||||
const numInitialized = Object.keys(segmentsCachedStats).length;
|
||||
|
||||
// Calculate percentage completed
|
||||
const percentComplete = Math.round(
|
||||
(numInitialized / allRTStructData.length) * 100
|
||||
);
|
||||
|
||||
this._broadcastEvent(EVENTS.SEGMENT_LOADING_COMPLETE, {
|
||||
percentComplete,
|
||||
// Note: this is not the geometryIds length since there might be
|
||||
// some missing ROINumbers
|
||||
numSegments: allRTStructData.length,
|
||||
});
|
||||
};
|
||||
|
||||
const promiseArray = [];
|
||||
|
||||
@@ -15,7 +15,7 @@ const EVENTS = {
|
||||
* sync group declared.
|
||||
*/
|
||||
export type SyncCreator = (
|
||||
id: string,
|
||||
type: string,
|
||||
options?: Record<string, unknown>
|
||||
) => Synchronizer;
|
||||
|
||||
@@ -83,7 +83,7 @@ export default class SyncGroupService {
|
||||
* @param type is the type of the synchronizer to create
|
||||
* @param creator
|
||||
*/
|
||||
public addSynchronizerType(type: string, creator: SyncCreator): void {
|
||||
public setSynchronizer(type: string, creator: SyncCreator): void {
|
||||
this.synchronizerCreators[type.toLowerCase()] = creator;
|
||||
}
|
||||
|
||||
|
||||
@@ -745,7 +745,7 @@ class CornerstoneViewportService extends PubSubService
|
||||
const viewport = this.getCornerstoneViewport(viewportId);
|
||||
const viewportCamera = viewport.getCamera();
|
||||
|
||||
if (viewport instanceof VolumeViewport || viewport instanceof VolumeViewport3D) {
|
||||
if (viewport instanceof VolumeViewport) {
|
||||
this._setVolumeViewport(viewport, viewportData, viewportInfo).then(() => {
|
||||
if (keepCamera) {
|
||||
viewport.setCamera(viewportCamera);
|
||||
|
||||
@@ -198,9 +198,7 @@ class ViewportInfo {
|
||||
// via cornerstoneViewportService
|
||||
let viewportData = this.getViewportData();
|
||||
|
||||
if (viewportData.viewportType === Enums.ViewportType.ORTHOGRAPHIC ||
|
||||
viewportData.viewportType === Enums.ViewportType.VOLUME_3D
|
||||
) {
|
||||
if (viewportData.viewportType === Enums.ViewportType.ORTHOGRAPHIC) {
|
||||
viewportData = viewportData as VolumeViewportData;
|
||||
return viewportData.data.some(
|
||||
({ displaySetInstanceUID: dsUID }) => dsUID === displaySetInstanceUID
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { Types } from '@ohif/core';
|
||||
import ToolGroupService from '../services/ToolGroupService';
|
||||
import SyncGroupService from '../services/SyncGroupService';
|
||||
import SegmentationService from '../services/SegmentationService';
|
||||
import CornerstoneCacheService from '../services/CornerstoneCacheService';
|
||||
import CornerstoneViewportService from '../services/ViewportService/CornerstoneViewportService';
|
||||
import ToolGroupService from './services/ToolGroupService';
|
||||
import SyncGroupService from './services/SyncGroupService';
|
||||
import SegmentationService from './services/SegmentationService';
|
||||
import CornerstoneCacheService from './services/CornerstoneCacheService';
|
||||
import CornerstoneViewportService from './services/ViewportService/CornerstoneViewportService';
|
||||
|
||||
interface CornerstoneServices extends Types.Services {
|
||||
cornerstoneViewportService: CornerstoneViewportService;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React from 'react';
|
||||
import { Input, Dialog, ButtonEnums } from '@ohif/ui';
|
||||
import { Input, Dialog } from '@ohif/ui';
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -60,8 +60,8 @@ function callInputDialog(
|
||||
noCloseButton: true,
|
||||
onClose: () => uiDialogService.dismiss({ id: dialogId }),
|
||||
actions: [
|
||||
{ id: 'cancel', text: 'Cancel', type: ButtonEnums.type.secondary },
|
||||
{ id: 'save', text: 'Save', type: ButtonEnums.type.primary },
|
||||
{ id: 'cancel', text: 'Cancel', type: 'primary' },
|
||||
{ id: 'save', text: 'Save', type: 'secondary' },
|
||||
],
|
||||
onSubmit: onSubmitHandler,
|
||||
body: ({ value, setValue }) => {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ohif/extension-default",
|
||||
"version": "3.7.0-beta.32",
|
||||
"version": "3.6.0",
|
||||
"description": "Common/default features and functionality for basic image viewing",
|
||||
"author": "OHIF Core Team",
|
||||
"license": "MIT",
|
||||
@@ -30,8 +30,8 @@
|
||||
"start": "yarn run dev"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@ohif/core": "3.7.0-beta.32",
|
||||
"@ohif/i18n": "3.7.0-beta.32",
|
||||
"@ohif/core": "3.6.0",
|
||||
"@ohif/i18n": "3.6.0",
|
||||
"dcmjs": "^0.29.5",
|
||||
"dicomweb-client": "^0.10.2",
|
||||
"prop-types": "^15.6.2",
|
||||
|
||||
@@ -60,42 +60,15 @@ function createDicomWebApi(dicomWebConfig, userAuthenticationService) {
|
||||
supportsReject,
|
||||
staticWado,
|
||||
singlepart,
|
||||
omitQuotationForMultipartRequest,
|
||||
acceptHeader,
|
||||
requestTransferSyntaxUID,
|
||||
} = dicomWebConfig;
|
||||
|
||||
const dicomWebConfigCopy = JSON.parse(JSON.stringify(dicomWebConfig));
|
||||
|
||||
const getAuthrorizationHeader = () => {
|
||||
const xhrRequestHeaders = {};
|
||||
const authHeaders = userAuthenticationService.getAuthorizationHeader();
|
||||
if (authHeaders && authHeaders.Authorization) {
|
||||
xhrRequestHeaders.Authorization = authHeaders.Authorization;
|
||||
}
|
||||
return xhrRequestHeaders;
|
||||
};
|
||||
|
||||
const generateWadoHeader = () => {
|
||||
let authorizationHeader = getAuthrorizationHeader();
|
||||
//Generate accept header depending on config params
|
||||
let formattedAcceptHeader = utils.generateAcceptHeader(
|
||||
acceptHeader,
|
||||
requestTransferSyntaxUID,
|
||||
omitQuotationForMultipartRequest
|
||||
);
|
||||
|
||||
return {
|
||||
...authorizationHeader,
|
||||
Accept: formattedAcceptHeader,
|
||||
};
|
||||
};
|
||||
|
||||
const qidoConfig = {
|
||||
url: qidoRoot,
|
||||
staticWado,
|
||||
singlepart,
|
||||
headers: getAuthrorizationHeader(),
|
||||
headers: userAuthenticationService.getAuthorizationHeader(),
|
||||
errorInterceptor: errorHandler.getHTTPErrorHandler(),
|
||||
};
|
||||
|
||||
@@ -103,7 +76,7 @@ function createDicomWebApi(dicomWebConfig, userAuthenticationService) {
|
||||
url: wadoRoot,
|
||||
staticWado,
|
||||
singlepart,
|
||||
headers: generateWadoHeader(),
|
||||
headers: userAuthenticationService.getAuthorizationHeader(),
|
||||
errorInterceptor: errorHandler.getHTTPErrorHandler(),
|
||||
};
|
||||
|
||||
@@ -137,7 +110,11 @@ function createDicomWebApi(dicomWebConfig, userAuthenticationService) {
|
||||
studies: {
|
||||
mapParams: mapParams.bind(),
|
||||
search: async function(origParams) {
|
||||
qidoDicomWebClient.headers = getAuthrorizationHeader();
|
||||
const headers = userAuthenticationService.getAuthorizationHeader();
|
||||
if (headers) {
|
||||
qidoDicomWebClient.headers = headers;
|
||||
}
|
||||
|
||||
const { studyInstanceUid, seriesInstanceUid, ...mappedParams } =
|
||||
mapParams(origParams, {
|
||||
supportsFuzzyMatching,
|
||||
@@ -158,7 +135,11 @@ function createDicomWebApi(dicomWebConfig, userAuthenticationService) {
|
||||
series: {
|
||||
// mapParams: mapParams.bind(),
|
||||
search: async function(studyInstanceUid) {
|
||||
qidoDicomWebClient.headers = getAuthrorizationHeader();
|
||||
const headers = userAuthenticationService.getAuthorizationHeader();
|
||||
if (headers) {
|
||||
qidoDicomWebClient.headers = headers;
|
||||
}
|
||||
|
||||
const results = await seriesInStudy(
|
||||
qidoDicomWebClient,
|
||||
studyInstanceUid
|
||||
@@ -170,7 +151,11 @@ function createDicomWebApi(dicomWebConfig, userAuthenticationService) {
|
||||
},
|
||||
instances: {
|
||||
search: (studyInstanceUid, queryParameters) => {
|
||||
qidoDicomWebClient.headers = getAuthrorizationHeader();
|
||||
const headers = userAuthenticationService.getAuthorizationHeader();
|
||||
if (headers) {
|
||||
qidoDicomWebClient.headers = headers;
|
||||
}
|
||||
|
||||
qidoSearch.call(
|
||||
undefined,
|
||||
qidoDicomWebClient,
|
||||
@@ -197,7 +182,6 @@ function createDicomWebApi(dicomWebConfig, userAuthenticationService) {
|
||||
return getDirectURL({ wadoRoot, singlepart }, params);
|
||||
},
|
||||
bulkDataURI: async ({ StudyInstanceUID, BulkDataURI }) => {
|
||||
qidoDicomWebClient.headers = getAuthrorizationHeader();
|
||||
const options = {
|
||||
multipart: false,
|
||||
BulkDataURI,
|
||||
@@ -216,6 +200,11 @@ function createDicomWebApi(dicomWebConfig, userAuthenticationService) {
|
||||
sortFunction,
|
||||
madeInClient = false,
|
||||
} = {}) => {
|
||||
const headers = userAuthenticationService.getAuthorizationHeader();
|
||||
if (headers) {
|
||||
wadoDicomWebClient.headers = headers;
|
||||
}
|
||||
|
||||
if (!StudyInstanceUID) {
|
||||
throw new Error(
|
||||
'Unable to query for SeriesMetadata without StudyInstanceUID'
|
||||
@@ -245,12 +234,17 @@ function createDicomWebApi(dicomWebConfig, userAuthenticationService) {
|
||||
|
||||
store: {
|
||||
dicom: async (dataset, request) => {
|
||||
wadoDicomWebClient.headers = getAuthrorizationHeader();
|
||||
const headers = userAuthenticationService.getAuthorizationHeader();
|
||||
if (headers) {
|
||||
wadoDicomWebClient.headers = headers;
|
||||
}
|
||||
|
||||
if (dataset instanceof ArrayBuffer) {
|
||||
const options = {
|
||||
datasets: [dataset],
|
||||
request,
|
||||
};
|
||||
|
||||
await wadoDicomWebClient.storeInstances(options);
|
||||
} else {
|
||||
const meta = {
|
||||
@@ -288,7 +282,7 @@ function createDicomWebApi(dicomWebConfig, userAuthenticationService) {
|
||||
madeInClient
|
||||
) => {
|
||||
const enableStudyLazyLoad = false;
|
||||
wadoDicomWebClient.headers = generateWadoHeader();
|
||||
|
||||
// data is all SOPInstanceUIDs
|
||||
const data = await retrieveStudyMetadata(
|
||||
wadoDicomWebClient,
|
||||
@@ -359,7 +353,6 @@ function createDicomWebApi(dicomWebConfig, userAuthenticationService) {
|
||||
madeInClient = false
|
||||
) => {
|
||||
const enableStudyLazyLoad = true;
|
||||
wadoDicomWebClient.headers = generateWadoHeader();
|
||||
// Get Series
|
||||
const {
|
||||
preLoadData: seriesSummaryMetadata,
|
||||
|
||||
@@ -2,7 +2,7 @@ import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { LegacyButton, ButtonGroup } from '@ohif/ui';
|
||||
import { Button, ButtonGroup } from '@ohif/ui';
|
||||
|
||||
function ActionButtons({ onExportClick, onCreateReportClick }) {
|
||||
const { t } = useTranslation('MeasurementTable');
|
||||
@@ -10,16 +10,12 @@ function ActionButtons({ onExportClick, onCreateReportClick }) {
|
||||
return (
|
||||
<React.Fragment>
|
||||
<ButtonGroup color="black" size="inherit">
|
||||
{/* TODO Revisit design of ButtonGroup later - for now use LegacyButton for its children.*/}
|
||||
<LegacyButton className="px-2 py-2 text-base" onClick={onExportClick}>
|
||||
<Button className="px-2 py-2 text-base" onClick={onExportClick}>
|
||||
{t('Export CSV')}
|
||||
</LegacyButton>
|
||||
<LegacyButton
|
||||
className="px-2 py-2 text-base"
|
||||
onClick={onCreateReportClick}
|
||||
>
|
||||
</Button>
|
||||
<Button className="px-2 py-2 text-base" onClick={onCreateReportClick}>
|
||||
{t('Create Report')}
|
||||
</LegacyButton>
|
||||
</Button>
|
||||
</ButtonGroup>
|
||||
</React.Fragment>
|
||||
);
|
||||
|
||||
@@ -3,7 +3,7 @@ import classnames from 'classnames';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { useAppConfig } from '@state';
|
||||
|
||||
import { Button, ButtonEnums } from '@ohif/ui';
|
||||
import { Button } from '@ohif/ui';
|
||||
|
||||
function DataSourceSelector() {
|
||||
const [appConfig] = useAppConfig();
|
||||
@@ -33,8 +33,7 @@ function DataSourceSelector() {
|
||||
<div key={ds.sourceName}>
|
||||
<h1 className="text-white">{ds.friendlyName}</h1>
|
||||
<Button
|
||||
type={ButtonEnums.type.primary}
|
||||
className={classnames('ml-2')}
|
||||
className={classnames('font-bold', 'ml-2')}
|
||||
onClick={() => {
|
||||
navigate({
|
||||
pathname: '/',
|
||||
|
||||
@@ -1,13 +1,7 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { utils, ServicesManager } from '@ohif/core';
|
||||
import {
|
||||
MeasurementTable,
|
||||
Dialog,
|
||||
Input,
|
||||
useViewportGrid,
|
||||
ButtonEnums,
|
||||
} from '@ohif/ui';
|
||||
import { MeasurementTable, Dialog, Input, useViewportGrid } from '@ohif/ui';
|
||||
import ActionButtons from './ActionButtons';
|
||||
import debounce from 'lodash.debounce';
|
||||
|
||||
@@ -195,8 +189,9 @@ export default function PanelMeasurementTable({
|
||||
);
|
||||
},
|
||||
actions: [
|
||||
{ id: 'cancel', text: 'Cancel', type: ButtonEnums.type.secondary },
|
||||
{ id: 'save', text: 'Save', type: ButtonEnums.type.primary },
|
||||
// temp: swap button types until colors are updated
|
||||
{ id: 'cancel', text: 'Cancel', type: 'primary' },
|
||||
{ id: 'save', text: 'Save', type: 'secondary' },
|
||||
],
|
||||
onSubmit: onSubmitHandler,
|
||||
},
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* eslint-disable react/display-name */
|
||||
import React from 'react';
|
||||
import { ButtonEnums, Dialog, Input, Select } from '@ohif/ui';
|
||||
import { Dialog, Input, Select } from '@ohif/ui';
|
||||
|
||||
export const CREATE_REPORT_DIALOG_RESPONSE = {
|
||||
CANCEL: 0,
|
||||
@@ -81,8 +81,8 @@ export default function createReportDialogPrompt(
|
||||
noCloseButton: true,
|
||||
onClose: _handleClose,
|
||||
actions: [
|
||||
{ id: 'cancel', text: 'Cancel', type: ButtonEnums.type.secondary },
|
||||
{ id: 'save', text: 'Save', type: ButtonEnums.type.primary },
|
||||
{ id: 'cancel', text: 'Cancel', type: 'primary' },
|
||||
{ id: 'save', text: 'Save', type: 'secondary' },
|
||||
],
|
||||
// TODO: Should be on button press...
|
||||
onSubmit: _handleFormSubmit,
|
||||
|
||||
@@ -29,7 +29,7 @@ export default function Toolbar({ servicesManager }) {
|
||||
|
||||
return (
|
||||
<>
|
||||
{toolbarButtons.map(toolDef => {
|
||||
{toolbarButtons.map((toolDef, index) => {
|
||||
const { id, Component, componentProps } = toolDef;
|
||||
// TODO: ...
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ohif/extension-dicom-microscopy",
|
||||
"version": "3.7.0-beta.32",
|
||||
"version": "3.6.0",
|
||||
"description": "OHIF extension for DICOM microscopy",
|
||||
"author": "Bill Wallace, md-prog",
|
||||
"license": "MIT",
|
||||
@@ -28,10 +28,10 @@
|
||||
"start": "yarn run dev"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@ohif/core": "3.7.0-beta.32",
|
||||
"@ohif/extension-default": "3.7.0-beta.32",
|
||||
"@ohif/i18n": "3.7.0-beta.32",
|
||||
"@ohif/ui": "3.7.0-beta.32",
|
||||
"@ohif/core": "3.6.0",
|
||||
"@ohif/extension-default": "3.6.0",
|
||||
"@ohif/i18n": "3.6.0",
|
||||
"@ohif/ui": "3.6.0",
|
||||
"prop-types": "^15.6.2",
|
||||
"react": "^17.0.2",
|
||||
"react-dom": "^17.0.2",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React from 'react';
|
||||
import { Input, Dialog, ButtonEnums } from '@ohif/ui';
|
||||
import { Input, Dialog } from '@ohif/ui';
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -14,7 +14,7 @@ export default function callInputDialog({
|
||||
uiDialogService,
|
||||
title = 'Annotation',
|
||||
defaultValue = '',
|
||||
callback = (value: string, action: string) => {},
|
||||
callback = (value: string, action: string) => {}
|
||||
}) {
|
||||
const dialogId = 'microscopy-input-dialog';
|
||||
|
||||
@@ -43,8 +43,8 @@ export default function callInputDialog({
|
||||
noCloseButton: true,
|
||||
onClose: () => uiDialogService.dismiss({ id: dialogId }),
|
||||
actions: [
|
||||
{ id: 'cancel', text: 'Cancel', type: ButtonEnums.type.secondary },
|
||||
{ id: 'save', text: 'Save', type: ButtonEnums.type.primary },
|
||||
{ id: 'cancel', text: 'Cancel', type: 'primary' },
|
||||
{ id: 'save', text: 'Save', type: 'secondary' },
|
||||
],
|
||||
onSubmit: onSubmitHandler,
|
||||
body: ({ value, setValue }) => {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ohif/extension-dicom-pdf",
|
||||
"version": "3.7.0-beta.32",
|
||||
"version": "3.6.0",
|
||||
"description": "OHIF extension for PDF display",
|
||||
"author": "OHIF",
|
||||
"license": "MIT",
|
||||
@@ -28,8 +28,8 @@
|
||||
"test:unit:ci": "jest --ci --runInBand --collectCoverage --passWithNoTests"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@ohif/core": "3.7.0-beta.32",
|
||||
"@ohif/ui": "3.7.0-beta.32",
|
||||
"@ohif/core": "3.6.0",
|
||||
"@ohif/ui": "3.6.0",
|
||||
"dcmjs": "^0.29.5",
|
||||
"dicom-parser": "^1.8.9",
|
||||
"hammerjs": "^2.0.8",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ohif/extension-dicom-video",
|
||||
"version": "3.7.0-beta.32",
|
||||
"version": "3.6.0",
|
||||
"description": "OHIF extension for video display",
|
||||
"author": "OHIF",
|
||||
"license": "MIT",
|
||||
@@ -28,8 +28,8 @@
|
||||
"test:unit:ci": "jest --ci --runInBand --collectCoverage --passWithNoTests"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@ohif/core": "3.7.0-beta.32",
|
||||
"@ohif/ui": "3.7.0-beta.32",
|
||||
"@ohif/core": "3.6.0",
|
||||
"@ohif/ui": "3.6.0",
|
||||
"dcmjs": "^0.29.5",
|
||||
"dicom-parser": "^1.8.9",
|
||||
"hammerjs": "^2.0.8",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ohif/extension-measurement-tracking",
|
||||
"version": "3.7.0-beta.32",
|
||||
"version": "3.6.0",
|
||||
"description": "Tracking features and functionality for basic image viewing",
|
||||
"author": "OHIF Core Team",
|
||||
"license": "MIT",
|
||||
@@ -30,11 +30,11 @@
|
||||
"start": "yarn run dev"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@cornerstonejs/core": "^1.4.1",
|
||||
"@cornerstonejs/tools": "^1.4.1",
|
||||
"@ohif/core": "3.7.0-beta.32",
|
||||
"@ohif/extension-cornerstone-dicom-sr": "3.7.0-beta.32",
|
||||
"@ohif/ui": "3.7.0-beta.32",
|
||||
"@cornerstonejs/core": "^1.1.0",
|
||||
"@cornerstonejs/tools": "^1.1.0",
|
||||
"@ohif/core": "3.6.0",
|
||||
"@ohif/extension-cornerstone-dicom-sr": "3.6.0",
|
||||
"@ohif/ui": "3.6.0",
|
||||
"classnames": "^2.3.2",
|
||||
"dcmjs": "^0.29.5",
|
||||
"lodash.debounce": "^4.17.21",
|
||||
@@ -46,7 +46,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.20.13",
|
||||
"@ohif/ui": "3.7.0-beta.32",
|
||||
"@ohif/ui": "3.6.0",
|
||||
"@xstate/react": "^0.8.1",
|
||||
"xstate": "^4.10.0"
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* eslint-disable react/display-name */
|
||||
import React from 'react';
|
||||
import { ButtonEnums, Dialog, Input } from '@ohif/ui';
|
||||
import { Dialog, Input } from '@ohif/ui';
|
||||
import RESPONSE from './PROMPT_RESPONSES';
|
||||
|
||||
export default function createReportDialogPrompt(uiDialogService) {
|
||||
@@ -20,19 +20,12 @@ export default function createReportDialogPrompt(uiDialogService) {
|
||||
* @param {string} param0.value - value from input field
|
||||
*/
|
||||
const _handleFormSubmit = ({ action, value }) => {
|
||||
uiDialogService.dismiss({ id: dialogId });
|
||||
switch (action.id) {
|
||||
case 'save':
|
||||
// Only save if description is not blank otherwise ignore
|
||||
if (value.label && value.label.trim() !== '') {
|
||||
resolve({
|
||||
action: RESPONSE.CREATE_REPORT,
|
||||
value: value.label.trim(),
|
||||
});
|
||||
uiDialogService.dismiss({ id: dialogId });
|
||||
}
|
||||
resolve({ action: RESPONSE.CREATE_REPORT, value: value.label });
|
||||
break;
|
||||
case 'cancel':
|
||||
uiDialogService.dismiss({ id: dialogId });
|
||||
resolve({ action: RESPONSE.CANCEL, value: undefined });
|
||||
break;
|
||||
}
|
||||
@@ -50,8 +43,8 @@ export default function createReportDialogPrompt(uiDialogService) {
|
||||
noCloseButton: true,
|
||||
onClose: _handleClose,
|
||||
actions: [
|
||||
{ id: 'cancel', text: 'Cancel', type: ButtonEnums.type.secondary },
|
||||
{ id: 'save', text: 'Save', type: ButtonEnums.type.primary },
|
||||
{ id: 'cancel', text: 'Cancel', type: 'primary' },
|
||||
{ id: 'save', text: 'Save', type: 'secondary' },
|
||||
],
|
||||
// TODO: Should be on button press...
|
||||
onSubmit: _handleFormSubmit,
|
||||
@@ -62,8 +55,8 @@ export default function createReportDialogPrompt(uiDialogService) {
|
||||
};
|
||||
const onKeyPressHandler = event => {
|
||||
if (event.key === 'Enter') {
|
||||
// Trigger form submit
|
||||
_handleFormSubmit({ action: { id: 'save' }, value });
|
||||
uiDialogService.dismiss({ id: dialogId });
|
||||
resolve({ action: RESPONSE.CREATE_REPORT, value: value.label });
|
||||
}
|
||||
};
|
||||
return (
|
||||
|
||||
+3
-5
@@ -1,5 +1,3 @@
|
||||
import { ButtonEnums } from '@ohif/ui';
|
||||
|
||||
const RESPONSE = {
|
||||
NO_NEVER: -1,
|
||||
CANCEL: 0,
|
||||
@@ -33,19 +31,19 @@ function _askTrackMeasurements(uiViewportDialogService, viewportIndex) {
|
||||
const actions = [
|
||||
{
|
||||
id: 'prompt-begin-tracking-cancel',
|
||||
type: ButtonEnums.type.secondary,
|
||||
type: 'cancel',
|
||||
text: 'No',
|
||||
value: RESPONSE.CANCEL,
|
||||
},
|
||||
{
|
||||
id: 'prompt-begin-tracking-no-do-not-ask-again',
|
||||
type: ButtonEnums.type.secondary,
|
||||
type: 'secondary',
|
||||
text: 'No, do not ask again',
|
||||
value: RESPONSE.NO_NEVER,
|
||||
},
|
||||
{
|
||||
id: 'prompt-begin-tracking-yes',
|
||||
type: ButtonEnums.type.primary,
|
||||
type: 'primary',
|
||||
text: 'Yes',
|
||||
value: RESPONSE.SET_STUDY_AND_SERIES,
|
||||
},
|
||||
|
||||
+2
-3
@@ -1,5 +1,4 @@
|
||||
import { hydrateStructuredReport } from '@ohif/extension-cornerstone-dicom-sr';
|
||||
import { ButtonEnums } from '@ohif/ui';
|
||||
|
||||
const RESPONSE = {
|
||||
NO_NEVER: -1,
|
||||
@@ -62,12 +61,12 @@ function _askTrackMeasurements(uiViewportDialogService, viewportIndex) {
|
||||
'Do you want to continue tracking measurements for this study?';
|
||||
const actions = [
|
||||
{
|
||||
type: ButtonEnums.type.secondary,
|
||||
type: 'secondary',
|
||||
text: 'No',
|
||||
value: RESPONSE.CANCEL,
|
||||
},
|
||||
{
|
||||
type: ButtonEnums.type.primary,
|
||||
type: 'primary',
|
||||
text: 'Yes',
|
||||
value: RESPONSE.HYDRATE_REPORT,
|
||||
},
|
||||
|
||||
+3
-9
@@ -1,5 +1,3 @@
|
||||
import { ButtonEnums } from '@ohif/ui';
|
||||
|
||||
const RESPONSE = {
|
||||
NO_NEVER: -1,
|
||||
CANCEL: 0,
|
||||
@@ -40,18 +38,14 @@ function _askShouldAddMeasurements(uiViewportDialogService, viewportIndex) {
|
||||
const message =
|
||||
'Do you want to add this measurement to the existing report?';
|
||||
const actions = [
|
||||
{ type: 'cancel', text: 'Cancel', value: RESPONSE.CANCEL },
|
||||
{
|
||||
type: ButtonEnums.type.secondary,
|
||||
text: 'Cancel',
|
||||
value: RESPONSE.CANCEL,
|
||||
},
|
||||
{
|
||||
type: ButtonEnums.type.primary,
|
||||
type: 'secondary',
|
||||
text: 'Create new report',
|
||||
value: RESPONSE.CREATE_REPORT,
|
||||
},
|
||||
{
|
||||
type: ButtonEnums.type.primary,
|
||||
type: 'primary',
|
||||
text: 'Add to existing report',
|
||||
value: RESPONSE.ADD_SERIES,
|
||||
},
|
||||
|
||||
+11
-6
@@ -2,7 +2,7 @@ import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { Button, ButtonEnums } from '@ohif/ui';
|
||||
import { Button, ButtonGroup } from '@ohif/ui';
|
||||
|
||||
function ActionButtons({ onExportClick, onCreateReportClick, disabled }) {
|
||||
const { t } = useTranslation('MeasurementTable');
|
||||
@@ -10,18 +10,23 @@ function ActionButtons({ onExportClick, onCreateReportClick, disabled }) {
|
||||
return (
|
||||
<React.Fragment>
|
||||
<Button
|
||||
className="text-base px-2 py-2"
|
||||
size="initial"
|
||||
variant={disabled ? 'disabled' : 'outlined'}
|
||||
color="black"
|
||||
border="primaryActive"
|
||||
onClick={onExportClick}
|
||||
disabled={disabled}
|
||||
type={ButtonEnums.type.secondary}
|
||||
size={ButtonEnums.size.small}
|
||||
>
|
||||
{t('Export')}
|
||||
</Button>
|
||||
<Button
|
||||
className="ml-2"
|
||||
className="ml-2 px-2 text-base"
|
||||
variant={disabled ? 'disabled' : 'outlined'}
|
||||
size="initial"
|
||||
color="black"
|
||||
border="primaryActive"
|
||||
onClick={onCreateReportClick}
|
||||
type={ButtonEnums.type.secondary}
|
||||
size={ButtonEnums.size.small}
|
||||
disabled={disabled}
|
||||
>
|
||||
{t('Create Report')}
|
||||
|
||||
@@ -6,7 +6,6 @@ import {
|
||||
Dialog,
|
||||
Input,
|
||||
useViewportGrid,
|
||||
ButtonEnums,
|
||||
} from '@ohif/ui';
|
||||
import { DicomMetadataStore, utils } from '@ohif/core';
|
||||
import { useDebounce } from '@hooks';
|
||||
@@ -218,8 +217,9 @@ function PanelMeasurementTableTracking({ servicesManager, extensionManager }) {
|
||||
);
|
||||
},
|
||||
actions: [
|
||||
{ id: 'cancel', text: 'Cancel', type: ButtonEnums.type.secondary },
|
||||
{ id: 'save', text: 'Save', type: ButtonEnums.type.primary },
|
||||
// temp: swap button types until colors are updated
|
||||
{ id: 'cancel', text: 'Cancel', type: 'primary' },
|
||||
{ id: 'save', text: 'Save', type: 'secondary' },
|
||||
],
|
||||
onSubmit: onSubmitHandler,
|
||||
},
|
||||
|
||||
+35
-12
@@ -1,5 +1,4 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import PropTypes from 'prop-types';
|
||||
import { utils } from '@ohif/core';
|
||||
import {
|
||||
@@ -7,7 +6,6 @@ import {
|
||||
useImageViewer,
|
||||
useViewportGrid,
|
||||
Dialog,
|
||||
ButtonEnums,
|
||||
} from '@ohif/ui';
|
||||
import { useTrackedMeasurements } from '../../getContextModule';
|
||||
|
||||
@@ -25,20 +23,19 @@ function PanelStudyBrowserTracking({
|
||||
dataSource,
|
||||
}) {
|
||||
const {
|
||||
measurementService,
|
||||
displaySetService,
|
||||
uiDialogService,
|
||||
hangingProtocolService,
|
||||
uiNotificationService,
|
||||
} = servicesManager.services;
|
||||
|
||||
const { t } = useTranslation('Common');
|
||||
|
||||
// Normally you nest the components so the tree isn't so deep, and the data
|
||||
// doesn't have to have such an intense shape. This works well enough for now.
|
||||
// Tabs --> Studies --> DisplaySets --> Thumbnails
|
||||
const { StudyInstanceUIDs } = useImageViewer();
|
||||
const [
|
||||
{ activeViewportIndex, viewports },
|
||||
{ activeViewportIndex, viewports, numCols, numRows },
|
||||
viewportGridService,
|
||||
] = useViewportGrid();
|
||||
const [
|
||||
@@ -79,6 +76,36 @@ function PanelStudyBrowserTracking({
|
||||
const activeViewportDisplaySetInstanceUIDs =
|
||||
viewports[activeViewportIndex]?.displaySetInstanceUIDs;
|
||||
|
||||
useEffect(() => {
|
||||
const added = measurementService.EVENTS.MEASUREMENT_ADDED;
|
||||
const addedRaw = measurementService.EVENTS.RAW_MEASUREMENT_ADDED;
|
||||
const subscriptions = [];
|
||||
|
||||
[added, addedRaw].forEach(evt => {
|
||||
subscriptions.push(
|
||||
measurementService.subscribe(evt, ({ source, measurement }) => {
|
||||
const {
|
||||
referenceSeriesUID: SeriesInstanceUID,
|
||||
referenceStudyUID: StudyInstanceUID,
|
||||
} = measurement;
|
||||
|
||||
sendTrackedMeasurementsEvent('SET_DIRTY', { SeriesInstanceUID });
|
||||
sendTrackedMeasurementsEvent('TRACK_SERIES', {
|
||||
viewportIndex: activeViewportIndex,
|
||||
StudyInstanceUID,
|
||||
SeriesInstanceUID,
|
||||
});
|
||||
}).unsubscribe
|
||||
);
|
||||
});
|
||||
|
||||
return () => {
|
||||
subscriptions.forEach(unsub => {
|
||||
unsub();
|
||||
});
|
||||
};
|
||||
}, [measurementService, activeViewportIndex, sendTrackedMeasurementsEvent]);
|
||||
|
||||
const { trackedSeries } = trackedMeasurements.context;
|
||||
|
||||
// ~~ studyDisplayList
|
||||
@@ -106,7 +133,7 @@ function PanelStudyBrowserTracking({
|
||||
const actuallyMappedStudies = mappedStudies.map(qidoStudy => {
|
||||
return {
|
||||
studyInstanceUid: qidoStudy.StudyInstanceUID,
|
||||
date: formatDate(qidoStudy.StudyDate) || t('NoStudyDate'),
|
||||
date: formatDate(qidoStudy.StudyDate),
|
||||
description: qidoStudy.StudyDescription,
|
||||
modalities: qidoStudy.ModalitiesInStudy,
|
||||
numInstances: qidoStudy.NumInstances,
|
||||
@@ -480,15 +507,11 @@ function _mapDisplaySets(
|
||||
</div>
|
||||
),
|
||||
actions: [
|
||||
{
|
||||
id: 'cancel',
|
||||
text: 'Cancel',
|
||||
type: ButtonEnums.type.secondary,
|
||||
},
|
||||
{ id: 'cancel', text: 'Cancel', type: 'secondary' },
|
||||
{
|
||||
id: 'yes',
|
||||
text: 'Yes',
|
||||
type: ButtonEnums.type.primary,
|
||||
type: 'primary',
|
||||
classes: ['reject-yes-button'],
|
||||
},
|
||||
],
|
||||
|
||||
@@ -22,22 +22,17 @@ function TrackedCornerstoneViewport(props) {
|
||||
viewportOptions,
|
||||
} = props;
|
||||
|
||||
const { t } = useTranslation('Common');
|
||||
const { t } = useTranslation('TrackedViewport');
|
||||
|
||||
const {
|
||||
measurementService,
|
||||
cornerstoneViewportService,
|
||||
viewportGridService,
|
||||
} = servicesManager.services;
|
||||
|
||||
// Todo: handling more than one displaySet on the same viewport
|
||||
const displaySet = displaySets[0];
|
||||
|
||||
const [
|
||||
trackedMeasurements,
|
||||
sendTrackedMeasurementsEvent,
|
||||
] = useTrackedMeasurements();
|
||||
|
||||
const [trackedMeasurements] = useTrackedMeasurements();
|
||||
const [isTracked, setIsTracked] = useState(false);
|
||||
const [trackedMeasurementUID, setTrackedMeasurementUID] = useState(null);
|
||||
const [viewportElem, setViewportElem] = useState(null);
|
||||
@@ -59,7 +54,6 @@ function TrackedCornerstoneViewport(props) {
|
||||
PatientAge,
|
||||
SliceThickness,
|
||||
SpacingBetweenSlices,
|
||||
StudyDate,
|
||||
ManufacturerModelName,
|
||||
} = displaySet.images[0];
|
||||
|
||||
@@ -154,55 +148,6 @@ function TrackedCornerstoneViewport(props) {
|
||||
};
|
||||
}, [isTracked]);
|
||||
|
||||
/**
|
||||
* The effect for listening to measurement service measurement added events
|
||||
* and in turn firing an event to update the measurement tracking state machine.
|
||||
* The TrackedCornerstoneViewport is the best place for this because when
|
||||
* a measurement is added, at least one TrackedCornerstoneViewport will be in
|
||||
* the DOM and thus can react to the events fired.
|
||||
*/
|
||||
useEffect(() => {
|
||||
const added = measurementService.EVENTS.MEASUREMENT_ADDED;
|
||||
const addedRaw = measurementService.EVENTS.RAW_MEASUREMENT_ADDED;
|
||||
const subscriptions = [];
|
||||
|
||||
[added, addedRaw].forEach(evt => {
|
||||
subscriptions.push(
|
||||
measurementService.subscribe(evt, ({ source, measurement }) => {
|
||||
const { activeViewportIndex } = viewportGridService.getState();
|
||||
|
||||
// Each TrackedCornerstoneViewport receives the MeasurementService's events.
|
||||
// Only send the tracked measurements event for the active viewport to avoid
|
||||
// sending it more than once.
|
||||
if (viewportIndex === activeViewportIndex) {
|
||||
const {
|
||||
referenceStudyUID: StudyInstanceUID,
|
||||
referenceSeriesUID: SeriesInstanceUID,
|
||||
} = measurement;
|
||||
|
||||
sendTrackedMeasurementsEvent('SET_DIRTY', { SeriesInstanceUID });
|
||||
sendTrackedMeasurementsEvent('TRACK_SERIES', {
|
||||
viewportIndex,
|
||||
StudyInstanceUID,
|
||||
SeriesInstanceUID,
|
||||
});
|
||||
}
|
||||
}).unsubscribe
|
||||
);
|
||||
});
|
||||
|
||||
return () => {
|
||||
subscriptions.forEach(unsub => {
|
||||
unsub();
|
||||
});
|
||||
};
|
||||
}, [
|
||||
measurementService,
|
||||
sendTrackedMeasurementsEvent,
|
||||
viewportIndex,
|
||||
viewportGridService,
|
||||
]);
|
||||
|
||||
function switchMeasurement(direction) {
|
||||
const newTrackedMeasurementUID = _getNextMeasurementUID(
|
||||
direction,
|
||||
@@ -249,8 +194,7 @@ function TrackedCornerstoneViewport(props) {
|
||||
getStatusComponent={() => _getStatusComponent(isTracked)}
|
||||
studyData={{
|
||||
label: viewportLabel,
|
||||
studyDate:
|
||||
formatDate(SeriesDate) || formatDate(StudyDate) || t('NoStudyDate'),
|
||||
studyDate: formatDate(SeriesDate), // TODO: This is series date. Is that ok?
|
||||
currentSeries: SeriesNumber, // TODO - switch entire currentSeries to be UID based or actual position based
|
||||
seriesDescription: SeriesDescription,
|
||||
patientInformation: {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ohif/extension-test",
|
||||
"version": "3.7.0-beta.32",
|
||||
"version": "3.6.0",
|
||||
"description": "OHIF extension used inside e2e testing",
|
||||
"author": "OHIF",
|
||||
"license": "MIT",
|
||||
@@ -28,8 +28,8 @@
|
||||
"test:unit:ci": "jest --ci --runInBand --collectCoverage --passWithNoTests"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@ohif/core": "3.7.0-beta.32",
|
||||
"@ohif/ui": "3.7.0-beta.32",
|
||||
"@ohif/core": "3.6.0",
|
||||
"@ohif/ui": "3.6.0",
|
||||
"dcmjs": "0.29.4",
|
||||
"dicom-parser": "^1.8.9",
|
||||
"hammerjs": "^2.0.8",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ohif/extension-tmtv",
|
||||
"version": "3.7.0-beta.32",
|
||||
"version": "3.6.0",
|
||||
"description": "OHIF extension for Total Metabolic Tumor Volume",
|
||||
"author": "OHIF",
|
||||
"license": "MIT",
|
||||
@@ -28,8 +28,8 @@
|
||||
"test:unit:ci": "jest --ci --runInBand --collectCoverage --passWithNoTests"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@ohif/core": "3.7.0-beta.32",
|
||||
"@ohif/ui": "3.7.0-beta.32",
|
||||
"@ohif/core": "3.6.0",
|
||||
"@ohif/ui": "3.6.0",
|
||||
"dcmjs": "^0.29.5",
|
||||
"dicom-parser": "^1.8.9",
|
||||
"hammerjs": "^2.0.8",
|
||||
|
||||
@@ -225,7 +225,9 @@ export default function PanelPetSUV({ servicesManager, commandsManager }) {
|
||||
value={metadata.SeriesTime || ''}
|
||||
onChange={() => {}}
|
||||
/>
|
||||
<Button onClick={updateMetadata}>Reload Data</Button>
|
||||
<Button color="primary" onClick={updateMetadata}>
|
||||
Reload Data
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React from 'react';
|
||||
import { LegacyButton, ButtonGroup } from '@ohif/ui';
|
||||
import { Button, ButtonGroup } from '@ohif/ui';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
function ExportReports({ segmentations, tmtvValue, config, commandsManager }) {
|
||||
@@ -9,9 +9,8 @@ function ExportReports({ segmentations, tmtvValue, config, commandsManager }) {
|
||||
<>
|
||||
{segmentations?.length ? (
|
||||
<div className="flex justify-center mt-4 space-x-2">
|
||||
{/* TODO Revisit design of ButtonGroup later - for now use LegacyButton for its children.*/}
|
||||
<ButtonGroup color="black" size="inherit">
|
||||
<LegacyButton
|
||||
<Button
|
||||
className="px-2 py-2 text-base"
|
||||
disabled={tmtvValue === null}
|
||||
onClick={() => {
|
||||
@@ -23,10 +22,10 @@ function ExportReports({ segmentations, tmtvValue, config, commandsManager }) {
|
||||
}}
|
||||
>
|
||||
{t('Export CSV')}
|
||||
</LegacyButton>
|
||||
</Button>
|
||||
</ButtonGroup>
|
||||
<ButtonGroup color="black" size="inherit">
|
||||
<LegacyButton
|
||||
<Button
|
||||
className="px-2 py-2 text-base"
|
||||
onClick={() => {
|
||||
commandsManager.runCommand('createTMTVRTReport');
|
||||
@@ -34,7 +33,7 @@ function ExportReports({ segmentations, tmtvValue, config, commandsManager }) {
|
||||
disabled={tmtvValue === null}
|
||||
>
|
||||
{t('Create RT Report')}
|
||||
</LegacyButton>
|
||||
</Button>
|
||||
</ButtonGroup>
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
+4
-1
@@ -181,6 +181,7 @@ export default function PanelRoiThresholdSegmentation({
|
||||
<div className="overflow-x-hidden overflow-y-auto invisible-scrollbar">
|
||||
<div className="flex mx-4 my-4 mb-4 space-x-4">
|
||||
<Button
|
||||
color="primary"
|
||||
onClick={() => {
|
||||
setLabelmapLoading(true);
|
||||
setTimeout(() => {
|
||||
@@ -193,7 +194,9 @@ export default function PanelRoiThresholdSegmentation({
|
||||
>
|
||||
{labelmapLoading ? 'loading ...' : 'New Label'}
|
||||
</Button>
|
||||
<Button onClick={handleROIThresholding}>Run</Button>
|
||||
<Button color="primary" onClick={handleROIThresholding}>
|
||||
Run
|
||||
</Button>
|
||||
</div>
|
||||
<div
|
||||
className="flex items-center justify-around h-8 mb-2 border-t outline-none cursor-pointer select-none bg-secondary-dark first:border-0 border-secondary-light"
|
||||
|
||||
+5
-6
@@ -1,5 +1,5 @@
|
||||
import React from 'react';
|
||||
import { Input, Label, Select, LegacyButton, ButtonGroup } from '@ohif/ui';
|
||||
import { Input, Label, Select, Button, ButtonGroup } from '@ohif/ui';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
export const ROI_STAT = 'roi_stat';
|
||||
@@ -38,9 +38,8 @@ function ROIThresholdConfiguration({ config, dispatch, runCommand }) {
|
||||
/>
|
||||
</div>
|
||||
<div className="w-1/2">
|
||||
{/* TODO Revisit design of ButtonGroup later - for now use LegacyButton for its children.*/}
|
||||
<ButtonGroup>
|
||||
<LegacyButton
|
||||
<Button
|
||||
size="initial"
|
||||
className="px-2 py-2 text-base text-white"
|
||||
color="primaryLight"
|
||||
@@ -48,8 +47,8 @@ function ROIThresholdConfiguration({ config, dispatch, runCommand }) {
|
||||
onClick={() => runCommand('setStartSliceForROIThresholdTool')}
|
||||
>
|
||||
{t('Start')}
|
||||
</LegacyButton>
|
||||
<LegacyButton
|
||||
</Button>
|
||||
<Button
|
||||
size="initial"
|
||||
color="primaryLight"
|
||||
variant="outlined"
|
||||
@@ -57,7 +56,7 @@ function ROIThresholdConfiguration({ config, dispatch, runCommand }) {
|
||||
onClick={() => runCommand('setEndSliceForROIThresholdTool')}
|
||||
>
|
||||
{t('End')}
|
||||
</LegacyButton>
|
||||
</Button>
|
||||
</ButtonGroup>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
+15
-12
@@ -1,5 +1,5 @@
|
||||
import React from 'react';
|
||||
import { Input, Dialog, ButtonEnums } from '@ohif/ui';
|
||||
import { Input, Dialog } from '@ohif/ui';
|
||||
|
||||
function segmentationItemEditHandler({ id, servicesManager }) {
|
||||
const { segmentationService, uiDialogService } = servicesManager.services;
|
||||
@@ -44,20 +44,23 @@ function segmentationItemEditHandler({ id, servicesManager }) {
|
||||
}
|
||||
};
|
||||
return (
|
||||
<Input
|
||||
autoFocus
|
||||
className="bg-black border-primary-main"
|
||||
type="text"
|
||||
containerClassName="mr-2"
|
||||
value={value.label}
|
||||
onChange={onChangeHandler}
|
||||
onKeyPress={onKeyPressHandler}
|
||||
/>
|
||||
<div className="p-4 bg-primary-dark">
|
||||
<Input
|
||||
autoFocus
|
||||
className="mt-2 bg-black border-primary-main"
|
||||
type="text"
|
||||
containerClassName="mr-2"
|
||||
value={value.label}
|
||||
onChange={onChangeHandler}
|
||||
onKeyPress={onKeyPressHandler}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
actions: [
|
||||
{ id: 'cancel', text: 'Cancel', type: ButtonEnums.type.secondary },
|
||||
{ id: 'save', text: 'Save', type: ButtonEnums.type.primary },
|
||||
// temp: swap button types until colors are updated
|
||||
{ id: 'cancel', text: 'Cancel', type: 'primary' },
|
||||
{ id: 'save', text: 'Save', type: 'secondary' },
|
||||
],
|
||||
onSubmit: onSubmitHandler,
|
||||
},
|
||||
|
||||
@@ -553,16 +553,7 @@ const commandsModule = ({
|
||||
commandsManager.runCommand('setViewportColormap', {
|
||||
viewportIndex,
|
||||
displaySetInstanceUID: ptDisplaySet.displaySetInstanceUID,
|
||||
colormap: {
|
||||
name: colormap,
|
||||
// TODO: This opacity mapping matches that in hpViewports, but
|
||||
// ideally making this editable in a side panel would be useful
|
||||
opacity: [
|
||||
{ value: 0, opacity: 0 },
|
||||
{ value: 0.1, opacity: 0.9 },
|
||||
{ value: 1, opacity: 0.95 },
|
||||
],
|
||||
},
|
||||
colormap,
|
||||
});
|
||||
|
||||
viewports.push(
|
||||
|
||||
@@ -254,20 +254,16 @@ const fusionAXIAL = {
|
||||
id: 'ctDisplaySet',
|
||||
},
|
||||
{
|
||||
id: 'ptDisplaySet',
|
||||
options: {
|
||||
colormap: {
|
||||
name: 'hsv',
|
||||
opacity: [
|
||||
{ value: 0, opacity: 0 },
|
||||
{ value: 0.1, opacity: 0.9 },
|
||||
{ value: 1, opacity: 0.95 },
|
||||
],
|
||||
opacityMapping: [{ value: 0.1, opacity: 0.9 }],
|
||||
},
|
||||
voi: {
|
||||
custom: 'getPTVOIRange',
|
||||
},
|
||||
},
|
||||
id: 'ptDisplaySet',
|
||||
},
|
||||
],
|
||||
};
|
||||
@@ -314,20 +310,16 @@ const fusionSAGITTAL = {
|
||||
id: 'ctDisplaySet',
|
||||
},
|
||||
{
|
||||
id: 'ptDisplaySet',
|
||||
options: {
|
||||
colormap: {
|
||||
name: 'hsv',
|
||||
opacity: [
|
||||
{ value: 0, opacity: 0 },
|
||||
{ value: 0.1, opacity: 0.9 },
|
||||
{ value: 1, opacity: 0.95 },
|
||||
],
|
||||
opacityMapping: [{ value: 0.1, opacity: 0.9 }],
|
||||
},
|
||||
voi: {
|
||||
custom: 'getPTVOIRange',
|
||||
},
|
||||
},
|
||||
id: 'ptDisplaySet',
|
||||
},
|
||||
],
|
||||
};
|
||||
@@ -374,20 +366,16 @@ const fusionCORONAL = {
|
||||
id: 'ctDisplaySet',
|
||||
},
|
||||
{
|
||||
id: 'ptDisplaySet',
|
||||
options: {
|
||||
colormap: {
|
||||
name: 'hsv',
|
||||
opacity: [
|
||||
{ value: 0, opacity: 0 },
|
||||
{ value: 0.1, opacity: 0.9 },
|
||||
{ value: 1, opacity: 0.95 },
|
||||
],
|
||||
opacityMapping: [{ value: 0.1, opacity: 0.9 }],
|
||||
},
|
||||
voi: {
|
||||
custom: 'getPTVOIRange',
|
||||
},
|
||||
},
|
||||
id: 'ptDisplaySet',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"version": "3.7.0-beta.32",
|
||||
"version": "3.6.0",
|
||||
"packages": ["extensions/*", "platform/*", "modes/*"],
|
||||
"npmClient": "yarn",
|
||||
"useWorkspaces": true
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ohif/mode-basic-dev-mode",
|
||||
"version": "3.7.0-beta.32",
|
||||
"version": "3.6.0",
|
||||
"description": "Basic OHIF Viewer Using Cornerstone",
|
||||
"author": "OHIF",
|
||||
"license": "MIT",
|
||||
@@ -29,12 +29,12 @@
|
||||
"test:unit:ci": "jest --ci --runInBand --collectCoverage --passWithNoTests"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@ohif/core": "3.7.0-beta.32",
|
||||
"@ohif/extension-cornerstone": "3.7.0-beta.32",
|
||||
"@ohif/extension-cornerstone-dicom-sr": "3.7.0-beta.32",
|
||||
"@ohif/extension-default": "3.7.0-beta.32",
|
||||
"@ohif/extension-dicom-pdf": "3.7.0-beta.32",
|
||||
"@ohif/extension-dicom-video": "3.7.0-beta.32"
|
||||
"@ohif/core": "3.6.0",
|
||||
"@ohif/extension-cornerstone": "3.6.0",
|
||||
"@ohif/extension-cornerstone-dicom-sr": "3.6.0",
|
||||
"@ohif/extension-default": "3.6.0",
|
||||
"@ohif/extension-dicom-pdf": "3.6.0",
|
||||
"@ohif/extension-dicom-video": "3.6.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.20.13"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ohif/mode-test",
|
||||
"version": "3.7.0-beta.32",
|
||||
"version": "3.6.0",
|
||||
"description": "Basic mode for testing",
|
||||
"author": "OHIF",
|
||||
"license": "MIT",
|
||||
@@ -32,14 +32,14 @@
|
||||
"test:unit:ci": "jest --ci --runInBand --collectCoverage --passWithNoTests"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@ohif/core": "3.7.0-beta.32",
|
||||
"@ohif/extension-cornerstone": "3.7.0-beta.32",
|
||||
"@ohif/extension-cornerstone-dicom-sr": "3.7.0-beta.32",
|
||||
"@ohif/extension-default": "3.7.0-beta.32",
|
||||
"@ohif/extension-dicom-pdf": "3.7.0-beta.32",
|
||||
"@ohif/extension-dicom-video": "3.7.0-beta.32",
|
||||
"@ohif/extension-measurement-tracking": "3.7.0-beta.32",
|
||||
"@ohif/extension-test": "3.7.0-beta.32"
|
||||
"@ohif/core": "3.6.0",
|
||||
"@ohif/extension-cornerstone": "3.6.0",
|
||||
"@ohif/extension-cornerstone-dicom-sr": "3.6.0",
|
||||
"@ohif/extension-default": "3.6.0",
|
||||
"@ohif/extension-dicom-pdf": "3.6.0",
|
||||
"@ohif/extension-dicom-video": "3.6.0",
|
||||
"@ohif/extension-measurement-tracking": "3.6.0",
|
||||
"@ohif/extension-test": "3.6.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.20.13"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ohif/mode-longitudinal",
|
||||
"version": "3.7.0-beta.32",
|
||||
"version": "3.6.0",
|
||||
"description": "Longitudinal Workflow",
|
||||
"author": "OHIF",
|
||||
"license": "MIT",
|
||||
@@ -32,15 +32,15 @@
|
||||
"test:unit:ci": "jest --ci --runInBand --collectCoverage --passWithNoTests"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@ohif/core": "3.7.0-beta.32",
|
||||
"@ohif/extension-cornerstone": "3.7.0-beta.32",
|
||||
"@ohif/extension-cornerstone-dicom-rt": "3.7.0-beta.32",
|
||||
"@ohif/extension-cornerstone-dicom-seg": "3.7.0-beta.32",
|
||||
"@ohif/extension-cornerstone-dicom-sr": "3.7.0-beta.32",
|
||||
"@ohif/extension-default": "3.7.0-beta.32",
|
||||
"@ohif/extension-dicom-pdf": "3.7.0-beta.32",
|
||||
"@ohif/extension-dicom-video": "3.7.0-beta.32",
|
||||
"@ohif/extension-measurement-tracking": "3.7.0-beta.32"
|
||||
"@ohif/core": "3.6.0",
|
||||
"@ohif/extension-cornerstone": "3.6.0",
|
||||
"@ohif/extension-cornerstone-dicom-rt": "3.6.0",
|
||||
"@ohif/extension-cornerstone-dicom-seg": "3.6.0",
|
||||
"@ohif/extension-cornerstone-dicom-sr": "3.6.0",
|
||||
"@ohif/extension-default": "3.6.0",
|
||||
"@ohif/extension-dicom-pdf": "3.6.0",
|
||||
"@ohif/extension-dicom-video": "3.6.0",
|
||||
"@ohif/extension-measurement-tracking": "3.6.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.20.13"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ohif/mode-microscopy",
|
||||
"version": "3.7.0-beta.32",
|
||||
"version": "3.6.0",
|
||||
"description": "OHIF mode for DICOM microscopy",
|
||||
"author": "OHIF",
|
||||
"license": "MIT",
|
||||
@@ -33,8 +33,8 @@
|
||||
"test:unit:ci": "jest --ci --runInBand --collectCoverage --passWithNoTests"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@ohif/core": "3.7.0-beta.32",
|
||||
"@ohif/extension-dicom-microscopy": "3.7.0-beta.32"
|
||||
"@ohif/core": "3.6.0",
|
||||
"@ohif/extension-dicom-microscopy": "3.6.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.20.13"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ohif/mode-tmtv",
|
||||
"version": "3.7.0-beta.32",
|
||||
"version": "3.6.0",
|
||||
"description": "Total Metabolic Tumor Volume Workflow",
|
||||
"author": "OHIF",
|
||||
"license": "MIT",
|
||||
@@ -32,13 +32,13 @@
|
||||
"test:unit:ci": "jest --ci --runInBand --collectCoverage --passWithNoTests"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@ohif/core": "3.7.0-beta.32",
|
||||
"@ohif/extension-cornerstone": "3.7.0-beta.32",
|
||||
"@ohif/extension-cornerstone-dicom-sr": "3.7.0-beta.32",
|
||||
"@ohif/extension-default": "3.7.0-beta.32",
|
||||
"@ohif/extension-dicom-pdf": "3.7.0-beta.32",
|
||||
"@ohif/extension-dicom-video": "3.7.0-beta.32",
|
||||
"@ohif/extension-measurement-tracking": "3.7.0-beta.32"
|
||||
"@ohif/core": "3.6.0",
|
||||
"@ohif/extension-cornerstone": "3.6.0",
|
||||
"@ohif/extension-cornerstone-dicom-sr": "3.6.0",
|
||||
"@ohif/extension-default": "3.6.0",
|
||||
"@ohif/extension-dicom-pdf": "3.6.0",
|
||||
"@ohif/extension-dicom-video": "3.6.0",
|
||||
"@ohif/extension-measurement-tracking": "3.6.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.20.13"
|
||||
|
||||
@@ -220,8 +220,7 @@ function modeFactory({ modeConfiguration }) {
|
||||
return {
|
||||
id: ohif.layout,
|
||||
props: {
|
||||
leftPanels: [ohif.thumbnailList],
|
||||
leftPanelDefaultClosed: true,
|
||||
// leftPanels: [ohif.thumbnailList],
|
||||
rightPanels: [tmtv.ROIThresholdPanel, tmtv.petSUV],
|
||||
viewports: [
|
||||
{
|
||||
|
||||
@@ -113,7 +113,7 @@ function _initToolGroups(toolNames, Enums, toolGroupService, commandsManager) {
|
||||
rotateIncrementDegrees: 0.1,
|
||||
},
|
||||
[toolNames.MipJumpToClick]: {
|
||||
toolGroupId: toolGroupIds.PT,
|
||||
targetViewportIds: ['ptAXIAL', 'ptCORONAL', 'ptSAGITTAL'],
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -24,8 +24,9 @@ function _createButton(type, id, icon, label, commands, tooltip) {
|
||||
|
||||
function _createColormap(label, colormap) {
|
||||
return {
|
||||
id: label,
|
||||
label,
|
||||
id: label.toString(),
|
||||
title: label,
|
||||
subtitle: label,
|
||||
type: 'action',
|
||||
commands: [
|
||||
{
|
||||
@@ -35,6 +36,13 @@ function _createColormap(label, colormap) {
|
||||
colormap,
|
||||
},
|
||||
},
|
||||
{
|
||||
commandName: 'setFusionPTColormap',
|
||||
commandOptions: {
|
||||
toolGroupId: toolGroupIds.Fusion,
|
||||
colormap,
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
@@ -305,8 +313,7 @@ const toolbarButtons = [
|
||||
commandName: 'displayNotification',
|
||||
commandOptions: {
|
||||
title: 'RectangleROI Threshold Tip',
|
||||
text:
|
||||
'RectangleROI Threshold tool should be used on PT Axial Viewport',
|
||||
text: 'RectangleROI Threshold tool should be used on PT Axial Viewport',
|
||||
type: 'info',
|
||||
},
|
||||
},
|
||||
@@ -338,6 +345,7 @@ const toolbarButtons = [
|
||||
tooltip: 'PET Image Colormap',
|
||||
},
|
||||
isAction: true, // ?
|
||||
renderer: WindowLevelMenuItem,
|
||||
items: [
|
||||
_createColormap('HSV', 'hsv'),
|
||||
_createColormap('Hot Iron', 'hot_iron'),
|
||||
|
||||
@@ -149,6 +149,7 @@
|
||||
]
|
||||
},
|
||||
"resolutions": {
|
||||
"@cornerstonejs/core": "^1.1.0",
|
||||
"**/@babel/runtime": "^7.20.13",
|
||||
"commander": "8.3.0",
|
||||
"nth-check": "^2.1.1",
|
||||
|
||||
+4
-4
@@ -1,5 +1,5 @@
|
||||
describe('OHIF Context Menu', function() {
|
||||
beforeEach(function() {
|
||||
describe('OHIF Context Menu', function () {
|
||||
beforeEach(function () {
|
||||
cy.checkStudyRouteInViewer(
|
||||
'1.2.840.113619.2.5.1762583153.215519.978957063.78'
|
||||
);
|
||||
@@ -10,10 +10,10 @@ describe('OHIF Context Menu', function() {
|
||||
cy.resetViewport().wait(50);
|
||||
});
|
||||
|
||||
it('checks context menu customization', function() {
|
||||
it('checks context menu customization', function () {
|
||||
// Add length measurement
|
||||
cy.addLengthMeasurement();
|
||||
cy.get('[data-cy="prompt-begin-tracking-yes-btn"]').click();
|
||||
cy.get('[data-cy="prompt-begin-tracking-yes"]').click();
|
||||
cy.get('[data-cy="measurement-item"]').click();
|
||||
|
||||
const [x1, y1] = [150, 100];
|
||||
|
||||
+1
-1
@@ -113,7 +113,7 @@ describe('OHIF Cornerstone Toolbar', () => {
|
||||
cy.addLengthMeasurement();
|
||||
cy.get('[data-cy="viewport-notification"]').should('exist');
|
||||
cy.get('[data-cy="viewport-notification"]').should('be.visible');
|
||||
cy.get('[data-cy="prompt-begin-tracking-yes-btn"]').click();
|
||||
cy.get('[data-cy="prompt-begin-tracking-yes"]').click();
|
||||
|
||||
//Verify the measurement exists in the table
|
||||
cy.get('@measurementsPanel').should('be.visible');
|
||||
|
||||
@@ -27,7 +27,7 @@ describe('OHIF Measurement Panel', function() {
|
||||
cy.addLengthMeasurement();
|
||||
cy.get('[data-cy="viewport-notification"]').should('exist');
|
||||
cy.get('[data-cy="viewport-notification"]').should('be.visible');
|
||||
cy.get('[data-cy="prompt-begin-tracking-yes-btn"]').click();
|
||||
cy.get('[data-cy="prompt-begin-tracking-yes"]').click();
|
||||
cy.get('[data-cy="measurement-item"]').click();
|
||||
|
||||
cy.get('[data-cy="measurement-item"]')
|
||||
@@ -46,7 +46,7 @@ describe('OHIF Measurement Panel', function() {
|
||||
it('checks if image would jump when clicked on a measurement item', function() {
|
||||
// Add length measurement
|
||||
cy.addLengthMeasurement();
|
||||
cy.get('[data-cy="prompt-begin-tracking-yes-btn"]').click();
|
||||
cy.get('[data-cy="prompt-begin-tracking-yes"]').click();
|
||||
|
||||
cy.scrollToIndex(13);
|
||||
|
||||
|
||||
@@ -43,5 +43,3 @@
|
||||
# COMMENT: For sharedArrayBuffer, see https://developer.chrome.com/blog/enabling-shared-array-buffer/
|
||||
Cross-Origin-Embedder-Policy = "require-corp"
|
||||
Cross-Origin-Opener-Policy = "same-origin"
|
||||
# set CORP to cross-origin for anyone who wants to use the viewer in an iframe
|
||||
Cross-Origin-Resource-Policy = "cross-origin"
|
||||
+18
-18
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ohif/app",
|
||||
"version": "3.7.0-beta.32",
|
||||
"version": "3.6.0",
|
||||
"productVersion": "3.4.0",
|
||||
"description": "OHIF Viewer",
|
||||
"author": "OHIF Contributors",
|
||||
@@ -51,23 +51,23 @@
|
||||
"@cornerstonejs/codec-libjpeg-turbo-8bit": "^1.2.2",
|
||||
"@cornerstonejs/codec-openjpeg": "^1.2.2",
|
||||
"@cornerstonejs/codec-openjph": "^2.4.2",
|
||||
"@cornerstonejs/dicom-image-loader": "^1.4.1",
|
||||
"@ohif/core": "3.7.0-beta.32",
|
||||
"@ohif/extension-cornerstone": "3.7.0-beta.32",
|
||||
"@ohif/extension-cornerstone-dicom-rt": "3.7.0-beta.32",
|
||||
"@ohif/extension-cornerstone-dicom-seg": "3.7.0-beta.32",
|
||||
"@ohif/extension-cornerstone-dicom-sr": "3.7.0-beta.32",
|
||||
"@ohif/extension-default": "3.7.0-beta.32",
|
||||
"@ohif/extension-dicom-microscopy": "3.7.0-beta.32",
|
||||
"@ohif/extension-dicom-pdf": "3.7.0-beta.32",
|
||||
"@ohif/extension-dicom-video": "3.7.0-beta.32",
|
||||
"@ohif/extension-test": "3.7.0-beta.32",
|
||||
"@ohif/i18n": "3.7.0-beta.32",
|
||||
"@ohif/mode-basic-dev-mode": "3.7.0-beta.32",
|
||||
"@ohif/mode-longitudinal": "3.7.0-beta.32",
|
||||
"@ohif/mode-microscopy": "3.7.0-beta.32",
|
||||
"@ohif/mode-test": "3.7.0-beta.32",
|
||||
"@ohif/ui": "3.7.0-beta.32",
|
||||
"@cornerstonejs/dicom-image-loader": "^0.6.8",
|
||||
"@ohif/core": "3.6.0",
|
||||
"@ohif/extension-cornerstone": "3.6.0",
|
||||
"@ohif/extension-cornerstone-dicom-rt": "3.6.0",
|
||||
"@ohif/extension-cornerstone-dicom-seg": "3.6.0",
|
||||
"@ohif/extension-cornerstone-dicom-sr": "3.6.0",
|
||||
"@ohif/extension-default": "3.6.0",
|
||||
"@ohif/extension-dicom-microscopy": "3.6.0",
|
||||
"@ohif/extension-dicom-pdf": "3.6.0",
|
||||
"@ohif/extension-dicom-video": "3.6.0",
|
||||
"@ohif/extension-test": "3.6.0",
|
||||
"@ohif/i18n": "3.6.0",
|
||||
"@ohif/mode-basic-dev-mode": "3.6.0",
|
||||
"@ohif/mode-longitudinal": "3.6.0",
|
||||
"@ohif/mode-microscopy": "3.6.0",
|
||||
"@ohif/mode-test": "3.6.0",
|
||||
"@ohif/ui": "3.6.0",
|
||||
"@types/react": "^17.0.38",
|
||||
"classnames": "^2.3.2",
|
||||
"core-js": "^3.16.1",
|
||||
|
||||
@@ -4,7 +4,7 @@ window.config = {
|
||||
modes: [],
|
||||
showStudyList: true,
|
||||
// below flag is for performance reasons, but it might not work for all servers
|
||||
|
||||
omitQuotationForMultipartRequest: true,
|
||||
showWarningMessageForCrossOrigin: true,
|
||||
showCPUFallbackMessage: true,
|
||||
showLoadingIndicator: true,
|
||||
@@ -30,7 +30,6 @@ window.config = {
|
||||
supportsFuzzyMatching: false,
|
||||
supportsWildcard: false,
|
||||
staticWado: true,
|
||||
omitQuotationForMultipartRequest: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
|
||||
@@ -11,6 +11,7 @@ window.config = {
|
||||
// some windows systems have issues with more than 3 web workers
|
||||
maxNumberOfWebWorkers: 3,
|
||||
// below flag is for performance reasons, but it might not work for all servers
|
||||
omitQuotationForMultipartRequest: true,
|
||||
showWarningMessageForCrossOrigin: true,
|
||||
showCPUFallbackMessage: true,
|
||||
showLoadingIndicator: true,
|
||||
@@ -50,6 +51,7 @@ window.config = {
|
||||
wadoUriRoot: 'https://d33do7qe4w26qo.cloudfront.net/dicomweb',
|
||||
qidoRoot: 'https://d33do7qe4w26qo.cloudfront.net/dicomweb',
|
||||
wadoRoot: 'https://d33do7qe4w26qo.cloudfront.net/dicomweb',
|
||||
|
||||
qidoSupportsIncludeField: false,
|
||||
supportsReject: false,
|
||||
imageRendering: 'wadors',
|
||||
@@ -66,7 +68,6 @@ window.config = {
|
||||
enabled: true,
|
||||
relativeResolution: 'studies',
|
||||
},
|
||||
omitQuotationForMultipartRequest: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
|
||||
@@ -4,6 +4,7 @@ window.config = {
|
||||
extensions: [],
|
||||
showStudyList: true,
|
||||
// below flag is for performance reasons, but it might not work for all servers
|
||||
omitQuotationForMultipartRequest: true,
|
||||
showWarningMessageForCrossOrigin: true,
|
||||
strictZSpacingForVolumeViewport: true,
|
||||
showCPUFallbackMessage: true,
|
||||
@@ -24,7 +25,6 @@ window.config = {
|
||||
bulkDataURI: {
|
||||
enabled: false,
|
||||
},
|
||||
omitQuotationForMultipartRequest: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
|
||||
@@ -4,6 +4,7 @@ window.config = {
|
||||
modes: [],
|
||||
showStudyList: true,
|
||||
// below flag is for performance reasons, but it might not work for all servers
|
||||
omitQuotationForMultipartRequest: true,
|
||||
showWarningMessageForCrossOrigin: true,
|
||||
showCPUFallbackMessage: true,
|
||||
showLoadingIndicator: true,
|
||||
@@ -27,7 +28,6 @@ window.config = {
|
||||
enableStudyLazyLoad: true,
|
||||
supportsFuzzyMatching: false,
|
||||
supportsWildcard: false,
|
||||
omitQuotationForMultipartRequest: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
|
||||
@@ -5,6 +5,7 @@ window.config = {
|
||||
showStudyList: true,
|
||||
maxNumberOfWebWorkers: 3,
|
||||
// below flag is for performance reasons, but it might not work for all servers
|
||||
omitQuotationForMultipartRequest: true,
|
||||
showWarningMessageForCrossOrigin: true,
|
||||
showCPUFallbackMessage: true,
|
||||
showLoadingIndicator: true,
|
||||
@@ -30,7 +31,6 @@ window.config = {
|
||||
supportsWildcard: true,
|
||||
staticWado: true,
|
||||
singlepart: 'bulkdata,video,pdf',
|
||||
omitQuotationForMultipartRequest: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
|
||||
@@ -4,6 +4,7 @@ window.config = {
|
||||
extensions: [],
|
||||
modes: [],
|
||||
// below flag is for performance reasons, but it might not work for all servers
|
||||
omitQuotationForMultipartRequest: true,
|
||||
showWarningMessageForCrossOrigin: true,
|
||||
showCPUFallbackMessage: true,
|
||||
showLoadingIndicator: true,
|
||||
@@ -22,7 +23,6 @@ window.config = {
|
||||
qidoSupportsIncludeField: false,
|
||||
imageRendering: 'wadors',
|
||||
thumbnailRendering: 'wadors',
|
||||
omitQuotationForMultipartRequest: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
|
||||
@@ -2,6 +2,7 @@ window.config = {
|
||||
routerBasename: '/',
|
||||
showStudyList: true,
|
||||
// below flag is for performance reasons, but it might not work for all servers
|
||||
omitQuotationForMultipartRequest: true,
|
||||
showWarningMessageForCrossOrigin: true,
|
||||
showCPUFallbackMessage: true,
|
||||
showLoadingIndicator: true,
|
||||
@@ -17,7 +18,6 @@ window.config = {
|
||||
qidoSupportsIncludeField: false,
|
||||
imageRendering: 'wadors',
|
||||
thumbnailRendering: 'wadors',
|
||||
omitQuotationForMultipartRequest: true,
|
||||
// REQUIRED TAG:
|
||||
// TODO: Remove tag after https://github.com/OHIF/ohif-core/pull/19 is merged and we bump version
|
||||
// requestOptions: {
|
||||
|
||||
@@ -4,7 +4,7 @@ window.config = {
|
||||
extensions: [],
|
||||
modes: [],
|
||||
// below flag is for performance reasons, but it might not work for all servers
|
||||
|
||||
omitQuotationForMultipartRequest: true,
|
||||
showWarningMessageForCrossOrigin: true,
|
||||
showCPUFallbackMessage: true,
|
||||
showLoadingIndicator: true,
|
||||
@@ -23,7 +23,6 @@ window.config = {
|
||||
qidoSupportsIncludeField: false,
|
||||
imageRendering: 'wadors',
|
||||
thumbnailRendering: 'wadors',
|
||||
omitQuotationForMultipartRequest: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
|
||||
@@ -4,6 +4,7 @@ window.config = {
|
||||
modes: ['@ohif/mode-test'],
|
||||
showStudyList: true,
|
||||
// below flag is for performance reasons, but it might not work for all servers
|
||||
omitQuotationForMultipartRequest: true,
|
||||
maxNumberOfWebWorkers: 3,
|
||||
showWarningMessageForCrossOrigin: false,
|
||||
showCPUFallbackMessage: false,
|
||||
@@ -30,7 +31,6 @@ window.config = {
|
||||
supportsFuzzyMatching: false,
|
||||
supportsWildcard: true,
|
||||
singlepart: 'video,thumbnail,pdf',
|
||||
omitQuotationForMultipartRequest: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
|
||||
@@ -6,6 +6,7 @@ window.config = {
|
||||
},
|
||||
enableGoogleCloudAdapter: false,
|
||||
// below flag is for performance reasons, but it might not work for all servers
|
||||
omitQuotationForMultipartRequest: true,
|
||||
showWarningMessageForCrossOrigin: true,
|
||||
showCPUFallbackMessage: true,
|
||||
showLoadingIndicator: true,
|
||||
@@ -54,7 +55,6 @@ window.config = {
|
||||
supportsFuzzyMatching: true,
|
||||
supportsWildcard: false,
|
||||
dicomUploadEnabled: true,
|
||||
omitQuotationForMultipartRequest: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
|
||||
@@ -2,6 +2,7 @@ window.config = {
|
||||
routerBasename: '/',
|
||||
enableGoogleCloudAdapter: true,
|
||||
// below flag is for performance reasons, but it might not work for all servers
|
||||
omitQuotationForMultipartRequest: true,
|
||||
showWarningMessageForCrossOrigin: true,
|
||||
showCPUFallbackMessage: true,
|
||||
showLoadingIndicator: true,
|
||||
|
||||
@@ -8,6 +8,7 @@ window.config = {
|
||||
extensions: [],
|
||||
modes: [],
|
||||
// below flag is for performance reasons, but it might not work for all servers
|
||||
omitQuotationForMultipartRequest: true,
|
||||
showWarningMessageForCrossOrigin: true,
|
||||
showCPUFallbackMessage: true,
|
||||
showLoadingIndicator: true,
|
||||
@@ -38,7 +39,6 @@ window.config = {
|
||||
bulkDataURI: {
|
||||
enabled: true,
|
||||
},
|
||||
omitQuotationForMultipartRequest: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
|
||||
@@ -8,6 +8,7 @@ window.config = {
|
||||
showStudyList: true,
|
||||
maxNumberOfWebWorkers: 4,
|
||||
// below flag is for performance reasons, but it might not work for all servers
|
||||
omitQuotationForMultipartRequest: true,
|
||||
showWarningMessageForCrossOrigin: true,
|
||||
showCPUFallbackMessage: true,
|
||||
showLoadingIndicator: true,
|
||||
@@ -32,7 +33,6 @@ window.config = {
|
||||
supportsWildcard: true,
|
||||
staticWado: true,
|
||||
singlepart: 'bulkdata,video,pdf',
|
||||
omitQuotationForMultipartRequest: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
|
||||
@@ -16,6 +16,7 @@ window.config = {
|
||||
showStudyList: true,
|
||||
maxNumberOfWebWorkers: 4,
|
||||
// below flag is for performance reasons, but it might not work for all servers
|
||||
omitQuotationForMultipartRequest: true,
|
||||
showWarningMessageForCrossOrigin: true,
|
||||
showCPUFallbackMessage: true,
|
||||
showLoadingIndicator: true,
|
||||
@@ -41,7 +42,6 @@ window.config = {
|
||||
supportsWildcard: true,
|
||||
staticWado: true,
|
||||
singlepart: 'bulkdata,video,pdf',
|
||||
omitQuotationForMultipartRequest: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
|
||||
@@ -4,6 +4,7 @@ window.config = {
|
||||
modes: [],
|
||||
showStudyList: true,
|
||||
// below flag is for performance reasons, but it might not work for all servers
|
||||
omitQuotationForMultipartRequest: true,
|
||||
showWarningMessageForCrossOrigin: true,
|
||||
showCPUFallbackMessage: true,
|
||||
showLoadingIndicator: true,
|
||||
@@ -37,7 +38,6 @@ window.config = {
|
||||
enabled: true,
|
||||
relativeResolution: 'studies',
|
||||
},
|
||||
omitQuotationForMultipartRequest: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
|
||||
@@ -2,6 +2,7 @@ window.config = {
|
||||
routerBasename: '/',
|
||||
showStudyList: true,
|
||||
// below flag is for performance reasons, but it might not work for all servers
|
||||
omitQuotationForMultipartRequest: true,
|
||||
showWarningMessageForCrossOrigin: true,
|
||||
showCPUFallbackMessage: true,
|
||||
showLoadingIndicator: true,
|
||||
@@ -17,7 +18,6 @@ window.config = {
|
||||
imageRendering: 'wadors',
|
||||
thumbnailRendering: 'wadors',
|
||||
supportsFuzzyMatching: true,
|
||||
omitQuotationForMultipartRequest: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
@@ -15,7 +15,7 @@ import { utils, hotkeys, ServicesManager } from '@ohif/core';
|
||||
import {
|
||||
Icon,
|
||||
StudyListExpandedRow,
|
||||
LegacyButton,
|
||||
Button,
|
||||
EmptyStudies,
|
||||
StudyListTable,
|
||||
StudyListPagination,
|
||||
@@ -336,56 +336,46 @@ function WorkList({
|
||||
: []
|
||||
}
|
||||
>
|
||||
<div className="flex flex-row gap-2">
|
||||
{appConfig.loadedModes.map((mode, i) => {
|
||||
const isFirst = i === 0;
|
||||
{appConfig.loadedModes.map((mode, i) => {
|
||||
const isFirst = i === 0;
|
||||
|
||||
const modalitiesToCheck = modalities.replaceAll('/', '\\');
|
||||
const modalitiesToCheck = modalities.replaceAll('/', '\\');
|
||||
|
||||
const isValidMode = mode.isValidMode({
|
||||
modalities: modalitiesToCheck,
|
||||
study,
|
||||
});
|
||||
// TODO: Modes need a default/target route? We mostly support a single one for now.
|
||||
// We should also be using the route path, but currently are not
|
||||
// mode.routeName
|
||||
// mode.routes[x].path
|
||||
// Don't specify default data source, and it should just be picked up... (this may not currently be the case)
|
||||
// How do we know which params to pass? Today, it's just StudyInstanceUIDs and configUrl if exists
|
||||
const query = new URLSearchParams();
|
||||
if (filterValues.configUrl) {
|
||||
query.append('configUrl', filterValues.configUrl);
|
||||
}
|
||||
query.append('StudyInstanceUIDs', studyInstanceUid);
|
||||
return (
|
||||
<Link
|
||||
className={isValidMode ? '' : 'cursor-not-allowed'}
|
||||
key={i}
|
||||
to={`${dataPath ? '../../' : ''}${mode.routeName}${dataPath ||
|
||||
''}?${query.toString()}`}
|
||||
onClick={event => {
|
||||
// In case any event bubbles up for an invalid mode, prevent the navigation.
|
||||
// For example, the event bubbles up when the icon embedded in the disabled button is clicked.
|
||||
if (!isValidMode) {
|
||||
event.preventDefault();
|
||||
}
|
||||
}}
|
||||
// to={`${mode.routeName}/dicomweb?StudyInstanceUIDs=${studyInstanceUid}`}
|
||||
const isValidMode = mode.isValidMode({
|
||||
modalities: modalitiesToCheck,
|
||||
study,
|
||||
});
|
||||
// TODO: Modes need a default/target route? We mostly support a single one for now.
|
||||
// We should also be using the route path, but currently are not
|
||||
// mode.routeName
|
||||
// mode.routes[x].path
|
||||
// Don't specify default data source, and it should just be picked up... (this may not currently be the case)
|
||||
// How do we know which params to pass? Today, it's just StudyInstanceUIDs and configUrl if exists
|
||||
const query = new URLSearchParams();
|
||||
if (filterValues.configUrl) {
|
||||
query.append('configUrl', filterValues.configUrl);
|
||||
}
|
||||
query.append('StudyInstanceUIDs', studyInstanceUid);
|
||||
return (
|
||||
<Link
|
||||
key={i}
|
||||
to={`${dataPath ? '../../' : ''}${mode.routeName}${dataPath ||
|
||||
''}?${query.toString()}`}
|
||||
// to={`${mode.routeName}/dicomweb?StudyInstanceUIDs=${studyInstanceUid}`}
|
||||
>
|
||||
<Button
|
||||
rounded="full"
|
||||
variant={isValidMode ? 'contained' : 'disabled'}
|
||||
disabled={!isValidMode}
|
||||
endIcon={<Icon name="launch-arrow" />} // launch-arrow | launch-info
|
||||
className={classnames('font-medium ', { 'ml-2': !isFirst })}
|
||||
onClick={() => {}}
|
||||
>
|
||||
{/* TODO revisit the completely rounded style of buttons used for launching a mode from the worklist later - for now use LegacyButton*/}
|
||||
<LegacyButton
|
||||
rounded="full"
|
||||
variant={isValidMode ? 'contained' : 'disabled'}
|
||||
disabled={!isValidMode}
|
||||
endIcon={<Icon name="launch-arrow" />} // launch-arrow | launch-info
|
||||
onClick={() => {}}
|
||||
>
|
||||
{t(`Modes:${mode.displayName}`)}
|
||||
</LegacyButton>
|
||||
</Link>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
{t(`Modes:${mode.displayName}`)}
|
||||
</Button>
|
||||
</Link>
|
||||
);
|
||||
})}
|
||||
</StudyListExpandedRow>
|
||||
),
|
||||
onClickRow: () =>
|
||||
|
||||
@@ -74,16 +74,9 @@ module.exports = {
|
||||
},
|
||||
|
||||
customblue: {
|
||||
10: '#0A163F',
|
||||
20: '#0B1F54',
|
||||
30: '#09286e',
|
||||
40: '#0E307F',
|
||||
50: '#0F3A94',
|
||||
80: '#1454D4',
|
||||
100: '#c4fdff',
|
||||
200: '#38daff',
|
||||
300: '#1D204D',
|
||||
400: '#90A0C1',
|
||||
},
|
||||
|
||||
customgray: {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ohif/cli",
|
||||
"version": "3.7.0-beta.32",
|
||||
"version": "3.6.0",
|
||||
"description": "A CLI to bootstrap new OHIF extension or mode",
|
||||
"type": "module",
|
||||
"main": "src/index.js",
|
||||
|
||||
@@ -1,26 +1,5 @@
|
||||
// https://babeljs.io/docs/en/options#babelrcroots
|
||||
const { extendDefaultPlugins } = require('svgo');
|
||||
|
||||
module.exports = {
|
||||
plugins: [
|
||||
[
|
||||
'inline-react-svg',
|
||||
{
|
||||
svgo: {
|
||||
plugins: extendDefaultPlugins([
|
||||
{
|
||||
name: 'removeViewBox',
|
||||
active: false,
|
||||
},
|
||||
]),
|
||||
},
|
||||
},
|
||||
],
|
||||
['@babel/plugin-proposal-class-properties', { loose: true }],
|
||||
'@babel/plugin-transform-typescript',
|
||||
['@babel/plugin-proposal-private-property-in-object', { loose: true }],
|
||||
['@babel/plugin-proposal-private-methods', { loose: true }],
|
||||
],
|
||||
plugins: ['inline-react-svg', '@babel/plugin-proposal-class-properties'],
|
||||
env: {
|
||||
test: {
|
||||
presets: [
|
||||
@@ -31,16 +10,15 @@ module.exports = {
|
||||
modules: 'commonjs',
|
||||
debug: false,
|
||||
},
|
||||
"@babel/preset-typescript",
|
||||
],
|
||||
'@babel/preset-react',
|
||||
'@babel/preset-typescript',
|
||||
],
|
||||
plugins: [
|
||||
'@babel/plugin-proposal-object-rest-spread',
|
||||
'@babel/plugin-syntax-dynamic-import',
|
||||
'@babel/plugin-transform-regenerator',
|
||||
'@babel/plugin-transform-runtime',
|
||||
'@babel/plugin-transform-typescript',
|
||||
],
|
||||
},
|
||||
production: {
|
||||
@@ -48,7 +26,7 @@ module.exports = {
|
||||
// WebPack handles ES6 --> Target Syntax
|
||||
['@babel/preset-env', { modules: false }],
|
||||
'@babel/preset-react',
|
||||
'@babel/preset-typescript',
|
||||
"@babel/preset-typescript",
|
||||
],
|
||||
ignore: ['**/*.test.jsx', '**/*.test.js', '__snapshots__', '__tests__'],
|
||||
},
|
||||
@@ -57,7 +35,7 @@ module.exports = {
|
||||
// WebPack handles ES6 --> Target Syntax
|
||||
['@babel/preset-env', { modules: false }],
|
||||
'@babel/preset-react',
|
||||
'@babel/preset-typescript',
|
||||
"@babel/preset-typescript",
|
||||
],
|
||||
plugins: ['react-hot-loader/babel'],
|
||||
ignore: ['**/*.test.jsx', '**/*.test.js', '__snapshots__', '__tests__'],
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
},
|
||||
"scripts": {
|
||||
"dev": "cross-env NODE_ENV=development webpack --config .webpack/webpack.dev.js --watch --output-pathinfo",
|
||||
"dev:my-extension": "yarn run dev",
|
||||
"dev:dicom-pdf": "yarn run dev",
|
||||
"build": "cross-env NODE_ENV=production webpack --config .webpack/webpack.prod.js",
|
||||
"build:package": "yarn run build",
|
||||
"start": "yarn run dev"
|
||||
@@ -40,14 +40,14 @@
|
||||
"@babel/plugin-transform-arrow-functions": "^7.16.7",
|
||||
"@babel/plugin-transform-regenerator": "^7.16.7",
|
||||
"@babel/plugin-transform-runtime": "^7.17.0",
|
||||
"babel-plugin-inline-react-svg": "^2.0.1",
|
||||
"@babel/plugin-transform-typescript": "^7.13.0",
|
||||
"@babel/preset-env": "^7.16.11",
|
||||
"@babel/preset-react": "^7.16.7",
|
||||
"@babel/preset-typescript": "^7.13.0",
|
||||
"babel-eslint": "9.x",
|
||||
"babel-loader": "^8.2.4",
|
||||
"babel-plugin-inline-react-svg": "^2.0.2",
|
||||
"babel-plugin-module-resolver": "^5.0.0",
|
||||
|
||||
"babel-eslint": "^8.0.3",
|
||||
"babel-loader": "^8.0.0-beta.4",
|
||||
"clean-webpack-plugin": "^4.0.0",
|
||||
"copy-webpack-plugin": "^10.2.0",
|
||||
"cross-env": "^7.0.3",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ohif/core",
|
||||
"version": "3.7.0-beta.32",
|
||||
"version": "3.6.0",
|
||||
"description": "Generic business logic for web-based medical imaging applications",
|
||||
"author": "OHIF Core Team",
|
||||
"license": "MIT",
|
||||
@@ -35,8 +35,8 @@
|
||||
"@cornerstonejs/codec-libjpeg-turbo-8bit": "^1.2.2",
|
||||
"@cornerstonejs/codec-openjpeg": "^1.2.2",
|
||||
"@cornerstonejs/codec-openjph": "^2.4.2",
|
||||
"@cornerstonejs/dicom-image-loader": "^1.4.1",
|
||||
"@ohif/ui": "3.7.0-beta.32",
|
||||
"@cornerstonejs/dicom-image-loader": "^0.6.8",
|
||||
"@ohif/ui": "3.6.0",
|
||||
"cornerstone-math": "0.1.9",
|
||||
"dicom-parser": "^1.8.21"
|
||||
},
|
||||
|
||||
@@ -173,31 +173,30 @@ const bindings = [
|
||||
label: 'W/L Preset 5',
|
||||
keys: ['5'],
|
||||
},
|
||||
// These don't exist, so don't try applying them....
|
||||
// {
|
||||
// commandName: 'setWindowLevel',
|
||||
// commandOptions: windowLevelPresets[6],
|
||||
// label: 'W/L Preset 6',
|
||||
// keys: ['6'],
|
||||
// },
|
||||
// {
|
||||
// commandName: 'setWindowLevel',
|
||||
// commandOptions: windowLevelPresets[7],
|
||||
// label: 'W/L Preset 7',
|
||||
// keys: ['7'],
|
||||
// },
|
||||
// {
|
||||
// commandName: 'setWindowLevel',
|
||||
// commandOptions: windowLevelPresets[8],
|
||||
// label: 'W/L Preset 8',
|
||||
// keys: ['8'],
|
||||
// },
|
||||
// {
|
||||
// commandName: 'setWindowLevel',
|
||||
// commandOptions: windowLevelPresets[9],
|
||||
// label: 'W/L Preset 9',
|
||||
// keys: ['9'],
|
||||
// },
|
||||
{
|
||||
commandName: 'setWindowLevel',
|
||||
commandOptions: windowLevelPresets[6],
|
||||
label: 'W/L Preset 6',
|
||||
keys: ['6'],
|
||||
},
|
||||
{
|
||||
commandName: 'setWindowLevel',
|
||||
commandOptions: windowLevelPresets[7],
|
||||
label: 'W/L Preset 7',
|
||||
keys: ['7'],
|
||||
},
|
||||
{
|
||||
commandName: 'setWindowLevel',
|
||||
commandOptions: windowLevelPresets[8],
|
||||
label: 'W/L Preset 8',
|
||||
keys: ['8'],
|
||||
},
|
||||
{
|
||||
commandName: 'setWindowLevel',
|
||||
commandOptions: windowLevelPresets[9],
|
||||
label: 'W/L Preset 9',
|
||||
keys: ['9'],
|
||||
},
|
||||
];
|
||||
|
||||
export default bindings;
|
||||
@@ -695,18 +695,15 @@ export default class HangingProtocolService extends PubSubService {
|
||||
) {
|
||||
viewport.displaySets.forEach(displaySet => {
|
||||
const { id } = displaySet;
|
||||
const displaySetMatchDetail = displaySetMatchDetails.get(id);
|
||||
const {
|
||||
displaySetInstanceUID: oldDisplaySetInstanceUID,
|
||||
} = displaySetMatchDetails.get(id);
|
||||
|
||||
const { displaySetInstanceUID: oldDisplaySetInstanceUID } = displaySetMatchDetail;
|
||||
|
||||
const displaySetInstanceUID =
|
||||
displaySetInstanceUIDs.push(
|
||||
displaySet.id === displaySetSelectorId
|
||||
? newDisplaySetInstanceUID
|
||||
: oldDisplaySetInstanceUID;
|
||||
|
||||
displaySetMatchDetail.displaySetInstanceUID = displaySetInstanceUID;
|
||||
|
||||
displaySetInstanceUIDs.push(displaySetInstanceUID);
|
||||
: oldDisplaySetInstanceUID
|
||||
);
|
||||
displaySetOptions.push(displaySet);
|
||||
});
|
||||
}
|
||||
@@ -1392,20 +1389,17 @@ export default class HangingProtocolService extends PubSubService {
|
||||
this.studies.forEach(study => {
|
||||
// Skip non-active if active only
|
||||
if (matchActiveOnly && this.activeStudy !== study) return;
|
||||
|
||||
const studyDisplaySets = this.displaySets.filter(
|
||||
it => it.StudyInstanceUID === study.StudyInstanceUID
|
||||
it => it.StudyInstanceUID === study.StudyInstanceUID
|
||||
);
|
||||
|
||||
const studyMatchDetails = this.protocolEngine.findMatch(
|
||||
study,
|
||||
studyMatchingRules,
|
||||
{
|
||||
studies: this.studies,
|
||||
displaySets: studyDisplaySets,
|
||||
allDisplaySets: this.displaySets,
|
||||
displaySetMatchDetails: this.displaySetMatchDetails,
|
||||
}
|
||||
study,
|
||||
studyMatchingRules,
|
||||
{
|
||||
studies: this.studies,
|
||||
displaySets: studyDisplaySets,
|
||||
displaySetMatchDetails: this.displaySetMatchDetails,
|
||||
}
|
||||
);
|
||||
|
||||
// Prevent bestMatch from being updated if the matchDetails' required attribute check has failed
|
||||
@@ -1414,10 +1408,10 @@ export default class HangingProtocolService extends PubSubService {
|
||||
}
|
||||
|
||||
this.debug(
|
||||
'study',
|
||||
study.StudyInstanceUID,
|
||||
'display sets #',
|
||||
studyDisplaySets.length
|
||||
'study',
|
||||
study.StudyInstanceUID,
|
||||
'display sets #',
|
||||
studyDisplaySets.length
|
||||
);
|
||||
studyDisplaySets.forEach(displaySet => {
|
||||
const {
|
||||
@@ -1426,15 +1420,15 @@ export default class HangingProtocolService extends PubSubService {
|
||||
displaySetInstanceUID,
|
||||
} = displaySet;
|
||||
const seriesMatchDetails = this.protocolEngine.findMatch(
|
||||
displaySet,
|
||||
seriesMatchingRules,
|
||||
// Todo: why we have images here since the matching type does not have it
|
||||
{
|
||||
studies: this.studies,
|
||||
instance: displaySet.images?.[0],
|
||||
displaySetMatchDetails: this.displaySetMatchDetails,
|
||||
displaySets: studyDisplaySets,
|
||||
}
|
||||
displaySet,
|
||||
seriesMatchingRules,
|
||||
// Todo: why we have images here since the matching type does not have it
|
||||
{
|
||||
studies: this.studies,
|
||||
instance: displaySet.images?.[0],
|
||||
displaySetMatchDetails: this.displaySetMatchDetails,
|
||||
displaySets: studyDisplaySets,
|
||||
}
|
||||
);
|
||||
|
||||
// Prevent bestMatch from being updated if the matchDetails' required attribute check has failed
|
||||
|
||||
Loaded 100 of 578 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user