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",
"@kitware/vtk.js": "30.4.1",
"html2canvas": "^1.4.1",
"lodash.debounce": "4.0.8",
"lodash.debounce": "^4.0.8",
"lodash.merge": "^4.6.2",
"shader-loader": "^1.3.1",
"worker-loader": "^3.0.8"

View File

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

View File

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

View File

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

View File

@ -49,7 +49,8 @@
"gl-matrix": "^3.4.3",
"isomorphic-base64": "^1.0.2",
"lodash.clonedeep": "^4.5.0",
"lodash.merge": "^4.6.1",
"lodash.merge": "^4.6.2",
"lodash.mergewith": "^4.6.2",
"moment": "^2.24.0",
"object-hash": "2.1.1",
"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 { Customization, NestedStrings, Obj } from './types';
import { Customization, NestedStrings } from './types';
import { CommandsManager } from '../../classes';
const EVENTS = {
@ -28,6 +28,21 @@ const flattenNestedStrings = (
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
* 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);
return entry;
}
@ -107,10 +122,15 @@ export default class CustomizationService extends PubSubService {
return this.modeCustomizations;
}
public setModeCustomization(customizationId: string, customization: Customization): void {
this.modeCustomizations[customizationId] = merge(
this.modeCustomizations[customizationId] || {},
customization
public setModeCustomization(
customizationId: string,
customization: Customization,
merge = MergeEnum.Merge
): void {
this.modeCustomizations[customizationId] = this.mergeValue(
this.modeCustomizations[customizationId],
customization,
merge
);
this._broadcastEvent(this.EVENTS.CUSTOMIZATION_MODIFIED, {
buttons: this.modeCustomizations,
@ -209,8 +229,16 @@ export default class CustomizationService extends PubSubService {
return this.transform(this.globalCustomizations[id] ?? defaultValue);
}
setGlobalCustomization(id: string, value: Customization): void {
this.globalCustomizations[id] = value;
private mergeValue(oldValue, newValue, mergeType = MergeEnum.Replace) {
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();
}
@ -235,7 +263,7 @@ export default class CustomizationService extends PubSubService {
* A single reference is either an string to be loaded from a module,
* or a customization itself.
*/
addReference(value?: Obj | string, isGlobal = true, id?: string): void {
addReference(value?, isGlobal = true, id?: string, merge?: MergeEnum): void {
if (!value) {
return;
}
@ -243,12 +271,16 @@ export default class CustomizationService extends PubSubService {
const extensionValue = this.findExtensionValue(value);
// 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
this.addReference(extensionValue.value, isGlobal, extensionValue.name);
this.addReference(extensionValue.value, isGlobal, extensionValue.name, extensionValue.merge);
} else if (Array.isArray(value)) {
this.addReferences(value, isGlobal);
} else {
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 customization.
*/
addReferences(references?: Obj | Obj[], isGlobal = true): void {
addReferences(references?, isGlobal = true): void {
if (!references) {
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"
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"
resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a"
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:
version "4.1.1"
resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac"