feat!: Ability to configure cornerstone tools via extension configuration (#1229)
* Fix ExtensionManager bug and add test to bandaid * Add tools configuration to extension manager preinit * Fix reducing of configs * Merge internal with external configs * Merge internal with external configs * Remove dialog from init in measurementstable * Testing injected configuration * New way to set config * Add new prop to dialog provider to allow disabling last position * Remove code from preinit in cornerstone * Add new prop to dialog provider to allow disabling last position * Add centralize to dialogs * Reorder dialogs when adding them * Fix draggable styles (cursor) * Remove repositioning methods from labelling flow and remove overlay from labelling manager * Fix empty array being set in bringToFront * Add new command to update table and pass commands manager to modules/preinit hook * Ad UIContextMenu service / factory * Use new contextmenu service in measurementspanel extension * Use dialogs for arrow annotate in default * Remove positioning funcionality from tool context menu * Add context menu service * Pass commandsModule to extension * Update edit description dialog and simple dialog to position relative * Remove style code from labelling flow and manager * Remove eventdata from labelling * Remove labelling code from measurement init * Add commandsmanager to provider * Update contextmenu provider and service * Add touchstart and mouseclick to hide contextmenu * Hide labelling if click/touch * Remove labelling and context menu dead code * Fix undefined bug if ViewerMain grid has no children * Fix broken prop on context menu * Update commandsmodule based on master * Fix broken configuration * Update script tag config * Remove cornerstone from toolcontextmenu * Remove cornerstone from toolcontextmenu * Split labelling and context menu providers * Split labelling and context menu providers * Update test * Destructure extensions into new array * CR Update: Move default arrow config to cornerstone instead of default * CR Update: Fix app configuration props structure * CR Update: Fix app configuration prop in script tag and extract commands manager from providers * CR Update: Create custom providers to use commandsManager * CR Update: Use services directly in measurementspanel * CR Update: Pass components to providers * CR Update: Remove position from dialog * CR Update: fix dialog prop check * CR Update: Fix comments * CR Update: Update documentation * CR Update: Add test default configuration * CR Update: Add default empy array to extensions * CR Update: Update i18n configuration all ot match current function configuration * CR Update: Add defaults to injected dependencies in configuration and extension configuration * CR Update: Add defaults to configuration with no args * Update documentation * CR Update: Add default for tools * CR Update: Update config object to i18n * CR Update: spread defaults * CR Update: Add tool configuration example to cornerstone extension * CR Update: Add tool configuration to netlify (testing) * CR Update: Remove netlify config for tools * CR Update: Rollback changes to i18n to be fixed later * CR Update: Update documentation and pass whole cornerstone config object instead of tools key SEE: https://www.conventionalcommits.org/en/v1.0.0/#commit-message-with-both-and-breaking-change-footer BREAKING CHANGE: modifies the exposed react <App /> components props. The contract for providing configuration for the app has changed. Please reference updated documentation for guidance.
This commit is contained in:
1 parent
fd7620ced9
commit
55a580659e
66 files changed
+1464
-1223
No files matched your search
@@ -59,7 +59,7 @@ export class CommandsManager {
|
||||
*
|
||||
* @method
|
||||
* @param {string} contextName - Namespace for commands
|
||||
* @returs {Object} - the matched context
|
||||
* @returns {Object} - the matched context
|
||||
*/
|
||||
getContext(contextName) {
|
||||
const context = this.contexts[contextName];
|
||||
|
||||
@@ -26,7 +26,7 @@ export default class ExtensionManager {
|
||||
const hasConfiguration = Array.isArray(extension);
|
||||
|
||||
if (hasConfiguration) {
|
||||
const [ohifExtension, configuration] = extensions;
|
||||
const [ohifExtension, configuration] = extension;
|
||||
this.registerExtension(ohifExtension, configuration);
|
||||
} else {
|
||||
this.registerExtension(extension);
|
||||
|
||||
@@ -37,6 +37,24 @@ describe('ExtensionManager.js', () => {
|
||||
// Assert
|
||||
expect(extensionManager.registerExtension.mock.calls.length).toBe(3);
|
||||
});
|
||||
|
||||
it('calls registerExtension() for each extension passing its configuration if tuple', () => {
|
||||
const fakeConfiguration = { testing: true };
|
||||
extensionManager.registerExtension = jest.fn();
|
||||
|
||||
// SUT
|
||||
const fakeExtensions = [
|
||||
{ one: '1' },
|
||||
[{ two: '2' }, fakeConfiguration],
|
||||
{ three: '3 ' },
|
||||
];
|
||||
extensionManager.registerExtensions(fakeExtensions);
|
||||
|
||||
// Assert
|
||||
expect(extensionManager.registerExtension.mock.calls[1]).toContain(
|
||||
fakeConfiguration
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('registerExtension()', () => {
|
||||
|
||||
@@ -23,6 +23,8 @@ import {
|
||||
createUINotificationService,
|
||||
createUIModalService,
|
||||
createUIDialogService,
|
||||
createUIContextMenuService,
|
||||
createUILabellingFlowService,
|
||||
} from './services';
|
||||
|
||||
const OHIF = {
|
||||
@@ -53,6 +55,8 @@ const OHIF = {
|
||||
createUINotificationService,
|
||||
createUIModalService,
|
||||
createUIDialogService,
|
||||
createUIContextMenuService,
|
||||
createUILabellingFlowService,
|
||||
};
|
||||
|
||||
export {
|
||||
@@ -82,6 +86,8 @@ export {
|
||||
createUINotificationService,
|
||||
createUIModalService,
|
||||
createUIDialogService,
|
||||
createUIContextMenuService,
|
||||
createUILabellingFlowService,
|
||||
};
|
||||
|
||||
export { OHIF };
|
||||
|
||||
@@ -13,6 +13,8 @@ describe('Top level exports', () => {
|
||||
'createUINotificationService',
|
||||
'createUIModalService',
|
||||
'createUIDialogService',
|
||||
'createUIContextMenuService',
|
||||
'createUILabellingFlowService',
|
||||
//
|
||||
'utils',
|
||||
'studies',
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
/**
|
||||
* UI Context Menu
|
||||
*
|
||||
* @typedef {Object} ContextMenuProps
|
||||
* @property {Event} event The event with tool information.
|
||||
*/
|
||||
|
||||
const uiContextMenuServicePublicAPI = {
|
||||
name: 'UIContextMenuService',
|
||||
hide,
|
||||
show,
|
||||
setServiceImplementation,
|
||||
};
|
||||
|
||||
const uiContextMenuServiceImplementation = {
|
||||
_show: () => console.warn('show() NOT IMPLEMENTED'),
|
||||
_hide: () => console.warn('hide() NOT IMPLEMENTED'),
|
||||
};
|
||||
|
||||
function createUIContextMenuService() {
|
||||
return uiContextMenuServicePublicAPI;
|
||||
}
|
||||
|
||||
/**
|
||||
* Show a new UI ContextMenu dialog;
|
||||
*
|
||||
* @param {ContextMenuProps} props { event }
|
||||
*/
|
||||
function show({ event }) {
|
||||
return uiContextMenuServiceImplementation._show({
|
||||
event,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Hide a UI ContextMenu dialog;
|
||||
*
|
||||
*/
|
||||
function hide() {
|
||||
return uiContextMenuServiceImplementation._hide();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param {*} {
|
||||
* show: showImplementation,
|
||||
* hide: hideImplementation,
|
||||
* }
|
||||
*/
|
||||
function setServiceImplementation({
|
||||
show: showImplementation,
|
||||
hide: hideImplementation,
|
||||
}) {
|
||||
if (showImplementation) {
|
||||
uiContextMenuServiceImplementation._show = showImplementation;
|
||||
}
|
||||
if (hideImplementation) {
|
||||
uiContextMenuServiceImplementation._hide = hideImplementation;
|
||||
}
|
||||
}
|
||||
|
||||
export default createUIContextMenuService;
|
||||
@@ -17,8 +17,9 @@
|
||||
* @property {Object} contentProps The dialog content props.
|
||||
* @property {boolean} [isDraggable=true] Controls if dialog content is draggable or not.
|
||||
* @property {boolean} [showOverlay=false] Controls dialog overlay.
|
||||
* @property {boolean} [centralize=false] Center the dialog on the screen.
|
||||
* @property {boolean} [preservePosition=true] Use last position instead of default.
|
||||
* @property {ElementPosition} defaultPosition Specifies the `x` and `y` that the dragged item should start at.
|
||||
* @property {ElementPosition} position If this property is present, the item becomes 'controlled' and is not responsive to user input.
|
||||
* @property {Function} onStart Called when dragging starts. If `false` is returned any handler, the action will cancel.
|
||||
* @property {Function} onStop Called when dragging stops.
|
||||
* @property {Function} onDrag Called while dragging.
|
||||
@@ -45,7 +46,7 @@ function createUIDialogService() {
|
||||
/**
|
||||
* Show a new UI dialog;
|
||||
*
|
||||
* @param {DialogProps} props { id, content, contentProps, onStart, onDrag, onStop, isDraggable, showOverlay, defaultPosition, position }
|
||||
* @param {DialogProps} props { id, content, contentProps, onStart, onDrag, onStop, centralize, isDraggable, showOverlay, preservePosition, defaultPosition }
|
||||
*/
|
||||
function create({
|
||||
id,
|
||||
@@ -54,10 +55,11 @@ function create({
|
||||
onStart,
|
||||
onDrag,
|
||||
onStop,
|
||||
centralize = false,
|
||||
preservePosition = true,
|
||||
isDraggable = true,
|
||||
showOverlay = false,
|
||||
defaultPosition,
|
||||
position,
|
||||
}) {
|
||||
return uiDialogServiceImplementation._create({
|
||||
id,
|
||||
@@ -66,10 +68,11 @@ function create({
|
||||
onStart,
|
||||
onDrag,
|
||||
onStop,
|
||||
centralize,
|
||||
preservePosition,
|
||||
isDraggable,
|
||||
showOverlay,
|
||||
defaultPosition,
|
||||
position,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
/**
|
||||
* UI Labelling Flow
|
||||
*
|
||||
* @typedef {Object} LabellingFlowProps
|
||||
* @property {Object} defaultPosition The position of the labelling dialog.
|
||||
* @property {boolean} centralize conditional to center the labelling dialog.
|
||||
* @property {Object} props The labelling props.
|
||||
*
|
||||
*/
|
||||
|
||||
const uiLabellingFlowServicePublicAPI = {
|
||||
name: 'UILabellingFlowService',
|
||||
show,
|
||||
hide,
|
||||
setServiceImplementation,
|
||||
};
|
||||
|
||||
const uiLabellingFlowServiceImplementation = {
|
||||
_show: () => console.warn('show() NOT IMPLEMENTED'),
|
||||
_hide: () => console.warn('hide() NOT IMPLEMENTED'),
|
||||
};
|
||||
|
||||
function createUILabellingFlowService() {
|
||||
return uiLabellingFlowServicePublicAPI;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hide a UI LabellingFlow dialog;
|
||||
*
|
||||
*/
|
||||
function hide() {
|
||||
return uiLabellingFlowServiceImplementation._hide();
|
||||
}
|
||||
|
||||
/**
|
||||
* Show a new UI LabellingFlow dialog;
|
||||
*
|
||||
* @param {LabellingFlowProps} props { defaultPosition, centralize, props }
|
||||
*/
|
||||
function show({ defaultPosition, centralize, props }) {
|
||||
return uiLabellingFlowServiceImplementation._show({
|
||||
defaultPosition,
|
||||
centralize,
|
||||
props,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param {*} {
|
||||
* show: showImplementation,
|
||||
* hide: hideImplementation,
|
||||
* }
|
||||
*/
|
||||
function setServiceImplementation({
|
||||
show: showImplementation,
|
||||
hide: hideImplementation,
|
||||
}) {
|
||||
if (showImplementation) {
|
||||
uiLabellingFlowServiceImplementation._show = showImplementation;
|
||||
}
|
||||
if (hideImplementation) {
|
||||
uiLabellingFlowServiceImplementation._hide = hideImplementation;
|
||||
}
|
||||
}
|
||||
|
||||
export default createUILabellingFlowService;
|
||||
@@ -2,10 +2,14 @@ import ServicesManager from './ServicesManager.js';
|
||||
import createUINotificationService from './UINotificationService';
|
||||
import createUIModalService from './UIModalService';
|
||||
import createUIDialogService from './UIDialogService';
|
||||
import createUIContextMenuService from './UIContextMenuService';
|
||||
import createUILabellingFlowService from './UILabellingFlowService';
|
||||
|
||||
export {
|
||||
createUINotificationService,
|
||||
createUIModalService,
|
||||
createUIDialogService,
|
||||
createUIContextMenuService,
|
||||
createUILabellingFlowService,
|
||||
ServicesManager,
|
||||
};
|
||||
Reference in new issue
Block a user