feat: Add customization merge, append or replace functionality (#3871)

This commit is contained in:
Bill Wallace 2024-06-12 11:20:27 -04:00 committed by GitHub
parent efa6df8bfb
commit 55dcfa1f69
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 73 additions and 17 deletions

View File

@ -62,7 +62,7 @@
"@icr/polyseg-wasm": "^0.4.0", "@icr/polyseg-wasm": "^0.4.0",
"@kitware/vtk.js": "30.4.1", "@kitware/vtk.js": "30.4.1",
"html2canvas": "^1.4.1", "html2canvas": "^1.4.1",
"lodash.debounce": "4.0.8", "lodash.debounce": "^4.0.8",
"lodash.merge": "^4.6.2", "lodash.merge": "^4.6.2",
"shader-loader": "^1.3.1", "shader-loader": "^1.3.1",
"worker-loader": "^3.0.8" "worker-loader": "^3.0.8"

View File

@ -18,6 +18,7 @@ export default function getCustomizationModule({ servicesManager, extensionManag
return [ return [
{ {
name: 'helloPage', name: 'helloPage',
merge: 'Append',
value: { value: {
id: 'customRoutes', id: 'customRoutes',
routes: [ routes: [
@ -32,6 +33,7 @@ export default function getCustomizationModule({ servicesManager, extensionManag
// Example customization to list a set of datasources // Example customization to list a set of datasources
{ {
name: 'datasources', name: 'datasources',
merge: 'Append',
value: { value: {
id: 'customRoutes', id: 'customRoutes',
routes: [ routes: [

View File

@ -39,7 +39,7 @@
"@ohif/ui": "3.9.0-beta.40", "@ohif/ui": "3.9.0-beta.40",
"classnames": "^2.3.2", "classnames": "^2.3.2",
"dcmjs": "^0.29.12", "dcmjs": "^0.29.12",
"lodash.debounce": "^4.17.21", "lodash.debounce": "^4.0.8",
"prop-types": "^15.6.2", "prop-types": "^15.6.2",
"react": "^18.3.1", "react": "^18.3.1",
"react-dom": "^18.3.1", "react-dom": "^18.3.1",

View File

@ -10,6 +10,13 @@ window.config = {
showCPUFallbackMessage: false, showCPUFallbackMessage: false,
strictZSpacingForVolumeViewport: true, strictZSpacingForVolumeViewport: true,
// filterQueryParam: false, // filterQueryParam: false,
// Add some customizations to the default e2e datasource
customizationService: [
'@ohif/extension-default.customizationModule.datasources',
'@ohif/extension-default.customizationModule.helloPage',
],
defaultDataSourceName: 'e2e', defaultDataSourceName: 'e2e',
investigationalUseDialog: { investigationalUseDialog: {
option: 'never', option: 'never',

View File

@ -49,7 +49,8 @@
"gl-matrix": "^3.4.3", "gl-matrix": "^3.4.3",
"isomorphic-base64": "^1.0.2", "isomorphic-base64": "^1.0.2",
"lodash.clonedeep": "^4.5.0", "lodash.clonedeep": "^4.5.0",
"lodash.merge": "^4.6.1", "lodash.merge": "^4.6.2",
"lodash.mergewith": "^4.6.2",
"moment": "^2.24.0", "moment": "^2.24.0",
"object-hash": "2.1.1", "object-hash": "2.1.1",
"query-string": "^6.14.0", "query-string": "^6.14.0",

View File

@ -1,6 +1,6 @@
import merge from 'lodash.merge'; import mergeWith from 'lodash.mergewith';
import { PubSubService } from '../_shared/pubSubServiceInterface'; import { PubSubService } from '../_shared/pubSubServiceInterface';
import { Customization, NestedStrings, Obj } from './types'; import { Customization, NestedStrings } from './types';
import { CommandsManager } from '../../classes'; import { CommandsManager } from '../../classes';
const EVENTS = { const EVENTS = {
@ -28,6 +28,21 @@ const flattenNestedStrings = (
return ret; return ret;
}; };
export enum MergeEnum {
/**
* Append values in the nested arrays
*/
Append = 'Append',
/**
* Merge values, replacing arrays
*/
Merge = 'Merge',
/**
* Replace the given value - this is the default
*/
Replace = 'Replace',
}
/** /**
* The CustomizationService allows for retrieving of custom components * The CustomizationService allows for retrieving of custom components
* and configuration for mode and global values. * and configuration for mode and global values.
@ -93,7 +108,7 @@ export default class CustomizationService extends PubSubService {
}); });
} }
findExtensionValue(value: string): Obj | void { findExtensionValue(value: string) {
const entry = this.extensionManager.getModuleEntry(value); const entry = this.extensionManager.getModuleEntry(value);
return entry; return entry;
} }
@ -107,10 +122,15 @@ export default class CustomizationService extends PubSubService {
return this.modeCustomizations; return this.modeCustomizations;
} }
public setModeCustomization(customizationId: string, customization: Customization): void { public setModeCustomization(
this.modeCustomizations[customizationId] = merge( customizationId: string,
this.modeCustomizations[customizationId] || {}, customization: Customization,
customization merge = MergeEnum.Merge
): void {
this.modeCustomizations[customizationId] = this.mergeValue(
this.modeCustomizations[customizationId],
customization,
merge
); );
this._broadcastEvent(this.EVENTS.CUSTOMIZATION_MODIFIED, { this._broadcastEvent(this.EVENTS.CUSTOMIZATION_MODIFIED, {
buttons: this.modeCustomizations, buttons: this.modeCustomizations,
@ -209,8 +229,16 @@ export default class CustomizationService extends PubSubService {
return this.transform(this.globalCustomizations[id] ?? defaultValue); return this.transform(this.globalCustomizations[id] ?? defaultValue);
} }
setGlobalCustomization(id: string, value: Customization): void { private mergeValue(oldValue, newValue, mergeType = MergeEnum.Replace) {
this.globalCustomizations[id] = value; if (mergeType === MergeEnum.Replace) {
return newValue;
}
return mergeWith(oldValue || {}, newValue, mergeCustomizer.bind(null, mergeType));
}
public setGlobalCustomization(id: string, value: Customization, merge = MergeEnum.Replace): void {
this.globalCustomizations[id] = this.mergeValue(this.globalCustomizations[id], value, merge);
this._broadcastGlobalCustomizationModified(); this._broadcastGlobalCustomizationModified();
} }
@ -235,7 +263,7 @@ export default class CustomizationService extends PubSubService {
* A single reference is either an string to be loaded from a module, * A single reference is either an string to be loaded from a module,
* or a customization itself. * or a customization itself.
*/ */
addReference(value?: Obj | string, isGlobal = true, id?: string): void { addReference(value?, isGlobal = true, id?: string, merge?: MergeEnum): void {
if (!value) { if (!value) {
return; return;
} }
@ -243,12 +271,16 @@ export default class CustomizationService extends PubSubService {
const extensionValue = this.findExtensionValue(value); const extensionValue = this.findExtensionValue(value);
// The child of a reference is only a set of references when an array, // The child of a reference is only a set of references when an array,
// so call the addReference direct. It could be a secondary reference perhaps // so call the addReference direct. It could be a secondary reference perhaps
this.addReference(extensionValue.value, isGlobal, extensionValue.name); this.addReference(extensionValue.value, isGlobal, extensionValue.name, extensionValue.merge);
} else if (Array.isArray(value)) { } else if (Array.isArray(value)) {
this.addReferences(value, isGlobal); this.addReferences(value, isGlobal);
} else { } else {
const useId = value.id || id; const useId = value.id || id;
this[isGlobal ? 'setGlobalCustomization' : 'setModeCustomization'](useId as string, value); this[isGlobal ? 'setGlobalCustomization' : 'setModeCustomization'](
useId as string,
value,
merge
);
} }
} }
@ -257,7 +289,7 @@ export default class CustomizationService extends PubSubService {
* or as an object whose key is the reference id, and the value is the string * or as an object whose key is the reference id, and the value is the string
* or customization. * or customization.
*/ */
addReferences(references?: Obj | Obj[], isGlobal = true): void { addReferences(references?, isGlobal = true): void {
if (!references) { if (!references) {
return; return;
} }
@ -273,3 +305,12 @@ export default class CustomizationService extends PubSubService {
} }
} }
} }
/**
* Custom merging function, to handle merging arrays
*/
function mergeCustomizer(merge: MergeEnum, obj, src) {
if (merge === MergeEnum.Append && Array.isArray(obj)) {
return obj.concat(src);
}
}

View File

@ -15122,11 +15122,16 @@ lodash.memoize@^4.1.2:
resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe"
integrity sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag== integrity sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==
lodash.merge@^4.6.1, lodash.merge@^4.6.2: lodash.merge@^4.6.2:
version "4.6.2" version "4.6.2"
resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a"
integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==
lodash.mergewith@^4.6.2:
version "4.6.2"
resolved "https://registry.yarnpkg.com/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz#617121f89ac55f59047c7aec1ccd6654c6590f55"
integrity sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==
lodash.once@^4.1.1: lodash.once@^4.1.1:
version "4.1.1" version "4.1.1"
resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac" resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac"