diff --git a/extensions/cornerstone-dicom-pmap/package.json b/extensions/cornerstone-dicom-pmap/package.json index e1b6538e3..fa671a7b9 100644 --- a/extensions/cornerstone-dicom-pmap/package.json +++ b/extensions/cornerstone-dicom-pmap/package.json @@ -46,8 +46,8 @@ }, "dependencies": { "@babel/runtime": "^7.20.13", - "@cornerstonejs/adapters": "^2.2.1", - "@cornerstonejs/core": "^2.2.1", + "@cornerstonejs/adapters": "^2.2.3", + "@cornerstonejs/core": "^2.2.3", "@kitware/vtk.js": "32.1.0", "react-color": "^2.19.3" } diff --git a/extensions/cornerstone-dicom-seg/package.json b/extensions/cornerstone-dicom-seg/package.json index 43b9078d6..86ecdb717 100644 --- a/extensions/cornerstone-dicom-seg/package.json +++ b/extensions/cornerstone-dicom-seg/package.json @@ -46,8 +46,8 @@ }, "dependencies": { "@babel/runtime": "^7.20.13", - "@cornerstonejs/adapters": "^2.2.1", - "@cornerstonejs/core": "^2.2.1", + "@cornerstonejs/adapters": "^2.2.3", + "@cornerstonejs/core": "^2.2.3", "@kitware/vtk.js": "32.1.0", "react-color": "^2.19.3" } diff --git a/extensions/cornerstone-dicom-sr/package.json b/extensions/cornerstone-dicom-sr/package.json index e5cd19893..098bd6dc0 100644 --- a/extensions/cornerstone-dicom-sr/package.json +++ b/extensions/cornerstone-dicom-sr/package.json @@ -46,9 +46,9 @@ }, "dependencies": { "@babel/runtime": "^7.20.13", - "@cornerstonejs/adapters": "^2.2.1", - "@cornerstonejs/core": "^2.2.1", - "@cornerstonejs/tools": "^2.2.1", + "@cornerstonejs/adapters": "^2.2.3", + "@cornerstonejs/core": "^2.2.3", + "@cornerstonejs/tools": "^2.2.3", "classnames": "^2.3.2" } } diff --git a/extensions/cornerstone-dynamic-volume/package.json b/extensions/cornerstone-dynamic-volume/package.json index d9ced5029..92ad492b5 100644 --- a/extensions/cornerstone-dynamic-volume/package.json +++ b/extensions/cornerstone-dynamic-volume/package.json @@ -42,8 +42,8 @@ }, "dependencies": { "@babel/runtime": "^7.20.13", - "@cornerstonejs/core": "^2.2.1", - "@cornerstonejs/tools": "^2.2.1", + "@cornerstonejs/core": "^2.2.3", + "@cornerstonejs/tools": "^2.2.3", "classnames": "^2.3.2" } } diff --git a/extensions/cornerstone/package.json b/extensions/cornerstone/package.json index e95f49314..0fecd958a 100644 --- a/extensions/cornerstone/package.json +++ b/extensions/cornerstone/package.json @@ -38,7 +38,7 @@ "@cornerstonejs/codec-libjpeg-turbo-8bit": "^1.2.2", "@cornerstonejs/codec-openjpeg": "^1.2.4", "@cornerstonejs/codec-openjph": "^2.4.5", - "@cornerstonejs/dicom-image-loader": "^2.2.1", + "@cornerstonejs/dicom-image-loader": "^2.2.3", "@icr/polyseg-wasm": "^0.4.0", "@ohif/core": "3.9.0-beta.110", "@ohif/ui": "3.9.0-beta.110", @@ -55,9 +55,9 @@ }, "dependencies": { "@babel/runtime": "^7.20.13", - "@cornerstonejs/adapters": "^2.2.1", - "@cornerstonejs/core": "^2.2.1", - "@cornerstonejs/tools": "^2.2.1", + "@cornerstonejs/adapters": "^2.2.3", + "@cornerstonejs/core": "^2.2.3", + "@cornerstonejs/tools": "^2.2.3", "@icr/polyseg-wasm": "^0.4.0", "@kitware/vtk.js": "32.1.0", "html2canvas": "^1.4.1", diff --git a/extensions/cornerstone/src/getPanelModule.tsx b/extensions/cornerstone/src/getPanelModule.tsx index 48cbd6eaa..bb3f65d9d 100644 --- a/extensions/cornerstone/src/getPanelModule.tsx +++ b/extensions/cornerstone/src/getPanelModule.tsx @@ -3,6 +3,7 @@ import React from 'react'; import { Toolbox } from '@ohif/ui-next'; import PanelSegmentation from './panels/PanelSegmentation'; import ActiveViewportWindowLevel from './components/ActiveViewportWindowLevel'; +import PanelMeasurementTable from './panels/PanelMeasurement'; const getPanelModule = ({ commandsManager, servicesManager, extensionManager }: withAppTypes) => { const wrappedPanelSegmentation = ({ configuration }) => { @@ -56,6 +57,19 @@ const getPanelModule = ({ commandsManager, servicesManager, extensionManager }: ); }; + const wrappedPanelMeasurement = ({ configuration }) => { + return ( + + ); + }; + return [ { name: 'activeViewportWindowLevel', @@ -63,6 +77,13 @@ const getPanelModule = ({ commandsManager, servicesManager, extensionManager }: return ; }, }, + { + name: 'panelMeasurement', + iconName: 'tab-linear', + iconLabel: 'Measure', + label: 'Measurement', + component: wrappedPanelMeasurement, + }, { name: 'panelSegmentation', iconName: 'tab-segmentation', diff --git a/extensions/cornerstone/src/initMeasurementService.ts b/extensions/cornerstone/src/initMeasurementService.ts index 1672ea79f..9433bb5ef 100644 --- a/extensions/cornerstone/src/initMeasurementService.ts +++ b/extensions/cornerstone/src/initMeasurementService.ts @@ -330,6 +330,9 @@ const connectMeasurementServiceToTools = (measurementService, cornerstoneViewpor } removeAnnotation(uid); } + + // trigger a render + cornerstoneViewportService.getRenderingEngine().render(); }); measurementService.subscribe( diff --git a/extensions/cornerstone/src/services/SyncGroupService/SyncGroupService.ts b/extensions/cornerstone/src/services/SyncGroupService/SyncGroupService.ts index 517231eb9..5a32367ce 100644 --- a/extensions/cornerstone/src/services/SyncGroupService/SyncGroupService.ts +++ b/extensions/cornerstone/src/services/SyncGroupService/SyncGroupService.ts @@ -148,6 +148,11 @@ export default class SyncGroupService { const { type, target = true, source = true, options = {}, id = type } = syncGroupObj; const synchronizer = this._getOrCreateSynchronizer(type, id, options); + + if (!synchronizer) { + return; + } + synchronizer.setOptions(viewportId, options); const viewportInfo = { viewportId, renderingEngineId }; diff --git a/extensions/cornerstone/src/services/ViewportService/CornerstoneViewportService.ts b/extensions/cornerstone/src/services/ViewportService/CornerstoneViewportService.ts index 51c7ce3fe..329610148 100644 --- a/extensions/cornerstone/src/services/ViewportService/CornerstoneViewportService.ts +++ b/extensions/cornerstone/src/services/ViewportService/CornerstoneViewportService.ts @@ -763,9 +763,11 @@ class CornerstoneViewportService extends PubSubService implements IViewportServi }); } - if (!volumesNotLoaded.length) { - return; - } + // It's crucial not to return here because the volume may be loaded, + // but the viewport also needs to set the volume. + // if (!volumesNotLoaded.length) { + // return; + // } // This returns the async continuation only return this.setVolumesForViewport(viewport, volumeInputArray, presentations); diff --git a/extensions/default/src/Panels/StudyBrowser/PanelStudyBrowserHeader.tsx b/extensions/default/src/Panels/StudyBrowser/PanelStudyBrowserHeader.tsx index 0a5d43f6f..0c55559ba 100644 --- a/extensions/default/src/Panels/StudyBrowser/PanelStudyBrowserHeader.tsx +++ b/extensions/default/src/Panels/StudyBrowser/PanelStudyBrowserHeader.tsx @@ -19,7 +19,18 @@ function PanelStudyBrowserHeader({
-
+
+
+ {actionIcons.map((icon: actionIcon, index) => + React.createElement(Icons[icon.iconName] || Icons.MissingIcon, { + key: index, + onClick: () => updateActionIconValue(icon), + className: `cursor-pointer`, + }) + )} +
+
+
preset.selected)[0].id} @@ -40,18 +51,6 @@ function PanelStudyBrowserHeader({ ))}
- -
-
- {actionIcons.map((icon: actionIcon, index) => - React.createElement(Icons[icon.iconName] || Icons.MissingIcon, { - key: index, - onClick: () => updateActionIconValue(icon), - className: `cursor-pointer`, - }) - )} -
-
diff --git a/extensions/default/src/index.ts b/extensions/default/src/index.ts index a2d7a6179..90976e045 100644 --- a/extensions/default/src/index.ts +++ b/extensions/default/src/index.ts @@ -35,6 +35,7 @@ import colorPickerDialog from './utils/colorPickerDialog'; import promptSaveReport from './utils/promptSaveReport'; import promptLabelAnnotation from './utils/promptLabelAnnotation'; import usePatientInfo from './hooks/usePatientInfo'; +import { PanelStudyBrowserHeader } from './Panels/StudyBrowser/PanelStudyBrowserHeader'; import * as utils from './utils'; const defaultExtension: Types.Extensions.Extension = { @@ -99,5 +100,6 @@ export { promptLabelAnnotation, colorPickerDialog, usePatientInfo, + PanelStudyBrowserHeader, utils, }; diff --git a/extensions/measurement-tracking/package.json b/extensions/measurement-tracking/package.json index b3f5628cf..5deee141e 100644 --- a/extensions/measurement-tracking/package.json +++ b/extensions/measurement-tracking/package.json @@ -32,8 +32,8 @@ "start": "yarn run dev" }, "peerDependencies": { - "@cornerstonejs/core": "^2.2.1", - "@cornerstonejs/tools": "^2.2.1", + "@cornerstonejs/core": "^2.2.3", + "@cornerstonejs/tools": "^2.2.3", "@ohif/core": "3.9.0-beta.110", "@ohif/extension-cornerstone-dicom-sr": "3.9.0-beta.110", "@ohif/extension-default": "3.9.0-beta.110", diff --git a/extensions/measurement-tracking/src/contexts/TrackedMeasurementsContext/TrackedMeasurementsContext.tsx b/extensions/measurement-tracking/src/contexts/TrackedMeasurementsContext/TrackedMeasurementsContext.tsx index 21b9efe9b..5b8c008fa 100644 --- a/extensions/measurement-tracking/src/contexts/TrackedMeasurementsContext/TrackedMeasurementsContext.tsx +++ b/extensions/measurement-tracking/src/contexts/TrackedMeasurementsContext/TrackedMeasurementsContext.tsx @@ -30,12 +30,7 @@ function TrackedMeasurementsContextProvider( const [viewportGrid, viewportGridService] = useViewportGrid(); const { activeViewportId, viewports } = viewportGrid; - const { - measurementService, - displaySetService, - customizationService, - cornerstoneViewportService, - } = servicesManager.services; + const { measurementService, displaySetService, customizationService } = servicesManager.services; const machineOptions = Object.assign({}, defaultOptions); machineOptions.actions = Object.assign({}, machineOptions.actions, { diff --git a/extensions/measurement-tracking/src/panels/PanelMeasurementTableTracking.tsx b/extensions/measurement-tracking/src/panels/PanelMeasurementTableTracking.tsx index 7ac0ebcc1..619c5d653 100644 --- a/extensions/measurement-tracking/src/panels/PanelMeasurementTableTracking.tsx +++ b/extensions/measurement-tracking/src/panels/PanelMeasurementTableTracking.tsx @@ -118,7 +118,7 @@ function PanelMeasurementTableTracking({ downloadCSVReport(trackedMeasurements); }} > - + CSV +
diff --git a/extensions/measurement-tracking/src/panels/PanelStudyBrowserTracking/PanelStudyBrowserTracking.tsx b/extensions/measurement-tracking/src/panels/PanelStudyBrowserTracking/PanelStudyBrowserTracking.tsx index 16de940d7..3c1df9190 100644 --- a/extensions/measurement-tracking/src/panels/PanelStudyBrowserTracking/PanelStudyBrowserTracking.tsx +++ b/extensions/measurement-tracking/src/panels/PanelStudyBrowserTracking/PanelStudyBrowserTracking.tsx @@ -8,7 +8,7 @@ import { StudyBrowser } from '@ohif/ui-next'; import { useTrackedMeasurements } from '../../getContextModule'; import { Separator } from '@ohif/ui-next'; -import { PanelStudyBrowserTrackingHeader } from './PanelStudyBrowserTrackingHeader'; +import { PanelStudyBrowserHeader } from '@ohif/extension-default'; import { defaultActionIcons, defaultViewPresets } from './constants'; const { formatDate, createStudyBrowserTabs } = utils; @@ -482,7 +482,7 @@ function PanelStudyBrowserTracking({ return ( <> <> - void; - actionIcons: actionIcon[]; - updateActionIconValue: (actionIcon: actionIcon) => void; -}) { - return ( - <> -
-
-
-
- preset.selected)[0].id} - onValueChange={value => { - const selectedViewPreset = viewPresets.find(preset => preset.id === value); - updateViewPresetValue(selectedViewPreset); - }} - > - {viewPresets.map((viewPreset: viewPreset, index) => ( - - {React.createElement(Icons[viewPreset.iconName] || Icons.MissingIcon)} - - ))} - -
-
-
- {actionIcons.map((icon: actionIcon, index) => - React.createElement(Icons[icon.iconName] || Icons.MissingIcon, { - key: index, - onClick: () => updateActionIconValue(icon), - className: `cursor-pointer`, - }) - )} -
-
-
-
-
- - ); -} - -export { PanelStudyBrowserTrackingHeader }; diff --git a/modes/longitudinal/src/index.ts b/modes/longitudinal/src/index.ts index 1e1617eff..68ce4ae38 100644 --- a/modes/longitudinal/src/index.ts +++ b/modes/longitudinal/src/index.ts @@ -19,7 +19,7 @@ const ohif = { }; const cornerstone = { - measurements: '@ohif/extension-cornerstone.panelModule.measurements', + measurements: '@ohif/extension-cornerstone.panelModule.panelMeasurement', segmentation: '@ohif/extension-cornerstone.panelModule.panelSegmentation', }; diff --git a/platform/app/cypress/integration/measurement-tracking/OHIFMeasurementPanel.spec.js b/platform/app/cypress/integration/measurement-tracking/OHIFMeasurementPanel.spec.js index 1cd9fa334..ad6837564 100644 --- a/platform/app/cypress/integration/measurement-tracking/OHIFMeasurementPanel.spec.js +++ b/platform/app/cypress/integration/measurement-tracking/OHIFMeasurementPanel.spec.js @@ -16,7 +16,12 @@ describe('OHIF Measurement Panel', function () { cy.get('@measurementsPanel').should('not.exist'); cy.get('@RightCollapseBtn').click(); - cy.get('@measurementsPanel').should('exist'); + + // segmentation panel should be visible + cy.get('@segmentationPanel').should('be.visible'); + + // measurements panel should be clickable + cy.get('@measurementsBtn').click(); cy.get('@measurementsPanel').should('be.visible'); }); diff --git a/platform/app/cypress/support/aliases.js b/platform/app/cypress/support/aliases.js index 1453c6f66..af1ad6c1c 100644 --- a/platform/app/cypress/support/aliases.js +++ b/platform/app/cypress/support/aliases.js @@ -27,6 +27,7 @@ export function initCommonElementsAliases(skipMarkers) { // TODO: Panels are not in DOM when closed, move this somewhere else cy.get('[data-cy="trackedMeasurements-panel"]').as('measurementsPanel'); + cy.get('[data-cy="panelSegmentation-btn"]').as('segmentationPanel'); cy.get('[data-cy="studyBrowser-panel"]').as('seriesPanel'); cy.get('[data-cy="viewport-overlay-top-right"]').as('viewportInfoTopRight'); cy.get('[data-cy="viewport-overlay-top-left"]').as('viewportInfoTopLeft'); diff --git a/platform/app/package.json b/platform/app/package.json index 1241939d2..84528ff26 100644 --- a/platform/app/package.json +++ b/platform/app/package.json @@ -53,7 +53,7 @@ "@cornerstonejs/codec-libjpeg-turbo-8bit": "^1.2.2", "@cornerstonejs/codec-openjpeg": "^1.2.4", "@cornerstonejs/codec-openjph": "^2.4.5", - "@cornerstonejs/dicom-image-loader": "^2.2.1", + "@cornerstonejs/dicom-image-loader": "^2.2.3", "@emotion/serialize": "^1.1.3", "@ohif/core": "3.9.0-beta.110", "@ohif/extension-cornerstone": "3.9.0-beta.110", diff --git a/platform/core/package.json b/platform/core/package.json index 3660a1ed2..afdcbccc6 100644 --- a/platform/core/package.json +++ b/platform/core/package.json @@ -37,7 +37,7 @@ "@cornerstonejs/codec-libjpeg-turbo-8bit": "^1.2.2", "@cornerstonejs/codec-openjpeg": "^1.2.4", "@cornerstonejs/codec-openjph": "^2.4.5", - "@cornerstonejs/dicom-image-loader": "^2.2.1", + "@cornerstonejs/dicom-image-loader": "^2.2.3", "@ohif/ui": "3.9.0-beta.110", "cornerstone-math": "0.1.9", "dicom-parser": "^1.8.21" diff --git a/platform/docs/docs/migration-guide/3p8-to-3p9/2-Renamings.md b/platform/docs/docs/migration-guide/3p8-to-3p9/2-Renamings.md index 2ad24c0a8..6c0763f3c 100644 --- a/platform/docs/docs/migration-guide/3p8-to-3p9/2-Renamings.md +++ b/platform/docs/docs/migration-guide/3p8-to-3p9/2-Renamings.md @@ -10,11 +10,11 @@ import TabItem from '@theme/TabItem'; ## Panel Measurements -The panel in the default extension is renamed from `measure` to `measurements` to be more consistent with the rest of the extensions. +The panel in the default extension is renamed from `measure` to `panelMeasurement` to be more consistent with the rest of the extensions. **Action Needed** -Update any references to the `measure` panel to `measurements` in your code. +Update any references to the `measure` panel to `panelMeasurement` in your code. Find and replace @@ -23,7 +23,7 @@ Find and replace @ohif/extension-default.panelModule.measure - @ohif/extension-default.panelModule.measurements + @ohif/extension-cornerstone.panelModule.panelMeasurement diff --git a/platform/docs/docs/migration-guide/3p8-to-3p9/7-UI.md b/platform/docs/docs/migration-guide/3p8-to-3p9/7-UI.md index 2dbb01c42..71e625d93 100644 --- a/platform/docs/docs/migration-guide/3p8-to-3p9/7-UI.md +++ b/platform/docs/docs/migration-guide/3p8-to-3p9/7-UI.md @@ -3,6 +3,15 @@ title: UI --- + + +## New Components + +You can explore our new playground at `docs.ohif.org/ui` to see the latest components and their properties. We haven't provided a migration guide yet because the old components are still available. Feel free to update your codebase, including custom extensions and UI, to use the new Button, Dropdown, Icons, and other new components from `@ohif/ui-next`. The old methods (importing from `@ohif/ui`) will continue to work for now. However, the new components have a slightly different API, and we plan to deprecate the old components in a future release, as we see the new ones as the future of OHIF. + + + + ## `UINotificationService` diff --git a/platform/ui-next/src/components/Icons/Icons.tsx b/platform/ui-next/src/components/Icons/Icons.tsx index 1c2e9596c..67577f20f 100644 --- a/platform/ui-next/src/components/Icons/Icons.tsx +++ b/platform/ui-next/src/components/Icons/Icons.tsx @@ -612,7 +612,6 @@ export const Icons = { xmlns="http://www.w3.org/2000/svg" {...props} > - icon-list-view