Migration Guide
There are two main things that need to be taken care of.
New Toolbar Button definitionsβ
Update Active Tool Handlingβ
The concept of activeTool
and its associated getter and setter has been removed. The active tool should now be derived from the toolGroup and the viewport.
Action Needed
Remove any code that sets the default tool using toolbarService.setDefaultTool()
and activates the tool using
toolbarService.recordInteraction()
. For example, the following code should be removed:
let unsubscribe;
toolbarService.setDefaultTool({
groupId: "WindowLevel",
itemId: "WindowLevel",
interactionType: "tool",
commands: [
{
commandName: "setToolActive",
commandOptions: {
toolName: "WindowLevel",
},
context: "CORNERSTONE",
},
],
});
const activateTool = () => {
toolbarService.recordInteraction(toolbarService.getDefaultTool());
unsubscribe();
};
({ unsubscribe } = toolGroupService.subscribe(
toolGroupService.EVENTS.VIEWPORT_ADDED,
activateTool
));
Instead, focus on defining the buttons and their placement in the toolbar using toolbarService.addButtons()
and toolbarService.createButtonSection()
. For example:
toolbarService.addButtons([...toolbarButtons, ...moreTools]);
toolbarService.createButtonSection("primary", [
"MeasurementTools",
"Zoom",
"WindowLevel",
"Pan",
"Capture",
"Layout",
"MPR",
"Crosshairs",
"MoreTools",
]);
Update Button Definitionsβ
The concept of button types (toggle, action, tool) has been removed. Buttons are now defined using a simplified object-based definition.
Action Needed
Update your button definitions to use the new object-based format and remove the type
property. Use the uiType
property for the top-level UI type definition. For example:
// Old Implementation
{
id: 'Capture',
type: 'ohif.action',
props: {
icon: 'tool-capture',
label: 'Capture',
type: 'action',
commands: [
{
commandName: 'showDownloadViewportModal',
commandOptions: {},
context: 'CORNERSTONE',
},
],
},
},
is now
// New Implementation
{
id: 'Capture',
uiType: 'ohif.radioGroup',
props: {
icon: 'tool-capture',
label: 'Capture',
commands: [
{
commandName: 'showDownloadViewportModal',
context: 'CORNERSTONE',
},
],
evaluate: 'evaluate.action',
},
},
Add Evaluators to Button Definitionsβ
Introduce the ο»Ώevaluate property in your button definitions to determine the state of the button based on the app context.
Action Needed
Add the appropriate evaluate
property to each button definition. For example:
- Use
evaluate.cornerstoneTool
if the button should be highlighted only when it is the active primary tool (left mouse). - Use
evaluate.cornerstoneTool.toggle
if the tool is a toggle tool (like reference lines or image overlay).
Refer to the modes/longitudinal/src/toolbarButtons.ts
file for examples of using the evaluate
property.
Additional Resources
- For more information on the new toolbar module and its usage, refer to the Toolbar documentation.
- Consult the updated button definitions in
modes/longitudinal/src/toolbarButtons.ts
for examples of the new object-based button definition format and the usage of evaluators.
Tool listenersβ
Some tools can be configured to listen to events to trigger, for example
createButton({
id: 'ReferenceLines',
icon: 'tool-referenceLines',
label: 'Reference Lines',
tooltip: 'Show Reference Lines',
commands: 'toggleEnabledDisabledToolbar',
listeners: {
[ViewportGridService.EVENTS.ACTIVE_VIEWPORT_ID_CHANGED]:
ReferenceLinesListeners,
[ViewportGridService.EVENTS.VIEWPORTS_READY]:
ReferenceLinesListeners,
},
evaluate: 'evaluate.cornerstoneTool.toggle',
}),
If you have a custom viewport component, and you are overriding the onElementEnabled
handler, than ensure to call viewportGridService.setViewportIsReady(viewportId, true)
in your own handler so that eventually the VIEWPORTS_READY
event fires as expected, if you are not modifying the handler, then an existing handler that is automatically passed down via the props will call that for you, it is passed down from ViewportGrid.tsx
<ViewportComponent
displaySets={displaySets}
viewportLabel={viewports.size > 1 ? viewportLabel : ''}
viewportId={viewportId}
dataSource={dataSource}
viewportOptions={viewportOptions}
displaySetOptions={displaySetOptions}
needsRerendering={displaySetsNeedsRerendering}
isHangingProtocolLayout={isHangingProtocolLayout}
onElementEnabled={() => {
viewportGridService.setViewportIsReady(viewportId, true);
}}
/>
Toolbar Serviceβ
toolbarService.init is not a function.
Action Needed remove the call to toolbarService.init() from your codebase.
leftPanelDefaultClosed and rightPanelDefaultClosedβ
Now they are renamed to leftPanelClosed
and rightPanelClosed
respectively.
StudyInstanceUID in the URL paramβ
Previously there were two params that you could choose: seriesInstanceUID and seriesInstanceUIDs, they have been replaced with seriesInstanceUIDs so even if you would like to filter one series use ``seriesInstanceUIDs`
UIβ
Headerβ
Header in @ohif/ui now needs servicesManager and appConfig as input.
Panelsβ
Left and right panel lists are no longer injected into the LayoutTemplate, and have been moved to a PanelService where you have to fetch them from.
If you're using the main layout, you're fine. However, if you have a custom layout, you'll need to update it. To get the panels, see the
extensions/default/src/ViewerLayout/index.tsx
Refactoringβ
- TimingEnum (and I guess all enums exported from OHIF core have now moved from Types to Enums export).