2023-02-10 20:30:56 +01:00
|
|
|
import MODULE_TYPES from './MODULE_TYPES';
|
|
|
|
|
import log from '../log';
|
|
|
|
|
import { AppConfig } from '../types/AppConfig';
|
|
|
|
|
import { ServicesManager } from '../services';
|
|
|
|
|
import { HotkeysManager, CommandsManager } from '../classes';
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* This is the arguments given to create the extension.
|
|
|
|
|
*/
|
|
|
|
|
export interface ExtensionConstructor {
|
|
|
|
|
servicesManager: ServicesManager;
|
|
|
|
|
commandsManager: CommandsManager;
|
|
|
|
|
hotkeysManager: HotkeysManager;
|
|
|
|
|
appConfig: AppConfig;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* The configuration of an extension.
|
|
|
|
|
* This uses type as the extension manager only knows that the configuration
|
|
|
|
|
* is an object of some sort, and doesn't know anything else about it.
|
|
|
|
|
*/
|
|
|
|
|
export type ExtensionConfiguration = Record<string, unknown>;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* The parameters passed to the extension.
|
|
|
|
|
*/
|
|
|
|
|
export interface ExtensionParams extends ExtensionConstructor {
|
|
|
|
|
extensionManager: ExtensionManager;
|
|
|
|
|
configuration?: ExtensionConfiguration;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* The type of an actual extension instance.
|
|
|
|
|
* This is an interface as it declares possible calls, but extensions can
|
|
|
|
|
* have more values than this.
|
|
|
|
|
*/
|
|
|
|
|
export interface Extension {
|
2023-02-17 21:04:07 +01:00
|
|
|
id: string;
|
2023-03-22 22:45:28 +01:00
|
|
|
preRegistration?: (p: ExtensionParams) => Promise<void> | void;
|
|
|
|
|
onModeExit?: () => void;
|
|
|
|
|
getHangingProtocolModule?: (p: ExtensionParams) => unknown;
|
|
|
|
|
getCommandsModule?: (p: ExtensionParams) => CommandsModule;
|
2023-02-10 20:30:56 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export type ExtensionRegister = {
|
|
|
|
|
id: string;
|
|
|
|
|
create: (p: ExtensionParams) => Extension;
|
|
|
|
|
};
|
2019-08-13 21:36:46 +02:00
|
|
|
|
2023-03-22 22:45:28 +01:00
|
|
|
export type CommandsModule = {
|
|
|
|
|
actions: Record<string, unknown>;
|
|
|
|
|
definitions: Record<string, unknown>;
|
|
|
|
|
defaultContext?: string;
|
|
|
|
|
};
|
|
|
|
|
|
2019-08-13 21:36:46 +02:00
|
|
|
export default class ExtensionManager {
|
2023-02-10 20:30:56 +01:00
|
|
|
private _commandsManager: CommandsManager;
|
|
|
|
|
private _servicesManager: ServicesManager;
|
|
|
|
|
private _hotkeysManager: HotkeysManager;
|
|
|
|
|
|
2021-05-28 20:32:48 +02:00
|
|
|
constructor({
|
|
|
|
|
commandsManager,
|
|
|
|
|
servicesManager,
|
|
|
|
|
hotkeysManager,
|
|
|
|
|
appConfig = {},
|
2023-02-10 20:30:56 +01:00
|
|
|
}: ExtensionConstructor) {
|
2019-08-13 21:36:46 +02:00
|
|
|
this.modules = {};
|
|
|
|
|
this.registeredExtensionIds = [];
|
|
|
|
|
this.moduleTypeNames = Object.values(MODULE_TYPES);
|
|
|
|
|
//
|
|
|
|
|
this._commandsManager = commandsManager;
|
2019-11-13 21:02:14 +01:00
|
|
|
this._servicesManager = servicesManager;
|
2020-08-19 21:02:59 +02:00
|
|
|
this._hotkeysManager = hotkeysManager;
|
2019-12-16 20:07:53 +01:00
|
|
|
this._appConfig = appConfig;
|
2019-08-13 21:36:46 +02:00
|
|
|
|
2020-05-07 20:04:33 +02:00
|
|
|
this.modulesMap = {};
|
2019-08-13 21:36:46 +02:00
|
|
|
this.moduleTypeNames.forEach(moduleType => {
|
|
|
|
|
this.modules[moduleType] = [];
|
|
|
|
|
});
|
2020-08-04 11:11:23 +02:00
|
|
|
this._extensionLifeCycleHooks = { onModeEnter: {}, onModeExit: {} };
|
2020-05-07 20:04:33 +02:00
|
|
|
this.dataSourceMap = {};
|
2022-12-29 16:13:06 +01:00
|
|
|
this.dataSourceDefs = {};
|
2020-06-05 17:36:11 +02:00
|
|
|
this.defaultDataSourceName = appConfig.defaultDataSourceName;
|
|
|
|
|
this.activeDataSource = undefined;
|
|
|
|
|
}
|
2020-05-13 12:06:13 +02:00
|
|
|
|
2023-02-10 20:30:56 +01:00
|
|
|
public setActiveDataSource(dataSourceName: string): void {
|
2020-06-05 17:36:11 +02:00
|
|
|
this.activeDataSource = dataSourceName;
|
2019-08-13 21:36:46 +02:00
|
|
|
}
|
|
|
|
|
|
2023-02-10 20:30:56 +01:00
|
|
|
/**
|
|
|
|
|
* Calls all the services and extension on mode enters.
|
|
|
|
|
* The service onModeEnter is called first
|
|
|
|
|
* Then registered extensions onModeEnter is called
|
|
|
|
|
* This is supposed to setup the extension for a standard entry.
|
|
|
|
|
*/
|
|
|
|
|
public onModeEnter(): void {
|
2020-07-03 19:18:59 +02:00
|
|
|
const {
|
|
|
|
|
registeredExtensionIds,
|
|
|
|
|
_servicesManager,
|
|
|
|
|
_commandsManager,
|
2020-08-19 21:02:59 +02:00
|
|
|
_hotkeysManager,
|
2020-07-03 19:18:59 +02:00
|
|
|
_extensionLifeCycleHooks,
|
|
|
|
|
} = this;
|
|
|
|
|
|
2022-12-09 16:58:01 +01:00
|
|
|
// The onModeEnter of the service must occur BEFORE the extension
|
|
|
|
|
// onModeEnter in order to reset the state to a standard state
|
|
|
|
|
// before the extension restores and cached data.
|
2022-11-24 22:28:10 +01:00
|
|
|
for (const service of Object.values(_servicesManager.services)) {
|
|
|
|
|
service?.onModeEnter?.();
|
|
|
|
|
}
|
2020-08-04 11:11:23 +02:00
|
|
|
|
2020-07-03 19:18:59 +02:00
|
|
|
registeredExtensionIds.forEach(extensionId => {
|
|
|
|
|
const onModeEnter = _extensionLifeCycleHooks.onModeEnter[extensionId];
|
|
|
|
|
|
|
|
|
|
if (typeof onModeEnter === 'function') {
|
|
|
|
|
onModeEnter({
|
|
|
|
|
servicesManager: _servicesManager,
|
|
|
|
|
commandsManager: _commandsManager,
|
2021-05-28 20:32:48 +02:00
|
|
|
hotkeysManager: _hotkeysManager,
|
2020-07-03 19:18:59 +02:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2023-02-10 20:30:56 +01:00
|
|
|
public onModeExit(): void {
|
2020-08-04 11:11:23 +02:00
|
|
|
const {
|
|
|
|
|
registeredExtensionIds,
|
|
|
|
|
_servicesManager,
|
|
|
|
|
_commandsManager,
|
|
|
|
|
_extensionLifeCycleHooks,
|
|
|
|
|
} = this;
|
|
|
|
|
|
|
|
|
|
registeredExtensionIds.forEach(extensionId => {
|
|
|
|
|
const onModeExit = _extensionLifeCycleHooks.onModeExit[extensionId];
|
|
|
|
|
|
|
|
|
|
if (typeof onModeExit === 'function') {
|
|
|
|
|
onModeExit({
|
|
|
|
|
servicesManager: _servicesManager,
|
|
|
|
|
commandsManager: _commandsManager,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
});
|
2022-12-09 16:58:01 +01:00
|
|
|
|
|
|
|
|
// The service onModeExit calls must occur after the extension ones
|
|
|
|
|
// so that extension ones can store/restore data.
|
|
|
|
|
for (const service of Object.values(_servicesManager.services)) {
|
|
|
|
|
try {
|
|
|
|
|
service?.onModeExit?.();
|
|
|
|
|
} catch (e) {
|
|
|
|
|
console.warn('onModeExit caught', e);
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-08-04 11:11:23 +02:00
|
|
|
}
|
|
|
|
|
|
2019-08-13 21:36:46 +02:00
|
|
|
/**
|
|
|
|
|
* An array of extensions, or an array of arrays that contains extension
|
|
|
|
|
* configuration pairs.
|
|
|
|
|
*
|
|
|
|
|
* @param {Object[]} extensions - Array of extensions
|
|
|
|
|
*/
|
2023-02-10 20:30:56 +01:00
|
|
|
public registerExtensions = async (
|
|
|
|
|
extensions: (
|
|
|
|
|
| ExtensionRegister
|
|
|
|
|
| [ExtensionRegister, ExtensionConfiguration]
|
|
|
|
|
)[],
|
|
|
|
|
dataSources: unknown[] = []
|
|
|
|
|
): Promise<void> => {
|
2022-07-27 18:39:04 +02:00
|
|
|
// Todo: we ideally should be able to run registrations in parallel
|
|
|
|
|
// but currently since some extensions need to be registered before
|
|
|
|
|
// others, we need to run them sequentially. We need a postInit hook
|
|
|
|
|
// to avoid this sequential async registration
|
2023-02-17 21:04:07 +01:00
|
|
|
for (let i = 0; i < extensions.length; i++) {
|
|
|
|
|
const extension = extensions[i];
|
2019-08-13 21:36:46 +02:00
|
|
|
const hasConfiguration = Array.isArray(extension);
|
2022-07-27 18:39:04 +02:00
|
|
|
try {
|
|
|
|
|
if (hasConfiguration) {
|
2023-02-17 21:04:07 +01:00
|
|
|
// Important: for some reason in the line below the type
|
|
|
|
|
// of extension is not recognized as [ExtensionRegister,
|
|
|
|
|
// ExtensionConfiguration] by babel DON"T CHANGE IT
|
|
|
|
|
// Same for the for loop above don't use
|
|
|
|
|
// for (const extension of extensions)
|
|
|
|
|
const ohifExtension = extension[0];
|
|
|
|
|
const configuration = extension[1];
|
2022-07-27 18:39:04 +02:00
|
|
|
await this.registerExtension(
|
|
|
|
|
ohifExtension,
|
|
|
|
|
configuration,
|
|
|
|
|
dataSources
|
|
|
|
|
);
|
|
|
|
|
} else {
|
|
|
|
|
await this.registerExtension(extension, {}, dataSources);
|
|
|
|
|
}
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error(error);
|
2019-08-13 21:36:46 +02:00
|
|
|
}
|
2022-07-27 18:39:04 +02:00
|
|
|
}
|
2020-05-09 20:23:43 +02:00
|
|
|
};
|
2019-08-13 21:36:46 +02:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
*
|
|
|
|
|
* TODO: Id Management: SopClassHandlers currently refer to viewport module by id; setting the extension id as viewport module id is a workaround for now
|
|
|
|
|
* @param {Object} extension
|
|
|
|
|
* @param {Object} configuration
|
|
|
|
|
*/
|
2023-02-10 20:30:56 +01:00
|
|
|
public registerExtension = async (
|
|
|
|
|
extension: ExtensionRegister,
|
2022-07-27 18:39:04 +02:00
|
|
|
configuration = {},
|
|
|
|
|
dataSources = []
|
2023-02-10 20:30:56 +01:00
|
|
|
): Promise<void> => {
|
2019-08-13 21:36:46 +02:00
|
|
|
if (!extension) {
|
2021-05-28 20:32:48 +02:00
|
|
|
throw new Error('Attempting to register a null/undefined extension.');
|
2019-08-13 21:36:46 +02:00
|
|
|
}
|
|
|
|
|
|
2023-02-10 20:30:56 +01:00
|
|
|
const extensionId = extension.id;
|
2019-08-13 21:36:46 +02:00
|
|
|
|
|
|
|
|
if (!extensionId) {
|
2020-05-13 12:06:13 +02:00
|
|
|
// Note: Mode framework cannot function without IDs.
|
|
|
|
|
log.warn(extension);
|
|
|
|
|
throw new Error(`Extension ID not set`);
|
2019-08-13 21:36:46 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (this.registeredExtensionIds.includes(extensionId)) {
|
|
|
|
|
log.warn(
|
|
|
|
|
`Extension ID ${extensionId} has already been registered. Exiting before duplicating modules.`
|
|
|
|
|
);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// preRegistrationHook
|
|
|
|
|
if (extension.preRegistration) {
|
2022-07-27 18:39:04 +02:00
|
|
|
await extension.preRegistration({
|
2019-11-14 15:50:37 +01:00
|
|
|
servicesManager: this._servicesManager,
|
2019-12-02 17:29:04 +01:00
|
|
|
commandsManager: this._commandsManager,
|
2020-08-19 21:02:59 +02:00
|
|
|
hotkeysManager: this._hotkeysManager,
|
2022-07-27 18:39:04 +02:00
|
|
|
extensionManager: this,
|
2019-12-16 20:07:53 +01:00
|
|
|
appConfig: this._appConfig,
|
2019-11-13 21:02:14 +01:00
|
|
|
configuration,
|
|
|
|
|
});
|
2019-08-13 21:36:46 +02:00
|
|
|
}
|
|
|
|
|
|
2020-07-03 19:18:59 +02:00
|
|
|
if (extension.onModeEnter) {
|
|
|
|
|
this._extensionLifeCycleHooks.onModeEnter[extensionId] =
|
|
|
|
|
extension.onModeEnter;
|
|
|
|
|
}
|
|
|
|
|
|
2020-08-04 11:11:23 +02:00
|
|
|
if (extension.onModeExit) {
|
|
|
|
|
this._extensionLifeCycleHooks.onModeExit[extensionId] =
|
|
|
|
|
extension.onModeExit;
|
|
|
|
|
}
|
|
|
|
|
|
2019-08-13 21:36:46 +02:00
|
|
|
// Register Modules
|
|
|
|
|
this.moduleTypeNames.forEach(moduleType => {
|
|
|
|
|
const extensionModule = this._getExtensionModule(
|
|
|
|
|
moduleType,
|
|
|
|
|
extension,
|
2019-12-16 20:07:53 +01:00
|
|
|
extensionId,
|
|
|
|
|
configuration
|
2019-08-13 21:36:46 +02:00
|
|
|
);
|
|
|
|
|
|
|
|
|
|
if (extensionModule) {
|
2020-05-13 12:06:13 +02:00
|
|
|
switch (moduleType) {
|
|
|
|
|
case MODULE_TYPES.COMMANDS:
|
|
|
|
|
this._initCommandsModule(extensionModule);
|
|
|
|
|
break;
|
|
|
|
|
case MODULE_TYPES.DATA_SOURCE:
|
|
|
|
|
this._initDataSourcesModule(
|
|
|
|
|
extensionModule,
|
|
|
|
|
extensionId,
|
|
|
|
|
dataSources
|
|
|
|
|
);
|
|
|
|
|
break;
|
2022-09-21 05:40:26 +02:00
|
|
|
case MODULE_TYPES.HANGING_PROTOCOL:
|
|
|
|
|
this._initHangingProtocolsModule(extensionModule, extensionId);
|
2020-05-13 12:06:13 +02:00
|
|
|
case MODULE_TYPES.TOOLBAR:
|
2020-05-15 19:07:21 +02:00
|
|
|
case MODULE_TYPES.VIEWPORT:
|
2020-05-13 12:06:13 +02:00
|
|
|
case MODULE_TYPES.PANEL:
|
|
|
|
|
case MODULE_TYPES.SOP_CLASS_HANDLER:
|
|
|
|
|
case MODULE_TYPES.CONTEXT:
|
|
|
|
|
case MODULE_TYPES.LAYOUT_TEMPLATE:
|
2022-11-24 22:28:10 +01:00
|
|
|
case MODULE_TYPES.CUSTOMIZATION:
|
2023-02-10 20:30:56 +01:00
|
|
|
case MODULE_TYPES.STATE_SYNC:
|
2022-07-27 18:39:04 +02:00
|
|
|
case MODULE_TYPES.UTILITY:
|
2020-05-13 12:06:13 +02:00
|
|
|
// Default for most extension points,
|
|
|
|
|
// Just adds each entry ready for consumption by mode.
|
|
|
|
|
extensionModule.forEach(element => {
|
2023-03-10 04:30:09 +01:00
|
|
|
const id = `${extensionId}.${moduleType}.${element.name}`;
|
|
|
|
|
element.id = id;
|
|
|
|
|
this.modulesMap[id] = element;
|
2020-05-13 12:06:13 +02:00
|
|
|
});
|
2020-05-15 19:07:21 +02:00
|
|
|
break;
|
2021-03-01 16:52:54 +01:00
|
|
|
default:
|
|
|
|
|
throw new Error(`Module type invalid: ${moduleType}`);
|
2020-05-13 12:06:13 +02:00
|
|
|
}
|
2019-08-13 21:36:46 +02:00
|
|
|
|
|
|
|
|
this.modules[moduleType].push({
|
|
|
|
|
extensionId,
|
|
|
|
|
module: extensionModule,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Track extension registration
|
|
|
|
|
this.registeredExtensionIds.push(extensionId);
|
2020-05-09 20:23:43 +02:00
|
|
|
};
|
2019-08-13 21:36:46 +02:00
|
|
|
|
2020-05-09 20:23:43 +02:00
|
|
|
getModuleEntry = stringEntry => {
|
2020-05-07 20:04:33 +02:00
|
|
|
return this.modulesMap[stringEntry];
|
2020-05-09 20:23:43 +02:00
|
|
|
};
|
2020-05-07 20:04:33 +02:00
|
|
|
|
2020-05-11 18:56:46 +02:00
|
|
|
getDataSources = dataSourceName => {
|
2020-06-05 17:36:11 +02:00
|
|
|
if (dataSourceName === undefined) {
|
2020-06-26 11:01:13 +02:00
|
|
|
// Default to the activeDataSource
|
2020-06-05 17:36:11 +02:00
|
|
|
dataSourceName = this.activeDataSource;
|
|
|
|
|
}
|
|
|
|
|
|
2020-05-09 10:57:52 +02:00
|
|
|
// Note: this currently uses the data source name, which feels weird...
|
2020-05-11 18:56:46 +02:00
|
|
|
return this.dataSourceMap[dataSourceName];
|
2020-05-09 20:23:43 +02:00
|
|
|
};
|
2020-05-07 20:04:33 +02:00
|
|
|
|
2020-06-26 11:01:13 +02:00
|
|
|
getActiveDataSource = () => {
|
2020-07-03 19:18:59 +02:00
|
|
|
return this.dataSourceMap[this.activeDataSource];
|
2020-06-26 11:01:13 +02:00
|
|
|
};
|
|
|
|
|
|
2021-05-28 20:32:48 +02:00
|
|
|
getDataSource = () => {
|
|
|
|
|
return this.dataSourceMap[this.activeDataSource];
|
|
|
|
|
};
|
|
|
|
|
|
2019-08-13 21:36:46 +02:00
|
|
|
/**
|
|
|
|
|
* @private
|
|
|
|
|
* @param {string} moduleType
|
|
|
|
|
* @param {Object} extension
|
|
|
|
|
* @param {string} extensionId - Used for logging warnings
|
|
|
|
|
*/
|
2020-05-09 20:23:43 +02:00
|
|
|
_getExtensionModule = (moduleType, extension, extensionId, configuration) => {
|
2019-08-13 21:36:46 +02:00
|
|
|
const getModuleFnName = 'get' + _capitalizeFirstCharacter(moduleType);
|
|
|
|
|
const getModuleFn = extension[getModuleFnName];
|
|
|
|
|
|
|
|
|
|
if (!getModuleFn) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try {
|
2023-03-22 22:45:28 +01:00
|
|
|
const extensionModule = extension[getModuleFnName]({
|
2020-06-15 03:18:29 +02:00
|
|
|
appConfig: this._appConfig,
|
2019-12-02 17:29:04 +01:00
|
|
|
commandsManager: this._commandsManager,
|
2020-06-15 03:18:29 +02:00
|
|
|
servicesManager: this._servicesManager,
|
2020-08-19 21:02:59 +02:00
|
|
|
hotkeysManager: this._hotkeysManager,
|
|
|
|
|
extensionManager: this,
|
2019-12-16 20:07:53 +01:00
|
|
|
configuration,
|
2019-11-14 23:29:40 +01:00
|
|
|
});
|
2019-08-13 21:36:46 +02:00
|
|
|
|
|
|
|
|
if (!extensionModule) {
|
|
|
|
|
log.warn(
|
|
|
|
|
`Null or undefined returned when registering the ${getModuleFnName} module for the ${extensionId} extension`
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return extensionModule;
|
|
|
|
|
} catch (ex) {
|
2023-03-22 22:45:28 +01:00
|
|
|
console.log(ex);
|
2021-03-01 16:52:54 +01:00
|
|
|
throw new Error(
|
2019-08-13 21:36:46 +02:00
|
|
|
`Exception thrown while trying to call ${getModuleFnName} for the ${extensionId} extension`
|
|
|
|
|
);
|
|
|
|
|
}
|
2020-05-09 20:23:43 +02:00
|
|
|
};
|
2019-08-13 21:36:46 +02:00
|
|
|
|
2022-09-21 05:40:26 +02:00
|
|
|
_initHangingProtocolsModule = (extensionModule, extensionId) => {
|
2023-02-10 22:46:09 +01:00
|
|
|
const { hangingProtocolService } = this._servicesManager.services;
|
2022-09-21 05:40:26 +02:00
|
|
|
extensionModule.forEach(({ id, protocol }) => {
|
2022-10-05 14:32:54 +02:00
|
|
|
if (protocol) {
|
|
|
|
|
// Only auto-register if protocol specified, otherwise let mode register
|
2023-02-10 22:46:09 +01:00
|
|
|
hangingProtocolService.addProtocol(id, protocol);
|
2022-10-05 14:32:54 +02:00
|
|
|
}
|
2022-09-21 05:40:26 +02:00
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
2021-03-01 16:52:54 +01:00
|
|
|
_initDataSourcesModule(extensionModule, extensionId, dataSources = []) {
|
2023-02-13 14:55:55 +01:00
|
|
|
const { userAuthenticationService } = this._servicesManager.services;
|
2022-12-29 16:13:06 +01:00
|
|
|
dataSources.forEach(dataSource => {
|
|
|
|
|
this.dataSourceDefs[dataSource.sourceName] = dataSource;
|
|
|
|
|
});
|
2021-06-23 20:41:27 +02:00
|
|
|
|
2020-05-13 12:06:13 +02:00
|
|
|
extensionModule.forEach(element => {
|
|
|
|
|
const namespace = `${extensionId}.${MODULE_TYPES.DATA_SOURCE}.${element.name}`;
|
|
|
|
|
|
|
|
|
|
dataSources.forEach(dataSource => {
|
|
|
|
|
if (dataSource.namespace === namespace) {
|
|
|
|
|
const dataSourceInstance = element.createDataSource(
|
2021-06-23 20:41:27 +02:00
|
|
|
dataSource.configuration,
|
2023-02-13 14:55:55 +01:00
|
|
|
userAuthenticationService
|
2020-05-13 12:06:13 +02:00
|
|
|
);
|
|
|
|
|
|
|
|
|
|
if (this.dataSourceMap[dataSource.sourceName]) {
|
|
|
|
|
this.dataSourceMap[dataSource.sourceName].push(dataSourceInstance);
|
|
|
|
|
} else {
|
|
|
|
|
this.dataSourceMap[dataSource.sourceName] = [dataSourceInstance];
|
|
|
|
|
}
|
2019-08-13 21:36:46 +02:00
|
|
|
}
|
2020-05-13 12:06:13 +02:00
|
|
|
});
|
|
|
|
|
});
|
2020-05-09 10:57:52 +02:00
|
|
|
|
2020-05-13 12:06:13 +02:00
|
|
|
extensionModule.forEach(element => {
|
|
|
|
|
this.modulesMap[
|
|
|
|
|
`${extensionId}.${MODULE_TYPES.DATA_SOURCE}.${element.name}`
|
|
|
|
|
] = element;
|
|
|
|
|
});
|
|
|
|
|
}
|
2019-08-13 21:36:46 +02:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
*
|
|
|
|
|
* @private
|
|
|
|
|
* @param {Object[]} commandDefinitions
|
|
|
|
|
*/
|
2020-05-13 12:06:13 +02:00
|
|
|
_initCommandsModule = extensionModule => {
|
|
|
|
|
let { definitions, defaultContext } = extensionModule;
|
|
|
|
|
if (!definitions || Object.keys(definitions).length === 0) {
|
|
|
|
|
log.warn('Commands Module contains no command definitions');
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
defaultContext = defaultContext || 'VIEWER';
|
|
|
|
|
|
2019-08-13 21:36:46 +02:00
|
|
|
if (!this._commandsManager.getContext(defaultContext)) {
|
|
|
|
|
this._commandsManager.createContext(defaultContext);
|
|
|
|
|
}
|
|
|
|
|
|
2020-05-13 12:06:13 +02:00
|
|
|
Object.keys(definitions).forEach(commandName => {
|
|
|
|
|
const commandDefinition = definitions[commandName];
|
2019-08-13 21:36:46 +02:00
|
|
|
const commandHasContextThatDoesNotExist =
|
|
|
|
|
commandDefinition.context &&
|
|
|
|
|
!this._commandsManager.getContext(commandDefinition.context);
|
|
|
|
|
|
|
|
|
|
if (commandHasContextThatDoesNotExist) {
|
|
|
|
|
this._commandsManager.createContext(commandDefinition.context);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this._commandsManager.registerCommand(
|
|
|
|
|
commandDefinition.context || defaultContext,
|
|
|
|
|
commandName,
|
|
|
|
|
commandDefinition
|
|
|
|
|
);
|
|
|
|
|
});
|
2020-05-09 20:23:43 +02:00
|
|
|
};
|
2019-08-13 21:36:46 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @private
|
|
|
|
|
* @param {string} lower
|
|
|
|
|
*/
|
|
|
|
|
function _capitalizeFirstCharacter(lower) {
|
2022-11-10 19:29:55 +01:00
|
|
|
return lower.charAt(0).toUpperCase() + lower.substring(1);
|
2019-08-13 21:36:46 +02:00
|
|
|
}
|