chore(prettier): full repo linting and code reformatting once and for all (#3627)
This commit is contained in:
1 parent
01500a2d4c
commit
9045ddaedc
656 files changed
+21737
-20628
No files matched your search
@@ -11,7 +11,7 @@ const extensionManager = {
|
||||
registeredExtensionIds: [],
|
||||
moduleEntries: {},
|
||||
|
||||
getModuleEntry: function(id) {
|
||||
getModuleEntry: function (id) {
|
||||
return this.moduleEntries[id];
|
||||
},
|
||||
};
|
||||
@@ -20,7 +20,7 @@ const commandsManager = {};
|
||||
|
||||
const ohifOverlayItem = {
|
||||
id: 'ohif.overlayItem',
|
||||
content: function(props) {
|
||||
content: function (props) {
|
||||
return {
|
||||
label: this.label,
|
||||
value: props[this.attribute],
|
||||
@@ -59,29 +59,27 @@ describe('CustomizationService.ts', () => {
|
||||
it('configurationRegistered', () => {
|
||||
configuration.testItem = testItem;
|
||||
customizationService.init(extensionManager);
|
||||
expect(customizationService.getGlobalCustomization('testItem')).toBe(
|
||||
testItem
|
||||
);
|
||||
expect(customizationService.getGlobalCustomization('testItem')).toBe(testItem);
|
||||
});
|
||||
|
||||
it('defaultRegistered', () => {
|
||||
extensionManager.registeredExtensionIds.push('@testExtension');
|
||||
extensionManager.moduleEntries[
|
||||
'@testExtension.customizationModule.default'
|
||||
] = { name: 'default', value: [testItem] };
|
||||
extensionManager.moduleEntries['@testExtension.customizationModule.default'] = {
|
||||
name: 'default',
|
||||
value: [testItem],
|
||||
};
|
||||
customizationService.init(extensionManager);
|
||||
expect(customizationService.getGlobalCustomization('testItem')).toBe(
|
||||
testItem
|
||||
);
|
||||
expect(customizationService.getGlobalCustomization('testItem')).toBe(testItem);
|
||||
});
|
||||
});
|
||||
|
||||
describe('customizationType', () => {
|
||||
it('inherits type', () => {
|
||||
extensionManager.registeredExtensionIds.push('@testExtension');
|
||||
extensionManager.moduleEntries[
|
||||
'@testExtension.customizationModule.default'
|
||||
] = { name: 'default', value: [ohifOverlayItem] };
|
||||
extensionManager.moduleEntries['@testExtension.customizationModule.default'] = {
|
||||
name: 'default',
|
||||
value: [ohifOverlayItem],
|
||||
};
|
||||
configuration.testItem = testItem;
|
||||
customizationService.init(extensionManager);
|
||||
|
||||
@@ -96,9 +94,10 @@ describe('CustomizationService.ts', () => {
|
||||
|
||||
it('inline default inherits type', () => {
|
||||
extensionManager.registeredExtensionIds.push('@testExtension');
|
||||
extensionManager.moduleEntries[
|
||||
'@testExtension.customizationModule.default'
|
||||
] = { name: 'default', value: [ohifOverlayItem] };
|
||||
extensionManager.moduleEntries['@testExtension.customizationModule.default'] = {
|
||||
name: 'default',
|
||||
value: [ohifOverlayItem],
|
||||
};
|
||||
configuration.testItem = testItem;
|
||||
customizationService.init(extensionManager);
|
||||
|
||||
@@ -121,20 +120,17 @@ describe('CustomizationService.ts', () => {
|
||||
describe('mode customization', () => {
|
||||
it('onModeEnter can add extensions', () => {
|
||||
extensionManager.registeredExtensionIds.push('@testExtension');
|
||||
extensionManager.moduleEntries[
|
||||
'@testExtension.customizationModule.default'
|
||||
] = { name: 'default', value: [ohifOverlayItem] };
|
||||
extensionManager.moduleEntries['@testExtension.customizationModule.default'] = {
|
||||
name: 'default',
|
||||
value: [ohifOverlayItem],
|
||||
};
|
||||
customizationService.init(extensionManager);
|
||||
|
||||
expect(
|
||||
customizationService.getModeCustomization('testItem')
|
||||
).toBeUndefined();
|
||||
expect(customizationService.getModeCustomization('testItem')).toBeUndefined();
|
||||
|
||||
customizationService.addModeCustomizations([testItem]);
|
||||
|
||||
expect(
|
||||
customizationService.getGlobalCustomization('testItem')
|
||||
).toBeUndefined();
|
||||
expect(customizationService.getGlobalCustomization('testItem')).toBeUndefined();
|
||||
|
||||
const item = customizationService.getModeCustomization('testItem');
|
||||
|
||||
@@ -147,16 +143,15 @@ describe('CustomizationService.ts', () => {
|
||||
|
||||
it('global customizations override modes', () => {
|
||||
extensionManager.registeredExtensionIds.push('@testExtension');
|
||||
extensionManager.moduleEntries[
|
||||
'@testExtension.customizationModule.default'
|
||||
] = { name: 'default', value: [ohifOverlayItem] };
|
||||
extensionManager.moduleEntries['@testExtension.customizationModule.default'] = {
|
||||
name: 'default',
|
||||
value: [ohifOverlayItem],
|
||||
};
|
||||
configuration.testItem = testItem;
|
||||
customizationService.init(extensionManager);
|
||||
|
||||
// Add a mode customization that would otherwise fail below
|
||||
customizationService.addModeCustomizations([
|
||||
{ ...testItem, label: 'other' },
|
||||
]);
|
||||
customizationService.addModeCustomizations([{ ...testItem, label: 'other' }]);
|
||||
|
||||
const item = customizationService.getModeCustomization('testItem');
|
||||
|
||||
|
||||
@@ -107,10 +107,7 @@ export default class CustomizationService extends PubSubService {
|
||||
return this.modeCustomizations;
|
||||
}
|
||||
|
||||
public setModeCustomization(
|
||||
customizationId: string,
|
||||
customization: Customization
|
||||
): void {
|
||||
public setModeCustomization(customizationId: string, customization: Customization): void {
|
||||
this.modeCustomizations[customizationId] = merge(
|
||||
this.modeCustomizations[customizationId] || {},
|
||||
customization
|
||||
@@ -155,10 +152,7 @@ export default class CustomizationService extends PubSubService {
|
||||
}
|
||||
|
||||
public hasModeCustomization(customizationId: string) {
|
||||
return (
|
||||
this.globalCustomizations[customizationId] ||
|
||||
this.modeCustomizations[customizationId]
|
||||
);
|
||||
return this.globalCustomizations[customizationId] || this.modeCustomizations[customizationId];
|
||||
}
|
||||
/**
|
||||
* get is an alias for getModeCustomization, as it is the generic getter
|
||||
@@ -186,9 +180,7 @@ export default class CustomizationService extends PubSubService {
|
||||
return customization;
|
||||
}
|
||||
const parent = this.getCustomization(customizationType);
|
||||
const result = parent
|
||||
? Object.assign(Object.create(parent), customization)
|
||||
: customization;
|
||||
const result = parent ? Object.assign(Object.create(parent), customization) : customization;
|
||||
// Execute an nested type information
|
||||
return result.transform?.(this) || result;
|
||||
}
|
||||
@@ -213,10 +205,7 @@ export default class CustomizationService extends PubSubService {
|
||||
* the modes. They include things like settings for the search screen.
|
||||
* Reset does NOT clear global customizations.
|
||||
*/
|
||||
getGlobalCustomization(
|
||||
id: string,
|
||||
defaultValue?: Customization
|
||||
): Customization | void {
|
||||
getGlobalCustomization(id: string, defaultValue?: Customization): Customization | void {
|
||||
return this.transform(this.globalCustomizations[id] ?? defaultValue);
|
||||
}
|
||||
|
||||
@@ -225,15 +214,10 @@ export default class CustomizationService extends PubSubService {
|
||||
this._broadcastGlobalCustomizationModified();
|
||||
}
|
||||
|
||||
protected setConfigGlobalCustomization(
|
||||
configuration: AppConfigCustomization
|
||||
): void {
|
||||
protected setConfigGlobalCustomization(configuration: AppConfigCustomization): void {
|
||||
this.globalCustomizations = {};
|
||||
const keys = flattenNestedStrings(configuration.globalCustomizations);
|
||||
this.readCustomizationTypes(
|
||||
v => keys[v.name] && v.customization,
|
||||
this.globalCustomizations
|
||||
);
|
||||
this.readCustomizationTypes(v => keys[v.name] && v.customization, this.globalCustomizations);
|
||||
|
||||
// TODO - iterate over customizations, loading them from the extension
|
||||
// manager.
|
||||
@@ -264,10 +248,7 @@ export default class CustomizationService extends PubSubService {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -54,9 +54,7 @@ function _getStudyInstanceUIDs() {
|
||||
}
|
||||
|
||||
function _getStudy(StudyInstanceUID) {
|
||||
return _model.studies.find(
|
||||
aStudy => aStudy.StudyInstanceUID === StudyInstanceUID
|
||||
);
|
||||
return _model.studies.find(aStudy => aStudy.StudyInstanceUID === StudyInstanceUID);
|
||||
}
|
||||
|
||||
function _getSeries(StudyInstanceUID, SeriesInstanceUID) {
|
||||
@@ -66,9 +64,7 @@ function _getSeries(StudyInstanceUID, SeriesInstanceUID) {
|
||||
return;
|
||||
}
|
||||
|
||||
return study.series.find(
|
||||
aSeries => aSeries.SeriesInstanceUID === SeriesInstanceUID
|
||||
);
|
||||
return study.series.find(aSeries => aSeries.SeriesInstanceUID === SeriesInstanceUID);
|
||||
}
|
||||
|
||||
function _getInstance(StudyInstanceUID, SeriesInstanceUID, SOPInstanceUID) {
|
||||
@@ -78,9 +74,7 @@ function _getInstance(StudyInstanceUID, SeriesInstanceUID, SOPInstanceUID) {
|
||||
return;
|
||||
}
|
||||
|
||||
return series.instances.find(
|
||||
instance => instance.SOPInstanceUID === SOPInstanceUID
|
||||
);
|
||||
return series.instances.find(instance => instance.SOPInstanceUID === SOPInstanceUID);
|
||||
}
|
||||
|
||||
function _getInstanceByImageId(imageId) {
|
||||
@@ -102,20 +96,14 @@ function _getInstanceByImageId(imageId) {
|
||||
* @param {*} metadata metadata inform of key value pairs
|
||||
* @returns
|
||||
*/
|
||||
function _updateMetadataForSeries(
|
||||
StudyInstanceUID,
|
||||
SeriesInstanceUID,
|
||||
metadata
|
||||
) {
|
||||
function _updateMetadataForSeries(StudyInstanceUID, SeriesInstanceUID, metadata) {
|
||||
const study = _getStudy(StudyInstanceUID);
|
||||
|
||||
if (!study) {
|
||||
return;
|
||||
}
|
||||
|
||||
const series = study.series.find(
|
||||
aSeries => aSeries.SeriesInstanceUID === SeriesInstanceUID
|
||||
);
|
||||
const series = study.series.find(aSeries => aSeries.SeriesInstanceUID === SeriesInstanceUID);
|
||||
|
||||
const { instances } = series;
|
||||
// update all instances metadata for this series with the new metadata
|
||||
@@ -149,9 +137,7 @@ const BaseImplementation = {
|
||||
|
||||
// If Arraybuffer, parse to DICOMJSON before naturalizing.
|
||||
if (dicomJSONDatasetOrP10ArrayBuffer instanceof ArrayBuffer) {
|
||||
const dicomData = dcmjs.data.DicomMessage.readFile(
|
||||
dicomJSONDatasetOrP10ArrayBuffer
|
||||
);
|
||||
const dicomData = dcmjs.data.DicomMessage.readFile(dicomJSONDatasetOrP10ArrayBuffer);
|
||||
|
||||
dicomJSONDataset = dicomData.dict;
|
||||
} else {
|
||||
@@ -161,18 +147,14 @@ const BaseImplementation = {
|
||||
let naturalizedDataset;
|
||||
|
||||
if (dicomJSONDataset['SeriesInstanceUID'] === undefined) {
|
||||
naturalizedDataset = dcmjs.data.DicomMetaDictionary.naturalizeDataset(
|
||||
dicomJSONDataset
|
||||
);
|
||||
naturalizedDataset = dcmjs.data.DicomMetaDictionary.naturalizeDataset(dicomJSONDataset);
|
||||
} else {
|
||||
naturalizedDataset = dicomJSONDataset;
|
||||
}
|
||||
|
||||
const { StudyInstanceUID } = naturalizedDataset;
|
||||
|
||||
let study = _model.studies.find(
|
||||
study => study.StudyInstanceUID === StudyInstanceUID
|
||||
);
|
||||
let study = _model.studies.find(study => study.StudyInstanceUID === StudyInstanceUID);
|
||||
|
||||
if (!study) {
|
||||
_model.studies.push(createStudyMetadata(StudyInstanceUID));
|
||||
@@ -184,9 +166,7 @@ const BaseImplementation = {
|
||||
addInstances(instances, madeInClient = false) {
|
||||
const { StudyInstanceUID, SeriesInstanceUID } = instances[0];
|
||||
|
||||
let study = _model.studies.find(
|
||||
study => study.StudyInstanceUID === StudyInstanceUID
|
||||
);
|
||||
let study = _model.studies.find(study => study.StudyInstanceUID === StudyInstanceUID);
|
||||
|
||||
if (!study) {
|
||||
_model.studies.push(createStudyMetadata(StudyInstanceUID));
|
||||
@@ -236,9 +216,7 @@ const BaseImplementation = {
|
||||
addStudy(study) {
|
||||
const { StudyInstanceUID } = study;
|
||||
|
||||
const existingStudy = _model.studies.find(
|
||||
study => study.StudyInstanceUID === StudyInstanceUID
|
||||
);
|
||||
const existingStudy = _model.studies.find(study => study.StudyInstanceUID === StudyInstanceUID);
|
||||
|
||||
if (!existingStudy) {
|
||||
const newStudy = createStudyMetadata(StudyInstanceUID);
|
||||
|
||||
@@ -12,14 +12,12 @@ function createStudyMetadata(StudyInstanceUID) {
|
||||
* @param {object} instance
|
||||
* @returns {bool} true if series were added; false if series already exist
|
||||
*/
|
||||
addInstanceToSeries: function(instance) {
|
||||
addInstanceToSeries: function (instance) {
|
||||
const { SeriesInstanceUID } = instance;
|
||||
if (!this.StudyDescription) {
|
||||
this.StudyDescription = instance.StudyDescription;
|
||||
}
|
||||
const existingSeries = this.series.find(
|
||||
s => s.SeriesInstanceUID === SeriesInstanceUID
|
||||
);
|
||||
const existingSeries = this.series.find(s => s.SeriesInstanceUID === SeriesInstanceUID);
|
||||
|
||||
if (existingSeries) {
|
||||
existingSeries.instances.push(instance);
|
||||
@@ -39,23 +37,19 @@ function createStudyMetadata(StudyInstanceUID) {
|
||||
* @param {string} instances[].StudyDescription
|
||||
* @returns {bool} true if series were added; false if series already exist
|
||||
*/
|
||||
addInstancesToSeries: function(instances) {
|
||||
addInstancesToSeries: function (instances) {
|
||||
const { SeriesInstanceUID } = instances[0];
|
||||
if (!this.StudyDescription) {
|
||||
this.StudyDescription = instances[0].StudyDescription;
|
||||
}
|
||||
const existingSeries = this.series.find(
|
||||
s => s.SeriesInstanceUID === SeriesInstanceUID
|
||||
);
|
||||
const existingSeries = this.series.find(s => s.SeriesInstanceUID === SeriesInstanceUID);
|
||||
|
||||
if (existingSeries) {
|
||||
// Only add instances not already present, so generate a map
|
||||
// of existing instances and filter the to add by things
|
||||
// already present.
|
||||
const sopMap = {};
|
||||
existingSeries.instances.forEach(
|
||||
it => (sopMap[it.SOPInstanceUID] = it)
|
||||
);
|
||||
existingSeries.instances.forEach(it => (sopMap[it.SOPInstanceUID] = it));
|
||||
const newInstances = instances.filter(it => !sopMap[it.SOPInstanceUID]);
|
||||
existingSeries.instances.push(...newInstances);
|
||||
} else {
|
||||
@@ -64,10 +58,8 @@ function createStudyMetadata(StudyInstanceUID) {
|
||||
}
|
||||
},
|
||||
|
||||
setSeriesMetadata: function(SeriesInstanceUID, seriesMetadata) {
|
||||
let existingSeries = this.series.find(
|
||||
s => s.SeriesInstanceUID === SeriesInstanceUID
|
||||
);
|
||||
setSeriesMetadata: function (SeriesInstanceUID, seriesMetadata) {
|
||||
let existingSeries = this.series.find(s => s.SeriesInstanceUID === SeriesInstanceUID);
|
||||
|
||||
if (existingSeries) {
|
||||
existingSeries = Object.assign(existingSeries, seriesMetadata);
|
||||
|
||||
@@ -19,15 +19,11 @@ const filterInstances = (
|
||||
if (!dsInstances) {
|
||||
console.warn('No instances in', ds);
|
||||
} else {
|
||||
dsInstances.forEach(instance =>
|
||||
dsInstancesSOP.add(instance.SOPInstanceUID)
|
||||
);
|
||||
dsInstances.forEach(instance => dsInstancesSOP.add(instance.SOPInstanceUID));
|
||||
}
|
||||
});
|
||||
|
||||
return instances.filter(
|
||||
instance => !dsInstancesSOP.has(instance.SOPInstanceUID)
|
||||
);
|
||||
return instances.filter(instance => !dsInstancesSOP.has(instance.SOPInstanceUID));
|
||||
};
|
||||
|
||||
export default class DisplaySetService extends PubSubService {
|
||||
@@ -119,9 +115,7 @@ export default class DisplaySetService extends PubSubService {
|
||||
return this.activeDisplaySets;
|
||||
}
|
||||
|
||||
public getDisplaySetsForSeries = (
|
||||
seriesInstanceUID: string
|
||||
): DisplaySet[] => {
|
||||
public getDisplaySetsForSeries = (seriesInstanceUID: string): DisplaySet[] => {
|
||||
return [...displaySetCache.values()].filter(
|
||||
displaySet => displaySet.SeriesInstanceUID === seriesInstanceUID
|
||||
);
|
||||
@@ -137,9 +131,7 @@ export default class DisplaySetService extends PubSubService {
|
||||
: [...this.getDisplaySetCache().values()];
|
||||
|
||||
const displaySet = displaySets.find(ds => {
|
||||
return (
|
||||
ds.images && ds.images.some(i => i.SOPInstanceUID === sopInstanceUID)
|
||||
);
|
||||
return ds.images && ds.images.some(i => i.SOPInstanceUID === sopInstanceUID);
|
||||
});
|
||||
|
||||
return displaySet;
|
||||
@@ -195,18 +187,13 @@ export default class DisplaySetService extends PubSubService {
|
||||
* @param {*} param1: settings: initialViewportSettings by HP or callbacks after rendering
|
||||
* @returns {string[]} - added displaySetInstanceUIDs
|
||||
*/
|
||||
makeDisplaySets = (
|
||||
input,
|
||||
{ batch = false, madeInClient = false, settings = {} } = {}
|
||||
) => {
|
||||
makeDisplaySets = (input, { batch = false, madeInClient = false, settings = {} } = {}) => {
|
||||
if (!input || !input.length) {
|
||||
throw new Error('No instances were provided.');
|
||||
}
|
||||
|
||||
if (batch && !input[0].length) {
|
||||
throw new Error(
|
||||
'Batch displaySet creation does not contain array of array of instances.'
|
||||
);
|
||||
throw new Error('Batch displaySet creation does not contain array of array of instances.');
|
||||
}
|
||||
|
||||
// If array of instances => One instance.
|
||||
@@ -215,10 +202,7 @@ export default class DisplaySetService extends PubSubService {
|
||||
if (batch) {
|
||||
for (let i = 0; i < input.length; i++) {
|
||||
const instances = input[i];
|
||||
const displaySets = this.makeDisplaySetForInstances(
|
||||
instances,
|
||||
settings
|
||||
);
|
||||
const displaySets = this.makeDisplaySetForInstances(instances, settings);
|
||||
|
||||
displaySetsAdded.push(...displaySets);
|
||||
}
|
||||
@@ -272,22 +256,16 @@ export default class DisplaySetService extends PubSubService {
|
||||
* @param settings
|
||||
* @returns
|
||||
*/
|
||||
public makeDisplaySetForInstances(
|
||||
instancesSrc: InstanceMetadata[],
|
||||
settings
|
||||
): DisplaySet[] {
|
||||
public makeDisplaySetForInstances(instancesSrc: InstanceMetadata[], settings): DisplaySet[] {
|
||||
// creating a sopClassUID list and for each sopClass associate its respective
|
||||
// instance list
|
||||
const instancesForSetSOPClasses = instancesSrc.reduce(
|
||||
(sopClassList, instance) => {
|
||||
if (!(instance.SOPClassUID in sopClassList)) {
|
||||
sopClassList[instance.SOPClassUID] = [];
|
||||
}
|
||||
sopClassList[instance.SOPClassUID].push(instance);
|
||||
return sopClassList;
|
||||
},
|
||||
{}
|
||||
);
|
||||
const instancesForSetSOPClasses = instancesSrc.reduce((sopClassList, instance) => {
|
||||
if (!(instance.SOPClassUID in sopClassList)) {
|
||||
sopClassList[instance.SOPClassUID] = [];
|
||||
}
|
||||
sopClassList[instance.SOPClassUID].push(instance);
|
||||
return sopClassList;
|
||||
}, {});
|
||||
// for each sopClassUID, call the old makeDisplaySetForInstances with a
|
||||
// instance list composed only by instances with the same sopClassUID and
|
||||
// accumulate the displaySets in the variable allDisplaySets
|
||||
@@ -319,17 +297,13 @@ export default class DisplaySetService extends PubSubService {
|
||||
* @param settings are settings to add
|
||||
* @returns Array of the display sets added.
|
||||
*/
|
||||
private _makeDisplaySetForInstances(
|
||||
instancesSrc: InstanceMetadata[],
|
||||
settings
|
||||
): DisplaySet[] {
|
||||
private _makeDisplaySetForInstances(instancesSrc: InstanceMetadata[], settings): DisplaySet[] {
|
||||
// Some of the sop class handlers take a direct reference to instances
|
||||
// so make sure it gets copied here so that they have their own ref
|
||||
let instances = [...instancesSrc];
|
||||
const instance = instances[0];
|
||||
|
||||
const existingDisplaySets =
|
||||
this.getDisplaySetsForSeries(instance.SeriesInstanceUID) || [];
|
||||
const existingDisplaySets = this.getDisplaySetsForSeries(instance.SeriesInstanceUID) || [];
|
||||
|
||||
const SOPClassHandlerIds = this.SOPClassHandlerIds;
|
||||
const allDisplaySets = [];
|
||||
@@ -357,9 +331,7 @@ export default class DisplaySetService extends PubSubService {
|
||||
this.activeDisplaySetsChanged = true;
|
||||
instances = filterInstances(instances, [addedDs]);
|
||||
this._addActiveDisplaySets([addedDs]);
|
||||
this.setDisplaySetMetadataInvalidated(
|
||||
addedDs.displaySetInstanceUID
|
||||
);
|
||||
this.setDisplaySetMetadataInvalidated(addedDs.displaySetInstanceUID);
|
||||
}
|
||||
// This means that all instances already existed or got added to
|
||||
// existing display sets, and had an invalidated event fired
|
||||
@@ -405,9 +377,7 @@ export default class DisplaySetService extends PubSubService {
|
||||
// applying the default sopClassUID handler
|
||||
if (allDisplaySets.length === 0) {
|
||||
// applying hp-defined viewport settings to the displaysets
|
||||
const handler = this.extensionManager.getModuleEntry(
|
||||
this.unsuportedSOPClassHandler
|
||||
);
|
||||
const handler = this.extensionManager.getModuleEntry(this.unsuportedSOPClassHandler);
|
||||
const displaySets = handler.getDisplaySetsFromSeries(instances);
|
||||
if (displaySets?.length) {
|
||||
displaySets.forEach(ds => {
|
||||
|
||||
@@ -9,12 +9,7 @@ import validate from './lib/validator';
|
||||
* @param {object[]} options.displaySets is a list of the display sets
|
||||
* @return {Object} Matching Object with score and details (which rule passed or failed)
|
||||
*/
|
||||
const match = (
|
||||
metadataInstance,
|
||||
rules = [],
|
||||
customAttributeRetrievalCallbacks,
|
||||
options
|
||||
) => {
|
||||
const match = (metadataInstance, rules = [], customAttributeRetrievalCallbacks, options) => {
|
||||
const validateOptions = {
|
||||
format: 'grouped',
|
||||
};
|
||||
@@ -46,12 +41,13 @@ const match = (
|
||||
const { attribute, from = 'metadataInstance' } = rule;
|
||||
// Do not use the custom attribute from the metadataInstance since it is subject to change
|
||||
if (customAttributeRetrievalCallbacks.hasOwnProperty(attribute)) {
|
||||
readValues[attribute] = customAttributeRetrievalCallbacks[
|
||||
attribute
|
||||
].callback.call(rule, metadataInstance, options);
|
||||
readValues[attribute] = customAttributeRetrievalCallbacks[attribute].callback.call(
|
||||
rule,
|
||||
metadataInstance,
|
||||
options
|
||||
);
|
||||
} else {
|
||||
readValues[attribute] =
|
||||
fromSrc[from]?.[attribute] ?? instance?.[attribute];
|
||||
readValues[attribute] = fromSrc[from]?.[attribute] ?? instance?.[attribute];
|
||||
}
|
||||
|
||||
// Format the constraint as required by Validate.js
|
||||
|
||||
@@ -149,10 +149,7 @@ describe('HangingProtocolService', () => {
|
||||
},
|
||||
},
|
||||
};
|
||||
const hangingProtocolService = new HangingProtocolService(
|
||||
commandsManager,
|
||||
servicesManager
|
||||
);
|
||||
const hangingProtocolService = new HangingProtocolService(commandsManager, servicesManager);
|
||||
let initialScaling;
|
||||
|
||||
afterEach(() => {
|
||||
@@ -177,10 +174,7 @@ describe('HangingProtocolService', () => {
|
||||
|
||||
describe('with protocol generator', () => {
|
||||
beforeAll(() => {
|
||||
hangingProtocolService.addProtocol(
|
||||
testProtocol.id,
|
||||
testProtocolGenerator
|
||||
);
|
||||
hangingProtocolService.addProtocol(testProtocol.id, testProtocolGenerator);
|
||||
});
|
||||
|
||||
it('has one protocol', () => {
|
||||
|
||||
@@ -8,10 +8,7 @@ import IDisplaySet from '../DisplaySetService/IDisplaySet';
|
||||
import { CommandsManager } from '../../classes';
|
||||
import ServicesManager from '../ServicesManager';
|
||||
import * as HangingProtocol from '../../types/HangingProtocol';
|
||||
import {
|
||||
isDisplaySetFromUrl,
|
||||
sopInstanceLocation,
|
||||
} from './custom-attribute/isDisplaySetFromUrl';
|
||||
import { isDisplaySetFromUrl, sopInstanceLocation } from './custom-attribute/isDisplaySetFromUrl';
|
||||
import numberOfDisplaySetsWithImages from './custom-attribute/numberOfDisplaySetsWithImages';
|
||||
import seriesDescriptionsFromDisplaySets from './custom-attribute/seriesDescriptionsFromDisplaySets';
|
||||
import uuidv4 from '../../utils/uuidv4';
|
||||
@@ -37,8 +34,7 @@ export default class HangingProtocolService extends PubSubService {
|
||||
// Fired when the stages within the current protocol are known to have
|
||||
// the status set - that is, they are activated (or deactivated).
|
||||
STAGE_ACTIVATION: 'event::hanging_protocol_stage_activation',
|
||||
CUSTOM_IMAGE_LOAD_PERFORMED:
|
||||
'event::hanging_protocol_custom_image_load_performed',
|
||||
CUSTOM_IMAGE_LOAD_PERFORMED: 'event::hanging_protocol_custom_image_load_performed',
|
||||
};
|
||||
|
||||
public static REGISTRATION = {
|
||||
@@ -74,8 +70,7 @@ export default class HangingProtocolService extends PubSubService {
|
||||
customAttributeRetrievalCallbacks = {
|
||||
NumberOfStudyRelatedSeries: {
|
||||
name: 'The number of series in the study',
|
||||
callback: metadata =>
|
||||
metadata.NumberOfStudyRelatedSeries ?? metadata.series?.length,
|
||||
callback: metadata => metadata.NumberOfStudyRelatedSeries ?? metadata.series?.length,
|
||||
},
|
||||
NumberOfSeriesRelatedInstances: {
|
||||
name: 'The number of instances in the display set',
|
||||
@@ -278,9 +273,7 @@ export default class HangingProtocolService extends PubSubService {
|
||||
|
||||
if (protocol instanceof Function) {
|
||||
try {
|
||||
const { protocol: generatedProtocol } = this._getProtocolFromGenerator(
|
||||
protocol
|
||||
);
|
||||
const { protocol: generatedProtocol } = this._getProtocolFromGenerator(protocol);
|
||||
|
||||
return generatedProtocol;
|
||||
} catch (error) {
|
||||
@@ -304,9 +297,7 @@ export default class HangingProtocolService extends PubSubService {
|
||||
*/
|
||||
public addProtocol(protocolId: string, protocol: Protocol): void {
|
||||
if (this.protocols.has(protocolId)) {
|
||||
console.warn(
|
||||
`A protocol with id ${protocolId} already exists. It will be overwritten.`
|
||||
);
|
||||
console.warn(`A protocol with id ${protocolId} already exists. It will be overwritten.`);
|
||||
}
|
||||
|
||||
if (!(protocol instanceof Function)) {
|
||||
@@ -356,9 +347,7 @@ export default class HangingProtocolService extends PubSubService {
|
||||
* specifically, but will show another study instead.
|
||||
*/
|
||||
public setActiveStudyUID(activeStudyUID: string): void {
|
||||
this.activeStudy = this.studies.find(
|
||||
it => it.StudyInstanceUID === activeStudyUID
|
||||
);
|
||||
this.activeStudy = this.studies.find(it => it.StudyInstanceUID === activeStudyUID);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -410,9 +399,7 @@ export default class HangingProtocolService extends PubSubService {
|
||||
public hasCustomImageLoadStrategy(): boolean {
|
||||
return (
|
||||
this.activeImageLoadStrategyName !== null &&
|
||||
this.registeredImageLoadStrategies[
|
||||
this.activeImageLoadStrategyName
|
||||
] instanceof Function
|
||||
this.registeredImageLoadStrategies[this.activeImageLoadStrategyName] instanceof Function
|
||||
);
|
||||
}
|
||||
|
||||
@@ -436,9 +423,7 @@ export default class HangingProtocolService extends PubSubService {
|
||||
* @returns A boolean indicating whether a custom image load should be performed or not.
|
||||
*/
|
||||
public getShouldPerformCustomImageLoad(): boolean {
|
||||
return (
|
||||
this.hasCustomImageLoadStrategy() && !this.getCustomImageLoadPerformed()
|
||||
);
|
||||
return this.hasCustomImageLoadStrategy() && !this.getCustomImageLoadPerformed();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -464,10 +449,7 @@ export default class HangingProtocolService extends PubSubService {
|
||||
public addCustomAttribute(
|
||||
attributeId: string,
|
||||
attributeName: string,
|
||||
callback: (
|
||||
metadata: Record<string, unknown>,
|
||||
extraData?: Record<string, unknown>
|
||||
) => unknown,
|
||||
callback: (metadata: Record<string, unknown>, extraData?: Record<string, unknown>) => unknown,
|
||||
options: Record<string, unknown> = {}
|
||||
): void {
|
||||
this.customAttributeRetrievalCallbacks[attributeId] = {
|
||||
@@ -483,9 +465,7 @@ export default class HangingProtocolService extends PubSubService {
|
||||
* if no strategy is set, the default strategy is used
|
||||
*/
|
||||
runImageLoadStrategy(data): boolean {
|
||||
const loader = this.registeredImageLoadStrategies[
|
||||
this.activeImageLoadStrategyName
|
||||
];
|
||||
const loader = this.registeredImageLoadStrategies[this.activeImageLoadStrategyName];
|
||||
const loadedData = loader({
|
||||
data,
|
||||
displaySetsMatchDetails: this.displaySetMatchDetails,
|
||||
@@ -504,9 +484,7 @@ export default class HangingProtocolService extends PubSubService {
|
||||
return true;
|
||||
}
|
||||
|
||||
_validateProtocol(
|
||||
protocol: HangingProtocol.Protocol
|
||||
): HangingProtocol.Protocol {
|
||||
_validateProtocol(protocol: HangingProtocol.Protocol): HangingProtocol.Protocol {
|
||||
protocol.id = protocol.id || protocol.name;
|
||||
const defaultViewportOptions = {
|
||||
toolGroupId: 'default',
|
||||
@@ -570,9 +548,7 @@ export default class HangingProtocolService extends PubSubService {
|
||||
return protocol;
|
||||
}
|
||||
|
||||
private _getProtocolFromGenerator(
|
||||
protocolGenerator: HangingProtocol.ProtocolGenerator
|
||||
): {
|
||||
private _getProtocolFromGenerator(protocolGenerator: HangingProtocol.ProtocolGenerator): {
|
||||
protocol: HangingProtocol.Protocol;
|
||||
} {
|
||||
const { protocol } = protocolGenerator({
|
||||
@@ -589,9 +565,7 @@ export default class HangingProtocolService extends PubSubService {
|
||||
|
||||
getViewportsRequireUpdate(viewportId, displaySetInstanceUID) {
|
||||
const { displaySetService } = this._servicesManager.services;
|
||||
const displaySet = displaySetService.getDisplaySetByUID(
|
||||
displaySetInstanceUID
|
||||
);
|
||||
const displaySet = displaySetService.getDisplaySetByUID(displaySetInstanceUID);
|
||||
if (displaySet?.unsupported) {
|
||||
throw new Error('Unsupported displaySet');
|
||||
}
|
||||
@@ -643,12 +617,9 @@ export default class HangingProtocolService extends PubSubService {
|
||||
// if the viewport is not empty, then we check the displaySets it is showing
|
||||
// currently, which means we need to check if the requested updated displaySet
|
||||
// follow the same rules as the current displaySets
|
||||
const {
|
||||
id: displaySetSelectorId,
|
||||
matchedDisplaySetsIndex = 0,
|
||||
} = protocolViewport.displaySets[0];
|
||||
const displaySetSelector =
|
||||
protocol.displaySetSelectors[displaySetSelectorId];
|
||||
const { id: displaySetSelectorId, matchedDisplaySetsIndex = 0 } =
|
||||
protocolViewport.displaySets[0];
|
||||
const displaySetSelector = protocol.displaySetSelectors[displaySetSelectorId];
|
||||
|
||||
if (!displaySetSelector) {
|
||||
return defaultReturn;
|
||||
@@ -704,15 +675,13 @@ export default class HangingProtocolService extends PubSubService {
|
||||
const originalViewportOptions = originalViewport.viewportOptions;
|
||||
const originalDisplaySetOptions = originalViewport.displaySets;
|
||||
|
||||
viewport.viewportOptions = this.getComputedOptions(
|
||||
originalViewportOptions,
|
||||
[newDisplaySetInstanceUID]
|
||||
);
|
||||
viewport.viewportOptions = this.getComputedOptions(originalViewportOptions, [
|
||||
newDisplaySetInstanceUID,
|
||||
]);
|
||||
|
||||
viewport.displaySets = this.getComputedOptions(
|
||||
originalDisplaySetOptions,
|
||||
[newDisplaySetInstanceUID]
|
||||
);
|
||||
viewport.displaySets = this.getComputedOptions(originalDisplaySetOptions, [
|
||||
newDisplaySetInstanceUID,
|
||||
]);
|
||||
}
|
||||
|
||||
const displaySetInstanceUIDs = [];
|
||||
@@ -751,9 +720,7 @@ export default class HangingProtocolService extends PubSubService {
|
||||
const { id } = displaySet;
|
||||
const displaySetMatchDetail = displaySetMatchDetails.get(id);
|
||||
|
||||
const {
|
||||
displaySetInstanceUID: oldDisplaySetInstanceUID,
|
||||
} = displaySetMatchDetail;
|
||||
const { displaySetInstanceUID: oldDisplaySetInstanceUID } = displaySetMatchDetail;
|
||||
|
||||
const displaySetInstanceUID =
|
||||
displaySet.id === displaySetSelectorId
|
||||
@@ -781,9 +748,7 @@ export default class HangingProtocolService extends PubSubService {
|
||||
): any {
|
||||
// Base case: if options is an array, map over the array and recursively call getComputedOptions
|
||||
if (Array.isArray(options)) {
|
||||
return options.map(option =>
|
||||
this.getComputedOptions(option, displaySetUIDs)
|
||||
);
|
||||
return options.map(option => this.getComputedOptions(option, displaySetUIDs));
|
||||
}
|
||||
|
||||
if (options === null) {
|
||||
@@ -806,8 +771,7 @@ export default class HangingProtocolService extends PubSubService {
|
||||
);
|
||||
}
|
||||
|
||||
const callback = this.customAttributeRetrievalCallbacks[customKey]
|
||||
.callback;
|
||||
const callback = this.customAttributeRetrievalCallbacks[customKey].callback;
|
||||
let newOptions = callback.call(options, displaySets);
|
||||
|
||||
if (newOptions === undefined) {
|
||||
@@ -912,18 +876,12 @@ export default class HangingProtocolService extends PubSubService {
|
||||
*
|
||||
* @returns the stage number to apply initially, given the options.
|
||||
*/
|
||||
private _updateStageStatus(
|
||||
options = null as HangingProtocol.SetProtocolOptions
|
||||
) {
|
||||
private _updateStageStatus(options = null as HangingProtocol.SetProtocolOptions) {
|
||||
const stages = this.protocol.stages;
|
||||
for (let i = 0; i < stages.length; i++) {
|
||||
const stage = stages[i];
|
||||
|
||||
const { matchedViewports } = this._matchAllViewports(
|
||||
stage,
|
||||
options,
|
||||
new Map()
|
||||
);
|
||||
const { matchedViewports } = this._matchAllViewports(stage, options, new Map());
|
||||
const activation = stage.stageActivation || {};
|
||||
if (this.matchActivation(matchedViewports, activation.passive, 0)) {
|
||||
if (this.matchActivation(matchedViewports, activation.enabled, 1)) {
|
||||
@@ -942,9 +900,7 @@ export default class HangingProtocolService extends PubSubService {
|
||||
});
|
||||
}
|
||||
|
||||
private _findStageIndex(
|
||||
options = null as HangingProtocol.SetProtocolOptions
|
||||
): number | void {
|
||||
private _findStageIndex(options = null as HangingProtocol.SetProtocolOptions): number | void {
|
||||
const stageId = options?.stageId;
|
||||
const protocol = this.protocol;
|
||||
const stages = protocol.stages;
|
||||
@@ -993,10 +949,7 @@ export default class HangingProtocolService extends PubSubService {
|
||||
const { imageLoadStrategy } = protocol;
|
||||
if (imageLoadStrategy) {
|
||||
// check if the imageLoadStrategy is a valid strategy
|
||||
if (
|
||||
this.registeredImageLoadStrategies[imageLoadStrategy] instanceof
|
||||
Function
|
||||
) {
|
||||
if (this.registeredImageLoadStrategies[imageLoadStrategy] instanceof Function) {
|
||||
this.activeImageLoadStrategyName = imageLoadStrategy;
|
||||
}
|
||||
}
|
||||
@@ -1006,9 +959,7 @@ export default class HangingProtocolService extends PubSubService {
|
||||
|
||||
const stage = this._findStageIndex(options);
|
||||
if (stage === undefined) {
|
||||
throw new Error(
|
||||
`Can't find applicable stage ${protocol.id} ${options?.stageIndex}`
|
||||
);
|
||||
throw new Error(`Can't find applicable stage ${protocol.id} ${options?.stageIndex}`);
|
||||
}
|
||||
this.stageIndex = stage as number;
|
||||
this._updateViewports(options);
|
||||
@@ -1054,11 +1005,7 @@ export default class HangingProtocolService extends PubSubService {
|
||||
* undefined if no protocol or stages are set
|
||||
*/
|
||||
_getNumProtocolStages() {
|
||||
if (
|
||||
!this.protocol ||
|
||||
!this.protocol.stages ||
|
||||
!this.protocol.stages.length
|
||||
) {
|
||||
if (!this.protocol || !this.protocol.stages || !this.protocol.stages.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1201,9 +1148,7 @@ export default class HangingProtocolService extends PubSubService {
|
||||
) {
|
||||
matchedViewports++;
|
||||
} else {
|
||||
console.log(
|
||||
'Adding an empty set of display sets for mapping purposes'
|
||||
);
|
||||
console.log('Adding an empty set of display sets for mapping purposes');
|
||||
matchDetails.displaySetsInfo = viewport.displaySets.map(it => ({
|
||||
displaySetOptions: it,
|
||||
}));
|
||||
@@ -1236,11 +1181,7 @@ export default class HangingProtocolService extends PubSubService {
|
||||
return matchDetails;
|
||||
}
|
||||
for (let i = 0; i < matchDetails.matchingScores.length; i++) {
|
||||
if (
|
||||
inDisplay.indexOf(
|
||||
matchDetails.matchingScores[i].displaySetInstanceUID
|
||||
) === -1
|
||||
) {
|
||||
if (inDisplay.indexOf(matchDetails.matchingScores[i].displaySetInstanceUID) === -1) {
|
||||
const match = matchDetails.matchingScores[i];
|
||||
return match.matchingScore > 0
|
||||
? {
|
||||
@@ -1272,9 +1213,7 @@ export default class HangingProtocolService extends PubSubService {
|
||||
return;
|
||||
}
|
||||
}
|
||||
throw new Error(
|
||||
`Reused viewport details ${id} with ds ${displaySetUID} not valid`
|
||||
);
|
||||
throw new Error(`Reused viewport details ${id} with ds ${displaySetUID} not valid`);
|
||||
}
|
||||
|
||||
protected _matchViewport(
|
||||
@@ -1296,9 +1235,7 @@ export default class HangingProtocolService extends PubSubService {
|
||||
console.warn('No display set selector for', displaySetId);
|
||||
continue;
|
||||
}
|
||||
const { bestMatch, matchingScores } = this._matchImages(
|
||||
displaySetSelector
|
||||
);
|
||||
const { bestMatch, matchingScores } = this._matchImages(displaySetSelector);
|
||||
displaySetMatchDetails.set(displaySetId, bestMatch);
|
||||
|
||||
if (bestMatch) {
|
||||
@@ -1315,10 +1252,7 @@ export default class HangingProtocolService extends PubSubService {
|
||||
viewport.displaySets.forEach(displaySetOptions => {
|
||||
const { id, matchedDisplaySetsIndex = 0 } = displaySetOptions;
|
||||
const reuseDisplaySetUID =
|
||||
id &&
|
||||
displaySetSelectorMap[
|
||||
`${activeStudyUID}:${id}:${matchedDisplaySetsIndex || 0}`
|
||||
];
|
||||
id && displaySetSelectorMap[`${activeStudyUID}:${id}:${matchedDisplaySetsIndex || 0}`];
|
||||
const viewportDisplaySetMain = this.displaySetMatchDetails.get(id);
|
||||
|
||||
const viewportDisplaySet = this.findDeduplicatedMatchDetails(
|
||||
@@ -1330,11 +1264,7 @@ export default class HangingProtocolService extends PubSubService {
|
||||
// Use the display set provided instead
|
||||
if (reuseDisplaySetUID) {
|
||||
if (viewportOptions.allowUnmatchedView !== true) {
|
||||
this.validateDisplaySetSelectMatch(
|
||||
viewportDisplaySet,
|
||||
id,
|
||||
reuseDisplaySetUID
|
||||
);
|
||||
this.validateDisplaySetSelectMatch(viewportDisplaySet, id, reuseDisplaySetUID);
|
||||
}
|
||||
const displaySetInfo: HangingProtocol.DisplaySetInfo = {
|
||||
displaySetInstanceUID: reuseDisplaySetUID,
|
||||
@@ -1378,8 +1308,7 @@ export default class HangingProtocolService extends PubSubService {
|
||||
): void {
|
||||
const { displaySetService } = this._servicesManager.services;
|
||||
const protocolViewportDisplaySets = protocolViewport.displaySets;
|
||||
const numDisplaySetsToSet =
|
||||
displaySetAndViewportOptions.displaySetInstanceUIDs.length;
|
||||
const numDisplaySetsToSet = displaySetAndViewportOptions.displaySetInstanceUIDs.length;
|
||||
|
||||
if (
|
||||
protocolViewportDisplaySets.length > 0 &&
|
||||
@@ -1390,24 +1319,20 @@ export default class HangingProtocolService extends PubSubService {
|
||||
);
|
||||
}
|
||||
|
||||
displaySetAndViewportOptions.displaySetInstanceUIDs.forEach(
|
||||
displaySetInstanceUID => {
|
||||
const displaySet = displaySetService.getDisplaySetByUID(
|
||||
displaySetInstanceUID
|
||||
);
|
||||
displaySetAndViewportOptions.displaySetInstanceUIDs.forEach(displaySetInstanceUID => {
|
||||
const displaySet = displaySetService.getDisplaySetByUID(displaySetInstanceUID);
|
||||
|
||||
const { displaySets: displaySetsInfo } = protocolViewport;
|
||||
const { displaySets: displaySetsInfo } = protocolViewport;
|
||||
|
||||
for (const displaySetInfo of displaySetsInfo) {
|
||||
const displaySetSelector = displaySetSelectors[displaySetInfo.id];
|
||||
for (const displaySetInfo of displaySetsInfo) {
|
||||
const displaySetSelector = displaySetSelectors[displaySetInfo.id];
|
||||
|
||||
if (!displaySetSelector) {
|
||||
continue;
|
||||
}
|
||||
this._validateRequiredSelectors(displaySetSelector, displaySet);
|
||||
if (!displaySetSelector) {
|
||||
continue;
|
||||
}
|
||||
this._validateRequiredSelectors(displaySetSelector, displaySet);
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
private _validateRequiredSelectors(
|
||||
@@ -1433,19 +1358,15 @@ export default class HangingProtocolService extends PubSubService {
|
||||
const { displaySetService } = this._servicesManager.services;
|
||||
const { displaySetSelectorMap } = options;
|
||||
if (displaySetSelectorMap) {
|
||||
Object.entries(displaySetSelectorMap).forEach(
|
||||
([key, displaySetInstanceUID]) => {
|
||||
const displaySet = displaySetService.getDisplaySetByUID(
|
||||
displaySetInstanceUID
|
||||
);
|
||||
Object.entries(displaySetSelectorMap).forEach(([key, displaySetInstanceUID]) => {
|
||||
const displaySet = displaySetService.getDisplaySetByUID(displaySetInstanceUID);
|
||||
|
||||
if (!displaySet) {
|
||||
throw new Error(
|
||||
`The displaySetInstanceUID ${displaySetInstanceUID} is not found in the displaySetService`
|
||||
);
|
||||
}
|
||||
if (!displaySet) {
|
||||
throw new Error(
|
||||
`The displaySetInstanceUID ${displaySetInstanceUID} is not found in the displaySetService`
|
||||
);
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1455,20 +1376,12 @@ export default class HangingProtocolService extends PubSubService {
|
||||
// level matching needs to be added in future
|
||||
|
||||
// Todo: handle fusion viewports by not taking the first displaySet rule for the viewport
|
||||
const {
|
||||
id,
|
||||
studyMatchingRules = [],
|
||||
seriesMatchingRules,
|
||||
} = displaySetRules;
|
||||
const { id, studyMatchingRules = [], seriesMatchingRules } = displaySetRules;
|
||||
|
||||
const matchingScores = [];
|
||||
let highestSeriesMatchingScore = 0;
|
||||
|
||||
console.log(
|
||||
'ProtocolEngine::matchImages',
|
||||
studyMatchingRules,
|
||||
seriesMatchingRules
|
||||
);
|
||||
console.log('ProtocolEngine::matchImages', studyMatchingRules, seriesMatchingRules);
|
||||
const matchActiveOnly = this.protocol.numberOfPriorsReferenced === -1;
|
||||
this.studies.forEach((study, studyInstanceUIDsIndex) => {
|
||||
// Skip non-active if active only
|
||||
@@ -1480,35 +1393,22 @@ export default class HangingProtocolService extends PubSubService {
|
||||
it => it.StudyInstanceUID === study.StudyInstanceUID && !it?.unsupported
|
||||
);
|
||||
|
||||
const studyMatchDetails = this.protocolEngine.findMatch(
|
||||
study,
|
||||
studyMatchingRules,
|
||||
{
|
||||
studies: this.studies,
|
||||
displaySets: studyDisplaySets,
|
||||
allDisplaySets: this.displaySets,
|
||||
displaySetMatchDetails: this.displaySetMatchDetails,
|
||||
studyInstanceUIDsIndex,
|
||||
}
|
||||
);
|
||||
const studyMatchDetails = this.protocolEngine.findMatch(study, studyMatchingRules, {
|
||||
studies: this.studies,
|
||||
displaySets: studyDisplaySets,
|
||||
allDisplaySets: this.displaySets,
|
||||
displaySetMatchDetails: this.displaySetMatchDetails,
|
||||
studyInstanceUIDsIndex,
|
||||
});
|
||||
|
||||
// Prevent bestMatch from being updated if the matchDetails' required attribute check has failed
|
||||
if (studyMatchDetails.requiredFailed === true) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.debug(
|
||||
'study',
|
||||
study.StudyInstanceUID,
|
||||
'display sets #',
|
||||
studyDisplaySets.length
|
||||
);
|
||||
this.debug('study', study.StudyInstanceUID, 'display sets #', studyDisplaySets.length);
|
||||
studyDisplaySets.forEach(displaySet => {
|
||||
const {
|
||||
StudyInstanceUID,
|
||||
SeriesInstanceUID,
|
||||
displaySetInstanceUID,
|
||||
} = displaySet;
|
||||
const { StudyInstanceUID, SeriesInstanceUID, displaySetInstanceUID } = displaySet;
|
||||
const seriesMatchDetails = this.protocolEngine.findMatch(
|
||||
displaySet,
|
||||
seriesMatchingRules,
|
||||
@@ -1523,41 +1423,25 @@ export default class HangingProtocolService extends PubSubService {
|
||||
|
||||
// Prevent bestMatch from being updated if the matchDetails' required attribute check has failed
|
||||
if (seriesMatchDetails.requiredFailed === true) {
|
||||
this.debug(
|
||||
'Display set required failed',
|
||||
displaySet,
|
||||
seriesMatchingRules
|
||||
);
|
||||
this.debug('Display set required failed', displaySet, seriesMatchingRules);
|
||||
return;
|
||||
}
|
||||
|
||||
this.debug('Found displaySet for rules', displaySet);
|
||||
highestSeriesMatchingScore = Math.max(
|
||||
seriesMatchDetails.score,
|
||||
highestSeriesMatchingScore
|
||||
);
|
||||
highestSeriesMatchingScore = Math.max(seriesMatchDetails.score, highestSeriesMatchingScore);
|
||||
|
||||
const matchDetails = {
|
||||
passed: [],
|
||||
failed: [],
|
||||
};
|
||||
|
||||
matchDetails.passed = matchDetails.passed.concat(
|
||||
seriesMatchDetails.details.passed
|
||||
);
|
||||
matchDetails.passed = matchDetails.passed.concat(
|
||||
studyMatchDetails.details.passed
|
||||
);
|
||||
matchDetails.passed = matchDetails.passed.concat(seriesMatchDetails.details.passed);
|
||||
matchDetails.passed = matchDetails.passed.concat(studyMatchDetails.details.passed);
|
||||
|
||||
matchDetails.failed = matchDetails.failed.concat(
|
||||
seriesMatchDetails.details.failed
|
||||
);
|
||||
matchDetails.failed = matchDetails.failed.concat(
|
||||
studyMatchDetails.details.failed
|
||||
);
|
||||
matchDetails.failed = matchDetails.failed.concat(seriesMatchDetails.details.failed);
|
||||
matchDetails.failed = matchDetails.failed.concat(studyMatchDetails.details.failed);
|
||||
|
||||
const totalMatchScore =
|
||||
seriesMatchDetails.score + studyMatchDetails.score;
|
||||
const totalMatchScore = seriesMatchDetails.score + studyMatchDetails.score;
|
||||
|
||||
const imageDetails = {
|
||||
StudyInstanceUID,
|
||||
@@ -1593,17 +1477,11 @@ export default class HangingProtocolService extends PubSubService {
|
||||
},
|
||||
this._getSeriesFieldForDisplaySetSort()
|
||||
);
|
||||
matchingScores.sort((a, b) =>
|
||||
sortingFunction(a.sortingInfo, b.sortingInfo)
|
||||
);
|
||||
matchingScores.sort((a, b) => sortingFunction(a.sortingInfo, b.sortingInfo));
|
||||
|
||||
const bestMatch = matchingScores[0];
|
||||
|
||||
console.log(
|
||||
'ProtocolEngine::matchImages bestMatch',
|
||||
bestMatch,
|
||||
matchingScores
|
||||
);
|
||||
console.log('ProtocolEngine::matchImages bestMatch', bestMatch, matchingScores);
|
||||
|
||||
return {
|
||||
bestMatch,
|
||||
@@ -1672,9 +1550,7 @@ export default class HangingProtocolService extends PubSubService {
|
||||
this.stageIndex = i;
|
||||
|
||||
// Log the new stage
|
||||
this.debug(
|
||||
`ProtocolEngine::setCurrentProtocolStage stage = ${this.stageIndex}`
|
||||
);
|
||||
this.debug(`ProtocolEngine::setCurrentProtocolStage stage = ${this.stageIndex}`);
|
||||
|
||||
// Since stage has changed, we need to update the viewports
|
||||
// and redo matchings
|
||||
|
||||
@@ -92,12 +92,7 @@ export default class ProtocolEngine {
|
||||
* @returns
|
||||
*/
|
||||
findMatch(metaData, rules, options) {
|
||||
return HPMatcher.match(
|
||||
metaData,
|
||||
rules,
|
||||
this.customAttributeRetrievalCallbacks,
|
||||
options
|
||||
);
|
||||
return HPMatcher.match(metaData, rules, this.customAttributeRetrievalCallbacks, options);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -142,8 +137,7 @@ export default class ProtocolEngine {
|
||||
// if not select the first protocol in the list
|
||||
if (!matched.length) {
|
||||
const protocol =
|
||||
this.protocols.find(protocol => protocol.id === 'default') ??
|
||||
this.protocols[0];
|
||||
this.protocols.find(protocol => protocol.id === 'default') ?? this.protocols[0];
|
||||
console.log('No protocol matches, defaulting to', protocol);
|
||||
return [
|
||||
{
|
||||
@@ -174,9 +168,7 @@ export default class ProtocolEngine {
|
||||
if (!Object.keys(this.matchedProtocolScores).length) {
|
||||
return;
|
||||
}
|
||||
const highestScoringProtocolId = this._largestKeyByValue(
|
||||
this.matchedProtocolScores
|
||||
);
|
||||
const highestScoringProtocolId = this._largestKeyByValue(this.matchedProtocolScores);
|
||||
return this.matchedProtocols.get(highestScoringProtocolId);
|
||||
}
|
||||
}
|
||||
+2
-7
@@ -8,19 +8,14 @@ import { getSplitParam } from '../../../utils';
|
||||
*/
|
||||
const isDisplaySetFromUrl = (displaySet): boolean => {
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
const initialSeriesInstanceUID = getSplitParam(
|
||||
'initialseriesinstanceuid',
|
||||
params
|
||||
);
|
||||
const initialSeriesInstanceUID = getSplitParam('initialseriesinstanceuid', params);
|
||||
const initialSOPInstanceUID = getSplitParam('initialsopinstanceuid', params);
|
||||
if (!initialSeriesInstanceUID && !initialSOPInstanceUID) {
|
||||
return false;
|
||||
}
|
||||
const isSeriesMatch =
|
||||
!initialSeriesInstanceUID ||
|
||||
initialSeriesInstanceUID.some(
|
||||
seriesUID => displaySet.SeriesInstanceUID === seriesUID
|
||||
);
|
||||
initialSeriesInstanceUID.some(seriesUID => displaySet.SeriesInstanceUID === seriesUID);
|
||||
const isSopMatch =
|
||||
!initialSOPInstanceUID ||
|
||||
displaySet.instances?.some?.(instance =>
|
||||
|
||||
+1
-2
@@ -1,6 +1,5 @@
|
||||
export default (study, extraData) => {
|
||||
const ret = extraData?.displaySets?.filter(ds => ds.numImageFrames > 0)
|
||||
?.length;
|
||||
const ret = extraData?.displaySets?.filter(ds => ds.numImageFrames > 0)?.length;
|
||||
console.log('number of display sets with images', ret);
|
||||
return ret;
|
||||
};
|
||||
+1
-2
@@ -1,2 +1 @@
|
||||
export default (study, extraData) =>
|
||||
extraData?.displaySets?.map(ds => ds.SeriesDescription);
|
||||
export default (study, extraData) => extraData?.displaySets?.map(ds => ds.SeriesDescription);
|
||||
@@ -64,8 +64,7 @@ function displayConstraint(attributeId, constraint, attributes) {
|
||||
}
|
||||
|
||||
const attributeText = getAttributeText(attributeId, attributes);
|
||||
const constraintText =
|
||||
attributeText + ' ' + humanize(comparator).toLowerCase() + ' ' + value;
|
||||
const constraintText = attributeText + ' ' + humanize(comparator).toLowerCase() + ' ' + value;
|
||||
|
||||
return constraintText;
|
||||
}
|
||||
@@ -20,7 +20,7 @@ import validate from 'validate.js';
|
||||
* = 'Attenuation' (Fail)
|
||||
*
|
||||
* */
|
||||
validate.validators.equals = function(value, options, key) {
|
||||
validate.validators.equals = function (value, options, key) {
|
||||
const testValue = getTestValue(options);
|
||||
const dicomArrayValue = dicomTagToArray(value);
|
||||
|
||||
@@ -60,7 +60,7 @@ validate.validators.equals = function(value, options, key) {
|
||||
* = 'Attenuation Corrected' (Fail)
|
||||
* = 'Attenuation' (Fail)
|
||||
* */
|
||||
validate.validators.doesNotEqual = function(value, options, key) {
|
||||
validate.validators.doesNotEqual = function (value, options, key) {
|
||||
const testValue = getTestValue(options);
|
||||
const dicomArrayValue = dicomTagToArray(value);
|
||||
|
||||
@@ -103,16 +103,14 @@ validate.validators.doesNotEqual = function(value, options, key) {
|
||||
* testValue = ['Attenuation Corrected', 'Corrected'] (Valid)
|
||||
* = ['Attenuation', 'Corrected'] (Fail)
|
||||
* */
|
||||
validate.validators.includes = function(value, options, key) {
|
||||
validate.validators.includes = function (value, options, key) {
|
||||
const testValue = getTestValue(options);
|
||||
const dicomArrayValue = dicomTagToArray(value);
|
||||
|
||||
if (Array.isArray(testValue)) {
|
||||
const includedValues = testValue.filter(el => dicomArrayValue.includes(el));
|
||||
if (includedValues.length === 0) {
|
||||
return `${key} must include at least one of the following values: ${testValue.join(
|
||||
', '
|
||||
)}`;
|
||||
return `${key} must include at least one of the following values: ${testValue.join(', ')}`;
|
||||
}
|
||||
} else {
|
||||
return `${key} ${testValue} must be an array`;
|
||||
@@ -141,7 +139,7 @@ validate.validators.includes = function(value, options, key) {
|
||||
* testValue = ['Attenuation Corrected', 'Corrected'] (Fail)
|
||||
* = ['Attenuation', 'Corrected'] (Valid)
|
||||
* */
|
||||
validate.validators.doesNotInclude = function(value, options, key) {
|
||||
validate.validators.doesNotInclude = function (value, options, key) {
|
||||
const testValue = getTestValue(options);
|
||||
const dicomArrayValue = dicomTagToArray(value);
|
||||
|
||||
@@ -175,36 +173,23 @@ validate.validators.doesNotInclude = function(value, options, key) {
|
||||
* = ['cat', 'dog'] (Fail)
|
||||
*
|
||||
* */
|
||||
validate.validators.containsI = function(value, options, key) {
|
||||
validate.validators.containsI = function (value, options, key) {
|
||||
const testValue = getTestValue(options);
|
||||
if (Array.isArray(value)) {
|
||||
if (
|
||||
value.some(
|
||||
item => !validate.validators.containsI(item.toLowerCase(), options, key)
|
||||
)
|
||||
) {
|
||||
if (value.some(item => !validate.validators.containsI(item.toLowerCase(), options, key))) {
|
||||
return undefined;
|
||||
}
|
||||
return `No item of ${value.join(',')} contains ${JSON.stringify(
|
||||
testValue
|
||||
)}`;
|
||||
return `No item of ${value.join(',')} contains ${JSON.stringify(testValue)}`;
|
||||
}
|
||||
if (Array.isArray(testValue)) {
|
||||
if (
|
||||
testValue.some(
|
||||
subTest =>
|
||||
!validate.validators.containsI(value, subTest.toLowerCase(), key)
|
||||
)
|
||||
testValue.some(subTest => !validate.validators.containsI(value, subTest.toLowerCase(), key))
|
||||
) {
|
||||
return;
|
||||
}
|
||||
return `${key} must contain at least one of ${testValue.join(',')}`;
|
||||
}
|
||||
if (
|
||||
testValue &&
|
||||
value.indexOf &&
|
||||
value.toLowerCase().indexOf(testValue.toLowerCase()) === -1
|
||||
) {
|
||||
if (testValue && value.indexOf && value.toLowerCase().indexOf(testValue.toLowerCase()) === -1) {
|
||||
return key + 'must contain any case of' + testValue;
|
||||
}
|
||||
};
|
||||
@@ -224,22 +209,16 @@ validate.validators.containsI = function(value, options, key) {
|
||||
* = ['cat', 'dog'] (Fail)
|
||||
*
|
||||
* */
|
||||
validate.validators.contains = function(value, options, key) {
|
||||
validate.validators.contains = function (value, options, key) {
|
||||
const testValue = getTestValue(options);
|
||||
if (Array.isArray(value)) {
|
||||
if (value.some(item => !validate.validators.contains(item, options, key))) {
|
||||
return undefined;
|
||||
}
|
||||
return `No item of ${value.join(',')} contains ${JSON.stringify(
|
||||
testValue
|
||||
)}`;
|
||||
return `No item of ${value.join(',')} contains ${JSON.stringify(testValue)}`;
|
||||
}
|
||||
if (Array.isArray(testValue)) {
|
||||
if (
|
||||
testValue.some(
|
||||
subTest => !validate.validators.contains(value, subTest, key)
|
||||
)
|
||||
) {
|
||||
if (testValue.some(subTest => !validate.validators.contains(value, subTest, key))) {
|
||||
return;
|
||||
}
|
||||
return `${key} must contain at least one of ${testValue.join(',')}`;
|
||||
@@ -264,7 +243,7 @@ validate.validators.contains = function(value, options, key) {
|
||||
* = ['cat', 'dog'] (Valid)
|
||||
*
|
||||
* */
|
||||
validate.validators.doesNotContain = function(value, options, key) {
|
||||
validate.validators.doesNotContain = function (value, options, key) {
|
||||
const containsResult = validate.validators.contains(value, options, key);
|
||||
if (!containsResult) {
|
||||
return `No item of ${value} should contain ${getTestValue(options)}`;
|
||||
@@ -287,7 +266,7 @@ validate.validators.doesNotContain = function(value, options, key) {
|
||||
* = ['cat', 'dog'] (Valid)
|
||||
*
|
||||
* */
|
||||
validate.validators.doesNotContainI = function(value, options, key) {
|
||||
validate.validators.doesNotContainI = function (value, options, key) {
|
||||
const containsResult = validate.validators.containsI(value, options, key);
|
||||
if (!containsResult) {
|
||||
return `No item of ${value} should not contain ${getTestValue(options)}`;
|
||||
@@ -308,7 +287,7 @@ validate.validators.doesNotContainI = function(value, options, key) {
|
||||
* = ['cat', 'dog'] (Fail)
|
||||
*
|
||||
* */
|
||||
validate.validators.startsWith = function(value, options, key) {
|
||||
validate.validators.startsWith = function (value, options, key) {
|
||||
let testValues = getTestValue(options);
|
||||
|
||||
if (typeof testValues === 'string') {
|
||||
@@ -356,7 +335,7 @@ validate.validators.startsWith = function(value, options, key) {
|
||||
* = ['cat', 'dog'] (Fail)
|
||||
*
|
||||
* */
|
||||
validate.validators.endsWith = function(value, options, key) {
|
||||
validate.validators.endsWith = function (value, options, key) {
|
||||
let testValues = getTestValue(options);
|
||||
|
||||
if (typeof testValues === 'string') {
|
||||
@@ -395,7 +374,7 @@ validate.validators.endsWith = function(value, options, key) {
|
||||
* = 40 (Fail)
|
||||
*
|
||||
* */
|
||||
validate.validators.greaterThan = function(value, options, key) {
|
||||
validate.validators.greaterThan = function (value, options, key) {
|
||||
const testValue = getTestValue(options);
|
||||
if (Array.isArray(value) || typeof value === 'string') {
|
||||
return `${key} is not allowed as an array or string`;
|
||||
@@ -421,7 +400,7 @@ validate.validators.greaterThan = function(value, options, key) {
|
||||
* = 20 (Fail)
|
||||
*
|
||||
* */
|
||||
validate.validators.lessThan = function(value, options, key) {
|
||||
validate.validators.lessThan = function (value, options, key) {
|
||||
const testValue = getTestValue(options);
|
||||
if (Array.isArray(testValue)) {
|
||||
if (testValue.length === 1) {
|
||||
@@ -450,7 +429,7 @@ validate.validators.lessThan = function(value, options, key) {
|
||||
* = [45] (Fail)
|
||||
*
|
||||
* */
|
||||
validate.validators.range = function(value, options, key) {
|
||||
validate.validators.range = function (value, options, key) {
|
||||
const testValue = getTestValue(options);
|
||||
if (Array.isArray(testValue) && testValue.length === 2) {
|
||||
const min = Math.min(testValue[0], testValue[1]);
|
||||
|
||||
@@ -17,176 +17,98 @@ describe('validator', () => {
|
||||
describe('equals', () => {
|
||||
it('returned undefined on strictly equals', () => {
|
||||
expect(
|
||||
validate(attributeMap, { listStr: { equals: ['Attenuation'] } }, [
|
||||
options,
|
||||
])
|
||||
validate(attributeMap, { listStr: { equals: ['Attenuation'] } }, [options])
|
||||
).not.toBeUndefined();
|
||||
expect(
|
||||
validate(attributeMap, { listStr: { equals: 'Attenuation' } }, [
|
||||
options,
|
||||
])
|
||||
validate(attributeMap, { listStr: { equals: 'Attenuation' } }, [options])
|
||||
).not.toBeUndefined();
|
||||
expect(
|
||||
validate(
|
||||
attributeMap,
|
||||
{ listStr: { equals: 'Attenuation Corrected' } },
|
||||
[options]
|
||||
)
|
||||
validate(attributeMap, { listStr: { equals: 'Attenuation Corrected' } }, [options])
|
||||
).toBeUndefined();
|
||||
expect(
|
||||
validate(
|
||||
attributeMap,
|
||||
{ listStr: { equals: ['Attenuation Corrected'] } },
|
||||
[options]
|
||||
)
|
||||
validate(attributeMap, { listStr: { equals: ['Attenuation Corrected'] } }, [options])
|
||||
).toBeUndefined();
|
||||
expect(
|
||||
validate(attributeMap, { str: { equals: 'Attenuation Corrected' } }, [
|
||||
options,
|
||||
])
|
||||
validate(attributeMap, { str: { equals: 'Attenuation Corrected' } }, [options])
|
||||
).toBeUndefined();
|
||||
|
||||
expect(
|
||||
validate(
|
||||
attributeMap,
|
||||
{ str: { equals: { value: 'Attenuation Corrected' } } },
|
||||
[options]
|
||||
)
|
||||
validate(attributeMap, { str: { equals: { value: 'Attenuation Corrected' } } }, [options])
|
||||
).toBeUndefined();
|
||||
expect(
|
||||
validate(attributeMap, { str: { equals: ['Attenuation Corrected'] } }, [
|
||||
options,
|
||||
])
|
||||
validate(attributeMap, { str: { equals: ['Attenuation Corrected'] } }, [options])
|
||||
).toBeUndefined();
|
||||
expect(
|
||||
validate(attributeMap, { str: { equals: ['Attenuation'] } }, [options])
|
||||
).not.toBeUndefined();
|
||||
expect(
|
||||
validate(attributeMap, { list: { equals: ['abc', 'def', 'GHI'] } }, [
|
||||
options,
|
||||
])
|
||||
validate(attributeMap, { list: { equals: ['abc', 'def', 'GHI'] } }, [options])
|
||||
).toBeUndefined();
|
||||
expect(
|
||||
validate(attributeMap, { list: { equals: ['abc', 'GHI', 'def'] } }, [
|
||||
options,
|
||||
])
|
||||
validate(attributeMap, { list: { equals: ['abc', 'GHI', 'def'] } }, [options])
|
||||
).not.toBeUndefined();
|
||||
expect(
|
||||
validate(
|
||||
attributeMap,
|
||||
{ list: { equals: { value: ['abc', 'def', 'GHI'] } } },
|
||||
[options]
|
||||
)
|
||||
validate(attributeMap, { list: { equals: { value: ['abc', 'def', 'GHI'] } } }, [options])
|
||||
).toBeUndefined();
|
||||
});
|
||||
});
|
||||
describe('doesNotEqual', () => {
|
||||
it('returns undefined if value does not equal ', () => {
|
||||
expect(
|
||||
validate(
|
||||
attributeMap,
|
||||
{ listStr: { doesNotEqual: 'Attenuation Corrected' } },
|
||||
[options]
|
||||
)
|
||||
validate(attributeMap, { listStr: { doesNotEqual: 'Attenuation Corrected' } }, [options])
|
||||
).not.toBeUndefined();
|
||||
expect(
|
||||
validate(
|
||||
attributeMap,
|
||||
{ listStr: { doesNotEqual: ['Attenuation Corrected'] } },
|
||||
[options]
|
||||
)
|
||||
validate(attributeMap, { listStr: { doesNotEqual: ['Attenuation Corrected'] } }, [options])
|
||||
).not.toBeUndefined();
|
||||
expect(
|
||||
validate(attributeMap, { listStr: { doesNotEqual: 'Attenuation' } }, [
|
||||
options,
|
||||
])
|
||||
validate(attributeMap, { listStr: { doesNotEqual: 'Attenuation' } }, [options])
|
||||
).toBeUndefined();
|
||||
|
||||
expect(
|
||||
validate(attributeMap, { str: { doesNotEqual: 'Attenuation' } }, [
|
||||
options,
|
||||
])
|
||||
validate(attributeMap, { str: { doesNotEqual: 'Attenuation' } }, [options])
|
||||
).toBeUndefined();
|
||||
expect(
|
||||
validate(
|
||||
attributeMap,
|
||||
{ str: { doesNotEqual: { value: 'Attenuation' } } },
|
||||
[options]
|
||||
)
|
||||
validate(attributeMap, { str: { doesNotEqual: { value: 'Attenuation' } } }, [options])
|
||||
).toBeUndefined();
|
||||
expect(
|
||||
validate(attributeMap, { str: { doesNotEqual: ['Attenuation'] } }, [
|
||||
options,
|
||||
])
|
||||
validate(attributeMap, { str: { doesNotEqual: ['Attenuation'] } }, [options])
|
||||
).toBeUndefined();
|
||||
expect(
|
||||
validate(attributeMap, { str: { doesNotEqual: ['abc', 'def'] } }, [
|
||||
options,
|
||||
])
|
||||
validate(attributeMap, { str: { doesNotEqual: ['abc', 'def'] } }, [options])
|
||||
).toBeUndefined();
|
||||
expect(
|
||||
validate(
|
||||
attributeMap,
|
||||
{ list: { doesNotEqual: ['abc', 'GHI', 'def'] } },
|
||||
[options]
|
||||
)
|
||||
validate(attributeMap, { list: { doesNotEqual: ['abc', 'GHI', 'def'] } }, [options])
|
||||
).toBeUndefined();
|
||||
expect(
|
||||
validate(
|
||||
attributeMap,
|
||||
{ list: { doesNotEqual: ['abc', 'def', 'GHI'] } },
|
||||
[options]
|
||||
)
|
||||
validate(attributeMap, { list: { doesNotEqual: ['abc', 'def', 'GHI'] } }, [options])
|
||||
).not.toBeUndefined();
|
||||
});
|
||||
});
|
||||
describe('includes', () => {
|
||||
it('returns match any list includes', () => {
|
||||
expect(
|
||||
validate(
|
||||
attributeMap,
|
||||
{ listStr: { includes: 'Attenuation Corrected' } },
|
||||
[options]
|
||||
)
|
||||
validate(attributeMap, { listStr: { includes: 'Attenuation Corrected' } }, [options])
|
||||
).not.toBeUndefined();
|
||||
expect(
|
||||
validate(
|
||||
attributeMap,
|
||||
{ listStr: { includes: ['Attenuation Corrected'] } },
|
||||
[options]
|
||||
)
|
||||
validate(attributeMap, { listStr: { includes: ['Attenuation Corrected'] } }, [options])
|
||||
).toBeUndefined();
|
||||
expect(
|
||||
validate(
|
||||
attributeMap,
|
||||
{ listStr: { includes: ['Attenuation Corrected', 'Corrected'] } },
|
||||
[options]
|
||||
)
|
||||
validate(attributeMap, { listStr: { includes: ['Attenuation Corrected', 'Corrected'] } }, [
|
||||
options,
|
||||
])
|
||||
).toBeUndefined();
|
||||
expect(
|
||||
validate(
|
||||
attributeMap,
|
||||
{ listStr: { includes: ['Attenuation', 'Corrected'] } },
|
||||
[options]
|
||||
)
|
||||
validate(attributeMap, { listStr: { includes: ['Attenuation', 'Corrected'] } }, [options])
|
||||
).not.toBeUndefined();
|
||||
expect(
|
||||
validate(
|
||||
attributeMap,
|
||||
{ str: { includes: ['Attenuation Corrected', 'Corrected'] } },
|
||||
[options]
|
||||
)
|
||||
validate(attributeMap, { str: { includes: ['Attenuation Corrected', 'Corrected'] } }, [
|
||||
options,
|
||||
])
|
||||
).toBeUndefined();
|
||||
expect(
|
||||
validate(
|
||||
attributeMap,
|
||||
{ str: { includes: ['Attenuation', 'Corrected'] } },
|
||||
[options]
|
||||
)
|
||||
validate(attributeMap, { str: { includes: ['Attenuation', 'Corrected'] } }, [options])
|
||||
).not.toBeUndefined();
|
||||
expect(
|
||||
validate(attributeMap, { list: { includes: ['abc'] } }, [options])
|
||||
).toBeUndefined();
|
||||
expect(validate(attributeMap, { list: { includes: ['abc'] } }, [options])).toBeUndefined();
|
||||
expect(
|
||||
validate(attributeMap, { list: { includes: ['GHI', 'HI'] } }, [options])
|
||||
).toBeUndefined();
|
||||
@@ -198,11 +120,7 @@ describe('validator', () => {
|
||||
describe('doesNotInclude', () => {
|
||||
it('returns undefined if list does not includes', () => {
|
||||
expect(
|
||||
validate(
|
||||
attributeMap,
|
||||
{ listStr: { doesNotInclude: 'Attenuation Corrected' } },
|
||||
[options]
|
||||
)
|
||||
validate(attributeMap, { listStr: { doesNotInclude: 'Attenuation Corrected' } }, [options])
|
||||
).not.toBeUndefined();
|
||||
expect(
|
||||
validate(
|
||||
@@ -214,11 +132,9 @@ describe('validator', () => {
|
||||
)
|
||||
).not.toBeUndefined();
|
||||
expect(
|
||||
validate(
|
||||
attributeMap,
|
||||
{ listStr: { doesNotInclude: ['Attenuation', 'Corrected'] } },
|
||||
[options]
|
||||
)
|
||||
validate(attributeMap, { listStr: { doesNotInclude: ['Attenuation', 'Corrected'] } }, [
|
||||
options,
|
||||
])
|
||||
).toBeUndefined();
|
||||
expect(
|
||||
validate(
|
||||
@@ -228,116 +144,74 @@ describe('validator', () => {
|
||||
)
|
||||
).not.toBeUndefined();
|
||||
expect(
|
||||
validate(
|
||||
attributeMap,
|
||||
{ str: { doesNotInclude: ['Attenuation', 'Corrected'] } },
|
||||
[options]
|
||||
)
|
||||
validate(attributeMap, { str: { doesNotInclude: ['Attenuation', 'Corrected'] } }, [options])
|
||||
).toBeUndefined();
|
||||
expect(
|
||||
validate(attributeMap, { list: { doesNotInclude: ['Corr'] } }, [
|
||||
options,
|
||||
])
|
||||
validate(attributeMap, { list: { doesNotInclude: ['Corr'] } }, [options])
|
||||
).toBeUndefined();
|
||||
expect(
|
||||
validate(attributeMap, { list: { doesNotInclude: 'abc' } }, [options])
|
||||
).not.toBeUndefined();
|
||||
expect(
|
||||
validate(
|
||||
attributeMap,
|
||||
{ list: { doesNotInclude: { value: ['abc'] } } },
|
||||
[options]
|
||||
)
|
||||
validate(attributeMap, { list: { doesNotInclude: { value: ['abc'] } } }, [options])
|
||||
).not.toBeUndefined();
|
||||
expect(
|
||||
validate(
|
||||
attributeMap,
|
||||
{ list: { doesNotInclude: { value: ['att', 'cor'] } } },
|
||||
[options]
|
||||
)
|
||||
validate(attributeMap, { list: { doesNotInclude: { value: ['att', 'cor'] } } }, [options])
|
||||
).toBeUndefined();
|
||||
expect(
|
||||
validate(
|
||||
attributeMap,
|
||||
{ list: { doesNotInclude: { value: ['abc', 'def', 'dog'] } } },
|
||||
[options]
|
||||
)
|
||||
validate(attributeMap, { list: { doesNotInclude: { value: ['abc', 'def', 'dog'] } } }, [
|
||||
options,
|
||||
])
|
||||
).not.toBeUndefined();
|
||||
});
|
||||
});
|
||||
describe('containsI', () => {
|
||||
it('returns match any list contains case insensitive', () => {
|
||||
expect(
|
||||
validate(attributeMap, { upper: { containsI: ['hi', 'pre'] } }, [
|
||||
options,
|
||||
])
|
||||
validate(attributeMap, { upper: { containsI: ['hi', 'pre'] } }, [options])
|
||||
).not.toBeUndefined();
|
||||
expect(validate(attributeMap, { list: { containsI: 'hi' } }, [options])).toBeUndefined();
|
||||
expect(
|
||||
validate(attributeMap, { list: { containsI: 'hi' } }, [options])
|
||||
validate(attributeMap, { list: { containsI: ['ghi', 'bye'] } }, [options])
|
||||
).toBeUndefined();
|
||||
expect(
|
||||
validate(attributeMap, { list: { containsI: ['ghi', 'bye'] } }, [
|
||||
options,
|
||||
])
|
||||
).toBeUndefined();
|
||||
expect(
|
||||
validate(attributeMap, { list: { containsI: ['bye', 'hi'] } }, [
|
||||
options,
|
||||
])
|
||||
validate(attributeMap, { list: { containsI: ['bye', 'hi'] } }, [options])
|
||||
).toBeUndefined();
|
||||
expect(
|
||||
validate(attributeMap, { list: { containsI: ['ig', 'hi'] } }, [options])
|
||||
).toBeUndefined();
|
||||
expect(
|
||||
validate(attributeMap, { upper: { containsI: ['bye', 'per'] } }, [
|
||||
options,
|
||||
])
|
||||
validate(attributeMap, { upper: { containsI: ['bye', 'per'] } }, [options])
|
||||
).toBeUndefined();
|
||||
});
|
||||
});
|
||||
describe('contains', () => {
|
||||
it('returns match any list contains', () => {
|
||||
expect(validate(attributeMap, { str: { contains: 'Corr' } }, [options])).toBeUndefined();
|
||||
expect(
|
||||
validate(attributeMap, { str: { contains: 'Corr' } }, [options])
|
||||
).toBeUndefined();
|
||||
expect(
|
||||
validate(attributeMap, { str: { contains: { value: 'Corr' } } }, [
|
||||
options,
|
||||
])
|
||||
).toBeUndefined();
|
||||
expect(
|
||||
validate(attributeMap, { str: { contains: ['Corr'] } }, [options])
|
||||
validate(attributeMap, { str: { contains: { value: 'Corr' } } }, [options])
|
||||
).toBeUndefined();
|
||||
expect(validate(attributeMap, { str: { contains: ['Corr'] } }, [options])).toBeUndefined();
|
||||
expect(
|
||||
validate(attributeMap, { str: { contains: ['corr'] } }, [options])
|
||||
).not.toBeUndefined();
|
||||
expect(
|
||||
validate(attributeMap, { str: { contains: ['Att', 'Wall'] } }, [
|
||||
options,
|
||||
])
|
||||
).toBeUndefined();
|
||||
expect(
|
||||
validate(attributeMap, { list: { contains: 'GH' } }, [options])
|
||||
).toBeUndefined();
|
||||
expect(
|
||||
validate(attributeMap, { list: { contains: ['ab'] } }, [options])
|
||||
validate(attributeMap, { str: { contains: ['Att', 'Wall'] } }, [options])
|
||||
).toBeUndefined();
|
||||
expect(validate(attributeMap, { list: { contains: 'GH' } }, [options])).toBeUndefined();
|
||||
expect(validate(attributeMap, { list: { contains: ['ab'] } }, [options])).toBeUndefined();
|
||||
|
||||
expect(
|
||||
validate(attributeMap, { list: { contains: ['z', 'bc'] } }, [options])
|
||||
).toBeUndefined();
|
||||
expect(
|
||||
validate(attributeMap, { list: { contains: ['z'] } }, [options])
|
||||
).not.toBeUndefined();
|
||||
expect(validate(attributeMap, { list: { contains: ['z'] } }, [options])).not.toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe('doesNotContain', () => {
|
||||
it('returns undefined if string does not contain specified value', () => {
|
||||
expect(
|
||||
validate(attributeMap, { str: { doesNotContain: ['att', 'wall'] } }, [
|
||||
options,
|
||||
])
|
||||
validate(attributeMap, { str: { doesNotContain: ['att', 'wall'] } }, [options])
|
||||
).toBeUndefined();
|
||||
expect(
|
||||
validate(attributeMap, { str: { doesNotContain: 'Corr' } }, [options])
|
||||
@@ -346,29 +220,19 @@ describe('validator', () => {
|
||||
validate(attributeMap, { str: { doesNotContain: 'corr' } }, [options])
|
||||
).toBeUndefined();
|
||||
expect(
|
||||
validate(attributeMap, { str: { doesNotContain: { value: 'corr' } } }, [
|
||||
options,
|
||||
])
|
||||
validate(attributeMap, { str: { doesNotContain: { value: 'corr' } } }, [options])
|
||||
).toBeUndefined();
|
||||
expect(
|
||||
validate(attributeMap, { str: { doesNotContain: ['att', 'cor'] } }, [
|
||||
options,
|
||||
])
|
||||
validate(attributeMap, { str: { doesNotContain: ['att', 'cor'] } }, [options])
|
||||
).toBeUndefined();
|
||||
expect(
|
||||
validate(attributeMap, { str: { doesNotContain: ['Att', 'cor'] } }, [
|
||||
options,
|
||||
])
|
||||
validate(attributeMap, { str: { doesNotContain: ['Att', 'cor'] } }, [options])
|
||||
).not.toBeUndefined();
|
||||
expect(
|
||||
validate(attributeMap, { str: { doesNotContain: ['bye', 'hi'] } }, [
|
||||
options,
|
||||
])
|
||||
validate(attributeMap, { str: { doesNotContain: ['bye', 'hi'] } }, [options])
|
||||
).toBeUndefined();
|
||||
expect(
|
||||
validate(attributeMap, { list: { doesNotContain: ['GHI', 'hi'] } }, [
|
||||
options,
|
||||
])
|
||||
validate(attributeMap, { list: { doesNotContain: ['GHI', 'hi'] } }, [options])
|
||||
).not.toBeUndefined();
|
||||
expect(
|
||||
validate(attributeMap, { list: { doesNotContain: ['hi'] } }, [options])
|
||||
@@ -384,103 +248,63 @@ describe('validator', () => {
|
||||
validate(attributeMap, { str: { doesNotContainI: 'Corr' } }, [options])
|
||||
).not.toBeUndefined();
|
||||
expect(
|
||||
validate(attributeMap, { str: { doesNotContainI: ['att', 'cor'] } }, [
|
||||
options,
|
||||
])
|
||||
validate(attributeMap, { str: { doesNotContainI: ['att', 'cor'] } }, [options])
|
||||
).not.toBeUndefined();
|
||||
expect(
|
||||
validate(attributeMap, { str: { doesNotContainI: ['Att', 'wall'] } }, [
|
||||
options,
|
||||
])
|
||||
validate(attributeMap, { str: { doesNotContainI: ['Att', 'wall'] } }, [options])
|
||||
).not.toBeUndefined();
|
||||
expect(
|
||||
validate(attributeMap, { str: { doesNotContainI: ['bye', 'hi'] } }, [
|
||||
options,
|
||||
])
|
||||
validate(attributeMap, { str: { doesNotContainI: ['bye', 'hi'] } }, [options])
|
||||
).toBeUndefined();
|
||||
expect(
|
||||
validate(attributeMap, { list: { doesNotContainI: ['bye', 'ABC'] } }, [
|
||||
options,
|
||||
])
|
||||
validate(attributeMap, { list: { doesNotContainI: ['bye', 'ABC'] } }, [options])
|
||||
).not.toBeUndefined();
|
||||
expect(
|
||||
validate(attributeMap, { list: { doesNotContainI: 'bye' } }, [options])
|
||||
).toBeUndefined();
|
||||
expect(
|
||||
validate(attributeMap, { list: { doesNotContainI: ['bye', 'ABC'] } }, [
|
||||
options,
|
||||
])
|
||||
validate(attributeMap, { list: { doesNotContainI: ['bye', 'ABC'] } }, [options])
|
||||
).not.toBeUndefined();
|
||||
});
|
||||
});
|
||||
describe('startsWith', () => {
|
||||
it('returns undefined if string starts with specified value', () => {
|
||||
expect(
|
||||
validate(attributeMap, { str: { startsWith: { value: 'Atte' } } }, [
|
||||
options,
|
||||
])
|
||||
validate(attributeMap, { str: { startsWith: { value: 'Atte' } } }, [options])
|
||||
).toBeUndefined();
|
||||
expect(validate(attributeMap, { str: { startsWith: 'Att' } }, [options])).toBeUndefined();
|
||||
expect(
|
||||
validate(attributeMap, { str: { startsWith: ['cat', 'dog', 'Att'] } }, [options])
|
||||
).toBeUndefined();
|
||||
expect(
|
||||
validate(attributeMap, { str: { startsWith: 'Att' } }, [options])
|
||||
).toBeUndefined();
|
||||
expect(
|
||||
validate(attributeMap, { str: { startsWith: ['cat', 'dog', 'Att'] } }, [
|
||||
options,
|
||||
])
|
||||
).toBeUndefined();
|
||||
expect(
|
||||
validate(attributeMap, { str: { startsWith: ['cat', 'dog'] } }, [
|
||||
options,
|
||||
])
|
||||
validate(attributeMap, { str: { startsWith: ['cat', 'dog'] } }, [options])
|
||||
).not.toBeUndefined();
|
||||
expect(validate(attributeMap, { list: { startsWith: ['GH'] } }, [options])).toBeUndefined();
|
||||
expect(
|
||||
validate(attributeMap, { list: { startsWith: ['GH'] } }, [options])
|
||||
validate(attributeMap, { list: { startsWith: ['de', 'bye'] } }, [options])
|
||||
).toBeUndefined();
|
||||
expect(
|
||||
validate(attributeMap, { list: { startsWith: ['de', 'bye'] } }, [
|
||||
options,
|
||||
])
|
||||
).toBeUndefined();
|
||||
expect(
|
||||
validate(attributeMap, { list: { startsWith: ['hi', 'bye'] } }, [
|
||||
options,
|
||||
])
|
||||
validate(attributeMap, { list: { startsWith: ['hi', 'bye'] } }, [options])
|
||||
).not.toBeUndefined();
|
||||
});
|
||||
});
|
||||
describe('endsWith', () => {
|
||||
it('returns undefined if string ends with specified value', () => {
|
||||
expect(validate(attributeMap, { str: { endsWith: 'ted' } }, [options])).toBeUndefined();
|
||||
expect(
|
||||
validate(attributeMap, { str: { endsWith: 'ted' } }, [options])
|
||||
validate(attributeMap, { str: { endsWith: { value: 'ted' } } }, [options])
|
||||
).toBeUndefined();
|
||||
expect(validate(attributeMap, { str: { endsWith: ['ted'] } }, [options])).toBeUndefined();
|
||||
expect(validate(attributeMap, { str: { endsWith: ['Att'] } }, [options])).not.toBeUndefined();
|
||||
expect(
|
||||
validate(attributeMap, { str: { endsWith: ['cat', 'dog', 'ted'] } }, [options])
|
||||
).toBeUndefined();
|
||||
expect(validate(attributeMap, { list: { endsWith: ['HI'] } }, [options])).toBeUndefined();
|
||||
expect(
|
||||
validate(attributeMap, { list: { endsWith: ['bc', 'dog', 'ted'] } }, [options])
|
||||
).toBeUndefined();
|
||||
expect(
|
||||
validate(attributeMap, { str: { endsWith: { value: 'ted' } } }, [
|
||||
options,
|
||||
])
|
||||
).toBeUndefined();
|
||||
expect(
|
||||
validate(attributeMap, { str: { endsWith: ['ted'] } }, [options])
|
||||
).toBeUndefined();
|
||||
expect(
|
||||
validate(attributeMap, { str: { endsWith: ['Att'] } }, [options])
|
||||
).not.toBeUndefined();
|
||||
expect(
|
||||
validate(attributeMap, { str: { endsWith: ['cat', 'dog', 'ted'] } }, [
|
||||
options,
|
||||
])
|
||||
).toBeUndefined();
|
||||
expect(
|
||||
validate(attributeMap, { list: { endsWith: ['HI'] } }, [options])
|
||||
).toBeUndefined();
|
||||
expect(
|
||||
validate(attributeMap, { list: { endsWith: ['bc', 'dog', 'ted'] } }, [
|
||||
options,
|
||||
])
|
||||
).toBeUndefined();
|
||||
expect(
|
||||
validate(attributeMap, { list: { endsWith: ['bye', 'dog'] } }, [
|
||||
options,
|
||||
])
|
||||
validate(attributeMap, { list: { endsWith: ['bye', 'dog'] } }, [options])
|
||||
).not.toBeUndefined();
|
||||
});
|
||||
});
|
||||
@@ -488,83 +312,47 @@ describe('validator', () => {
|
||||
describe('greaterThan', () => {
|
||||
it('returns undefined on greaterThan', () => {
|
||||
expect(
|
||||
validate(
|
||||
attributeMap,
|
||||
{ num: { greaterThan: { value: attributeMap.num - 1 } } },
|
||||
[options]
|
||||
)
|
||||
validate(attributeMap, { num: { greaterThan: { value: attributeMap.num - 1 } } }, [options])
|
||||
).toBeUndefined();
|
||||
expect(
|
||||
validate(attributeMap, { num: { greaterThan: attributeMap.num - 1 } }, [
|
||||
options,
|
||||
])
|
||||
validate(attributeMap, { num: { greaterThan: attributeMap.num - 1 } }, [options])
|
||||
).toBeUndefined();
|
||||
expect(
|
||||
validate(
|
||||
attributeMap,
|
||||
{ num: { greaterThan: [attributeMap.num - 1] } },
|
||||
[options]
|
||||
)
|
||||
validate(attributeMap, { num: { greaterThan: [attributeMap.num - 1] } }, [options])
|
||||
).toBeUndefined();
|
||||
expect(
|
||||
validate(
|
||||
attributeMap,
|
||||
{ num: { greaterThan: [attributeMap.num + 1] } },
|
||||
[options]
|
||||
)
|
||||
validate(attributeMap, { num: { greaterThan: [attributeMap.num + 1] } }, [options])
|
||||
).not.toBeUndefined();
|
||||
});
|
||||
});
|
||||
describe('lessThan', () => {
|
||||
it('returns undefined on lessThan', () => {
|
||||
expect(
|
||||
validate(
|
||||
attributeMap,
|
||||
{ num: { lessThan: { value: attributeMap.num + 1 } } },
|
||||
[options]
|
||||
)
|
||||
validate(attributeMap, { num: { lessThan: { value: attributeMap.num + 1 } } }, [options])
|
||||
).toBeUndefined();
|
||||
expect(
|
||||
validate(attributeMap, { num: { lessThan: attributeMap.num + 1 } }, [
|
||||
options,
|
||||
])
|
||||
validate(attributeMap, { num: { lessThan: attributeMap.num + 1 } }, [options])
|
||||
).toBeUndefined();
|
||||
expect(
|
||||
validate(attributeMap, { num: { lessThan: [attributeMap.num + 1] } }, [
|
||||
options,
|
||||
])
|
||||
validate(attributeMap, { num: { lessThan: [attributeMap.num + 1] } }, [options])
|
||||
).toBeUndefined();
|
||||
expect(
|
||||
validate(attributeMap, { num: { lessThan: [attributeMap.num - 1] } }, [
|
||||
options,
|
||||
])
|
||||
validate(attributeMap, { num: { lessThan: [attributeMap.num - 1] } }, [options])
|
||||
).not.toBeUndefined();
|
||||
});
|
||||
});
|
||||
describe('range', () => {
|
||||
it('returns undefined if the value is between', () => {
|
||||
expect(
|
||||
validate(
|
||||
attributeMap,
|
||||
{ num: { range: [attributeMap.num + 1, attributeMap.num - 1] } },
|
||||
[options]
|
||||
)
|
||||
validate(attributeMap, { num: { range: [attributeMap.num + 1, attributeMap.num - 1] } }, [
|
||||
options,
|
||||
])
|
||||
).toBeUndefined();
|
||||
expect(
|
||||
validate(attributeMap, { num: { range: [1, 4] } }, [options])
|
||||
).toBeUndefined();
|
||||
expect(
|
||||
validate(attributeMap, { num: { range: [1, 2] } }, [options])
|
||||
).not.toBeUndefined();
|
||||
expect(
|
||||
validate(attributeMap, { num: { range: [4, 5] } }, [options])
|
||||
).not.toBeUndefined();
|
||||
expect(
|
||||
validate(attributeMap, { num: { range: [5] } }, [options])
|
||||
).not.toBeUndefined();
|
||||
expect(
|
||||
validate(attributeMap, { num: { range: 5 } }, [options])
|
||||
).not.toBeUndefined();
|
||||
expect(validate(attributeMap, { num: { range: [1, 4] } }, [options])).toBeUndefined();
|
||||
expect(validate(attributeMap, { num: { range: [1, 2] } }, [options])).not.toBeUndefined();
|
||||
expect(validate(attributeMap, { num: { range: [4, 5] } }, [options])).not.toBeUndefined();
|
||||
expect(validate(attributeMap, { num: { range: [5] } }, [options])).not.toBeUndefined();
|
||||
expect(validate(attributeMap, { num: { range: 5 } }, [options])).not.toBeUndefined();
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -126,13 +126,7 @@ describe('MeasurementService.js', () => {
|
||||
|
||||
it('throws Error if no matching criteria provided', () => {
|
||||
expect(() => {
|
||||
measurementService.addMapping(
|
||||
source,
|
||||
annotationType,
|
||||
null,
|
||||
toSourceSchema,
|
||||
toMeasurement
|
||||
);
|
||||
measurementService.addMapping(source, annotationType, null, toSourceSchema, toMeasurement);
|
||||
}).toThrow(new Error('Matching criteria not provided.'));
|
||||
});
|
||||
|
||||
@@ -194,34 +188,16 @@ describe('MeasurementService.js', () => {
|
||||
toSourceSchema,
|
||||
toMeasurement
|
||||
);
|
||||
const measurementId = source.annotationToMeasurement(
|
||||
annotationType,
|
||||
annotation
|
||||
);
|
||||
const mappedAnnotation = source.getAnnotation(
|
||||
annotationType,
|
||||
measurementId
|
||||
);
|
||||
const measurementId = source.annotationToMeasurement(annotationType, annotation);
|
||||
const mappedAnnotation = source.getAnnotation(annotationType, measurementId);
|
||||
|
||||
expect(annotation).toBe(mappedAnnotation);
|
||||
});
|
||||
|
||||
it('get annotation based on source and annotationType', () => {
|
||||
measurementService.addMapping(
|
||||
source,
|
||||
annotationType,
|
||||
{},
|
||||
toSourceSchema,
|
||||
toMeasurement
|
||||
);
|
||||
const measurementId = source.annotationToMeasurement(
|
||||
annotationType,
|
||||
annotation
|
||||
);
|
||||
const mappedAnnotation = source.getAnnotation(
|
||||
annotationType,
|
||||
measurementId
|
||||
);
|
||||
measurementService.addMapping(source, annotationType, {}, toSourceSchema, toMeasurement);
|
||||
const measurementId = source.annotationToMeasurement(annotationType, annotation);
|
||||
const mappedAnnotation = source.getAnnotation(annotationType, measurementId);
|
||||
|
||||
expect(annotation).toBe(mappedAnnotation);
|
||||
});
|
||||
@@ -323,9 +299,7 @@ describe('MeasurementService.js', () => {
|
||||
|
||||
/* Add new measurement */
|
||||
source.annotationToMeasurement(annotationType, newMeasurement);
|
||||
const savedMeasurement = measurementService.getMeasurement(
|
||||
newMeasurement.uid
|
||||
);
|
||||
const savedMeasurement = measurementService.getMeasurement(newMeasurement.uid);
|
||||
|
||||
/* Clear dynamic data */
|
||||
delete newMeasurement.modifiedTimestamp;
|
||||
@@ -384,10 +358,7 @@ describe('MeasurementService.js', () => {
|
||||
let addCallbackWasCalled = false;
|
||||
|
||||
/* Subscribe to add event */
|
||||
measurementService.subscribe(
|
||||
MEASUREMENT_ADDED,
|
||||
() => (addCallbackWasCalled = true)
|
||||
);
|
||||
measurementService.subscribe(MEASUREMENT_ADDED, () => (addCallbackWasCalled = true));
|
||||
|
||||
/* Add new measurement - two calls needed for the start and the other for the completed*/
|
||||
const uid = source.annotationToMeasurement(annotationType, measurement);
|
||||
@@ -409,20 +380,13 @@ describe('MeasurementService.js', () => {
|
||||
let updateCallbackWasCalled = false;
|
||||
|
||||
/* Subscribe to update event */
|
||||
measurementService.subscribe(
|
||||
MEASUREMENT_UPDATED,
|
||||
() => (updateCallbackWasCalled = true)
|
||||
);
|
||||
measurementService.subscribe(MEASUREMENT_UPDATED, () => (updateCallbackWasCalled = true));
|
||||
|
||||
/* Create measurement */
|
||||
const uid = source.annotationToMeasurement(annotationType, measurement);
|
||||
|
||||
/* Update measurement */
|
||||
source.annotationToMeasurement(
|
||||
annotationType,
|
||||
{ uid, ...measurement },
|
||||
true
|
||||
);
|
||||
source.annotationToMeasurement(annotationType, { uid, ...measurement }, true);
|
||||
|
||||
expect(updateCallbackWasCalled).toBe(true);
|
||||
});
|
||||
@@ -468,10 +432,7 @@ describe('MeasurementService.js', () => {
|
||||
let addCallbackWasCalled = false;
|
||||
|
||||
/* Subscribe to add event */
|
||||
measurementService.subscribe(
|
||||
MEASUREMENT_ADDED,
|
||||
() => (addCallbackWasCalled = true)
|
||||
);
|
||||
measurementService.subscribe(MEASUREMENT_ADDED, () => (addCallbackWasCalled = true));
|
||||
|
||||
/* Add new measurement - two calls needed for the start and the other for the completed*/
|
||||
// expect exceptions for unmapped measurements
|
||||
@@ -502,10 +463,7 @@ describe('MeasurementService.js', () => {
|
||||
let removeCallbackWasCalled = false;
|
||||
|
||||
/* Subscribe to add event */
|
||||
measurementService.subscribe(
|
||||
MEASUREMENT_REMOVED,
|
||||
() => (removeCallbackWasCalled = true)
|
||||
);
|
||||
measurementService.subscribe(MEASUREMENT_REMOVED, () => (removeCallbackWasCalled = true));
|
||||
|
||||
/* Add new measurement - two calls needed for the start and the other for the completed*/
|
||||
// expect exceptions for unmapped measurements
|
||||
|
||||
@@ -146,9 +146,7 @@ class MeasurementService extends PubSubService {
|
||||
|
||||
// check if valuetype is valid , and if values are strings
|
||||
if (!valueType || typeof valueType !== 'object') {
|
||||
console.warn(
|
||||
`MeasurementService: addValueType: invalid valueType: ${valueType}`
|
||||
);
|
||||
console.warn(`MeasurementService: addValueType: invalid valueType: ${valueType}`);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -178,10 +176,7 @@ class MeasurementService extends PubSubService {
|
||||
return this.measurements.get(measurementUID);
|
||||
}
|
||||
|
||||
public setMeasurementSelected(
|
||||
measurementUID: string,
|
||||
selected: boolean
|
||||
): void {
|
||||
public setMeasurementSelected(measurementUID: string, selected: boolean): void {
|
||||
const measurement = this.getMeasurement(measurementUID);
|
||||
if (!measurement) {
|
||||
return;
|
||||
@@ -230,17 +225,8 @@ class MeasurementService extends PubSubService {
|
||||
version,
|
||||
};
|
||||
|
||||
source.annotationToMeasurement = (
|
||||
annotationType,
|
||||
annotation,
|
||||
isUpdate = false
|
||||
) => {
|
||||
return this.annotationToMeasurement(
|
||||
source,
|
||||
annotationType,
|
||||
annotation,
|
||||
isUpdate
|
||||
);
|
||||
source.annotationToMeasurement = (annotationType, annotation, isUpdate = false) => {
|
||||
return this.annotationToMeasurement(source, annotationType, annotation, isUpdate);
|
||||
};
|
||||
|
||||
source.remove = (measurementUID, eventDetails) => {
|
||||
@@ -281,13 +267,7 @@ class MeasurementService extends PubSubService {
|
||||
* @param {Function} toMeasurementSchema Mapping function to measurement schema
|
||||
* @return void
|
||||
*/
|
||||
addMapping(
|
||||
source,
|
||||
annotationType,
|
||||
matchingCriteria,
|
||||
toAnnotationSchema,
|
||||
toMeasurementSchema
|
||||
) {
|
||||
addMapping(source, annotationType, matchingCriteria, toAnnotationSchema, toMeasurementSchema) {
|
||||
if (!this._isValidSource(source)) {
|
||||
throw new Error('Invalid source.');
|
||||
}
|
||||
@@ -321,11 +301,7 @@ class MeasurementService extends PubSubService {
|
||||
this.mappings[source.uid] = [mapping];
|
||||
}
|
||||
|
||||
log.info(
|
||||
`New measurement mapping added to source '${this._getSourceToString(
|
||||
source
|
||||
)}'.`
|
||||
);
|
||||
log.info(`New measurement mapping added to source '${this._getSourceToString(source)}'.`);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -348,20 +324,13 @@ class MeasurementService extends PubSubService {
|
||||
}
|
||||
|
||||
const measurement = this.getMeasurement(measurementUID);
|
||||
const mapping = this._getMappingByMeasurementSource(
|
||||
measurement,
|
||||
annotationType
|
||||
);
|
||||
const mapping = this._getMappingByMeasurementSource(measurement, annotationType);
|
||||
|
||||
if (mapping) {
|
||||
return mapping.toAnnotationSchema(measurement, annotationType);
|
||||
}
|
||||
|
||||
const matchingMapping = this._getMatchingMapping(
|
||||
source,
|
||||
annotationType,
|
||||
measurement
|
||||
);
|
||||
const matchingMapping = this._getMatchingMapping(source, annotationType, measurement);
|
||||
|
||||
if (matchingMapping) {
|
||||
log.info('Matching mapping found:', matchingMapping);
|
||||
@@ -380,10 +349,7 @@ class MeasurementService extends PubSubService {
|
||||
modifiedTimestamp: Math.floor(Date.now() / 1000),
|
||||
};
|
||||
|
||||
log.info(
|
||||
`Updating internal measurement representation...`,
|
||||
updatedMeasurement
|
||||
);
|
||||
log.info(`Updating internal measurement representation...`, updatedMeasurement);
|
||||
|
||||
this.measurements.set(measurementUID, updatedMeasurement);
|
||||
|
||||
@@ -405,13 +371,7 @@ class MeasurementService extends PubSubService {
|
||||
* @param {object} data The data you wish to add to the source.
|
||||
* @param {function} toMeasurementSchema A function to get the `data` into the same shape as the source annotationType.
|
||||
*/
|
||||
addRawMeasurement(
|
||||
source,
|
||||
annotationType,
|
||||
data,
|
||||
toMeasurementSchema,
|
||||
dataSource = {}
|
||||
) {
|
||||
addRawMeasurement(source, annotationType, data, toMeasurementSchema, dataSource = {}) {
|
||||
if (!this._isValidSource(source)) {
|
||||
log.warn('Invalid source. Exiting early.');
|
||||
return;
|
||||
@@ -425,9 +385,7 @@ class MeasurementService extends PubSubService {
|
||||
}
|
||||
|
||||
if (!this._sourceHasMappings(source)) {
|
||||
log.warn(
|
||||
`No measurement mappings found for '${sourceInfo}' source. Exiting early.`
|
||||
);
|
||||
log.warn(`No measurement mappings found for '${sourceInfo}' source. Exiting early.`);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -496,12 +454,7 @@ class MeasurementService extends PubSubService {
|
||||
* @param {boolean} isUpdate is this an update or an add/completed instead?
|
||||
* @return {string} A measurement uid
|
||||
*/
|
||||
annotationToMeasurement(
|
||||
source,
|
||||
annotationType,
|
||||
sourceAnnotationDetail,
|
||||
isUpdate = false
|
||||
) {
|
||||
annotationToMeasurement(source, annotationType, sourceAnnotationDetail, isUpdate = false) {
|
||||
if (!this._isValidSource(source)) {
|
||||
throw new Error('Invalid source.');
|
||||
}
|
||||
@@ -512,9 +465,7 @@ class MeasurementService extends PubSubService {
|
||||
const sourceInfo = this._getSourceToString(source);
|
||||
|
||||
if (!this._sourceHasMappings(source)) {
|
||||
throw new Error(
|
||||
`No measurement mappings found for '${sourceInfo}' source. Exiting early.`
|
||||
);
|
||||
throw new Error(`No measurement mappings found for '${sourceInfo}' source. Exiting early.`);
|
||||
}
|
||||
|
||||
let measurement = {};
|
||||
@@ -599,8 +550,7 @@ class MeasurementService extends PubSubService {
|
||||
remove(measurementUID, source, eventDetails) {
|
||||
if (
|
||||
!measurementUID ||
|
||||
(!this.measurements.has(measurementUID) &&
|
||||
!this.unmappedMeasurements.has(measurementUID))
|
||||
(!this.measurements.has(measurementUID) && !this.unmappedMeasurements.has(measurementUID))
|
||||
) {
|
||||
log.warn(`No uid provided, or unable to find measurement by uid.`);
|
||||
return;
|
||||
@@ -679,9 +629,7 @@ class MeasurementService extends PubSubService {
|
||||
|
||||
_getMappingByMeasurementSource(measurement, annotationType) {
|
||||
if (this._isValidSource(measurement.source)) {
|
||||
return this.mappings[measurement.source.uid].find(
|
||||
m => m.annotationType === annotationType
|
||||
);
|
||||
return this.mappings[measurement.source.uid].find(m => m.annotationType === annotationType);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -702,10 +650,7 @@ class MeasurementService extends PubSubService {
|
||||
|
||||
/* Criteria Matching */
|
||||
return sourceMappingsByDefinition.find(({ matchingCriteria }) => {
|
||||
return (
|
||||
measurement.points &&
|
||||
measurement.points.length === matchingCriteria.points
|
||||
);
|
||||
return measurement.points && measurement.points.length === matchingCriteria.points;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -736,10 +681,7 @@ class MeasurementService extends PubSubService {
|
||||
* @return {boolean} Validation if source has mappings
|
||||
*/
|
||||
_sourceHasMappings(source) {
|
||||
return (
|
||||
Array.isArray(this.mappings[source.uid]) &&
|
||||
this.mappings[source.uid].length
|
||||
);
|
||||
return Array.isArray(this.mappings[source.uid]) && this.mappings[source.uid].length;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -38,9 +38,7 @@ describe('ServicesManager', () => {
|
||||
[{ name: 'UIModalTestService', create: jest.fn() }, fakeConfiguration],
|
||||
]);
|
||||
|
||||
expect(servicesManager.registerService.mock.calls[1][1]).toEqual(
|
||||
fakeConfiguration
|
||||
);
|
||||
expect(servicesManager.registerService.mock.calls[1][1]).toEqual(fakeConfiguration);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -78,9 +76,7 @@ describe('ServicesManager', () => {
|
||||
it('tracks which services have been registered', () => {
|
||||
servicesManager.registerService(fakeService);
|
||||
|
||||
expect(servicesManager.registeredServiceNames).toContain(
|
||||
fakeService.name
|
||||
);
|
||||
expect(servicesManager.registeredServiceNames).toContain(fakeService.name);
|
||||
});
|
||||
|
||||
it('logs a warning if the service has an name that has already been registered', () => {
|
||||
@@ -95,9 +91,7 @@ describe('ServicesManager', () => {
|
||||
|
||||
servicesManager.registerService(fakeService, configuration);
|
||||
|
||||
expect(fakeService.create.mock.calls[0][0].configuration.config).toBe(
|
||||
configuration.config
|
||||
);
|
||||
expect(fakeService.create.mock.calls[0][0].configuration.config).toBe(configuration.config);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -19,9 +19,7 @@ export default class ServicesManager {
|
||||
*/
|
||||
registerService(service, configuration = {}) {
|
||||
if (!service) {
|
||||
log.warn(
|
||||
'Attempting to register a null/undefined service. Exiting early.'
|
||||
);
|
||||
log.warn('Attempting to register a null/undefined service. Exiting early.');
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -90,11 +90,9 @@ export default class ToolbarService extends PubSubService {
|
||||
}
|
||||
case 'tool': {
|
||||
try {
|
||||
commands.forEach(
|
||||
({ commandName = 'setToolActive', commandOptions, context }) => {
|
||||
commandsManager.runCommand(commandName, commandOptions, context);
|
||||
}
|
||||
);
|
||||
commands.forEach(({ commandName = 'setToolActive', commandOptions, context }) => {
|
||||
commandsManager.runCommand(commandName, commandOptions, context);
|
||||
});
|
||||
|
||||
// only set the primary tool if no error was thrown
|
||||
this.state.primaryToolId = itemId;
|
||||
@@ -110,9 +108,7 @@ export default class ToolbarService extends PubSubService {
|
||||
|
||||
// only toggle if a command was executed
|
||||
this.state.toggles[itemId] =
|
||||
this.state.toggles[itemId] === undefined
|
||||
? true
|
||||
: !this.state.toggles[itemId];
|
||||
this.state.toggles[itemId] === undefined ? true : !this.state.toggles[itemId];
|
||||
|
||||
if (!commands) {
|
||||
break;
|
||||
@@ -213,14 +209,9 @@ export default class ToolbarService extends PubSubService {
|
||||
|
||||
_buttonTypes() {
|
||||
const buttonTypes = {};
|
||||
const registeredToolbarModules = this.extensionManager.modules[
|
||||
'toolbarModule'
|
||||
];
|
||||
const registeredToolbarModules = this.extensionManager.modules['toolbarModule'];
|
||||
|
||||
if (
|
||||
Array.isArray(registeredToolbarModules) &&
|
||||
registeredToolbarModules.length
|
||||
) {
|
||||
if (Array.isArray(registeredToolbarModules) && registeredToolbarModules.length) {
|
||||
registeredToolbarModules.forEach(toolbarModule =>
|
||||
toolbarModule.module.forEach(def => {
|
||||
buttonTypes[def.name] = def;
|
||||
@@ -302,8 +293,6 @@ export default class ToolbarService extends PubSubService {
|
||||
}
|
||||
|
||||
getButtonComponentForUIType(uiType: string) {
|
||||
return uiType
|
||||
? this._buttonTypes()[uiType]?.defaultComponent ?? null
|
||||
: null;
|
||||
return uiType ? this._buttonTypes()[uiType]?.defaultComponent ?? null : null;
|
||||
}
|
||||
}
|
||||
@@ -71,10 +71,7 @@ class UIModalService {
|
||||
* show: showImplementation,
|
||||
* }
|
||||
*/
|
||||
setServiceImplementation({
|
||||
hide: hideImplementation,
|
||||
show: showImplementation,
|
||||
}) {
|
||||
setServiceImplementation({ hide: hideImplementation, show: showImplementation }) {
|
||||
if (hideImplementation) {
|
||||
serviceImplementation._hide = hideImplementation;
|
||||
}
|
||||
|
||||
@@ -38,10 +38,7 @@ class UINotificationService {
|
||||
* show: showImplementation,
|
||||
* }
|
||||
*/
|
||||
public setServiceImplementation({
|
||||
hide: hideImplementation,
|
||||
show: showImplementation,
|
||||
}): void {
|
||||
public setServiceImplementation({ hide: hideImplementation, show: showImplementation }): void {
|
||||
if (hideImplementation) {
|
||||
serviceImplementation._hide = hideImplementation;
|
||||
}
|
||||
|
||||
@@ -26,15 +26,7 @@ const serviceImplementation = {
|
||||
*
|
||||
* @param {ViewportDialogProps} props { content, contentProps, viewportId }
|
||||
*/
|
||||
function _show({
|
||||
viewportId,
|
||||
id,
|
||||
type,
|
||||
message,
|
||||
actions,
|
||||
onSubmit,
|
||||
onOutsideClick,
|
||||
}) {
|
||||
function _show({ viewportId, id, type, message, actions, onSubmit, onOutsideClick }) {
|
||||
return serviceImplementation._show({
|
||||
viewportId,
|
||||
id,
|
||||
@@ -62,10 +54,7 @@ function _hide() {
|
||||
* viewportId,
|
||||
* }
|
||||
*/
|
||||
function setServiceImplementation({
|
||||
hide: hideImplementation,
|
||||
show: showImplementation,
|
||||
}) {
|
||||
function setServiceImplementation({ hide: hideImplementation, show: showImplementation }) {
|
||||
if (hideImplementation) {
|
||||
serviceImplementation._hide = hideImplementation;
|
||||
}
|
||||
|
||||
@@ -18,8 +18,7 @@ const serviceImplementation = {
|
||||
_getUser: () => console.warn('_setUser() NOT IMPLEMENTED'),
|
||||
_getAuthorizationHeader: () => {}, // TODO: have enabled/disabled state?
|
||||
//console.warn('_getAuthorizationHeader() NOT IMPLEMENTED'),
|
||||
_handleUnauthenticated: () =>
|
||||
console.warn('_handleUnauthenticated() NOT IMPLEMENTED'),
|
||||
_handleUnauthenticated: () => console.warn('_handleUnauthenticated() NOT IMPLEMENTED'),
|
||||
_reset: () => console.warn('reset() NOT IMPLEMENTED'),
|
||||
_set: () => console.warn('set() NOT IMPLEMENTED'),
|
||||
};
|
||||
|
||||
@@ -39,8 +39,7 @@ class ViewportGridService extends PubSubService {
|
||||
this.serviceImplementation._getState = getStateImplementation;
|
||||
}
|
||||
if (setActiveViewportIdImplementation) {
|
||||
this.serviceImplementation._setActiveViewport =
|
||||
setActiveViewportIdImplementation;
|
||||
this.serviceImplementation._setActiveViewport = setActiveViewportIdImplementation;
|
||||
}
|
||||
if (setDisplaySetsForViewportsImplementation) {
|
||||
this.serviceImplementation._setDisplaySetsForViewports =
|
||||
@@ -59,8 +58,7 @@ class ViewportGridService extends PubSubService {
|
||||
this.serviceImplementation._set = setImplementation;
|
||||
}
|
||||
if (getNumViewportPanesImplementation) {
|
||||
this.serviceImplementation._getNumViewportPanes =
|
||||
getNumViewportPanesImplementation;
|
||||
this.serviceImplementation._getNumViewportPanes = getNumViewportPanesImplementation;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,10 +89,7 @@ class ViewportGridService extends PubSubService {
|
||||
if (updatedViewport) {
|
||||
viewports.push(updatedViewport);
|
||||
} else {
|
||||
console.warn(
|
||||
"ViewportGridService::Didn't find updated viewport",
|
||||
viewport
|
||||
);
|
||||
console.warn("ViewportGridService::Didn't find updated viewport", viewport);
|
||||
}
|
||||
}
|
||||
this._broadcastEvent(ViewportGridService.EVENTS.GRID_STATE_CHANGED, {
|
||||
@@ -158,7 +153,9 @@ class ViewportGridService extends PubSubService {
|
||||
return this.serviceImplementation._getNumViewportPanes();
|
||||
}
|
||||
|
||||
public getLayoutOptionsFromState(state: any): { x: number; y: number; width: number; height: number }[] {
|
||||
public getLayoutOptionsFromState(
|
||||
state: any
|
||||
): { x: number; y: number; width: number; height: number }[] {
|
||||
return Array.from(state.viewports.entries()).map(([_, viewport]) => {
|
||||
return {
|
||||
x: viewport.x,
|
||||
|
||||
@@ -102,11 +102,7 @@ const getPresentationIds = (viewport, viewports): PresentationIds => {
|
||||
if (!viewport) {
|
||||
return;
|
||||
}
|
||||
const {
|
||||
viewportOptions,
|
||||
displaySetInstanceUIDs,
|
||||
displaySetOptions,
|
||||
} = viewport;
|
||||
const { viewportOptions, displaySetInstanceUIDs, displaySetOptions } = viewport;
|
||||
if (!viewportOptions || !displaySetInstanceUIDs?.length) {
|
||||
return;
|
||||
}
|
||||
@@ -128,8 +124,7 @@ const getPresentationIds = (viewport, viewports): PresentationIds => {
|
||||
// only add unique index if the viewport is getting inserted and not updated
|
||||
const isUpdatingSameViewport = Array.from(viewports.values()).some(v => {
|
||||
return (
|
||||
v.displaySetInstanceUIDs.toString() ===
|
||||
viewport.displaySetInstanceUIDs.toString() &&
|
||||
v.displaySetInstanceUIDs.toString() === viewport.displaySetInstanceUIDs.toString() &&
|
||||
v.viewportId === viewport.viewportId
|
||||
);
|
||||
});
|
||||
@@ -143,12 +138,7 @@ const getPresentationIds = (viewport, viewports): PresentationIds => {
|
||||
viewports,
|
||||
isUpdatingSameViewport
|
||||
);
|
||||
addUniqueIndex(
|
||||
lutPresentationArr,
|
||||
'lutPresentationId',
|
||||
viewports,
|
||||
isUpdatingSameViewport
|
||||
);
|
||||
addUniqueIndex(lutPresentationArr, 'lutPresentationId', viewports, isUpdatingSameViewport);
|
||||
|
||||
const lutPresentationId = lutPresentationArr.join(JOIN_STR);
|
||||
const positionPresentationId = positionPresentationArr.join(JOIN_STR);
|
||||
|
||||
+1
-1
@@ -117,6 +117,6 @@ export class PubSubService {
|
||||
consume: function Consume() {
|
||||
this.isConsumed = true;
|
||||
},
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -10,9 +10,7 @@ import ToolbarService from './ToolBarService';
|
||||
import ViewportGridService from './ViewportGridService';
|
||||
import CineService from './CineService';
|
||||
import HangingProtocolService from './HangingProtocolService';
|
||||
import pubSubServiceInterface, {
|
||||
PubSubService,
|
||||
} from './_shared/pubSubServiceInterface';
|
||||
import pubSubServiceInterface, { PubSubService } from './_shared/pubSubServiceInterface';
|
||||
import UserAuthenticationService from './UserAuthenticationService';
|
||||
import CustomizationService from './CustomizationService';
|
||||
|
||||
|
||||
Reference in new issue
Block a user