From 9b1b501d83502d13b285050bd5fca102b7f7612c Mon Sep 17 00:00:00 2001 From: Alireza Date: Fri, 16 May 2025 13:42:35 -0400 Subject: [PATCH] fix: backward compatibility with toolbar service (#5052) --- .../src/getPanelModule.tsx | 4 +- .../ViewportDataOverlayMenu.tsx | 2 +- extensions/cornerstone/src/getPanelModule.tsx | 4 +- .../cornerstone/src/hooks/useMeasurements.ts | 2 +- .../src/hooks/useViewportDisplaySets.ts | 27 ++++--- extensions/tmtv/src/getPanelModule.tsx | 6 +- modes/basic-dev-mode/src/index.ts | 2 +- modes/basic-dev-mode/src/toolbarButtons.ts | 6 +- modes/basic-test-mode/src/index.ts | 12 +-- modes/basic-test-mode/src/toolbarButtons.ts | 15 +--- modes/longitudinal/src/index.ts | 6 +- modes/longitudinal/src/toolbarButtons.ts | 6 +- modes/microscopy/src/index.tsx | 2 +- modes/microscopy/src/toolbarButtons.ts | 2 +- .../preclinical-4d/src/getWorkflowSettings.ts | 56 +++++++------ modes/preclinical-4d/src/index.tsx | 4 +- modes/preclinical-4d/src/toolbarButtons.tsx | 8 +- modes/segmentation/src/index.tsx | 12 +-- modes/segmentation/src/toolbarButtons.ts | 10 +-- modes/tmtv/src/index.ts | 4 +- modes/tmtv/src/toolbarButtons.ts | 8 +- .../integration/ImageConsistency.spec.js | 2 +- platform/cli/templates/mode/src/index.tsx | 8 +- .../services/ToolBarService/ToolbarService.ts | 49 ++++++++---- .../core/src/services/ToolBarService/types.ts | 4 +- .../WorkflowStepsService.ts | 2 +- .../3p10-to-3p11/toolbarService.md | 79 ++++++++++++------- 27 files changed, 198 insertions(+), 144 deletions(-) diff --git a/extensions/cornerstone-dynamic-volume/src/getPanelModule.tsx b/extensions/cornerstone-dynamic-volume/src/getPanelModule.tsx index a213ac1c1..ee55b0d77 100644 --- a/extensions/cornerstone-dynamic-volume/src/getPanelModule.tsx +++ b/extensions/cornerstone-dynamic-volume/src/getPanelModule.tsx @@ -5,6 +5,8 @@ import { PanelSegmentation } from '@ohif/extension-cornerstone'; import DynamicExport from './panels/DynamicExport'; function getPanelModule({ commandsManager, extensionManager, servicesManager, configuration }) { + const { toolbarService } = servicesManager.services; + const wrappedDynamicDataPanel = () => { return ( { diff --git a/extensions/cornerstone/src/getPanelModule.tsx b/extensions/cornerstone/src/getPanelModule.tsx index eea1b3616..19ec9d76e 100644 --- a/extensions/cornerstone/src/getPanelModule.tsx +++ b/extensions/cornerstone/src/getPanelModule.tsx @@ -33,10 +33,12 @@ const getPanelModule = ({ commandsManager, servicesManager, extensionManager }: }; const wrappedPanelSegmentationWithTools = ({ configuration }) => { + const { toolbarService } = servicesManager.services; + return ( <> true }) { const { servicesManager } = useSystem(); const { measurementService, displaySetService } = servicesManager.services; const [displayMeasurements, setDisplayMeasurements] = useState([]); diff --git a/extensions/cornerstone/src/hooks/useViewportDisplaySets.ts b/extensions/cornerstone/src/hooks/useViewportDisplaySets.ts index fef6901ca..b9bd56580 100644 --- a/extensions/cornerstone/src/hooks/useViewportDisplaySets.ts +++ b/extensions/cornerstone/src/hooks/useViewportDisplaySets.ts @@ -138,27 +138,29 @@ export function useViewportDisplaySets( }); }, [includeOverlay, segmentationRepresentations, displaySetService]); - const overlayDisplaySetUIDs = useMemo( - () => overlayDisplaySets.map(ds => ds.displaySetInstanceUID), - [overlayDisplaySets] - ); + const overlayDisplaySetUIDs = useMemo(() => { + return overlayDisplaySets.map(ds => ds.displaySetInstanceUID); + }, [overlayDisplaySets]); // Get enhanced display sets (only if needed) const needsEnhancedDisplaySets = includeBackground || includeForeground || includePotentialOverlay || includePotentialForeground; - const { viewportDisplaySets, enhancedDisplaySets } = useMemo(() => { + const { viewportDisplaySets = [], enhancedDisplaySets = [] } = useMemo(() => { if (!needsEnhancedDisplaySets) { return { viewportDisplaySets: [], enhancedDisplaySets: [] }; } - return getEnhancedDisplaySets({ - viewportId: viewportIdToUse, - services: { displaySetService, viewportGridService }, - }); + return ( + getEnhancedDisplaySets({ + viewportId: viewportIdToUse, + services: { displaySetService, viewportGridService }, + }) || { viewportDisplaySets: [], enhancedDisplaySets: [] } + ); }, [viewportIdToUse, displaySetService, viewportGridService, needsEnhancedDisplaySets]); const backgroundDisplaySet = useMemo( - () => (includeBackground ? viewportDisplaySets[0] : undefined), + () => + includeBackground && viewportDisplaySets.length > 0 ? viewportDisplaySets[0] : undefined, [includeBackground, viewportDisplaySets] ); @@ -227,7 +229,10 @@ export function useViewportDisplaySets( foregroundDisplaySetUIDs, ]); - const result: ViewportDisplaySets = { allDisplaySets, viewportDisplaySets }; + const result: ViewportDisplaySets = { + allDisplaySets: allDisplaySets || [], + viewportDisplaySets: viewportDisplaySets || [], + }; if (includeBackground) { result.backgroundDisplaySet = backgroundDisplaySet; diff --git a/extensions/tmtv/src/getPanelModule.tsx b/extensions/tmtv/src/getPanelModule.tsx index 9da4564f6..ec76c495e 100644 --- a/extensions/tmtv/src/getPanelModule.tsx +++ b/extensions/tmtv/src/getPanelModule.tsx @@ -4,6 +4,8 @@ import { Toolbox } from '@ohif/extension-default'; import PanelTMTV from './Panels/PanelTMTV'; function getPanelModule({ commandsManager, extensionManager, servicesManager }) { + const { toolbarService } = servicesManager.services; + const wrappedPanelPetSuv = () => { return ; }; @@ -11,7 +13,7 @@ function getPanelModule({ commandsManager, extensionManager, servicesManager }) const wrappedROIThresholdToolbox = () => { return ( ); @@ -25,7 +27,7 @@ function getPanelModule({ commandsManager, extensionManager, servicesManager }) return ( <> [ - { - commandName: 'setViewportForToolConfiguration', - commandOptions: { - toolName, - }, - }, -]; - const toolbarButtons: Button[] = [ { id: 'MeasurementTools', uiType: 'ohif.toolButtonList', props: { - buttonSection: 'measurementSection', + buttonSection: true, }, }, { id: 'MoreTools', uiType: 'ohif.toolButtonList', props: { - buttonSection: 'moreToolsSection', + buttonSection: true, }, }, { id: 'WindowLevelGroup', uiType: 'ohif.toolButtonList', props: { - buttonSection: 'windowLevelSection', + buttonSection: true, }, }, diff --git a/modes/longitudinal/src/index.ts b/modes/longitudinal/src/index.ts index 2004eaf2b..60f9d0a7f 100644 --- a/modes/longitudinal/src/index.ts +++ b/modes/longitudinal/src/index.ts @@ -112,7 +112,7 @@ function modeFactory({ modeConfiguration }) { 'AdvancedRenderingControls', ]); - toolbarService.updateSection(toolbarService.sections.advancedRenderingControlsSection, [ + toolbarService.updateSection('AdvancedRenderingControls', [ 'windowLevelMenuEmbedded', 'voiManualControlMenu', 'Colorbar', @@ -130,7 +130,7 @@ function modeFactory({ modeConfiguration }) { 'windowLevelMenu', ]); - toolbarService.updateSection(toolbarService.sections.measurementSection, [ + toolbarService.updateSection('MeasurementTools', [ 'Length', 'Bidirectional', 'ArrowAnnotate', @@ -142,7 +142,7 @@ function modeFactory({ modeConfiguration }) { 'LivewireContour', ]); - toolbarService.updateSection(toolbarService.sections.moreToolsSection, [ + toolbarService.updateSection('MoreTools', [ 'Reset', 'rotate-right', 'flipHorizontal', diff --git a/modes/longitudinal/src/toolbarButtons.ts b/modes/longitudinal/src/toolbarButtons.ts index 0f80e0a0e..58d3fc49c 100644 --- a/modes/longitudinal/src/toolbarButtons.ts +++ b/modes/longitudinal/src/toolbarButtons.ts @@ -25,21 +25,21 @@ const toolbarButtons: Button[] = [ id: 'MeasurementTools', uiType: 'ohif.toolButtonList', props: { - buttonSection: 'measurementSection', + buttonSection: true, }, }, { id: 'MoreTools', uiType: 'ohif.toolButtonList', props: { - buttonSection: 'moreToolsSection', + buttonSection: true, }, }, { id: 'AdvancedRenderingControls', uiType: 'ohif.advancedRenderingControls', props: { - buttonSection: 'advancedRenderingControlsSection', + buttonSection: true, }, }, // tool defs diff --git a/modes/microscopy/src/index.tsx b/modes/microscopy/src/index.tsx index 7deabc564..470dfd8e1 100644 --- a/modes/microscopy/src/index.tsx +++ b/modes/microscopy/src/index.tsx @@ -50,7 +50,7 @@ function modeFactory({ modeConfiguration }) { toolbarService.register(toolbarButtons); toolbarService.updateSection('primary', ['MeasurementTools', 'dragPan', 'TagBrowser']); - toolbarService.updateSection('measurementSection', [ + toolbarService.updateSection('MeasurementTools', [ 'line', 'point', 'polygon', diff --git a/modes/microscopy/src/toolbarButtons.ts b/modes/microscopy/src/toolbarButtons.ts index 1b3a6ab4e..519791296 100644 --- a/modes/microscopy/src/toolbarButtons.ts +++ b/modes/microscopy/src/toolbarButtons.ts @@ -13,7 +13,7 @@ const toolbarButtons: Button[] = [ id: 'MeasurementTools', uiType: 'ohif.toolButtonList', props: { - buttonSection: 'measurementSection', + buttonSection: true, }, }, { diff --git a/modes/preclinical-4d/src/getWorkflowSettings.ts b/modes/preclinical-4d/src/getWorkflowSettings.ts index ba69efa46..e5e1e3362 100644 --- a/modes/preclinical-4d/src/getWorkflowSettings.ts +++ b/modes/preclinical-4d/src/getWorkflowSettings.ts @@ -10,31 +10,35 @@ const cornerstone = { activeViewportWindowLevel: '@ohif/extension-cornerstone.panelModule.activeViewportWindowLevel', }; -const defaultButtons = [ - { - buttonSection: 'primary', - buttons: ['MeasurementTools', 'Zoom', 'WindowLevel', 'Crosshairs', 'Pan'], - }, - { - buttonSection: 'measurementSection', - buttons: ['Length', 'Bidirectional', 'ArrowAnnotate', 'EllipticalROI'], - }, -]; +function getDefaultButtons({ toolbarService }) { + return [ + { + buttonSection: toolbarService.sections.primary, + buttons: ['MeasurementTools', 'Zoom', 'WindowLevel', 'Crosshairs', 'Pan'], + }, + { + buttonSection: 'MeasurementTools', + buttons: ['Length', 'Bidirectional', 'ArrowAnnotate', 'EllipticalROI'], + }, + ]; +} -const ROIThresholdToolbox = [ - { - buttonSection: 'dynamic-toolbox', - buttons: ['SegmentationTools'], - }, - { - buttonSection: 'segmentationToolboxToolsSection', - buttons: ['BrushTools', 'RectangleROIStartEndThreshold'], - }, - { - buttonSection: 'brushToolsSection', - buttons: ['Brush', 'Eraser', 'Threshold'], - }, -]; +function getROIThresholdToolbox({ toolbarService }) { + return [ + { + buttonSection: toolbarService.sections.dynamicToolbox, + buttons: ['SegmentationTools'], + }, + { + buttonSection: 'SegmentationTools', + buttons: ['BrushTools', 'RectangleROIStartEndThreshold'], + }, + { + buttonSection: 'BrushTools', + buttons: ['Brush', 'Eraser', 'Threshold'], + }, + ]; +} const defaultLeftPanel = [[dynamicVolume.leftPanel, cornerstone.activeViewportWindowLevel]]; @@ -46,6 +50,10 @@ const defaultLayout = { }; function getWorkflowSettings({ servicesManager }) { + const { toolbarService } = servicesManager.services; + const defaultButtons = getDefaultButtons({ toolbarService }); + const ROIThresholdToolbox = getROIThresholdToolbox({ toolbarService }); + return { steps: [ { diff --git a/modes/preclinical-4d/src/index.tsx b/modes/preclinical-4d/src/index.tsx index 0080b7e72..029fcf891 100644 --- a/modes/preclinical-4d/src/index.tsx +++ b/modes/preclinical-4d/src/index.tsx @@ -56,7 +56,7 @@ function modeFactory({ modeConfiguration }) { toolbarService.register(toolbarButtons); - toolbarService.updateSection('secondary', ['ProgressDropdown']); + toolbarService.updateSection(toolbarService.sections.secondary, ['ProgressDropdown']); toolbarService.updateSection(toolbarService.sections.viewportActionMenu.topLeft, [ 'orientationMenu', @@ -72,7 +72,7 @@ function modeFactory({ modeConfiguration }) { 'AdvancedRenderingControls', ]); - toolbarService.updateSection(toolbarService.sections.advancedRenderingControlsSection, [ + toolbarService.updateSection('AdvancedRenderingControls', [ 'windowLevelMenuEmbedded', 'voiManualControlMenu', 'Colorbar', diff --git a/modes/preclinical-4d/src/toolbarButtons.tsx b/modes/preclinical-4d/src/toolbarButtons.tsx index 6721b9615..80a262ab5 100644 --- a/modes/preclinical-4d/src/toolbarButtons.tsx +++ b/modes/preclinical-4d/src/toolbarButtons.tsx @@ -22,28 +22,28 @@ const toolbarButtons = [ id: 'MeasurementTools', uiType: 'ohif.toolButtonList', props: { - buttonSection: 'measurementSection', + buttonSection: true, }, }, { id: 'BrushTools', uiType: 'ohif.toolBoxButtonGroup', props: { - buttonSection: 'brushToolsSection', + buttonSection: true, }, }, { id: 'SegmentationTools', uiType: 'ohif.toolBoxButton', props: { - buttonSection: 'segmentationToolboxToolsSection', + buttonSection: true, }, }, { id: 'AdvancedRenderingControls', uiType: 'ohif.advancedRenderingControls', props: { - buttonSection: 'advancedRenderingControlsSection', + buttonSection: true, }, }, { diff --git a/modes/segmentation/src/index.tsx b/modes/segmentation/src/index.tsx index bc6d702c2..3e0de17a7 100644 --- a/modes/segmentation/src/index.tsx +++ b/modes/segmentation/src/index.tsx @@ -83,7 +83,7 @@ function modeFactory({ modeConfiguration }) { 'AdvancedRenderingControls', ]); - toolbarService.updateSection(toolbarService.sections.advancedRenderingControlsSection, [ + toolbarService.updateSection('AdvancedRenderingControls', [ 'windowLevelMenuEmbedded', 'voiManualControlMenu', 'Colorbar', @@ -101,7 +101,7 @@ function modeFactory({ modeConfiguration }) { 'windowLevelMenu', ]); - toolbarService.updateSection('moreToolsSection', [ + toolbarService.updateSection('MoreTools', [ 'Reset', 'rotate-right', 'flipHorizontal', @@ -114,22 +114,22 @@ function modeFactory({ modeConfiguration }) { 'TagBrowser', ]); - toolbarService.updateSection('segmentationToolbox', [ + toolbarService.updateSection(toolbarService.sections.segmentationToolbox, [ 'SegmentationUtilities', 'SegmentationTools', ]); - toolbarService.updateSection('segmentationToolboxUtilitySection', [ + toolbarService.updateSection('SegmentationUtilities', [ 'LabelmapSlicePropagation', 'InterpolateLabelmap', 'SegmentBidirectional', ]); - toolbarService.updateSection('segmentationToolboxToolsSection', [ + toolbarService.updateSection('SegmentationTools', [ 'BrushTools', 'MarkerLabelmap', 'RegionSegmentPlus', 'Shapes', ]); - toolbarService.updateSection('brushToolsSection', ['Brush', 'Eraser', 'Threshold']); + toolbarService.updateSection('BrushTools', ['Brush', 'Eraser', 'Threshold']); }, onModeExit: ({ servicesManager }: withAppTypes) => { const { diff --git a/modes/segmentation/src/toolbarButtons.ts b/modes/segmentation/src/toolbarButtons.ts index af4b91ac8..f92d31895 100644 --- a/modes/segmentation/src/toolbarButtons.ts +++ b/modes/segmentation/src/toolbarButtons.ts @@ -22,7 +22,7 @@ const toolbarButtons: Button[] = [ id: 'AdvancedRenderingControls', uiType: 'ohif.advancedRenderingControls', props: { - buttonSection: 'advancedRenderingControlsSection', + buttonSection: true, }, }, { @@ -160,14 +160,14 @@ const toolbarButtons: Button[] = [ id: 'MoreTools', uiType: 'ohif.toolButtonList', props: { - buttonSection: 'moreToolsSection', + buttonSection: true, }, }, { id: 'BrushTools', uiType: 'ohif.toolBoxButtonGroup', props: { - buttonSection: 'brushToolsSection', + buttonSection: true, }, }, // Section containers for the nested toolbox @@ -175,14 +175,14 @@ const toolbarButtons: Button[] = [ id: 'SegmentationUtilities', uiType: 'ohif.toolBoxButton', props: { - buttonSection: 'segmentationToolboxUtilitySection', + buttonSection: true, }, }, { id: 'SegmentationTools', uiType: 'ohif.toolBoxButton', props: { - buttonSection: 'segmentationToolboxToolsSection', + buttonSection: true, }, }, // tool defs diff --git a/modes/tmtv/src/index.ts b/modes/tmtv/src/index.ts index c0262876f..5e809421b 100644 --- a/modes/tmtv/src/index.ts +++ b/modes/tmtv/src/index.ts @@ -106,7 +106,7 @@ function modeFactory({ modeConfiguration }) { 'AdvancedRenderingControls', ]); - toolbarService.updateSection(toolbarService.sections.advancedRenderingControlsSection, [ + toolbarService.updateSection('AdvancedRenderingControls', [ 'windowLevelMenuEmbedded', 'voiManualControlMenu', 'Colorbar', @@ -124,7 +124,7 @@ function modeFactory({ modeConfiguration }) { 'windowLevelMenu', ]); - toolbarService.updateSection('measurementSection', [ + toolbarService.updateSection('MeasurementTools', [ 'Length', 'Bidirectional', 'ArrowAnnotate', diff --git a/modes/tmtv/src/toolbarButtons.ts b/modes/tmtv/src/toolbarButtons.ts index 39e0eabba..cb28cbb7f 100644 --- a/modes/tmtv/src/toolbarButtons.ts +++ b/modes/tmtv/src/toolbarButtons.ts @@ -12,28 +12,28 @@ const toolbarButtons = [ id: 'MeasurementTools', uiType: 'ohif.toolButtonList', props: { - buttonSection: 'measurementSection', + buttonSection: true, }, }, { id: 'SegmentationTools', uiType: 'ohif.toolBoxButton', props: { - buttonSection: 'segmentationToolboxToolsSection', + buttonSection: true, }, }, { id: 'BrushTools', uiType: 'ohif.toolBoxButtonGroup', props: { - buttonSection: 'brushToolsSection', + buttonSection: true, }, }, { id: 'AdvancedRenderingControls', uiType: 'ohif.advancedRenderingControls', props: { - buttonSection: 'advancedRenderingControlsSection', + buttonSection: true, }, }, { diff --git a/platform/app/cypress/integration/ImageConsistency.spec.js b/platform/app/cypress/integration/ImageConsistency.spec.js index 37a03e547..94d52c2d4 100644 --- a/platform/app/cypress/integration/ImageConsistency.spec.js +++ b/platform/app/cypress/integration/ImageConsistency.spec.js @@ -56,7 +56,7 @@ describe('CS3D Image Consistency and Quality', () => { '2.16.124.113543.6004.101.103.20021117.061159.1.004' ); - cy.wait(2000); + cy.wait(3000); testPixel(1018, 1028, 255); // Horizontal and vertical delta from this should not be contaminated // by values from center diff --git a/platform/cli/templates/mode/src/index.tsx b/platform/cli/templates/mode/src/index.tsx index bcb637b45..a327b68cb 100644 --- a/platform/cli/templates/mode/src/index.tsx +++ b/platform/cli/templates/mode/src/index.tsx @@ -50,7 +50,7 @@ function modeFactory({ modeConfiguration }) { toolbarService.register([...toolbarButtons, ...moreTools]); toolbarService.updateSection('primary', [ - 'measurementSection', + 'MeasurementTools', 'Zoom', 'Pan', 'TrackballRotate', @@ -58,10 +58,10 @@ function modeFactory({ modeConfiguration }) { 'Capture', 'Layout', 'Crosshairs', - 'moreToolsSection', + 'MoreTools', ]); - toolbarService.updateSection('measurementSection', [ + toolbarService.updateSection('MeasurementTools', [ 'Length', 'Bidirectional', 'ArrowAnnotate', @@ -73,7 +73,7 @@ function modeFactory({ modeConfiguration }) { 'LivewireContour', ]); - toolbarService.updateSection('moreToolsSection', [ + toolbarService.updateSection('MoreTools', [ 'Reset', 'rotate-right', 'flipHorizontal', diff --git a/platform/core/src/services/ToolBarService/ToolbarService.ts b/platform/core/src/services/ToolBarService/ToolbarService.ts index 99252b29e..a132d779e 100644 --- a/platform/core/src/services/ToolBarService/ToolbarService.ts +++ b/platform/core/src/services/ToolBarService/ToolbarService.ts @@ -37,20 +37,10 @@ export const TOOLBAR_SECTIONS = { rightMiddle: 'viewportActionMenu.rightMiddle', }, - /** - * Measurement tools section - */ - measurementSection: 'measurementSection', - - /** - * More tools section - */ - moreToolsSection: 'moreToolsSection', - - /** - * Advanced rendering controls section - */ - advancedRenderingControlsSection: 'advancedRenderingControlsSection', + // mode specific + segmentationToolbox: 'segmentationToolbox', + dynamicToolbox: 'dynamic-toolbox', + roiThresholdToolbox: 'ROIThresholdToolbox', }; export enum ButtonLocation { @@ -199,6 +189,11 @@ export default class ToolbarService extends PubSubService { button.props = {} as ButtonProps; } + // if button section is true as boolean, we assign the id of the button to the buttonSection + if (button.props.buttonSection === true) { + button.props.buttonSection = button.id; + } + this.state.buttons[button.id] = button; } }); @@ -410,6 +405,19 @@ export default class ToolbarService extends PubSubService { return this.state.buttons[id]; } + /** + * @deprecated Use register() instead. This method will be removed in a future version. + * Adds buttons to the toolbar. + * @param buttons - The buttons to be added. + * @param replace - Flag indicating if any existing button with the same id as one being added should be replaced + */ + public addButtons(buttons: Button[], replace: boolean = false): void { + console.warn( + 'ToolbarService.addButtons() is deprecated. Use ToolbarService.register() instead.' + ); + this.register(buttons, replace); + } + /** * Retrieves the buttons from the toolbar service. * @returns An array of buttons. @@ -470,6 +478,19 @@ export default class ToolbarService extends PubSubService { this._broadcastEvent(this.EVENTS.TOOL_BAR_MODIFIED, { ...this.state }); } + /** + * @deprecated Use updateSection() instead. This method will be removed in a future version. + * Creates a button section with the specified key and buttons. + * @param {string} key - The key of the button section. + * @param {Array} buttons - The buttons to be added to the section. + */ + createButtonSection(key, buttons) { + console.warn( + 'ToolbarService.createButtonSection() is deprecated. Use ToolbarService.updateSection() instead.' + ); + this.updateSection(key, buttons); + } + /** * Retrieves the button section with the specified sectionId. * diff --git a/platform/core/src/services/ToolBarService/types.ts b/platform/core/src/services/ToolBarService/types.ts index 02ed1afe6..6e091f1f9 100644 --- a/platform/core/src/services/ToolBarService/types.ts +++ b/platform/core/src/services/ToolBarService/types.ts @@ -13,8 +13,6 @@ export type ToolbarSections = { bottomLeft: string; bottomRight: string; }; - measurementSection: string; - moreToolsSection: string; }; export type EvaluatePublic = @@ -59,7 +57,7 @@ export type ButtonProps = { evaluate?: EvaluatePublic; listeners?: Record; options?: ButtonOptions[]; - buttonSection?: string; + buttonSection?: string | boolean; }; export type Button = { diff --git a/platform/core/src/services/WorkflowStepsService/WorkflowStepsService.ts b/platform/core/src/services/WorkflowStepsService/WorkflowStepsService.ts index ee2a0c6ab..f7a2332ed 100644 --- a/platform/core/src/services/WorkflowStepsService/WorkflowStepsService.ts +++ b/platform/core/src/services/WorkflowStepsService/WorkflowStepsService.ts @@ -27,7 +27,7 @@ export const EVENTS = { sections: [ { key: 'primary', - buttons: [ 'measurementSection', 'Zoom', ... ], + buttons: [ 'MeasurementTools', 'Zoom', ... ], }, ], }, diff --git a/platform/docs/docs/migration-guide/3p10-to-3p11/toolbarService.md b/platform/docs/docs/migration-guide/3p10-to-3p11/toolbarService.md index 510ce538b..15e53ac9e 100644 --- a/platform/docs/docs/migration-guide/3p10-to-3p11/toolbarService.md +++ b/platform/docs/docs/migration-guide/3p10-to-3p11/toolbarService.md @@ -31,6 +31,7 @@ summary: Migration guide for OHIF 3.11's toolbar service changes, including the **Migration Steps:** 1. **Update `ToolbarService` Method Calls:** + * Although the previous method also works but gives warning in the console when used. * Replace all instances of `toolbarService.addButtons(...)` with `toolbarService.register(...)`. * Replace all instances of `toolbarService.createButtonSection(...)` with `toolbarService.updateSection(...)`. @@ -96,36 +97,60 @@ summary: Migration guide for OHIF 3.11's toolbar service changes, including the ``` 3. **Adapt Toolbar Button and Component Configurations:** - * For `ohif.toolButtonList` or `ohif.toolBoxButtonGroup` (and their wrappers), the `groupId` prop is no longer the primary way to define the set of buttons. Instead, ensure the `buttonSection` prop correctly points to the section name containing the desired buttons. The `id` prop on these wrapper components should be unique for the component instance. - ```diff - // Before - - { - - id: 'MeasurementTools', - - uiType: 'ohif.toolButtonList', - - props: { - - buttonSection: 'measurementSection', - - groupId: 'MeasurementTools', // groupId often matched buttonSection - - }, - - }, + The configuration of toolbar buttons, especially how they relate to sections - // After - + { - + id: 'MeasurementTools', // This is the ID of the ToolButtonList/ToolBox component itself - + uiType: 'ohif.toolButtonList', - + props: { - + // This section contains the actual tool buttons (e.g., Length, Bidirectional) - + buttonSection: 'measurementSection', - + }, - + }, - ``` - * Update wrappers like `ToolBoxButtonGroupWrapper` and `ToolButtonListWrapper`: - * The `groupId` prop is replaced by `id` (which is the ID of the wrapper button itself). - * The `onInteraction` callback in these wrappers now provides `id` (the wrapper's ID) instead of `groupId`. - * If you have custom `evaluate` functions, you can now use `evaluateProps: { hideWhenDisabled: true }` in your button definition to automatically hide the button if it evaluates to disabled. + * **Button Section Association via `props.buttonSection`:** + + The toolbar service now offers two ways to define this association: + + * **A. Simple Approach: `buttonSection: true` (Implicitly Uses Button's Own ID)** + + If a button definition includes `props: { buttonSection: true }`, the `ToolbarService` automatically sets the effective `buttonSection` ID to be the same as the button's own `id`. + + ```javascript + // Example: A ToolButtonList component's definition in toolbarButtons.ts + // { + // id: 'MeasurementTools', // ID of this ToolButtonList component + // uiType: 'ohif.toolButtonList', + // props: { + // buttonSection: true // This ToolButtonList will render the section named 'MeasurementTools' + // } + // } + ``` + + later you can use it like -5. **Adopt `IconPresentationProvider` (Optional but Recommended):** + ```javascript + toolbarService.updateSection('MeasurementTools', ['Length', 'Bidirectional', ...]); + ``` + + * **B. Flexible Approach: `buttonSection: 'customSectionName'` (Explicit Section ID)** + + You can explicitly provide a string for `props.buttonSection` if the button should be associated with a section ID that is different from its own `id`, or if you prefer explicit naming. + + ```javascript + // Example: A ToolButtonList component's definition + // { + // id: 'MySpecialToolList', // ID of this ToolButtonList component + // uiType: 'ohif.toolButtonList', + // props: { + // buttonSection: 'toolsForAdvancedUsers', // This list renders 'toolsForAdvancedUsers' section + // } + // } + ``` + + * **`evaluate` Function Enhancement:** + * Button `evaluate` functions can now leverage `evaluateProps: { hideWhenDisabled: true }` in your button definition to automatically hide a button when it's disabled. + + * **Wrapper Component `onInteraction` (e.g., `ToolButtonListWrapper`):** + * Update wrappers like `ToolBoxButtonGroupWrapper` and `ToolButtonListWrapper`: + * The `groupId` prop is replaced by `id` (which is the ID of the wrapper button component itself). + * The `onInteraction` callback in these wrappers now provides `id` (the wrapper's ID) instead of `groupId`. + + +4. **Adopt `IconPresentationProvider` (Optional but Recommended):** * For consistent icon styling across your application's toolbars, wrap a high-level component (like your main `Header` or layout component) with ``. * Custom tool button components can then use the `useIconPresentation` hook to get appropriate class names for icons or a pre-styled `IconContainer`. @@ -149,5 +174,5 @@ summary: Migration guide for OHIF 3.11's toolbar service changes, including the + } ``` -6. **Remove Legacy Component Usage:** +5. **Remove Legacy Component Usage:** * Replace any usage of `ToolbarSplitButtonWithServicesLegacy` and `ToolbarButtonGroupWithServicesLegacy` with the newer patterns, typically by configuring individual buttons and using `ToolButtonList` or `ButtonGroup` from `@ohif/ui-next` directly, driven by `useToolbar`.