CustomizationService
Key Changes:
-
Unified Customization Getter:
- The
getCustomization
method now uniformly retrieves customizations, prioritizingglobal
, thenmode
, and finallydefault
customizations. - The
defaultValue
parameter ingetCustomization
is no longer used for setting defaults. It simply returns if no customization is found. - The methods
getModeCustomization
andgetGlobalCustomization
are deprecated.
- The
-
Simplified Customization Registration:
-
The
customizationType
property in customization definitions is renamed toinheritsFrom
. -
The
merge
property in customization definitions is removed. Instead, a customization is merged using the helper methods. The basic update commands are listed in the table below, and you can learn more about the helper methods here.Command Description Example $set
Replace a value entirely Replace a list or object $push
Append items to an array Add to the end of a list $unshift
Prepend items to an array Add to the start of a list $splice
Insert, remove, or replace at specific index Modify specific indices in a list $merge
Update specific fields in an object Change a subset of fields $apply
Compute the new value dynamically Apply a function to transform values $filter
Find and update specific items in arrays Target nested structures based on matching criteria
-
-
New
$transform
command:- If you were using the
transform
command, you should now use the$transform
command. Just a simple rename to make it more consistent with the other commands.
- If you were using the
-
Renamed
CornerstoneOverlay
customizations:- The
cornerstoneOverlay
customizations (cornerstoneOverlayTopLeft
,cornerstoneOverlayTopRight
,cornerstoneOverlayBottomLeft
,cornerstoneOverlayBottomRight
) have been renamed toviewportOverlay.topLeft
,viewportOverlay.topRight
,viewportOverlay.bottomLeft
, andviewportOverlay.bottomRight
. See dedicated page for customizing viewport overlays here.
- The
-
Renamed
customRoutes
:- The
customRoutes
customization is renamed toroutes.customRoutes
.
- The
-
contextMenu
customization:- The
contextMenu
customization now uses theinheritsFrom
property to inherit from other context menus, previously it was calledcustomizationType
- The
-
New
immutability-helper
dependency: Theimmutability-helper
library is now used for merging customizations. If you encounter an error related to it, you'll need to install it - though OHIF should really handle the installation for you, so this is pretty much just a heads up.
Migration Steps:
-
Replace
getModeCustomization
andgetGlobalCustomization
withgetCustomization
:-
Before:
const tools = customizationService.getModeCustomization(
'cornerstone.overlayViewportTools'
)?.tools;
const globalValue = customizationService.getGlobalCustomization('someGlobalKey'); -
After:
const tools = customizationService.getCustomization('cornerstone.overlayViewportTools');
const globalValue = customizationService.getCustomization('someGlobalKey');noteThe returned value is the actual customization value, not an object that needs to be broken down.
-
-
Update Customization Definitions:
- We've moved away from using random items in the customization definition, and now we use the
id
property to identify the customization as a value. Previously, it was referred to asvalue
,values
, and so on, but now anid
is used to reference the customization. This approach really simplifies things - when you need to grab the customization, you can just use theid
to get it, and you don't have to bother with destructuring the value from the object.
- We've moved away from using random items in the customization definition, and now we use the
Example: Customizing a Panel
Before (v3.9):
// the default value was hardcoded inside the panel itself - bad idea!
// default was given in the panel itself
// PanelSegmentation.tsx
// Retrieve the onSegmentationAdd customization
const { onSegmentationAdd } = customizationService.getCustomization(
'PanelSegmentation.onSegmentationAdd',
{
id: 'segmentation.onSegmentationAdd',
onSegmentationAdd: handlers.onSegmentationAdd,
}
);
// Retrieve the disableEditing customization
const { disableEditing } = customizationService.getCustomization(
'PanelSegmentation.disableEditing',
{
id: 'default.disableEditing',
disableEditing: false,
}
);
// mode was customizing it via
customizationService.addModeCustomizations([
{
id: 'PanelSegmentation.tableMode',
mode: 'expanded',
},
{
id: 'PanelSegmentation.showAddSegment',
showAddSegment: false,
},
]);
After (v3.10):
// cornerstone extension getCustomizationModule
// centralized customization location for all extensions - good!
function getCustomizationModule() {
return [
{
name: 'default',
value: {
'panelSegmentation.disableEditing': false,
'panelSegmentation.showAddSegment': true,
},
},
];
}
// inside panelSegmentation.tsx
const disableEditing = customizationService.getCustomization('panelSegmentation.disableEditing');
const showAddSegment = customizationService.getCustomization('panelSegmentation.showAddSegment');
// mode can customize it via $ operators for mode customizations
customizationService.setCustomizations({
'panelSegmentation.disableEditing': { $set: true },
'panelSegmentation.showAddSegment': { $set: false },
});
//or via configuration for global customizations
window.config = {
// rest of config
customizationService: [
{
'panelSegmentation.disableEditing': {
$set: true, // Disables editing of segmentations in the panel
},
},
],
// rest of config
};
Example: Updating a Customization
Let's say you have a customization in v3.9 that adds a custom overlay item to the top-left corner:
Before (v3.9):
// In your mode's onModeEnter
customizationService.addModeCustomizations([
{
id: 'cornerstoneOverlayTopLeft',
items: [
{
id: 'myCustomOverlay',
customizationType: 'ohif.overlayItem',
attribute: 'PatientName',
label: 'Patient:',
},
],
},
]);
After (v3.10):
// In your mode's onModeEnter or elsewhere
customizationService.setCustomizations({
'viewportOverlay.topLeft': {
$push: [
{
id: 'myCustomOverlay',
inheritsFrom: 'ohif.overlayItem',
attribute: 'PatientName',
label: 'Patient:',
},
],
},
});
Note:
- The
customizationType
is replaced withinheritsFrom
.
Renaming​
To keep our customization system consistent, you should be aware of a few key renaming conventions. We now follow a straightforward naming convention for customizations: scopeName.customizationItem
.
Customization Key (Old) | Customization Key (New) | Description |
---|---|---|
PanelMeasurement.disableEditing | panelMeasurement.disableEditing | Disables editing measurements in the Measurement Panel and after SR hydration. |
PanelSegmentation.CustomDropdownMenuContent | panelSegmentation.customDropdownMenuContent | Custom content for the dropdown menu in the Segmentation Panel. |
PanelSegmentation.disableEditing | panelSegmentation.disableEditing | Disables editing segmentations in the Segmentation Panel. |
PanelSegmentation.showAddSegment | panelSegmentation.showAddSegment | Controls visibility of the "Add Segment" button in the Segmentation Panel. |
PanelSegmentation.onSegmentationAdd | panelSegmentation.onSegmentationAdd | Custom function to execute when a new segmentation is added. |
PanelSegmentation.tableMode | panelSegmentation.tableMode | Controls the table mode (collapsed/expanded) in the Segmentation Panel. |
PanelSegmentation.readableText | panelSegmentation.readableText | Custom readable text labels for the Segmentation Panel. |
PanelStudyBrowser.studyMode | studyBrowser.studyMode | Controls the study mode (all/primary/recent) in the Study Browser Panel. |
customRoutes | routes.customRoutes | Defines custom routes for the application. |
cornerstoneOverlayTopLeft | viewportOverlay.topLeft | Custom overlay items for the top-left corner of the viewport. |
cornerstoneOverlayTopRight | viewportOverlay.topRight | Custom overlay items for the top-right corner of the viewport. |
cornerstoneOverlayBottomLeft | viewportOverlay.bottomLeft | Custom overlay items for the bottom-left corner of the viewport. |
cornerstoneOverlayBottomRight | viewportOverlay.bottomRight | Custom overlay items for the bottom-right corner of the viewport. |