feat: separate checks for addWindowLevelActionMenu and addSegmentationOverlay (#4813)
This commit is contained in:
parent
7d67834159
commit
7f0cc0f60e
@ -15,7 +15,6 @@ import type { Types } from '@ohif/core';
|
||||
|
||||
import OHIFViewportActionCorners from '../components/OHIFViewportActionCorners';
|
||||
import { getWindowLevelActionMenu } from '../components/WindowLevelActionMenu/getWindowLevelActionMenu';
|
||||
import { useAppConfig } from '@state';
|
||||
import { getViewportDataOverlaySettingsMenu } from '../components/ViewportDataOverlaySettingMenu';
|
||||
import { getViewportPresentations } from '../utils/presentations/getViewportPresentations';
|
||||
import { useSynchronizersStore } from '../stores/useSynchronizersStore';
|
||||
@ -89,7 +88,6 @@ const OHIFCornerstoneViewport = React.memo(
|
||||
const [scrollbarHeight, setScrollbarHeight] = useState('100px');
|
||||
const [enabledVPElement, setEnabledVPElement] = useState(null);
|
||||
const elementRef = useRef() as React.MutableRefObject<HTMLDivElement>;
|
||||
const [appConfig] = useAppConfig();
|
||||
|
||||
const {
|
||||
displaySetService,
|
||||
@ -324,51 +322,52 @@ const OHIFCornerstoneViewport = React.memo(
|
||||
|
||||
// Set up the window level action menu in the viewport action corners.
|
||||
useEffect(() => {
|
||||
// Doing an === check here because the default config value when not set is true
|
||||
if (appConfig.addWindowLevelActionMenu === false) {
|
||||
return;
|
||||
const windowLevelActionMenu = customizationService.getCustomization(
|
||||
'viewportActionMenu.windowLevelActionMenu'
|
||||
);
|
||||
const segmentationOverlay = customizationService.getCustomization(
|
||||
'viewportActionMenu.segmentationOverlay'
|
||||
);
|
||||
|
||||
if (windowLevelActionMenu?.enabled) {
|
||||
viewportActionCornersService.addComponent({
|
||||
viewportId,
|
||||
id: 'windowLevelActionMenu',
|
||||
component: getWindowLevelActionMenu({
|
||||
viewportId,
|
||||
element: elementRef.current,
|
||||
displaySets,
|
||||
servicesManager,
|
||||
commandsManager,
|
||||
location: windowLevelActionMenu.location,
|
||||
verticalDirection: AllInOneMenu.VerticalDirection.TopToBottom,
|
||||
horizontalDirection: AllInOneMenu.HorizontalDirection.RightToLeft,
|
||||
}),
|
||||
location: windowLevelActionMenu.location,
|
||||
});
|
||||
}
|
||||
|
||||
const location = viewportActionCornersService.LOCATIONS.topRight;
|
||||
|
||||
// TODO: In the future we should consider using the customization service
|
||||
// to determine if and in which corner various action components should go.
|
||||
viewportActionCornersService.addComponent({
|
||||
viewportId,
|
||||
id: 'windowLevelActionMenu',
|
||||
component: getWindowLevelActionMenu({
|
||||
if (segmentationOverlay?.enabled) {
|
||||
viewportActionCornersService.addComponent({
|
||||
viewportId,
|
||||
element: elementRef.current,
|
||||
displaySets,
|
||||
servicesManager,
|
||||
commandsManager,
|
||||
location,
|
||||
verticalDirection: AllInOneMenu.VerticalDirection.TopToBottom,
|
||||
horizontalDirection: AllInOneMenu.HorizontalDirection.RightToLeft,
|
||||
}),
|
||||
location,
|
||||
});
|
||||
|
||||
viewportActionCornersService.addComponent({
|
||||
viewportId,
|
||||
id: 'segmentation',
|
||||
component: getViewportDataOverlaySettingsMenu({
|
||||
viewportId,
|
||||
element: elementRef.current,
|
||||
displaySets,
|
||||
servicesManager,
|
||||
commandsManager,
|
||||
location,
|
||||
}),
|
||||
location,
|
||||
});
|
||||
id: 'segmentation',
|
||||
component: getViewportDataOverlaySettingsMenu({
|
||||
viewportId,
|
||||
element: elementRef.current,
|
||||
displaySets,
|
||||
servicesManager,
|
||||
commandsManager,
|
||||
location: segmentationOverlay.location,
|
||||
}),
|
||||
location: segmentationOverlay.location,
|
||||
});
|
||||
}
|
||||
}, [
|
||||
displaySets,
|
||||
viewportId,
|
||||
viewportActionCornersService,
|
||||
servicesManager,
|
||||
commandsManager,
|
||||
appConfig,
|
||||
]);
|
||||
|
||||
const { ref: resizeRef } = useResizeDetector({
|
||||
|
||||
@ -0,0 +1,12 @@
|
||||
import viewportActionCornersService from '../services/ViewportActionCornersService/ViewportActionCornersService';
|
||||
|
||||
export default {
|
||||
'viewportActionMenu.windowLevelActionMenu': {
|
||||
enabled: true,
|
||||
location: viewportActionCornersService.LOCATIONS.topRight,
|
||||
},
|
||||
'viewportActionMenu.segmentationOverlay': {
|
||||
enabled: true,
|
||||
location: viewportActionCornersService.LOCATIONS.topRight,
|
||||
},
|
||||
};
|
||||
@ -9,6 +9,7 @@ import colorbarCustomization from './customizations/colorbarCustomization';
|
||||
import windowLevelPresetsCustomization from './customizations/windowLevelPresetsCustomization';
|
||||
import miscCustomization from './customizations/miscCustomization';
|
||||
import windowLevelActionMenuCustomization from './customizations/windowLevelActionMenuCustomization';
|
||||
import viewportActionMenuCustomizations from './customizations/viewportActionMenuCustomizations';
|
||||
|
||||
function getCustomizationModule({ commandsManager, servicesManager }) {
|
||||
return [
|
||||
@ -26,6 +27,7 @@ function getCustomizationModule({ commandsManager, servicesManager }) {
|
||||
...windowLevelPresetsCustomization,
|
||||
...miscCustomization,
|
||||
...windowLevelActionMenuCustomization,
|
||||
...viewportActionMenuCustomizations,
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
@ -129,7 +129,6 @@ declare global {
|
||||
showStudyList?: boolean;
|
||||
whiteLabeling?: Record<string, unknown>;
|
||||
httpErrorHandler?: (error: Error) => void;
|
||||
addWindowLevelActionMenu?: boolean;
|
||||
dangerouslyUseDynamicConfig?: {
|
||||
enabled: boolean;
|
||||
regex: RegExp;
|
||||
|
||||
BIN
platform/docs/docs/assets/img/segmentation-overlay.png
Normal file
BIN
platform/docs/docs/assets/img/segmentation-overlay.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 289 KiB |
@ -207,6 +207,86 @@ customizationService.setCustomizations({
|
||||
},
|
||||
});
|
||||
```
|
||||
```
|
||||
**Example: Customizing viewport action Menu**
|
||||
|
||||
**Before (v3.9):**
|
||||
|
||||
```javascript
|
||||
// In your configuration for global customizations
|
||||
window.config = {
|
||||
// rest of config
|
||||
addWindowLevelActionMenu: true,
|
||||
};
|
||||
```
|
||||
|
||||
**After (v3.10):**
|
||||
|
||||
```javascript
|
||||
// you can now handle each action menu item (windowLevelActionMenu and segmentationOverlay) separately
|
||||
|
||||
// cornerstone extension getCustomizationModule
|
||||
function getCustomizationModule() {
|
||||
return [
|
||||
{
|
||||
name: 'default',
|
||||
value: {
|
||||
'viewportActionMenu.windowLevelActionMenu': {
|
||||
enabled: true,
|
||||
location: viewportActionCornersService.LOCATIONS.topRight,
|
||||
},
|
||||
'viewportActionMenu.segmentationOverlay': {
|
||||
enabled: true,
|
||||
location: viewportActionCornersService.LOCATIONS.topRight,
|
||||
},
|
||||
},
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
// Accessing customizations within your component (e.g., OHIFCornerstoneViewport.tsx)
|
||||
const windowLevelActionMenu = customizationService.getCustomization('viewportActionMenu.windowLevelActionMenu');
|
||||
const segmentationOverlay = customizationService.getCustomization('viewportActionMenu.segmentationOverlay');
|
||||
|
||||
// Modifying customizations at runtime, for example, in your mode's onModeEnter
|
||||
customizationService.setCustomizations({
|
||||
'viewportActionMenu.windowLevelActionMenu': {
|
||||
$set: {
|
||||
enabled: false,
|
||||
location: viewportActionCornersService.LOCATIONS.bottomLeft,
|
||||
},
|
||||
},
|
||||
'viewportActionMenu.segmentationOverlay': {
|
||||
$set: {
|
||||
enabled: true,
|
||||
location: viewportActionCornersService.LOCATIONS.topLeft,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
// Alternatively, setting global customizations via configuration
|
||||
window.config = {
|
||||
// rest of config
|
||||
customizationService: [
|
||||
{
|
||||
'viewportActionMenu.windowLevelActionMenu': {
|
||||
$set: {
|
||||
enabled: false,
|
||||
location: 1,
|
||||
},
|
||||
},
|
||||
'viewportActionMenu.segmentationOverlay': {
|
||||
$set: {
|
||||
enabled: true,
|
||||
location: 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
// rest of config
|
||||
};
|
||||
```
|
||||
|
||||
**Note:**
|
||||
|
||||
@ -237,3 +317,5 @@ To keep our customization system consistent, you should be aware of a few key re
|
||||
| `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. |
|
||||
| (New) | `viewportActionMenu.windowLevelActionMenu` | Controls the display and the location of the window level action menu in the viewport. |
|
||||
| (New) | `viewportActionMenu.segmentationOverlay` | Controls the display and the location of segmentation overlays in the viewport. |
|
||||
|
||||
@ -16,6 +16,7 @@ import loadingIndicatorProgress from '../../../assets/img/loading-indicator-icon
|
||||
import loadingIndicatorPercent from '../../../assets/img/loading-indicator-percent.png';
|
||||
import viewportActionCorners from '../../../assets/img/viewport-action-corners.png';
|
||||
import contextMenu from '../../../assets/img/context-menu.jpg';
|
||||
import segmentationOverlay from '../../../assets/img/segmentation-overlay.png';
|
||||
|
||||
import segDisplayEditingTrue from '../../../assets/img/segDisplayEditingTrue.png';
|
||||
import segDisplayEditingFalse from '../../../assets/img/segDisplayEditingFalse.png';
|
||||
@ -784,6 +785,57 @@ window.config = {
|
||||
};
|
||||
`,
|
||||
},
|
||||
{
|
||||
id: 'viewportActionMenu.windowLevelActionMenu',
|
||||
description:
|
||||
'Configures the display and location of the window level action menu in the viewport.',
|
||||
image: windowLevelActionMenu,
|
||||
default: null,
|
||||
configuration: `
|
||||
window.config = {
|
||||
// rest of window config
|
||||
customizationService: [
|
||||
{
|
||||
'viewportActionMenu.windowLevelActionMenu': {
|
||||
$set: {
|
||||
enabled: true,
|
||||
location: 1, // Set the location of the menu in the viewport.
|
||||
// 0: topLeft
|
||||
// 1: topRight
|
||||
// 2: bottomLeft
|
||||
// 3: bottomRight
|
||||
}
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
`,
|
||||
},
|
||||
{
|
||||
id: 'viewportActionMenu.segmentationOverlay',
|
||||
description: 'Configures the display and location of the segmentation overlay in the viewport.',
|
||||
image: segmentationOverlay,
|
||||
default: null,
|
||||
configuration: `
|
||||
window.config = {
|
||||
// rest of window config
|
||||
customizationService: [
|
||||
{
|
||||
'viewportActionMenu.segmentationOverlay': {
|
||||
$set: {
|
||||
enabled: true,
|
||||
location: 1, // Set the location of the overlay in the viewport.
|
||||
// 0: topLeft
|
||||
// 1: topRight
|
||||
// 2: bottomLeft
|
||||
// 3: bottomRight
|
||||
}
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
`,
|
||||
},
|
||||
];
|
||||
|
||||
export const segmentationCustomizations = [
|
||||
|
||||
@ -192,7 +192,6 @@ if auth headers are used, a preflight request is required.
|
||||
- `allowMultiSelectExport`: (default to false), if set to true, the user will be able to select the datasource to export the report to.
|
||||
- `activateViewportBeforeInteraction`: (default to true), if set to false, tools can be used directly without the need to click and activate the viewport.
|
||||
- `autoPlayCine`: (default to false), if set to true, data sets with the DICOM frame time tag (i.e. (0018,1063)) will auto play when displayed
|
||||
- `addWindowLevelActionMenu`: (default to true), if set to false, the window level action menu item is NOT added to the viewport action corners
|
||||
- `dangerouslyUseDynamicConfig`: Dynamic config allows user to pass `configUrl` query string. This allows to load config without recompiling application. If the `configUrl` query string is passed, the worklist and modes will load from the referenced json rather than the default .env config. If there is no `configUrl` path provided, the default behaviour is used and there should not be any deviation from current user experience.<br/>
|
||||
Points to consider while using `dangerouslyUseDynamicConfig`:<br/>
|
||||
- User have to enable this feature by setting `dangerouslyUseDynamicConfig.enabled:true`. By default it is `false`.
|
||||
|
||||
Loading…
Reference in New Issue
Block a user