chore(prettier): full repo linting and code reformatting once and for all (#3627)

This commit is contained in:
Alireza authored and GitHub committed 2023-09-01 16:19:39 -04:00
1 parent 01500a2d4c
commit 9045ddaedc
656 files changed
+21737 -20628

No files matched your search

+10 -32
View File
@@ -1,7 +1,5 @@
{
"files": [
"README.md"
],
"files": ["README.md"],
"imageSize": 100,
"commit": false,
"contributors": [
@@ -10,83 +8,63 @@
"name": "Erik Ziegler",
"avatar_url": "https://avatars3.githubusercontent.com/u/607793?v=4",
"profile": "https://github.com/swederik",
"contributions": [
"code"
]
"contributions": ["code"]
},
{
"login": "evren217",
"name": "Evren Ozkan",
"avatar_url": "https://avatars1.githubusercontent.com/u/4920551?v=4",
"profile": "https://github.com/evren217",
"contributions": [
"code"
]
"contributions": ["code"]
},
{
"login": "galelis",
"name": "Gustavo André Lelis",
"avatar_url": "https://avatars3.githubusercontent.com/u/2378326?v=4",
"profile": "https://github.com/galelis",
"contributions": [
"code"
]
"contributions": ["code"]
},
{
"login": "dannyrb",
"name": "Danny Brown",
"avatar_url": "https://avatars1.githubusercontent.com/u/5797588?v=4",
"profile": "http://dannyrb.com/",
"contributions": [
"code"
]
"contributions": ["code"]
},
{
"login": "allcontributors",
"name": "allcontributors[bot]",
"avatar_url": "https://avatars3.githubusercontent.com/u/46843839?v=4",
"profile": "https://github.com/all-contributors/all-contributors-bot",
"contributions": [
"doc"
]
"contributions": ["doc"]
},
{
"login": "ivan-aksamentov",
"name": "Ivan Aksamentov",
"avatar_url": "https://avatars0.githubusercontent.com/u/9403403?v=4",
"profile": "https://github.com/ivan-aksamentov",
"contributions": [
"code",
"test"
]
"contributions": ["code", "test"]
},
{
"login": "igoroctaviano",
"name": "Igor Octaviano",
"avatar_url": "https://avatars0.githubusercontent.com/u/13886933?v=4",
"profile": "http://igoroctaviano.com",
"contributions": [
"code"
]
"contributions": ["code"]
},
{
"login": "dlwire",
"name": "David Wire",
"avatar_url": "https://avatars3.githubusercontent.com/u/1167291?v=4",
"profile": "https://github.com/dlwire",
"contributions": [
"code",
"test"
]
"contributions": ["code", "test"]
},
{
"login": "pavertomato",
"name": "Egor Lezhnin",
"avatar_url": "https://avatars0.githubusercontent.com/u/878990?v=4",
"profile": "http://egor.lezhn.in",
"contributions": [
"code"
]
"contributions": ["code"]
}
],
"contributorsPerLine": 7,
-2
View File
@@ -3,12 +3,10 @@ const webpackCommon = require('./../../../.webpack/webpack.base.js');
const SRC_DIR = path.join(__dirname, '../src');
const DIST_DIR = path.join(__dirname, '../dist');
const ENTRY = {
app: `${SRC_DIR}/index.ts`,
};
module.exports = (env, argv) => {
return webpackCommon(env, argv, { SRC_DIR, DIST_DIR, ENTRY });
};
+1 -6
View File
@@ -36,11 +36,6 @@ module.exports = (env, argv) => {
libraryTarget: 'umd',
filename: pkg.main,
},
externals: [
/\b(vtk.js)/,
/\b(dcmjs)/,
/\b(gl-matrix)/,
/^@cornerstonejs/,
],
externals: [/\b(vtk.js)/, /\b(dcmjs)/, /\b(gl-matrix)/, /^@cornerstonejs/],
});
};
+1 -1
View File
@@ -1 +1 @@
module.exports = require("../../babel.config.js");
module.exports = require('../../babel.config.js');
@@ -26,9 +26,7 @@ describe('getAttribute', () => {
expect(getAttribute(nullElement, defaultValue)).toEqual(defaultValue);
expect(getAttribute(undefinedElement, defaultValue)).toEqual(defaultValue);
expect(getAttribute(noValuePresentElement, defaultValue)).toEqual(
defaultValue
);
expect(getAttribute(noValuePresentElement, defaultValue)).toEqual(defaultValue);
});
it('should return 48 for element with value 0', () => {
@@ -28,9 +28,7 @@ describe('getAuthorizationHeader', () => {
};
const expectedAuthorizationHeader = {
Authorization: `Basic ${btoa(
validServerWithoutPassword.requestOptions.auth
)}`,
Authorization: `Basic ${btoa(validServerWithoutPassword.requestOptions.auth)}`,
};
const authentication = getAuthorizationHeader(validServerWithoutPassword);
@@ -23,9 +23,7 @@ describe('getModalities', () => {
vr: 'MOCKED_VALUE',
};
expect(getModalities(Modality, ModalitiesInStudy)).toEqual(
ModalitiesInStudy
);
expect(getModalities(Modality, ModalitiesInStudy)).toEqual(ModalitiesInStudy);
});
test('should return only the modalitues that exists in ModalitiesInStudy', () => {
@@ -67,8 +65,6 @@ describe('getModalities', () => {
vr: 'ANOTHER_VR',
};
expect(getModalities(Modality, ModalitiesInStudy)).toEqual(
ModalitiesInStudy
);
expect(getModalities(Modality, ModalitiesInStudy)).toEqual(ModalitiesInStudy);
});
});
+1 -6
View File
@@ -32,12 +32,7 @@ describe('getName', () => {
it('should return A for element when Alphabetic is [A, B, C, D]', () => {
const returnValue = 'A';
const element = {
Value: [
{ Alphabetic: 'A' },
{ Alphabetic: 'B' },
{ Alphabetic: 'C' },
{ Alphabetic: 'D' },
],
Value: [{ Alphabetic: 'A' }, { Alphabetic: 'B' }, { Alphabetic: 'C' }, { Alphabetic: 'D' }],
};
expect(getName(element, null)).toEqual(returnValue);
});
+1 -3
View File
@@ -26,9 +26,7 @@ describe('getNumber', () => {
expect(getNumber(nullElement, defaultValue)).toEqual(defaultValue);
expect(getNumber(undefinedElement, defaultValue)).toEqual(defaultValue);
expect(getNumber(noValuePresentElement, defaultValue)).toEqual(
defaultValue
);
expect(getNumber(noValuePresentElement, defaultValue)).toEqual(defaultValue);
});
it('should return 2.0 for element when element.Value[0] = 2', () => {
+1 -3
View File
@@ -26,9 +26,7 @@ describe('getString', () => {
expect(getString(nullElement, defaultValue)).toEqual(defaultValue);
expect(getString(undefinedElement, defaultValue)).toEqual(defaultValue);
expect(getString(noValuePresentElement, defaultValue)).toEqual(
defaultValue
);
expect(getString(noValuePresentElement, defaultValue)).toEqual(defaultValue);
});
it('should return A,B,C,D for element when element.Value[0] = [A, B, C, D]', () => {
+1 -8
View File
@@ -14,13 +14,6 @@ const DICOMWeb = {
getString,
};
export {
getAttribute,
getAuthorizationHeader,
getModalities,
getName,
getNumber,
getString,
};
export { getAttribute, getAuthorizationHeader, getModalities, getName, getNumber, getString };
export default DICOMWeb;
@@ -1,9 +1,9 @@
// import { api } from 'dicomweb-client'
const api = {
DICOMwebClient: jest.fn().mockImplementation(function() {
DICOMwebClient: jest.fn().mockImplementation(function () {
this.retrieveStudyMetadata = jest.fn().mockResolvedValue([]);
this.retrieveSeriesMetadata = jest.fn(function(options) {
this.retrieveSeriesMetadata = jest.fn(function (options) {
const { studyInstanceUID, seriesInstanceUID } = options;
return Promise.resolve([{ studyInstanceUID, seriesInstanceUID }]);
});
@@ -94,10 +94,7 @@ describe('CommandsManager', () => {
describe('getCommand()', () => {
it('returns undefined if context does not exist', () => {
const result = commandsManager.getCommand(
'TestCommand',
'NonExistentContext'
);
const result = commandsManager.getCommand('TestCommand', 'NonExistentContext');
expect(result).toBe(undefined);
});
@@ -131,9 +128,7 @@ describe('CommandsManager', () => {
describe('runCommand()', () => {
it('Logs a warning if commandName not found in context', () => {
const result = commandsManager.runCommand(
'CommandThatDoesNotExistInAnyContext'
);
const result = commandsManager.runCommand('CommandThatDoesNotExistInAnyContext');
expect(result).toBe(undefined);
expect(log.warn.mock.calls[0][0]).toEqual(
@@ -149,16 +144,8 @@ describe('CommandsManager', () => {
};
commandsManager.createContext(contextName);
commandsManager.registerCommand(
contextName,
'TestCommand',
commandWithNoCommmandFn
);
const result = commandsManager.runCommand(
'TestCommand',
null,
contextName
);
commandsManager.registerCommand(contextName, 'TestCommand', commandWithNoCommmandFn);
const result = commandsManager.runCommand('TestCommand', null, contextName);
expect(result).toBe(undefined);
expect(log.warn.mock.calls[0][0]).toEqual(
@@ -192,9 +179,7 @@ describe('CommandsManager', () => {
commandsManager.runCommand('TestCommand', runCommandOptions, 'VIEWER');
expect(command.commandFn.mock.calls.length).toBe(1);
expect(command.commandFn.mock.calls[0][0].test).toEqual(
runCommandOptions.test
);
expect(command.commandFn.mock.calls[0][0].test).toEqual(runCommandOptions.test);
});
it('Returns the result of commandFn', () => {
+14 -17
View File
@@ -181,30 +181,27 @@ export class CommandsManager {
const commands =
(Array.isArray(toRun) && toRun) ||
((toRun as Command).commandName && [toRun]) ||
(Array.isArray((toRun as Commands).commands) &&
(toRun as Commands).commands);
(Array.isArray((toRun as Commands).commands) && (toRun as Commands).commands);
if (!commands) {
console.log("Command isn't runnable", toRun);
return;
}
let result;
(commands as Command[]).forEach(
({ commandName, commandOptions, context }) => {
if (commandName) {
result = this.runCommand(
commandName,
{
...commandOptions,
...options,
},
context
);
} else {
console.warn('No command name supplied in', toRun);
}
(commands as Command[]).forEach(({ commandName, commandOptions, context }) => {
if (commandName) {
result = this.runCommand(
commandName,
{
...commandOptions,
...options,
},
context
);
} else {
console.warn('No command name supplied in', toRun);
}
);
});
return result;
}
@@ -21,11 +21,7 @@ describe('HotkeysManager', () => {
});
it('has expected properties', () => {
const allProperties = Object.keys(hotkeysManager);
const expectedProperties = [
'hotkeyDefinitions',
'hotkeyDefaults',
'isEnabled',
];
const expectedProperties = ['hotkeyDefinitions', 'hotkeyDefaults', 'isEnabled'];
const containsAllExpectedProperties = expectedProperties.every(expected =>
allProperties.includes(expected)
@@ -134,21 +130,16 @@ describe('HotkeysManager', () => {
hotkeysManager.registerHotkeys(definition);
const numOfHotkeyDefinitions = Object.keys(
hotkeysManager.hotkeyDefinitions
).length;
const numOfHotkeyDefinitions = Object.keys(hotkeysManager.hotkeyDefinitions).length;
const commandHash = objectHash({
commandName: definition.commandName,
commandOptions: definition.commandOptions,
});
const hotkeyDefinitionForRegisteredCommand =
hotkeysManager.hotkeyDefinitions[commandHash];
const hotkeyDefinitionForRegisteredCommand = hotkeysManager.hotkeyDefinitions[commandHash];
expect(numOfHotkeyDefinitions).toBe(1);
expect(Object.keys(hotkeysManager.hotkeyDefinitions)[0]).toEqual(
commandHash
);
expect(Object.keys(hotkeysManager.hotkeyDefinitions)[0]).toEqual(commandHash);
expect(hotkeyDefinitionForRegisteredCommand).toEqual(definition);
});
it('calls hotkeys.bind for the group of keys', () => {
@@ -182,9 +173,7 @@ describe('HotkeysManager', () => {
hotkeysManager.restoreDefaultBindings();
expect(hotkeysManager.setHotkeys.mock.calls[0][0]).toEqual(
hotkeysManager.hotkeyDefaults
);
expect(hotkeysManager.setHotkeys.mock.calls[0][0]).toEqual(hotkeysManager.hotkeyDefaults);
});
});
+3 -16
View File
@@ -174,14 +174,7 @@ export class HotkeysManager {
* @returns {undefined}
*/
registerHotkeys(
{
commandName,
commandOptions = {},
context,
keys,
label,
isEditable,
}: Hotkey = {},
{ commandName, commandOptions = {}, context, keys, label, isEditable }: Hotkey = {},
extension
) {
if (!commandName) {
@@ -189,9 +182,7 @@ export class HotkeysManager {
}
const commandHash = objectHash({ commandName, commandOptions });
const options = Object.keys(commandOptions).length
? JSON.stringify(commandOptions)
: 'no';
const options = Object.keys(commandOptions).length ? JSON.stringify(commandOptions) : 'no';
const previouslyRegisteredDefinition = this.hotkeyDefinitions[commandHash];
if (previouslyRegisteredDefinition) {
@@ -255,11 +246,7 @@ export class HotkeysManager {
hotkeys.bind(combinedKeys, evt => {
evt.preventDefault();
evt.stopPropagation();
this._commandsManager.runCommand(
commandName,
{ evt, ...commandOptions },
context
);
this._commandsManager.runCommand(commandName, { evt, ...commandOptions }, context);
});
}
+3 -3
View File
@@ -107,7 +107,7 @@ class ImageSet {
)
);
const distanceImagePairs = images.map(function(image: Image) {
const distanceImagePairs = images.map(function (image: Image) {
const ippVec = new Vector3(..._getImagePositionPatient(image));
const positionVector = refIppVec.clone().sub(ippVec);
const distance = positionVector.dot(scanAxisNormal);
@@ -118,13 +118,13 @@ class ImageSet {
};
});
distanceImagePairs.sort(function(a, b) {
distanceImagePairs.sort(function (a, b) {
return b.distance - a.distance;
});
const sortedImages = distanceImagePairs.map(a => a.image);
images.sort(function(a, b) {
images.sort(function (a, b) {
return sortedImages.indexOf(a) - sortedImages.indexOf(b);
});
}
+11 -40
View File
@@ -58,12 +58,7 @@ class MetadataProvider {
return;
}
const {
StudyInstanceUID,
SeriesInstanceUID,
SOPInstanceUID,
frameNumber,
} = uids;
const { StudyInstanceUID, SeriesInstanceUID, SOPInstanceUID, frameNumber } = uids;
const instance = DicomMetadataStore.getInstance(
StudyInstanceUID,
@@ -75,9 +70,7 @@ class MetadataProvider {
return;
}
return (
(frameNumber && combineFrameInstance(frameNumber, instance)) || instance
);
return (frameNumber && combineFrameInstance(frameNumber, instance)) || instance;
}
get(query, imageId, options = { fallback: false }) {
@@ -107,11 +100,7 @@ class MetadataProvider {
return this.get(INSTANCE, imageId);
}
getTagFromInstance(
naturalizedTagOrWADOImageLoaderTag,
instance,
options = { fallback: false }
) {
getTagFromInstance(naturalizedTagOrWADOImageLoaderTag, instance, options = { fallback: false }) {
if (!instance) {
return;
}
@@ -122,10 +111,7 @@ class MetadataProvider {
}
// Maybe its a legacy dicomImageLoader tag then:
return this._getCornerstoneDICOMImageLoaderTag(
naturalizedTagOrWADOImageLoaderTag,
instance
);
return this._getCornerstoneDICOMImageLoaderTag(naturalizedTagOrWADOImageLoaderTag, instance);
}
_getCornerstoneDICOMImageLoaderTag(wadoImageLoaderTag, instance) {
@@ -198,9 +184,7 @@ class MetadataProvider {
imageOrientationPatient: toNumber(ImageOrientationPatient),
rowCosines: toNumber(rowCosines || [0, 1, 0]),
columnCosines: toNumber(columnCosines || [0, 0, -1]),
imagePositionPatient: toNumber(
instance.ImagePositionPatient || [0, 0, 0]
),
imagePositionPatient: toNumber(instance.ImagePositionPatient || [0, 0, 0]),
sliceThickness: toNumber(instance.SliceThickness),
sliceLocation: toNumber(instance.SliceLocation),
pixelSpacing: toNumber(PixelSpacing || 1),
@@ -254,12 +238,8 @@ class MetadataProvider {
if (WindowCenter === undefined || WindowWidth === undefined) {
return;
}
const windowCenter = Array.isArray(WindowCenter)
? WindowCenter
: [WindowCenter];
const windowWidth = Array.isArray(WindowWidth)
? WindowWidth
: [WindowWidth];
const windowCenter = Array.isArray(WindowCenter) ? WindowCenter : [WindowCenter];
const windowWidth = Array.isArray(WindowWidth) ? WindowWidth : [WindowWidth];
metadata = {
windowCenter: toNumber(windowCenter),
@@ -296,16 +276,11 @@ class MetadataProvider {
? RadiopharmaceuticalInformationSequence[0]
: RadiopharmaceuticalInformationSequence;
const {
RadiopharmaceuticalStartTime,
RadionuclideTotalDose,
RadionuclideHalfLife,
} = RadiopharmaceuticalInformation;
const { RadiopharmaceuticalStartTime, RadionuclideTotalDose, RadionuclideHalfLife } =
RadiopharmaceuticalInformation;
const radiopharmaceuticalInfo = {
radiopharmaceuticalStartTime: dicomParser.parseTM(
RadiopharmaceuticalStartTime
),
radiopharmaceuticalStartTime: dicomParser.parseTM(RadiopharmaceuticalStartTime),
radionuclideTotalDose: RadionuclideTotalDose,
radionuclideHalfLife: RadionuclideHalfLife,
};
@@ -318,11 +293,7 @@ class MetadataProvider {
case WADO_IMAGE_LOADER_TAGS.OVERLAY_PLANE_MODULE:
const overlays = [];
for (
let overlayGroup = 0x00;
overlayGroup <= 0x1e;
overlayGroup += 0x02
) {
for (let overlayGroup = 0x00; overlayGroup <= 0x1e; overlayGroup += 0x02) {
let groupStr = `60${overlayGroup.toString(16)}`;
if (groupStr.length === 3) {
@@ -59,17 +59,11 @@ describe('ExtensionManager.ts', () => {
extensionManager.registerExtension = jest.fn();
// SUT
const fakeExtensions = [
{ one: '1' },
[{ two: '2' }, fakeConfiguration],
{ three: '3 ' },
];
const fakeExtensions = [{ one: '1' }, [{ two: '2' }, fakeConfiguration], { three: '3 ' }];
await extensionManager.registerExtensions(fakeExtensions);
// Assert
expect(extensionManager.registerExtension.mock.calls[1][1]).toEqual(
fakeConfiguration
);
expect(extensionManager.registerExtension.mock.calls[1][1]).toEqual(fakeConfiguration);
});
});
@@ -104,15 +98,11 @@ describe('ExtensionManager.ts', () => {
const undefinedExtension = undefined;
const nullExtension = null;
await expect(
extensionManager.registerExtension(undefinedExtension)
).rejects.toThrow(
await expect(extensionManager.registerExtension(undefinedExtension)).rejects.toThrow(
new Error('Attempting to register a null/undefined extension.')
);
await expect(
extensionManager.registerExtension(nullExtension)
).rejects.toThrow(
await expect(extensionManager.registerExtension(nullExtension)).rejects.toThrow(
new Error('Attempting to register a null/undefined extension.')
);
});
@@ -120,9 +110,9 @@ describe('ExtensionManager.ts', () => {
it('logs a warning if the extension does not have an id', async () => {
const extensionWithoutId = {};
await expect(
extensionManager.registerExtension(extensionWithoutId)
).rejects.toThrow(new Error('Extension ID not set'));
await expect(extensionManager.registerExtension(extensionWithoutId)).rejects.toThrow(
new Error('Extension ID not set')
);
});
it('tracks which extensions have been registered', () => {
@@ -156,9 +146,7 @@ describe('ExtensionManager.ts', () => {
extensionManager.registerExtension(extensionWithBadModule);
expect(log.warn.mock.calls.length).toBe(1);
expect(log.warn.mock.calls[0][0]).toContain(
'Null or undefined returned when registering'
);
expect(log.warn.mock.calls[0][0]).toContain('Null or undefined returned when registering');
});
it('logs an error if an exception is thrown while retrieving a module', async () => {
@@ -169,9 +157,7 @@ describe('ExtensionManager.ts', () => {
},
};
await expect(
extensionManager.registerExtension(extensionWithBadModule)
).rejects.toThrow();
await expect(extensionManager.registerExtension(extensionWithBadModule)).rejects.toThrow();
});
it('successfully passes dependencies to each module along with extension configuration', () => {
@@ -145,12 +145,8 @@ export default class ExtensionManager extends PubSubService {
}
public onModeExit(): void {
const {
registeredExtensionIds,
_servicesManager,
_commandsManager,
_extensionLifeCycleHooks,
} = this;
const { registeredExtensionIds, _servicesManager, _commandsManager, _extensionLifeCycleHooks } =
this;
registeredExtensionIds.forEach(extensionId => {
const onModeExit = _extensionLifeCycleHooks.onModeExit[extensionId];
@@ -181,10 +177,7 @@ export default class ExtensionManager extends PubSubService {
* @param {Object[]} extensions - Array of extensions
*/
public registerExtensions = async (
extensions: (
| ExtensionRegister
| [ExtensionRegister, ExtensionConfiguration]
)[],
extensions: (ExtensionRegister | [ExtensionRegister, ExtensionConfiguration])[],
dataSources: unknown[] = []
): Promise<void> => {
// Todo: we ideally should be able to run registrations in parallel
@@ -203,11 +196,7 @@ export default class ExtensionManager extends PubSubService {
// for (const extension of extensions)
const ohifExtension = extension[0];
const configuration = extension[1];
await this.registerExtension(
ohifExtension,
configuration,
dataSources
);
await this.registerExtension(ohifExtension, configuration, dataSources);
} else {
await this.registerExtension(extension, {}, dataSources);
}
@@ -260,13 +249,11 @@ export default class ExtensionManager extends PubSubService {
}
if (extension.onModeEnter) {
this._extensionLifeCycleHooks.onModeEnter[extensionId] =
extension.onModeEnter;
this._extensionLifeCycleHooks.onModeEnter[extensionId] = extension.onModeEnter;
}
if (extension.onModeExit) {
this._extensionLifeCycleHooks.onModeExit[extensionId] =
extension.onModeExit;
this._extensionLifeCycleHooks.onModeExit[extensionId] = extension.onModeExit;
}
// Register Modules
@@ -284,11 +271,7 @@ export default class ExtensionManager extends PubSubService {
this._initCommandsModule(extensionModule);
break;
case MODULE_TYPES.DATA_SOURCE:
this._initDataSourcesModule(
extensionModule,
extensionId,
dataSources
);
this._initDataSourcesModule(extensionModule, extensionId, dataSources);
break;
case MODULE_TYPES.HANGING_PROTOCOL:
this._initHangingProtocolsModule(extensionModule, extensionId);
@@ -425,10 +408,7 @@ export default class ExtensionManager extends PubSubService {
* @param dataSourceDef the data source definition to be added
* @param activate flag to indicate if the added data source should be set to the active data source
*/
addDataSource(
dataSourceDef: DataSourceDefinition,
options = { activate: false }
) {
addDataSource(dataSourceDef: DataSourceDefinition, options = { activate: false }) {
const existingDataSource = this.getDataSources(dataSourceDef.sourceName);
if (existingDataSource?.[0]) {
// The data source already exists and cannot be added.
@@ -448,10 +428,7 @@ export default class ExtensionManager extends PubSubService {
* @param dataSourceName the name of the data source to update
* @param dataSourceConfiguration the new configuration to update the data source with
*/
updateDataSourceConfiguration(
dataSourceName: string,
dataSourceConfiguration: any
) {
updateDataSourceConfiguration(dataSourceName: string, dataSourceConfiguration: any) {
const existingDataSource = this.getDataSources(dataSourceName);
if (!existingDataSource?.[0]) {
// Cannot update a non existent data source.
@@ -465,10 +442,7 @@ export default class ExtensionManager extends PubSubService {
if (this.activeDataSource === dataSourceName) {
// When the active data source is changed/set, fire an event to indicate that its configuration has changed.
this._broadcastEvent(
ExtensionManager.EVENTS.ACTIVE_DATA_SOURCE_CHANGED,
dataSourceDef
);
this._broadcastEvent(ExtensionManager.EVENTS.ACTIVE_DATA_SOURCE_CHANGED, dataSourceDef);
}
}
@@ -502,9 +476,7 @@ export default class ExtensionManager extends PubSubService {
dataSources: Array<DataSourceDefinition> = []
): void {
extensionModule.forEach(element => {
this.modulesMap[
`${extensionId}.${MODULE_TYPES.DATA_SOURCE}.${element.name}`
] = element;
this.modulesMap[`${extensionId}.${MODULE_TYPES.DATA_SOURCE}.${element.name}`] = element;
});
extensionModule.forEach(element => {
@@ -539,8 +511,7 @@ export default class ExtensionManager extends PubSubService {
Object.keys(definitions).forEach(commandName => {
const commandDefinition = definitions[commandName];
const commandHasContextThatDoesNotExist =
commandDefinition.context &&
!this._commandsManager.getContext(commandDefinition.context);
commandDefinition.context && !this._commandsManager.getContext(commandDefinition.context);
if (commandHasContextThatDoesNotExist) {
this._commandsManager.createContext(commandDefinition.context);
+1 -4
View File
@@ -33,10 +33,7 @@ import {
PanelService,
} from './services';
import {
DisplaySetMessage,
DisplaySetMessageList,
} from './services/DisplaySetService';
import { DisplaySetMessage, DisplaySetMessageList } from './services/DisplaySetService';
import IWebApiDataSource from './DataSources/IWebApiDataSource';
@@ -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);
}
}
@@ -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,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 @@
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);
@@ -117,6 +117,6 @@ export class PubSubService {
consume: function Consume() {
this.isConsumed = true;
},
}
};
}
}
+1 -3
View File
@@ -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';
+1 -4
View File
@@ -1,8 +1,5 @@
function isObject(subject) {
return (
subject instanceof Object ||
(typeof subject === 'object' && subject !== null)
);
return subject instanceof Object || (typeof subject === 'object' && subject !== null);
}
function isString(subject) {
+1 -4
View File
@@ -298,10 +298,7 @@ export type Protocol = {
* to the GUI when this is used, and it can be expensive to apply.
* Alternatives include using the custom attributes where possible.
*/
export type ProtocolGenerator = ({
servicesManager: any,
commandsManager: any,
}) => {
export type ProtocolGenerator = ({ servicesManager: any, commandsManager: any }) => {
protocol: Protocol;
};
+1 -4
View File
@@ -2,10 +2,7 @@ import Consumer from './Consumer';
export default interface IPubSub {
subscribe: (eventName: string, callback: Consumer) => void;
_broadcastEvent: (
eventName: string,
callbackProps: Record<string, unknown>
) => void;
_broadcastEvent: (eventName: string, callbackProps: Record<string, unknown>) => void;
_unsubscribe: (eventName: string, listenerId: string) => void;
_isValidEvent: (eventName: string) => boolean;
}
+4 -9
View File
@@ -1,4 +1,4 @@
import { PubSubService } from "../services";
import { PubSubService } from '../services';
type Panel = {
id?: string;
@@ -11,8 +11,8 @@ type Panel = {
type ActivatePanelTriggers = {
sourcePubSubService: PubSubService;
sourceEvents: string[]
}
sourceEvents: string[];
};
interface PanelEvent {
panelId: string;
@@ -22,9 +22,4 @@ interface ActivatePanelEvent extends PanelEvent {
forceActive: boolean;
}
export type {
ActivatePanelEvent,
ActivatePanelTriggers,
Panel,
PanelEvent,
};
export type { ActivatePanelEvent, ActivatePanelTriggers, Panel, PanelEvent };
+1 -3
View File
@@ -13,9 +13,7 @@ describe('absoluteUrl', () => {
writable: true,
});
const absoluteUrlOutput = absoluteUrl('/path_3/path_to_destination');
expect(absoluteUrlOutput).toEqual(
'/path_1/path_2/path_3/path_to_destination'
);
expect(absoluteUrlOutput).toEqual('/path_1/path_2/path_3/path_to_destination');
});
test('should return / when the path is not defined', () => {
+11 -21
View File
@@ -9,24 +9,21 @@
* single frame data. (eg frame is undefined is the same as frame===1).
*/
const combineFrameInstance = (frame, instance) => {
const {
PerFrameFunctionalGroupsSequence,
SharedFunctionalGroupsSequence,
NumberOfFrames,
} = instance;
const { PerFrameFunctionalGroupsSequence, SharedFunctionalGroupsSequence, NumberOfFrames } =
instance;
if (PerFrameFunctionalGroupsSequence || NumberOfFrames > 1) {
const frameNumber = Number.parseInt(frame || 1);
const shared = (SharedFunctionalGroupsSequence
? Object.values(SharedFunctionalGroupsSequence[0])
: []
const shared = (
SharedFunctionalGroupsSequence ? Object.values(SharedFunctionalGroupsSequence[0]) : []
)
.filter(it => !!it)
.map(it => it[0])
.filter(it => it !== undefined && typeof it === 'object');
const perFrame = (PerFrameFunctionalGroupsSequence
? Object.values(PerFrameFunctionalGroupsSequence[frameNumber - 1])
: []
const perFrame = (
PerFrameFunctionalGroupsSequence
? Object.values(PerFrameFunctionalGroupsSequence[frameNumber - 1])
: []
)
.filter(it => !!it)
.map(it => it[0])
@@ -34,19 +31,12 @@ const combineFrameInstance = (frame, instance) => {
// this is to fix NM multiframe datasets with position and orientation
// information inside DetectorInformationSequence
if (
!instance.ImageOrientationPatient &&
instance.DetectorInformationSequence
) {
if (!instance.ImageOrientationPatient && instance.DetectorInformationSequence) {
instance.ImageOrientationPatient =
instance.DetectorInformationSequence[0].ImageOrientationPatient;
}
if (
!instance.ImagePositionPatient &&
instance.DetectorInformationSequence
) {
instance.ImagePositionPatient =
instance.DetectorInformationSequence[0].ImagePositionPatient;
if (!instance.ImagePositionPatient && instance.DetectorInformationSequence) {
instance.ImagePositionPatient = instance.DetectorInformationSequence[0].ImagePositionPatient;
}
const newInstance = Object.assign(instance, { frameNumber: frameNumber });
+2 -2
View File
@@ -4,10 +4,10 @@
// leading edge, instead of the trailing.
function debounce(func, wait, immediate) {
var timeout;
return function() {
return function () {
var context = this,
args = arguments;
var later = function() {
var later = function () {
timeout = null;
if (!immediate) {
func.apply(context, args);
+3 -13
View File
@@ -17,22 +17,14 @@ export default function downloadCSVReport(measurementData) {
const reportMap = {};
measurementData.forEach(measurement => {
const {
referenceStudyUID,
referenceSeriesUID,
getReport,
uid,
} = measurement;
const { referenceStudyUID, referenceSeriesUID, getReport, uid } = measurement;
if (!getReport) {
console.warn('Measurement does not have a getReport function');
return;
}
const seriesMetadata = DicomMetadataStore.getSeries(
referenceStudyUID,
referenceSeriesUID
);
const seriesMetadata = DicomMetadataStore.getSeries(referenceStudyUID, referenceSeriesUID);
const commonRowItems = _getCommonRowItems(measurement, seriesMetadata);
const report = getReport(measurement);
@@ -57,9 +49,7 @@ export default function downloadCSVReport(measurementData) {
const results = _mapReportsToRowArray(reportMap, columns);
let csvContent =
'data:text/csv;charset=utf-8,' +
results.map(res => res.join(',')).join('\n');
let csvContent = 'data:text/csv;charset=utf-8,' + results.map(res => res.join(',')).join('\n');
_createAndDownloadFile(csvContent);
}
@@ -25,8 +25,7 @@ const generateAcceptHeader = (
return quotedParam;
}
if (mime.startsWith('transfer-syntax=')) {
const quotedParam =
'transfer-syntax="' + mime.substring(16, mime.length) + '"';
const quotedParam = 'transfer-syntax="' + mime.substring(16, mime.length) + '"';
return quotedParam;
} else {
return mime;
+1 -5
View File
@@ -38,11 +38,7 @@ export default function getImageId(instance, frame, thumbnail = false) {
const renderingAttr = thumbnail ? 'thumbnailRendering' : 'imageRendering';
if (
!instance[renderingAttr] ||
instance[renderingAttr] === 'wadouri' ||
!instance.wadorsuri
) {
if (!instance[renderingAttr] || instance[renderingAttr] === 'wadouri' || !instance.wadorsuri) {
let imageId = 'dicomweb:' + instance.wadouri;
if (frame !== undefined) {
imageId += '&frame=' + frame;
@@ -103,7 +103,7 @@ function print(list) {
let text = '';
if (Array.isArray(list)) {
let prev = [];
forEachValue(list, function(...args) {
forEachValue(list, function (...args) {
let prevLen = prev.length;
for (let i = 0, l = args.length; i < l; ++i) {
if (i < prevLen && args[i] === prev[i]) {
@@ -1,9 +1,9 @@
import { addToList, forEach, getItem, print } from './hierarchicalListUtils';
describe('hierarchicalListUtils', function() {
describe('hierarchicalListUtils', function () {
let sharedList;
beforeEach(function() {
beforeEach(function () {
sharedList = [
['1.2.3.1', ['1.2.3.1.1', '1.2.3.1.2']],
'1.2.3.2',
@@ -11,14 +11,14 @@ describe('hierarchicalListUtils', function() {
];
});
describe('getItem', function() {
it('should retrieve elements from a list by index', function() {
describe('getItem', function () {
it('should retrieve elements from a list by index', function () {
expect(getItem(sharedList, 0)).toBe('1.2.3.1');
expect(getItem(sharedList, 1)).toBe('1.2.3.2');
expect(getItem(sharedList, 2)).toBe('1.2.3.3');
expect(getItem(sharedList, 3)).toBeUndefined();
});
it('should retrieve elements from a list by path', function() {
it('should retrieve elements from a list by path', function () {
expect(getItem(sharedList, '0')).toBe('1.2.3.1');
expect(getItem(sharedList, '0/0')).toBe('1.2.3.1.1');
expect(getItem(sharedList, '0/1')).toBe('1.2.3.1.2');
@@ -35,8 +35,8 @@ describe('hierarchicalListUtils', function() {
});
});
describe('addToList', function() {
it('should support adding elements to a list hierarchically', function() {
describe('addToList', function () {
it('should support adding elements to a list hierarchically', function () {
const list = [];
addToList(list, '1.2.3.1', '1.2.3.1.1');
addToList(list, '1.2.3.1', '1.2.3.1.2');
@@ -46,7 +46,7 @@ describe('hierarchicalListUtils', function() {
addToList(list, '1.2.3.3', '1.2.3.3.2', '1.2.3.3.2.2');
expect(list).toStrictEqual(sharedList);
});
it('should change leaf nodes into non-leaf nodes', function() {
it('should change leaf nodes into non-leaf nodes', function () {
const listw = [];
const listx = [['x.1', ['x.1.1', 'x.1.2']], 'x.2'];
const listy = [
@@ -64,8 +64,8 @@ describe('hierarchicalListUtils', function() {
});
});
describe('forEach', function() {
it('should iterate through all leaf nodes of the tree', function() {
describe('forEach', function () {
it('should iterate through all leaf nodes of the tree', function () {
const fn = jest.fn();
forEach(sharedList, fn);
expect(fn).toHaveBeenCalledTimes(6);
@@ -78,8 +78,8 @@ describe('hierarchicalListUtils', function() {
});
});
describe('print', function() {
it('should pretty-print the hierarchical list', function() {
describe('print', function () {
it('should pretty-print the hierarchical list', function () {
expect(print(sharedList)).toBe(
'1.2.3.1\n' +
' 1.2.3.1.1\n' +
@@ -8,7 +8,7 @@
export default function pausePlugin(Mousetrap) {
var _originalStopCallback = Mousetrap.prototype.stopCallback;
Mousetrap.prototype.stopCallback = function(e, element, combo) {
Mousetrap.prototype.stopCallback = function (e, element, combo) {
var self = this;
if (self.paused) {
@@ -18,12 +18,12 @@ export default function pausePlugin(Mousetrap) {
return _originalStopCallback.call(self, e, element, combo);
};
Mousetrap.prototype.pause = function() {
Mousetrap.prototype.pause = function () {
var self = this;
self.paused = true;
};
Mousetrap.prototype.unpause = function() {
Mousetrap.prototype.unpause = function () {
var self = this;
self.paused = false;
};
@@ -122,7 +122,7 @@ export default function recordPlugin(Mousetrap, options = { timeout: 100 }) {
*/
function _normalizeSequence(sequence) {
for (let i = 0; i < sequence.length; ++i) {
sequence[i].sort(function(x, y) {
sequence[i].sort(function (x, y) {
// modifier keys always come first, in alphabetical order
if (x.length > 1 && y.length === 1) {
return -1;
@@ -177,10 +177,10 @@ export default function recordPlugin(Mousetrap, options = { timeout: 100 }) {
* @param {Function} callback
* @returns void
*/
Mousetrap.prototype.record = function(callback) {
Mousetrap.prototype.record = function (callback) {
var self = this;
self.recording = true;
_recordedSequenceCallback = function() {
_recordedSequenceCallback = function () {
self.recording = false;
callback.apply(self, arguments);
};
@@ -192,7 +192,7 @@ export default function recordPlugin(Mousetrap, options = { timeout: 100 }) {
* @param {Function} callback
* @returns void
*/
Mousetrap.prototype.stopRecord = function() {
Mousetrap.prototype.stopRecord = function () {
var self = this;
self.recording = false;
};
@@ -203,11 +203,11 @@ export default function recordPlugin(Mousetrap, options = { timeout: 100 }) {
* @param {Function} callback
* @returns void
*/
Mousetrap.prototype.startRecording = function() {
Mousetrap.prototype.startRecording = function () {
var self = this;
self.recording = true;
};
Mousetrap.prototype.handleKey = function() {
Mousetrap.prototype.handleKey = function () {
var self = this;
_handleKey.apply(self, arguments);
};
+3 -3
View File
@@ -1,13 +1,13 @@
import isDicomUid from './isDicomUid';
describe('isDicomUid', function() {
it('should return true for valid DICOM UIDs', function() {
describe('isDicomUid', function () {
it('should return true for valid DICOM UIDs', function () {
expect(isDicomUid('1')).toBe(true);
expect(isDicomUid('1.2')).toBe(true);
expect(isDicomUid('1.2.3')).toBe(true);
expect(isDicomUid('1.2.3.4')).toBe(true);
});
it('should return false for invalid DICOM UIDs', function() {
it('should return false for invalid DICOM UIDs', function () {
expect(isDicomUid('x')).toBe(false);
expect(isDicomUid('1.')).toBe(false);
expect(isDicomUid('1. 2')).toBe(false);
@@ -30,23 +30,17 @@ export default function isDisplaySetReconstructable(instances) {
}
// Can't reconstruct if all instances don't have the ImagePositionPatient.
if (
!isMultiframe &&
!instances.every(instance => instance.ImagePositionPatient)
) {
if (!isMultiframe && !instances.every(instance => instance.ImagePositionPatient)) {
return { value: false };
}
const sortedInstances = sortInstancesByPosition(instances);
return isMultiframe
? processMultiframe(sortedInstances[0])
: processSingleframe(sortedInstances);
return isMultiframe ? processMultiframe(sortedInstances[0]) : processSingleframe(sortedInstances);
}
function hasPixelMeasurements(multiFrameInstance) {
const perFrameSequence =
multiFrameInstance.PerFrameFunctionalGroupsSequence?.[0];
const perFrameSequence = multiFrameInstance.PerFrameFunctionalGroupsSequence?.[0];
const sharedSequence = multiFrameInstance.SharedFunctionalGroupsSequence;
return (
@@ -54,39 +48,34 @@ function hasPixelMeasurements(multiFrameInstance) {
Boolean(sharedSequence?.PixelMeasuresSequence) ||
Boolean(
multiFrameInstance.PixelSpacing &&
(multiFrameInstance.SliceThickness ||
multiFrameInstance.SpacingBetweenFrames)
(multiFrameInstance.SliceThickness || multiFrameInstance.SpacingBetweenFrames)
)
);
}
function hasOrientation(multiFrameInstance) {
const sharedSequence = multiFrameInstance.SharedFunctionalGroupsSequence;
const perFrameSequence =
multiFrameInstance.PerFrameFunctionalGroupsSequence?.[0];
const perFrameSequence = multiFrameInstance.PerFrameFunctionalGroupsSequence?.[0];
return (
Boolean(sharedSequence?.PlaneOrientationSequence) ||
Boolean(perFrameSequence?.PlaneOrientationSequence) ||
Boolean(
multiFrameInstance.ImageOrientationPatient ||
multiFrameInstance.DetectorInformationSequence?.[0]
?.ImageOrientationPatient
multiFrameInstance.DetectorInformationSequence?.[0]?.ImageOrientationPatient
)
);
}
function hasPosition(multiFrameInstance) {
const perFrameSequence =
multiFrameInstance.PerFrameFunctionalGroupsSequence?.[0];
const perFrameSequence = multiFrameInstance.PerFrameFunctionalGroupsSequence?.[0];
return (
Boolean(perFrameSequence?.PlanePositionSequence) ||
Boolean(perFrameSequence?.CTPositionSequence) ||
Boolean(
multiFrameInstance.ImagePositionPatient ||
multiFrameInstance.DetectorInformationSequence?.[0]
?.ImagePositionPatient
multiFrameInstance.DetectorInformationSequence?.[0]?.ImagePositionPatient
)
);
}
@@ -114,10 +103,7 @@ function processMultiframe(multiFrameInstance) {
return { value: false };
}
if (
multiFrameInstance.Modality.includes('NM') &&
!isNMReconstructable(multiFrameInstance)
) {
if (multiFrameInstance.Modality.includes('NM') && !isNMReconstructable(multiFrameInstance)) {
return { value: false };
}
@@ -130,9 +116,7 @@ function processSingleframe(instances) {
const firstImageRows = toNumber(firstImage.Rows);
const firstImageColumns = toNumber(firstImage.Columns);
const firstImageSamplesPerPixel = toNumber(firstImage.SamplesPerPixel);
const firstImageOrientationPatient = toNumber(
firstImage.ImageOrientationPatient
);
const firstImageOrientationPatient = toNumber(firstImage.ImageOrientationPatient);
const firstImagePositionPatient = toNumber(firstImage.ImagePositionPatient);
// Can't reconstruct if we:
@@ -141,12 +125,7 @@ function processSingleframe(instances) {
// -- Have different orientations within a displaySet.
for (let i = 1; i < instances.length; i++) {
const instance = instances[i];
const {
Rows,
Columns,
SamplesPerPixel,
ImageOrientationPatient,
} = instance;
const { Rows, Columns, SamplesPerPixel, ImageOrientationPatient } = instance;
const imageOrientationPatient = toNumber(ImageOrientationPatient);
@@ -167,9 +146,7 @@ function processSingleframe(instances) {
// If spacing is on a uniform grid but we are missing frames,
// Allow reconstruction, but pass back the number of missing frames.
if (instances.length > 2) {
const lastIpp = toNumber(
instances[instances.length - 1].ImagePositionPatient
);
const lastIpp = toNumber(instances[instances.length - 1].ImagePositionPatient);
// We can't reconstruct if we are missing ImagePositionPatient values
if (!firstImagePositionPatient || !lastIpp) {
@@ -177,8 +154,7 @@ function processSingleframe(instances) {
}
averageSpacingBetweenFrames =
_getPerpendicularDistance(firstImagePositionPatient, lastIpp) /
(instances.length - 1);
_getPerpendicularDistance(firstImagePositionPatient, lastIpp) / (instances.length - 1);
let previousImagePositionPatient = firstImagePositionPatient;
@@ -191,10 +167,7 @@ function processSingleframe(instances) {
imagePositionPatient,
previousImagePositionPatient
);
const spacingIssue = _getSpacingIssue(
spacingBetweenFrames,
averageSpacingBetweenFrames
);
const spacingIssue = _getSpacingIssue(spacingBetweenFrames, averageSpacingBetweenFrames);
if (spacingIssue) {
const issue = spacingIssue.issue;
@@ -262,11 +235,7 @@ function _getSpacingIssue(spacing, averageSpacing) {
}
function _getPerpendicularDistance(a, b) {
return Math.sqrt(
Math.pow(a[0] - b[0], 2) +
Math.pow(a[1] - b[1], 2) +
Math.pow(a[2] - b[2], 2)
);
return Math.sqrt(Math.pow(a[0] - b[0], 2) + Math.pow(a[1] - b[1], 2) + Math.pow(a[2] - b[2], 2));
}
const constructableModalities = ['MR', 'CT', 'PT', 'NM'];
+27 -81
View File
@@ -3,23 +3,17 @@ import { isImage } from './isImage';
describe('isImage', () => {
test('should return true when the image is of type sopClassDictionary.ComputedRadiographyImageStorage', () => {
const isImageStatus = isImage(
sopClassDictionary.ComputedRadiographyImageStorage
);
const isImageStatus = isImage(sopClassDictionary.ComputedRadiographyImageStorage);
expect(isImageStatus).toBe(true);
});
test('should return true when the image is of type sopClassDictionary.DigitalXRayImageStorageForPresentation', () => {
const isImageStatus = isImage(
sopClassDictionary.DigitalXRayImageStorageForPresentation
);
const isImageStatus = isImage(sopClassDictionary.DigitalXRayImageStorageForPresentation);
expect(isImageStatus).toBe(true);
});
test('should return true when the image is of type sopClassDictionary.DigitalXRayImageStorageForProcessing', () => {
const isImageStatus = isImage(
sopClassDictionary.DigitalXRayImageStorageForProcessing
);
const isImageStatus = isImage(sopClassDictionary.DigitalXRayImageStorageForProcessing);
expect(isImageStatus).toBe(true);
});
@@ -45,9 +39,7 @@ describe('isImage', () => {
});
test('should return true when the image is of type sopClassDictionary.DigitalIntraOralXRayImageStorageForProcessing', () => {
const isImageStatus = isImage(
sopClassDictionary.DigitalIntraOralXRayImageStorageForProcessing
);
const isImageStatus = isImage(sopClassDictionary.DigitalIntraOralXRayImageStorageForProcessing);
expect(isImageStatus).toBe(true);
});
@@ -62,16 +54,12 @@ describe('isImage', () => {
});
test('should return true when the image is of type sopClassDictionary.LegacyConvertedEnhancedCTImageStorage', () => {
const isImageStatus = isImage(
sopClassDictionary.LegacyConvertedEnhancedCTImageStorage
);
const isImageStatus = isImage(sopClassDictionary.LegacyConvertedEnhancedCTImageStorage);
expect(isImageStatus).toBe(true);
});
test('should return true when the image is of type sopClassDictionary.UltrasoundMultiframeImageStorage', () => {
const isImageStatus = isImage(
sopClassDictionary.UltrasoundMultiframeImageStorage
);
const isImageStatus = isImage(sopClassDictionary.UltrasoundMultiframeImageStorage);
expect(isImageStatus).toBe(true);
});
@@ -86,16 +74,12 @@ describe('isImage', () => {
});
test('should return true when the image is of type sopClassDictionary.EnhancedMRColorImageStorage', () => {
const isImageStatus = isImage(
sopClassDictionary.EnhancedMRColorImageStorage
);
const isImageStatus = isImage(sopClassDictionary.EnhancedMRColorImageStorage);
expect(isImageStatus).toBe(true);
});
test('should return true when the image is of type sopClassDictionary.LegacyConvertedEnhancedMRImageStorage', () => {
const isImageStatus = isImage(
sopClassDictionary.LegacyConvertedEnhancedMRImageStorage
);
const isImageStatus = isImage(sopClassDictionary.LegacyConvertedEnhancedMRImageStorage);
expect(isImageStatus).toBe(true);
});
@@ -105,9 +89,7 @@ describe('isImage', () => {
});
test('should return true when the image is of type sopClassDictionary.SecondaryCaptureImageStorage', () => {
const isImageStatus = isImage(
sopClassDictionary.SecondaryCaptureImageStorage
);
const isImageStatus = isImage(sopClassDictionary.SecondaryCaptureImageStorage);
expect(isImageStatus).toBe(true);
});
@@ -140,9 +122,7 @@ describe('isImage', () => {
});
test('should return true when the image is of type sopClassDictionary.XRayAngiographicImageStorage', () => {
const isImageStatus = isImage(
sopClassDictionary.XRayAngiographicImageStorage
);
const isImageStatus = isImage(sopClassDictionary.XRayAngiographicImageStorage);
expect(isImageStatus).toBe(true);
});
@@ -152,9 +132,7 @@ describe('isImage', () => {
});
test('should return true when the image is of type sopClassDictionary.XRayRadiofluoroscopicImageStorage', () => {
const isImageStatus = isImage(
sopClassDictionary.XRayRadiofluoroscopicImageStorage
);
const isImageStatus = isImage(sopClassDictionary.XRayRadiofluoroscopicImageStorage);
expect(isImageStatus).toBe(true);
});
@@ -164,23 +142,17 @@ describe('isImage', () => {
});
test('should return true when the image is of type sopClassDictionary.XRay3DAngiographicImageStorage', () => {
const isImageStatus = isImage(
sopClassDictionary.XRay3DAngiographicImageStorage
);
const isImageStatus = isImage(sopClassDictionary.XRay3DAngiographicImageStorage);
expect(isImageStatus).toBe(true);
});
test('should return true when the image is of type sopClassDictionary.XRay3DCraniofacialImageStorage', () => {
const isImageStatus = isImage(
sopClassDictionary.XRay3DCraniofacialImageStorage
);
const isImageStatus = isImage(sopClassDictionary.XRay3DCraniofacialImageStorage);
expect(isImageStatus).toBe(true);
});
test('should return true when the image is of type sopClassDictionary.BreastTomosynthesisImageStorage', () => {
const isImageStatus = isImage(
sopClassDictionary.BreastTomosynthesisImageStorage
);
const isImageStatus = isImage(sopClassDictionary.BreastTomosynthesisImageStorage);
expect(isImageStatus).toBe(true);
});
@@ -192,9 +164,7 @@ describe('isImage', () => {
});
test('should return true when the image is of type sopClassDictionary.BreastProjectionXRayImageStorageForProcessing', () => {
const isImageStatus = isImage(
sopClassDictionary.BreastProjectionXRayImageStorageForProcessing
);
const isImageStatus = isImage(sopClassDictionary.BreastProjectionXRayImageStorageForProcessing);
expect(isImageStatus).toBe(true);
});
@@ -213,9 +183,7 @@ describe('isImage', () => {
});
test('should return true when the image is of type sopClassDictionary.NuclearMedicineImageStorage', () => {
const isImageStatus = isImage(
sopClassDictionary.NuclearMedicineImageStorage
);
const isImageStatus = isImage(sopClassDictionary.NuclearMedicineImageStorage);
expect(isImageStatus).toBe(true);
});
@@ -225,9 +193,7 @@ describe('isImage', () => {
});
test('should return true when the image is of type sopClassDictionary.VideoEndoscopicImageStorage', () => {
const isImageStatus = isImage(
sopClassDictionary.VideoEndoscopicImageStorage
);
const isImageStatus = isImage(sopClassDictionary.VideoEndoscopicImageStorage);
expect(isImageStatus).toBe(true);
});
@@ -237,65 +203,47 @@ describe('isImage', () => {
});
test('should return true when the image is of type sopClassDictionary.VideoMicroscopicImageStorage', () => {
const isImageStatus = isImage(
sopClassDictionary.VideoMicroscopicImageStorage
);
const isImageStatus = isImage(sopClassDictionary.VideoMicroscopicImageStorage);
expect(isImageStatus).toBe(true);
});
test('should return true when the image is of type sopClassDictionary.VLSlideCoordinatesMicroscopicImageStorage', () => {
const isImageStatus = isImage(
sopClassDictionary.VLSlideCoordinatesMicroscopicImageStorage
);
const isImageStatus = isImage(sopClassDictionary.VLSlideCoordinatesMicroscopicImageStorage);
expect(isImageStatus).toBe(true);
});
test('should return true when the image is of type sopClassDictionary.VLPhotographicImageStorage', () => {
const isImageStatus = isImage(
sopClassDictionary.VLPhotographicImageStorage
);
const isImageStatus = isImage(sopClassDictionary.VLPhotographicImageStorage);
expect(isImageStatus).toBe(true);
});
test('should return true when the image is of type sopClassDictionary.VideoPhotographicImageStorage', () => {
const isImageStatus = isImage(
sopClassDictionary.VideoPhotographicImageStorage
);
const isImageStatus = isImage(sopClassDictionary.VideoPhotographicImageStorage);
expect(isImageStatus).toBe(true);
});
test('should return true when the image is of type sopClassDictionary.OphthalmicPhotography8BitImageStorage', () => {
const isImageStatus = isImage(
sopClassDictionary.OphthalmicPhotography8BitImageStorage
);
const isImageStatus = isImage(sopClassDictionary.OphthalmicPhotography8BitImageStorage);
expect(isImageStatus).toBe(true);
});
test('should return true when the image is of type sopClassDictionary.OphthalmicPhotography16BitImageStorage', () => {
const isImageStatus = isImage(
sopClassDictionary.OphthalmicPhotography16BitImageStorage
);
const isImageStatus = isImage(sopClassDictionary.OphthalmicPhotography16BitImageStorage);
expect(isImageStatus).toBe(true);
});
test('should return true when the image is of type sopClassDictionary.OphthalmicTomographyImageStorage', () => {
const isImageStatus = isImage(
sopClassDictionary.OphthalmicTomographyImageStorage
);
const isImageStatus = isImage(sopClassDictionary.OphthalmicTomographyImageStorage);
expect(isImageStatus).toBe(true);
});
test('should return true when the image is of type sopClassDictionary.VLWholeSlideMicroscopyImageStorage', () => {
const isImageStatus = isImage(
sopClassDictionary.VLWholeSlideMicroscopyImageStorage
);
const isImageStatus = isImage(sopClassDictionary.VLWholeSlideMicroscopyImageStorage);
expect(isImageStatus).toBe(true);
});
test('should return true when the image is of type sopClassDictionary.PositronEmissionTomographyImageStorage', () => {
const isImageStatus = isImage(
sopClassDictionary.PositronEmissionTomographyImageStorage
);
const isImageStatus = isImage(sopClassDictionary.PositronEmissionTomographyImageStorage);
expect(isImageStatus).toBe(true);
});
@@ -305,9 +253,7 @@ describe('isImage', () => {
});
test('should return true when the image is of type sopClassDictionary.LegacyConvertedEnhancedPETImageStorage', () => {
const isImageStatus = isImage(
sopClassDictionary.LegacyConvertedEnhancedPETImageStorage
);
const isImageStatus = isImage(sopClassDictionary.LegacyConvertedEnhancedPETImageStorage);
expect(isImageStatus).toBe(true);
});
@@ -1,10 +1,4 @@
const LOW_PRIORITY_MODALITIES = Object.freeze([
'SEG',
'KO',
'PR',
'SR',
'RTSTRUCT',
]);
const LOW_PRIORITY_MODALITIES = Object.freeze(['SEG', 'KO', 'PR', 'SR', 'RTSTRUCT']);
export default function isLowPriorityModality(Modality) {
return LOW_PRIORITY_MODALITIES.includes(Modality);
@@ -1,10 +1,4 @@
const LOW_PRIORITY_MODALITIES = Object.freeze([
'SEG',
'KO',
'PR',
'SR',
'RTSTRUCT',
]);
const LOW_PRIORITY_MODALITIES = Object.freeze(['SEG', 'KO', 'PR', 'SR', 'RTSTRUCT']);
export default function isLowPriorityModality(Modality) {
return LOW_PRIORITY_MODALITIES.includes(Modality);
+2 -2
View File
@@ -1,13 +1,13 @@
export default function makeCancelable(thenable) {
let isCanceled = false;
const promise = Promise.resolve(thenable).then(
function(result) {
function (result) {
if (isCanceled) {
throw Object.freeze({ isCanceled });
}
return result;
},
function(error) {
function (error) {
if (isCanceled) {
throw Object.freeze({ isCanceled, error });
}
+1 -1
View File
@@ -1,7 +1,7 @@
export default function makeDeferred() {
let reject,
resolve,
promise = new Promise(function(res, rej) {
promise = new Promise(function (res, rej) {
resolve = res;
reject = rej;
});
@@ -11,11 +11,7 @@
* @returns Array view containing the palette data, or a promise to return one.
* Returns undefined if the palette data is absent.
*/
export default function fetchPaletteColorLookupTableData(
item,
tag,
descriptorTag
) {
export default function fetchPaletteColorLookupTableData(item, tag, descriptorTag) {
const { PaletteColorLookupTableUID } = item;
const paletteData = item[tag];
if (paletteData === undefined && PaletteColorLookupTableUID === undefined) {
@@ -55,19 +51,12 @@ function _getPaletteColor(paletteColorLookupTableData, lutDescriptor) {
if (paletteColorLookupTableData.InlineBinary) {
try {
const arraybuffer = Uint8Array.from(
atob(paletteColorLookupTableData.InlineBinary),
c => c.charCodeAt(0)
const arraybuffer = Uint8Array.from(atob(paletteColorLookupTableData.InlineBinary), c =>
c.charCodeAt(0)
);
return (paletteColorLookupTableData.palette = arrayBufferToPaletteColorLUT(
arraybuffer
));
return (paletteColorLookupTableData.palette = arrayBufferToPaletteColorLUT(arraybuffer));
} catch (e) {
console.log(
"Couldn't decode",
paletteColorLookupTableData.InlineBinary,
e
);
console.log("Couldn't decode", paletteColorLookupTableData.InlineBinary, e);
return undefined;
}
}
@@ -75,12 +64,7 @@ function _getPaletteColor(paletteColorLookupTableData, lutDescriptor) {
if (paletteColorLookupTableData.retrieveBulkData) {
return paletteColorLookupTableData
.retrieveBulkData()
.then(
val =>
(paletteColorLookupTableData.palette = arrayBufferToPaletteColorLUT(
val
))
);
.then(val => (paletteColorLookupTableData.palette = arrayBufferToPaletteColorLUT(val)));
}
console.error(`No data found for ${paletteColorLookupTableData} palette`);
@@ -48,11 +48,7 @@ export default function getPixelSpacingInformation(instance) {
type: TYPES.UNKNOWN,
isProjection,
};
} else if (
PixelSpacing &&
ImagerPixelSpacing &&
PixelSpacing === ImagerPixelSpacing
) {
} else if (PixelSpacing && ImagerPixelSpacing && PixelSpacing === ImagerPixelSpacing) {
// If Imager Pixel Spacing and Pixel Spacing are present and they have the same values,
// then the user should be informed that the measurements are at the detector plane
return {
@@ -60,11 +56,7 @@ export default function getPixelSpacingInformation(instance) {
type: TYPES.DETECTOR,
isProjection,
};
} else if (
PixelSpacing &&
ImagerPixelSpacing &&
PixelSpacing !== ImagerPixelSpacing
) {
} else if (PixelSpacing && ImagerPixelSpacing && PixelSpacing !== ImagerPixelSpacing) {
// If Imager Pixel Spacing and Pixel Spacing are present and they have different values,
// then the user should be informed that these are "calibrated"
// (in some unknown manner if Pixel Spacing Calibration Type and/or
@@ -95,10 +87,7 @@ export default function getPixelSpacingInformation(instance) {
PixelSpacing: CorrectedImagerPixelSpacing,
isProjection,
};
} else if (
SequenceOfUltrasoundRegions &&
typeof SequenceOfUltrasoundRegions === 'object'
) {
} else if (SequenceOfUltrasoundRegions && typeof SequenceOfUltrasoundRegions === 'object') {
const { PhysicalDeltaX, PhysicalDeltaY } = SequenceOfUltrasoundRegions;
const USPixelSpacing = [PhysicalDeltaX * 10, PhysicalDeltaY * 10];
@@ -5,8 +5,7 @@ export default function unpackOverlay(arrayBuffer) {
for (let byteIndex = 0; byteIndex < byteArray.length; byteIndex++) {
const bitIndex = byteIndex % 8;
const bitByteIndex = Math.floor(byteIndex / 8);
byteArray[byteIndex] =
1 * ((bitArray[bitByteIndex] & (1 << bitIndex)) >> bitIndex);
byteArray[byteIndex] = 1 * ((bitArray[bitByteIndex] & (1 << bitIndex)) >> bitIndex);
}
return byteArray;
+1 -3
View File
@@ -85,9 +85,7 @@ export class ObjectPath {
* @return {Boolean} Returns "true" if the object is a real Object instance and "false" otherwise.
*/
static isValidObject(object) {
return (
typeof object === 'object' && object !== null && object instanceof Object
);
return typeof object === 'object' && object !== null && object instanceof Object;
}
static getPathComponents(path) {
@@ -149,10 +149,10 @@ function waitOn(list, thenable) {
const task = increaseList(list);
if (isTask(task)) {
task.awaiting = Promise.resolve(thenable).then(
function() {
function () {
finish(task);
},
function() {
function () {
task.failed = true;
finish(task);
}
@@ -226,11 +226,7 @@ function getTaskByName(list, name) {
* @returns {boolean} Returns true on success and false otherewise
*/
function addObserver(list, observer) {
if (
isList(list) &&
Array.isArray(list.observers) &&
typeof observer === 'function'
) {
if (isList(list) && Array.isArray(list.observers) && typeof observer === 'function') {
list.observers.push(observer);
return true;
}
@@ -244,11 +240,7 @@ function addObserver(list, observer) {
* @returns {boolean} Returns true on success and false otherewise
*/
function removeObserver(list, observer) {
if (
isList(list) &&
Array.isArray(list.observers) &&
list.observers.length > 0
) {
if (isList(list) && Array.isArray(list.observers) && list.observers.length > 0) {
const index = list.observers.indexOf(observer);
if (index >= 0) {
list.observers.splice(index, 1);
@@ -276,9 +268,7 @@ function objectWithType(type, object) {
}
function isOfType(type, subject) {
return (
subject !== null && typeof subject === 'object' && subject[TYPE] === type
);
return subject !== null && typeof subject === 'object' && subject[TYPE] === type;
}
function isValidProgress(value) {
@@ -299,12 +289,8 @@ function contains(list, task) {
}
function notify(list, data) {
if (
isList(list) &&
Array.isArray(list.observers) &&
list.observers.length > 0
) {
list.observers.slice().forEach(function(observer) {
if (isList(list) && Array.isArray(list.observers) && list.observers.length > 0) {
list.observers.slice().forEach(function (observer) {
if (typeof observer === 'function') {
try {
observer(data, list);
@@ -40,11 +40,7 @@ describe('progressTrackingUtils', () => {
it('should call observer twice for each task', () => {
const { list, observer } = context;
const promises = [
Promise.resolve('A'),
Promise.resolve('B'),
Promise.resolve('C'),
];
const promises = [Promise.resolve('A'), Promise.resolve('B'), Promise.resolve('C')];
promises.forEach(promise => void utils.waitOn(list, promise));
return Promise.all(promises).then(() => {
expect(observer).toBeCalledTimes(6);
+1 -3
View File
@@ -10,8 +10,6 @@ export default function resolveObjectPath(root, path, defaultValue) {
);
}
value = root[path];
return value === undefined && defaultValue !== undefined
? defaultValue
: value;
return value === undefined && defaultValue !== undefined ? defaultValue : value;
}
}
@@ -1,9 +1,9 @@
import resolveObjectPath from './resolveObjectPath';
describe('resolveObjectPath', function() {
describe('resolveObjectPath', function () {
let config;
beforeEach(function() {
beforeEach(function () {
config = {
active: {
user: {
@@ -21,13 +21,13 @@ describe('resolveObjectPath', function() {
};
});
it('should safely return deeply nested values from an object', function() {
it('should safely return deeply nested values from an object', function () {
expect(resolveObjectPath(config, 'active.user.name.first')).toBe('John');
expect(resolveObjectPath(config, 'active.user.name.last')).toBe('Doe');
expect(resolveObjectPath(config, 'active.servers.0.ipv4')).toBe('10.0.0.1');
});
it('should silently return undefined when intermediate values are not valid objects', function() {
it('should silently return undefined when intermediate values are not valid objects', function () {
expect(resolveObjectPath(config, 'active.usr.name.first')).toBeUndefined();
expect(resolveObjectPath(config, 'active.name.last')).toBeUndefined();
expect(resolveObjectPath(config, 'active.servers.7.ipv4')).toBeUndefined();
+13 -26
View File
@@ -3,14 +3,10 @@ export const sopClassDictionary = {
ComputedRadiographyImageStorage: '1.2.840.10008.5.1.4.1.1.1',
DigitalXRayImageStorageForPresentation: '1.2.840.10008.5.1.4.1.1.1.1',
DigitalXRayImageStorageForProcessing: '1.2.840.10008.5.1.4.1.1.1.1.1',
DigitalMammographyXRayImageStorageForPresentation:
'1.2.840.10008.5.1.4.1.1.1.2',
DigitalMammographyXRayImageStorageForProcessing:
'1.2.840.10008.5.1.4.1.1.1.2.1',
DigitalIntraOralXRayImageStorageForPresentation:
'1.2.840.10008.5.1.4.1.1.1.3',
DigitalIntraOralXRayImageStorageForProcessing:
'1.2.840.10008.5.1.4.1.1.1.3.1',
DigitalMammographyXRayImageStorageForPresentation: '1.2.840.10008.5.1.4.1.1.1.2',
DigitalMammographyXRayImageStorageForProcessing: '1.2.840.10008.5.1.4.1.1.1.2.1',
DigitalIntraOralXRayImageStorageForPresentation: '1.2.840.10008.5.1.4.1.1.1.3',
DigitalIntraOralXRayImageStorageForProcessing: '1.2.840.10008.5.1.4.1.1.1.3.1',
CTImageStorage: '1.2.840.10008.5.1.4.1.1.2',
EnhancedCTImageStorage: '1.2.840.10008.5.1.4.1.1.2.1',
LegacyConvertedEnhancedCTImageStorage: '1.2.840.10008.5.1.4.1.1.2.2',
@@ -23,14 +19,10 @@ export const sopClassDictionary = {
UltrasoundImageStorage: '1.2.840.10008.5.1.4.1.1.6.1',
EnhancedUSVolumeStorage: '1.2.840.10008.5.1.4.1.1.6.2',
SecondaryCaptureImageStorage: '1.2.840.10008.5.1.4.1.1.7',
MultiframeSingleBitSecondaryCaptureImageStorage:
'1.2.840.10008.5.1.4.1.1.7.1',
MultiframeGrayscaleByteSecondaryCaptureImageStorage:
'1.2.840.10008.5.1.4.1.1.7.2',
MultiframeGrayscaleWordSecondaryCaptureImageStorage:
'1.2.840.10008.5.1.4.1.1.7.3',
MultiframeTrueColorSecondaryCaptureImageStorage:
'1.2.840.10008.5.1.4.1.1.7.4',
MultiframeSingleBitSecondaryCaptureImageStorage: '1.2.840.10008.5.1.4.1.1.7.1',
MultiframeGrayscaleByteSecondaryCaptureImageStorage: '1.2.840.10008.5.1.4.1.1.7.2',
MultiframeGrayscaleWordSecondaryCaptureImageStorage: '1.2.840.10008.5.1.4.1.1.7.3',
MultiframeTrueColorSecondaryCaptureImageStorage: '1.2.840.10008.5.1.4.1.1.7.4',
Sop12LeadECGWaveformStorage: '1.2.840.10008.5.1.4.1.1.9.1.1',
GeneralECGWaveformStorage: '1.2.840.10008.5.1.4.1.1.9.1.2',
AmbulatoryECGWaveformStorage: '1.2.840.10008.5.1.4.1.1.9.1.3',
@@ -44,8 +36,7 @@ export const sopClassDictionary = {
ColorSoftcopyPresentationStateStorage: '1.2.840.10008.5.1.4.1.1.11.2',
PseudoColorSoftcopyPresentationStateStorage: '1.2.840.10008.5.1.4.1.1.11.3',
BlendingSoftcopyPresentationStateStorage: '1.2.840.10008.5.1.4.1.1.11.4',
XAXRFGrayscaleSoftcopyPresentationStateStorage:
'1.2.840.10008.5.1.4.1.1.11.5',
XAXRFGrayscaleSoftcopyPresentationStateStorage: '1.2.840.10008.5.1.4.1.1.11.5',
XRayAngiographicImageStorage: '1.2.840.10008.5.1.4.1.1.12.1',
EnhancedXAImageStorage: '1.2.840.10008.5.1.4.1.1.12.1.1',
XRayRadiofluoroscopicImageStorage: '1.2.840.10008.5.1.4.1.1.12.2',
@@ -53,14 +44,11 @@ export const sopClassDictionary = {
XRay3DAngiographicImageStorage: '1.2.840.10008.5.1.4.1.1.13.1.1',
XRay3DCraniofacialImageStorage: '1.2.840.10008.5.1.4.1.1.13.1.2',
BreastTomosynthesisImageStorage: '1.2.840.10008.5.1.4.1.1.13.1.3',
BreastProjectionXRayImageStorageForPresentation:
'1.2.840.10008.5.1.4.1.1.13.1.4',
BreastProjectionXRayImageStorageForProcessing:
'1.2.840.10008.5.1.4.1.1.13.1.5',
BreastProjectionXRayImageStorageForPresentation: '1.2.840.10008.5.1.4.1.1.13.1.4',
BreastProjectionXRayImageStorageForProcessing: '1.2.840.10008.5.1.4.1.1.13.1.5',
IntravascularOpticalCoherenceTomographyImageStorageForPresentation:
'1.2.840.10008.5.1.4.1.1.14.1',
IntravascularOpticalCoherenceTomographyImageStorageForProcessing:
'1.2.840.10008.5.1.4.1.1.14.2',
IntravascularOpticalCoherenceTomographyImageStorageForProcessing: '1.2.840.10008.5.1.4.1.1.14.2',
NuclearMedicineImageStorage: '1.2.840.10008.5.1.4.1.1.20',
RawDataStorage: '1.2.840.10008.5.1.4.1.1.66',
SpatialRegistrationStorage: '1.2.840.10008.5.1.4.1.1.66.1',
@@ -92,8 +80,7 @@ export const sopClassDictionary = {
OphthalmicAxialMeasurementsStorage: '1.2.840.10008.5.1.4.1.1.78.7',
IntraocularLensCalculationsStorage: '1.2.840.10008.5.1.4.1.1.78.8',
MacularGridThicknessandVolumeReport: '1.2.840.10008.5.1.4.1.1.79.1',
OphthalmicVisualFieldStaticPerimetryMeasurementsStorage:
'1.2.840.10008.5.1.4.1.1.80.1',
OphthalmicVisualFieldStaticPerimetryMeasurementsStorage: '1.2.840.10008.5.1.4.1.1.80.1',
OphthalmicThicknessMapStorage: '1.2.840.10008.5.1.4.1.1.81.1',
CornealTopographyMapStorage: '1.2.840.10008.5.1.4.1.1.82.1',
BasicTextSR: '1.2.840.10008.5.1.4.1.1.88.11',
+1 -1
View File
@@ -3,7 +3,7 @@ export default function sortBy() {
var fields = [].slice.call(arguments),
n_fields = fields.length;
return function(A, B) {
return function (A, B) {
var a, b, field, key, reverse, result, i;
for (i = 0; i < n_fields; i++) {
@@ -15,10 +15,8 @@ export default function sortInstances(instances: Array<any>) {
return instances;
}
const {
ImagePositionPatient: referenceImagePositionPatient,
ImageOrientationPatient,
} = instances[Math.floor(instances.length / 2)]; // this prevents getting scout image as test image
const { ImagePositionPatient: referenceImagePositionPatient, ImageOrientationPatient } =
instances[Math.floor(instances.length / 2)]; // this prevents getting scout image as test image
if (!referenceImagePositionPatient || !ImageOrientationPatient) {
return instances;
@@ -49,11 +47,7 @@ export default function sortInstances(instances: Array<any>) {
const positionVector = vec3.create();
vec3.sub(
positionVector,
referenceImagePositionPatient,
imagePositionPatient
);
vec3.sub(positionVector, referenceImagePositionPatient, imagePositionPatient);
const distance = vec3.dot(positionVector, scanAxisNormal);
+5 -19
View File
@@ -1,12 +1,8 @@
import isLowPriorityModality from './isLowPriorityModality';
const compareSeriesDateTime = (a, b) => {
const seriesDateA = Date.parse(
`${a.seriesDate ?? a.SeriesDate} ${a.seriesTime ?? a.SeriesTime}`
);
const seriesDateB = Date.parse(
`${a.seriesDate ?? a.SeriesDate} ${a.seriesTime ?? a.SeriesTime}`
);
const seriesDateA = Date.parse(`${a.seriesDate ?? a.SeriesDate} ${a.seriesTime ?? a.SeriesTime}`);
const seriesDateB = Date.parse(`${a.seriesDate ?? a.SeriesDate} ${a.seriesTime ?? a.SeriesTime}`);
return seriesDateA - seriesDateB;
};
@@ -26,12 +22,8 @@ const defaultSeriesSort = (a, b) => {
* @param {Object} secondSeries
*/
function seriesInfoSortingCriteria(firstSeries, secondSeries) {
const aLowPriority = isLowPriorityModality(
firstSeries.Modality ?? firstSeries.modality
);
const bLowPriority = isLowPriorityModality(
secondSeries.Modality ?? secondSeries.modality
);
const aLowPriority = isLowPriorityModality(firstSeries.Modality ?? firstSeries.modality);
const bLowPriority = isLowPriorityModality(secondSeries.Modality ?? secondSeries.modality);
if (aLowPriority) {
return bLowPriority ? defaultSeriesSort(secondSeries, firstSeries) : 1;
@@ -122,10 +114,4 @@ export default function sortStudy(
return study;
}
export {
sortStudy,
sortStudySeries,
sortStudyInstances,
sortingCriteria,
seriesSortCriteria,
};
export { sortStudy, sortStudySeries, sortStudyInstances, sortingCriteria, seriesSortCriteria };
+1 -3
View File
@@ -23,9 +23,7 @@ const getSplitParam = (
lowerCaseKey: string,
params = new URLSearchParams(window.location.search)
): string[] => {
const sourceKey = [...params.keys()].find(
it => it.toLowerCase() === lowerCaseKey
);
const sourceKey = [...params.keys()].find(it => it.toLowerCase() === lowerCaseKey);
if (!sourceKey) {
return;
}
@@ -20,10 +20,7 @@ function subscribeToNextViewportGridChange(
};
const subscriptions = [
viewportGridService.subscribe(
viewportGridService.EVENTS.LAYOUT_CHANGED,
callback
),
viewportGridService.subscribe(viewportGridService.EVENTS.LAYOUT_CHANGED, callback),
];
};