lint(curly): consistent use of curly brackets in codebase (#3584)
This commit is contained in:
parent
9ae3d9f769
commit
5d435424e2
@ -21,6 +21,10 @@
|
|||||||
"version": "detect"
|
"version": "detect"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"rules": {
|
||||||
|
// Enforce consistent brace style for all control statements for readability
|
||||||
|
"curly": "error"
|
||||||
|
},
|
||||||
"globals": {
|
"globals": {
|
||||||
"cy": true,
|
"cy": true,
|
||||||
"before": true,
|
"before": true,
|
||||||
|
|||||||
@ -2,13 +2,12 @@ import React from 'react';
|
|||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { Icon, Tooltip } from '@ohif/ui';
|
import { Icon, Tooltip } from '@ohif/ui';
|
||||||
|
|
||||||
|
|
||||||
export default function _getStatusComponent({ isHydrated, onStatusClick }) {
|
export default function _getStatusComponent({ isHydrated, onStatusClick }) {
|
||||||
let ToolTipMessage = null;
|
let ToolTipMessage = null;
|
||||||
let StatusIcon = null;
|
let StatusIcon = null;
|
||||||
|
|
||||||
const {t} = useTranslation("Common");
|
const { t } = useTranslation('Common');
|
||||||
const loadStr = t("LOAD");
|
const loadStr = t('LOAD');
|
||||||
|
|
||||||
switch (isHydrated) {
|
switch (isHydrated) {
|
||||||
case true:
|
case true:
|
||||||
@ -18,7 +17,7 @@ export default function _getStatusComponent({ isHydrated, onStatusClick }) {
|
|||||||
<div>This Segmentation is loaded in the segmentation panel</div>
|
<div>This Segmentation is loaded in the segmentation panel</div>
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
case false:
|
case false:
|
||||||
StatusIcon = () => <Icon name="status-untracked" />;
|
StatusIcon = () => <Icon name="status-untracked" />;
|
||||||
|
|
||||||
ToolTipMessage = () => <div>Click LOAD to load segmentation.</div>;
|
ToolTipMessage = () => <div>Click LOAD to load segmentation.</div>;
|
||||||
@ -42,7 +41,6 @@ export default function _getStatusComponent({ isHydrated, onStatusClick }) {
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{ToolTipMessage && (
|
{ToolTipMessage && (
|
||||||
|
|||||||
@ -308,8 +308,9 @@ function _measurementReferencesSOPInstanceUID(
|
|||||||
measurement.coords[0].ReferencedSOPSequence[0]?.ReferencedFrameNumber) ||
|
measurement.coords[0].ReferencedSOPSequence[0]?.ReferencedFrameNumber) ||
|
||||||
1;
|
1;
|
||||||
|
|
||||||
if (frameNumber && Number(frameNumber) !== Number(ReferencedFrameNumber))
|
if (frameNumber && Number(frameNumber) !== Number(ReferencedFrameNumber)) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
for (let j = 0; j < coords.length; j++) {
|
for (let j = 0; j < coords.length; j++) {
|
||||||
const coord = coords[j];
|
const coord = coords[j];
|
||||||
@ -670,7 +671,9 @@ function _getReferencedImagesList(ImagingMeasurementReportContentSequence) {
|
|||||||
|
|
||||||
_getSequenceAsArray(ImageLibraryGroup.ContentSequence).forEach(item => {
|
_getSequenceAsArray(ImageLibraryGroup.ContentSequence).forEach(item => {
|
||||||
const { ReferencedSOPSequence } = item;
|
const { ReferencedSOPSequence } = item;
|
||||||
if (!ReferencedSOPSequence) return;
|
if (!ReferencedSOPSequence) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
for (const ref of _getSequenceAsArray(ReferencedSOPSequence)) {
|
for (const ref of _getSequenceAsArray(ReferencedSOPSequence)) {
|
||||||
if (ref.ReferencedSOPClassUID) {
|
if (ref.ReferencedSOPClassUID) {
|
||||||
const { ReferencedSOPClassUID, ReferencedSOPInstanceUID } = ref;
|
const { ReferencedSOPClassUID, ReferencedSOPInstanceUID } = ref;
|
||||||
@ -687,7 +690,9 @@ function _getReferencedImagesList(ImagingMeasurementReportContentSequence) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function _getSequenceAsArray(sequence) {
|
function _getSequenceAsArray(sequence) {
|
||||||
if (!sequence) return [];
|
if (!sequence) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
return Array.isArray(sequence) ? sequence : [sequence];
|
return Array.isArray(sequence) ? sequence : [sequence];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -314,18 +314,16 @@ export default class DICOMSRDisplayTool extends AnnotationTool {
|
|||||||
);
|
);
|
||||||
let canvasCorners;
|
let canvasCorners;
|
||||||
if (rotation == 90 || rotation == 270) {
|
if (rotation == 90 || rotation == 270) {
|
||||||
canvasCorners = <Array<Types.Point2>>(
|
canvasCorners = utilities.math.ellipse.getCanvasEllipseCorners([
|
||||||
utilities.math.ellipse.getCanvasEllipseCorners([
|
canvasCoordinates[2],
|
||||||
canvasCoordinates[2],
|
canvasCoordinates[3],
|
||||||
canvasCoordinates[3],
|
canvasCoordinates[0],
|
||||||
canvasCoordinates[0],
|
canvasCoordinates[1],
|
||||||
canvasCoordinates[1],
|
]) as Array<Types.Point2>;
|
||||||
])
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
canvasCorners = <Array<Types.Point2>>(
|
canvasCorners = utilities.math.ellipse.getCanvasEllipseCorners(
|
||||||
utilities.math.ellipse.getCanvasEllipseCorners(canvasCoordinates)
|
canvasCoordinates
|
||||||
);
|
) as Array<Types.Point2>;
|
||||||
}
|
}
|
||||||
|
|
||||||
const lineUID = `${index}`;
|
const lineUID = `${index}`;
|
||||||
|
|||||||
@ -3,12 +3,16 @@ import { DisplaySetService, classes } from '@ohif/core';
|
|||||||
const ImageSet = classes.ImageSet;
|
const ImageSet = classes.ImageSet;
|
||||||
|
|
||||||
const findInstance = (measurement, displaySetService: DisplaySetService) => {
|
const findInstance = (measurement, displaySetService: DisplaySetService) => {
|
||||||
const { displaySetInstanceUID, ReferencedSOPInstanceUID: sopUid } =
|
const {
|
||||||
measurement;
|
displaySetInstanceUID,
|
||||||
|
ReferencedSOPInstanceUID: sopUid,
|
||||||
|
} = measurement;
|
||||||
const referencedDisplaySet = displaySetService.getDisplaySetByUID(
|
const referencedDisplaySet = displaySetService.getDisplaySetByUID(
|
||||||
displaySetInstanceUID
|
displaySetInstanceUID
|
||||||
);
|
);
|
||||||
if (!referencedDisplaySet.images) return;
|
if (!referencedDisplaySet.images) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
return referencedDisplaySet.images.find(it => it.SOPInstanceUID === sopUid);
|
return referencedDisplaySet.images.find(it => it.SOPInstanceUID === sopUid);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -24,8 +28,12 @@ const findReferencedInstances = (
|
|||||||
const instanceById = {};
|
const instanceById = {};
|
||||||
for (const measurement of displaySet.measurements) {
|
for (const measurement of displaySet.measurements) {
|
||||||
const { imageId } = measurement;
|
const { imageId } = measurement;
|
||||||
if (!imageId) continue;
|
if (!imageId) {
|
||||||
if (instanceById[imageId]) continue;
|
continue;
|
||||||
|
}
|
||||||
|
if (instanceById[imageId]) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
const instance = findInstance(measurement, displaySetService);
|
const instance = findInstance(measurement, displaySetService);
|
||||||
if (!instance) {
|
if (!instance) {
|
||||||
|
|||||||
@ -9,7 +9,9 @@ const findInstanceMetadataBySopInstanceUID = (displaySets, SOPInstanceUID) => {
|
|||||||
let instanceFound;
|
let instanceFound;
|
||||||
|
|
||||||
displaySets.find(displaySet => {
|
displaySets.find(displaySet => {
|
||||||
if (!displaySet.images) return false;
|
if (!displaySet.images) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
instanceFound = displaySet.images.find(
|
instanceFound = displaySet.images.find(
|
||||||
instanceMetadata =>
|
instanceMetadata =>
|
||||||
|
|||||||
@ -12,20 +12,26 @@ const CORNERSTONE_3D_TOOLS_SOURCE_VERSION = '0.1';
|
|||||||
const supportedLegacyCornerstoneTags = ['cornerstoneTools@^4.0.0'];
|
const supportedLegacyCornerstoneTags = ['cornerstoneTools@^4.0.0'];
|
||||||
|
|
||||||
const convertCode = (codingValues, code) => {
|
const convertCode = (codingValues, code) => {
|
||||||
if (!code || code.CodingSchemeDesignator === 'CORNERSTONEJS') return;
|
if (!code || code.CodingSchemeDesignator === 'CORNERSTONEJS') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
const ref = `${code.CodingSchemeDesignator}:${code.CodeValue}`;
|
const ref = `${code.CodingSchemeDesignator}:${code.CodeValue}`;
|
||||||
const ret = { ...codingValues[ref], ref, ...code, text: code.CodeMeaning };
|
const ret = { ...codingValues[ref], ref, ...code, text: code.CodeMeaning };
|
||||||
return ret;
|
return ret;
|
||||||
};
|
};
|
||||||
|
|
||||||
const convertSites = (codingValues, sites) => {
|
const convertSites = (codingValues, sites) => {
|
||||||
if (!sites || !sites.length) return;
|
if (!sites || !sites.length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
const ret = [];
|
const ret = [];
|
||||||
// Do as a loop to convert away from Proxy instances
|
// Do as a loop to convert away from Proxy instances
|
||||||
for (let i = 0; i < sites.length; i++) {
|
for (let i = 0; i < sites.length; i++) {
|
||||||
// Deal with irregular conversion from dcmjs
|
// Deal with irregular conversion from dcmjs
|
||||||
const site = convertCode(codingValues, sites[i][0] || sites[i]);
|
const site = convertCode(codingValues, sites[i][0] || sites[i]);
|
||||||
if (site) ret.push(site);
|
if (site) {
|
||||||
|
ret.push(site);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return (ret.length && ret) || undefined;
|
return (ret.length && ret) || undefined;
|
||||||
};
|
};
|
||||||
@ -287,7 +293,7 @@ function _mapLegacyDataSet(dataset) {
|
|||||||
return dataset;
|
return dataset;
|
||||||
}
|
}
|
||||||
|
|
||||||
const toArray = function (x) {
|
const toArray = function(x) {
|
||||||
return Array.isArray(x) ? x : [x];
|
return Array.isArray(x) ? x : [x];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -445,7 +445,9 @@ function _subscribeToJumpToMeasurementEvents(
|
|||||||
props => {
|
props => {
|
||||||
cacheJumpToMeasurementEvent = props;
|
cacheJumpToMeasurementEvent = props;
|
||||||
const { viewportIndex: jumpIndex, measurement, isConsumed } = props;
|
const { viewportIndex: jumpIndex, measurement, isConsumed } = props;
|
||||||
if (!measurement || isConsumed) return;
|
if (!measurement || isConsumed) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (cacheJumpToMeasurementEvent.cornerstoneViewport === undefined) {
|
if (cacheJumpToMeasurementEvent.cornerstoneViewport === undefined) {
|
||||||
// Decide on which viewport should handle this
|
// Decide on which viewport should handle this
|
||||||
cacheJumpToMeasurementEvent.cornerstoneViewport = cornerstoneViewportService.getViewportIndexToJump(
|
cacheJumpToMeasurementEvent.cornerstoneViewport = cornerstoneViewportService.getViewportIndexToJump(
|
||||||
@ -482,7 +484,9 @@ function _checkForCachedJumpToMeasurementEvents(
|
|||||||
viewportGridService,
|
viewportGridService,
|
||||||
cornerstoneViewportService
|
cornerstoneViewportService
|
||||||
) {
|
) {
|
||||||
if (!cacheJumpToMeasurementEvent) return;
|
if (!cacheJumpToMeasurementEvent) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (cacheJumpToMeasurementEvent.isConsumed) {
|
if (cacheJumpToMeasurementEvent.isConsumed) {
|
||||||
cacheJumpToMeasurementEvent = null;
|
cacheJumpToMeasurementEvent = null;
|
||||||
return;
|
return;
|
||||||
@ -490,7 +494,9 @@ function _checkForCachedJumpToMeasurementEvents(
|
|||||||
const displaysUIDs = displaySets.map(
|
const displaysUIDs = displaySets.map(
|
||||||
displaySet => displaySet.displaySetInstanceUID
|
displaySet => displaySet.displaySetInstanceUID
|
||||||
);
|
);
|
||||||
if (!displaysUIDs?.length) return;
|
if (!displaysUIDs?.length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Jump to measurement if the measurement exists
|
// Jump to measurement if the measurement exists
|
||||||
const { measurement } = cacheJumpToMeasurementEvent;
|
const { measurement } = cacheJumpToMeasurementEvent;
|
||||||
|
|||||||
@ -36,8 +36,9 @@ function CornerstoneOverlays(props) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (viewportData) {
|
if (viewportData) {
|
||||||
const viewportInfo =
|
const viewportInfo = cornerstoneViewportService.getViewportInfoByIndex(
|
||||||
cornerstoneViewportService.getViewportInfoByIndex(viewportIndex);
|
viewportIndex
|
||||||
|
);
|
||||||
|
|
||||||
if (viewportInfo?.viewportOptions?.customViewportProps?.hideOverlays) {
|
if (viewportInfo?.viewportOptions?.customViewportProps?.hideOverlays) {
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@ -35,9 +35,15 @@ const DEFAULT_CONTEXT_MENU_CLICKS = {
|
|||||||
function getEventName(evt) {
|
function getEventName(evt) {
|
||||||
const button = evt.detail.event.which;
|
const button = evt.detail.event.which;
|
||||||
const nameArr = [];
|
const nameArr = [];
|
||||||
if (evt.detail.event.altKey) nameArr.push('alt');
|
if (evt.detail.event.altKey) {
|
||||||
if (evt.detail.event.ctrlKey) nameArr.push('ctrl');
|
nameArr.push('alt');
|
||||||
if (evt.detail.event.shiftKey) nameArr.push('shift');
|
}
|
||||||
|
if (evt.detail.event.ctrlKey) {
|
||||||
|
nameArr.push('ctrl');
|
||||||
|
}
|
||||||
|
if (evt.detail.event.shiftKey) {
|
||||||
|
nameArr.push('shift');
|
||||||
|
}
|
||||||
nameArr.push('button');
|
nameArr.push('button');
|
||||||
nameArr.push(button);
|
nameArr.push(button);
|
||||||
return nameArr.join('');
|
return nameArr.join('');
|
||||||
@ -73,7 +79,9 @@ function initContextMenu({
|
|||||||
function elementEnabledHandler(evt) {
|
function elementEnabledHandler(evt) {
|
||||||
const { viewportId, element } = evt.detail;
|
const { viewportId, element } = evt.detail;
|
||||||
const viewportInfo = cornerstoneViewportService.getViewportInfo(viewportId);
|
const viewportInfo = cornerstoneViewportService.getViewportInfo(viewportId);
|
||||||
if (!viewportInfo) return;
|
if (!viewportInfo) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
const viewportIndex = viewportInfo.getViewportIndex();
|
const viewportIndex = viewportInfo.getViewportIndex();
|
||||||
// TODO check update upstream
|
// TODO check update upstream
|
||||||
setEnabledElement(viewportIndex, element);
|
setEnabledElement(viewportIndex, element);
|
||||||
|
|||||||
@ -21,9 +21,15 @@ const DEFAULT_DOUBLE_CLICK = {
|
|||||||
*/
|
*/
|
||||||
function getDoubleClickEventName(evt: CustomEvent) {
|
function getDoubleClickEventName(evt: CustomEvent) {
|
||||||
const nameArr = [];
|
const nameArr = [];
|
||||||
if (evt.detail.event.altKey) nameArr.push('alt');
|
if (evt.detail.event.altKey) {
|
||||||
if (evt.detail.event.ctrlKey) nameArr.push('ctrl');
|
nameArr.push('alt');
|
||||||
if (evt.detail.event.shiftKey) nameArr.push('shift');
|
}
|
||||||
|
if (evt.detail.event.ctrlKey) {
|
||||||
|
nameArr.push('ctrl');
|
||||||
|
}
|
||||||
|
if (evt.detail.event.shiftKey) {
|
||||||
|
nameArr.push('shift');
|
||||||
|
}
|
||||||
nameArr.push('doubleClick');
|
nameArr.push('doubleClick');
|
||||||
return nameArr.join('');
|
return nameArr.join('');
|
||||||
}
|
}
|
||||||
|
|||||||
@ -190,18 +190,26 @@ class CornerstoneViewportService extends PubSubService
|
|||||||
|
|
||||||
public setPresentations(viewport, presentations?: Presentations): void {
|
public setPresentations(viewport, presentations?: Presentations): void {
|
||||||
const properties = presentations?.lutPresentation?.properties;
|
const properties = presentations?.lutPresentation?.properties;
|
||||||
if (properties) viewport.setProperties(properties);
|
if (properties) {
|
||||||
|
viewport.setProperties(properties);
|
||||||
|
}
|
||||||
const camera = presentations?.positionPresentation?.camera;
|
const camera = presentations?.positionPresentation?.camera;
|
||||||
if (camera) viewport.setCamera(camera);
|
if (camera) {
|
||||||
|
viewport.setCamera(camera);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public getPresentation(viewportIndex: number): Presentation {
|
public getPresentation(viewportIndex: number): Presentation {
|
||||||
const viewportInfo = this.viewportsInfo.get(viewportIndex);
|
const viewportInfo = this.viewportsInfo.get(viewportIndex);
|
||||||
if (!viewportInfo) return;
|
if (!viewportInfo) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
const { viewportType, presentationIds } = viewportInfo.getViewportOptions();
|
const { viewportType, presentationIds } = viewportInfo.getViewportOptions();
|
||||||
|
|
||||||
const csViewport = this.getCornerstoneViewportByIndex(viewportIndex);
|
const csViewport = this.getCornerstoneViewportByIndex(viewportIndex);
|
||||||
if (!csViewport) return;
|
if (!csViewport) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const properties = csViewport.getProperties();
|
const properties = csViewport.getProperties();
|
||||||
if (properties.isComputedVOI) {
|
if (properties.isComputedVOI) {
|
||||||
@ -408,7 +416,9 @@ class CornerstoneViewportService extends PubSubService
|
|||||||
viewport.setStack(imageIds, initialImageIndexToUse).then(() => {
|
viewport.setStack(imageIds, initialImageIndexToUse).then(() => {
|
||||||
viewport.setProperties(properties);
|
viewport.setProperties(properties);
|
||||||
const camera = presentations.positionPresentation?.camera;
|
const camera = presentations.positionPresentation?.camera;
|
||||||
if (camera) viewport.setCamera(camera);
|
if (camera) {
|
||||||
|
viewport.setCamera(camera);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -745,7 +755,10 @@ class CornerstoneViewportService extends PubSubService
|
|||||||
const viewport = this.getCornerstoneViewport(viewportId);
|
const viewport = this.getCornerstoneViewport(viewportId);
|
||||||
const viewportCamera = viewport.getCamera();
|
const viewportCamera = viewport.getCamera();
|
||||||
|
|
||||||
if (viewport instanceof VolumeViewport || viewport instanceof VolumeViewport3D) {
|
if (
|
||||||
|
viewport instanceof VolumeViewport ||
|
||||||
|
viewport instanceof VolumeViewport3D
|
||||||
|
) {
|
||||||
this._setVolumeViewport(viewport, viewportData, viewportInfo).then(() => {
|
this._setVolumeViewport(viewport, viewportData, viewportInfo).then(() => {
|
||||||
if (keepCamera) {
|
if (keepCamera) {
|
||||||
viewport.setCamera(viewportCamera);
|
viewport.setCamera(viewportCamera);
|
||||||
|
|||||||
@ -95,7 +95,9 @@ const dataContains = (
|
|||||||
displaySetUID: string,
|
displaySetUID: string,
|
||||||
imageId?: string
|
imageId?: string
|
||||||
): boolean => {
|
): boolean => {
|
||||||
if (data.displaySetInstanceUID === displaySetUID) return true;
|
if (data.displaySetInstanceUID === displaySetUID) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
if (imageId && data.isCompositeStack && data.imageIds) {
|
if (imageId && data.isCompositeStack && data.imageIds) {
|
||||||
return !!data.imageIds.find(dataId => dataId === imageId);
|
return !!data.imageIds.find(dataId => dataId === imageId);
|
||||||
}
|
}
|
||||||
@ -123,7 +125,9 @@ class ViewportInfo {
|
|||||||
* OR if it is a composite stack and contains the given imageId
|
* OR if it is a composite stack and contains the given imageId
|
||||||
*/
|
*/
|
||||||
public contains(displaySetUID: string, imageId: string): boolean {
|
public contains(displaySetUID: string, imageId: string): boolean {
|
||||||
if (!this.viewportData?.data) return false;
|
if (!this.viewportData?.data) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (this.viewportData.data.length) {
|
if (this.viewportData.data.length) {
|
||||||
return !!this.viewportData.data.find(data =>
|
return !!this.viewportData.data.find(data =>
|
||||||
|
|||||||
@ -212,7 +212,9 @@ export default class DicomFileUploader extends PubSubService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private _checkDicomFile(arrayBuffer: ArrayBuffer) {
|
private _checkDicomFile(arrayBuffer: ArrayBuffer) {
|
||||||
if (arrayBuffer.length <= 132) return false;
|
if (arrayBuffer.length <= 132) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
const arr = new Uint8Array(arrayBuffer.slice(128, 132));
|
const arr = new Uint8Array(arrayBuffer.slice(128, 132));
|
||||||
// bytes from 128 to 132 must be "DICM"
|
// bytes from 128 to 132 must be "DICM"
|
||||||
return Array.from('DICM').every((char, i) => char.charCodeAt(0) === arr[i]);
|
return Array.from('DICM').every((char, i) => char.charCodeAt(0) === arr[i]);
|
||||||
|
|||||||
@ -35,8 +35,9 @@ function callInputDialog(
|
|||||||
const onSubmitHandler = ({ action, value }) => {
|
const onSubmitHandler = ({ action, value }) => {
|
||||||
switch (action.id) {
|
switch (action.id) {
|
||||||
case 'save':
|
case 'save':
|
||||||
if (typeof validateFunc === 'function' && !validateFunc(value.label))
|
if (typeof validateFunc === 'function' && !validateFunc(value.label)) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
callback(value.label, action.id);
|
callback(value.label, action.id);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@ -7,8 +7,12 @@
|
|||||||
* @returns [] reordered to be breadth first traversal of lists
|
* @returns [] reordered to be breadth first traversal of lists
|
||||||
*/
|
*/
|
||||||
export default function interleave(lists) {
|
export default function interleave(lists) {
|
||||||
if (!lists || !lists.length) return [];
|
if (!lists || !lists.length) {
|
||||||
if (lists.length === 1) return lists[0];
|
return [];
|
||||||
|
}
|
||||||
|
if (lists.length === 1) {
|
||||||
|
return lists[0];
|
||||||
|
}
|
||||||
console.time('interleave');
|
console.time('interleave');
|
||||||
const useLists = [...lists];
|
const useLists = [...lists];
|
||||||
const ret = [];
|
const ret = [];
|
||||||
|
|||||||
@ -3,7 +3,7 @@ import getSOPInstanceAttributes from './utils/getSOPInstanceAttributes';
|
|||||||
import { utils } from '@ohif/core';
|
import { utils } from '@ohif/core';
|
||||||
|
|
||||||
const Angle = {
|
const Angle = {
|
||||||
toAnnotation: measurement => { },
|
toAnnotation: measurement => {},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maps cornerstone annotation event data to measurement service format.
|
* Maps cornerstone annotation event data to measurement service format.
|
||||||
@ -198,7 +198,9 @@ function getDisplayText(mappedAnnotations, displaySet) {
|
|||||||
|
|
||||||
const instanceText = InstanceNumber ? ` I: ${InstanceNumber}` : '';
|
const instanceText = InstanceNumber ? ` I: ${InstanceNumber}` : '';
|
||||||
const frameText = displaySet.isMultiFrame ? ` F: ${frameNumber}` : '';
|
const frameText = displaySet.isMultiFrame ? ` F: ${frameNumber}` : '';
|
||||||
if (angle === undefined) return displayText;
|
if (angle === undefined) {
|
||||||
|
return displayText;
|
||||||
|
}
|
||||||
const roundedAngle = utils.roundNumber(angle, 2);
|
const roundedAngle = utils.roundNumber(angle, 2);
|
||||||
displayText.push(
|
displayText.push(
|
||||||
`${roundedAngle} ${unit} (S: ${SeriesNumber}${instanceText}${frameText})`
|
`${roundedAngle} ${unit} (S: ${SeriesNumber}${instanceText}${frameText})`
|
||||||
|
|||||||
@ -3,7 +3,7 @@ import getSOPInstanceAttributes from './utils/getSOPInstanceAttributes';
|
|||||||
import { utils } from '@ohif/core';
|
import { utils } from '@ohif/core';
|
||||||
|
|
||||||
const CobbAngle = {
|
const CobbAngle = {
|
||||||
toAnnotation: measurement => { },
|
toAnnotation: measurement => {},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maps cornerstone annotation event data to measurement service format.
|
* Maps cornerstone annotation event data to measurement service format.
|
||||||
@ -198,7 +198,9 @@ function getDisplayText(mappedAnnotations, displaySet) {
|
|||||||
|
|
||||||
const instanceText = InstanceNumber ? ` I: ${InstanceNumber}` : '';
|
const instanceText = InstanceNumber ? ` I: ${InstanceNumber}` : '';
|
||||||
const frameText = displaySet.isMultiFrame ? ` F: ${frameNumber}` : '';
|
const frameText = displaySet.isMultiFrame ? ` F: ${frameNumber}` : '';
|
||||||
if (angle === undefined) return displayText;
|
if (angle === undefined) {
|
||||||
|
return displayText;
|
||||||
|
}
|
||||||
const roundedAngle = utils.roundNumber(angle, 2);
|
const roundedAngle = utils.roundNumber(angle, 2);
|
||||||
displayText.push(
|
displayText.push(
|
||||||
`${roundedAngle} ${unit} (S: ${SeriesNumber}${instanceText}${frameText})`
|
`${roundedAngle} ${unit} (S: ${SeriesNumber}${instanceText}${frameText})`
|
||||||
|
|||||||
@ -32,12 +32,15 @@ const Length = {
|
|||||||
throw new Error('Tool not supported');
|
throw new Error('Tool not supported');
|
||||||
}
|
}
|
||||||
|
|
||||||
const { SOPInstanceUID, SeriesInstanceUID, StudyInstanceUID } =
|
const {
|
||||||
getSOPInstanceAttributes(
|
SOPInstanceUID,
|
||||||
referencedImageId,
|
SeriesInstanceUID,
|
||||||
cornerstoneViewportService,
|
StudyInstanceUID,
|
||||||
viewportId
|
} = getSOPInstanceAttributes(
|
||||||
);
|
referencedImageId,
|
||||||
|
cornerstoneViewportService,
|
||||||
|
viewportId
|
||||||
|
);
|
||||||
|
|
||||||
let displaySet;
|
let displaySet;
|
||||||
|
|
||||||
@ -101,8 +104,11 @@ function getMappedAnnotations(annotation, displaySetService) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const { SOPInstanceUID, SeriesInstanceUID, frameNumber } =
|
const {
|
||||||
getSOPInstanceAttributes(referencedImageId);
|
SOPInstanceUID,
|
||||||
|
SeriesInstanceUID,
|
||||||
|
frameNumber,
|
||||||
|
} = getSOPInstanceAttributes(referencedImageId);
|
||||||
|
|
||||||
const displaySet = displaySetService.getDisplaySetForSOPInstanceUID(
|
const displaySet = displaySetService.getDisplaySetForSOPInstanceUID(
|
||||||
SOPInstanceUID,
|
SOPInstanceUID,
|
||||||
@ -173,8 +179,12 @@ function getDisplayText(mappedAnnotations, displaySet) {
|
|||||||
const displayText = [];
|
const displayText = [];
|
||||||
|
|
||||||
// Area is the same for all series
|
// Area is the same for all series
|
||||||
const { length, SeriesNumber, SOPInstanceUID, frameNumber } =
|
const {
|
||||||
mappedAnnotations[0];
|
length,
|
||||||
|
SeriesNumber,
|
||||||
|
SOPInstanceUID,
|
||||||
|
frameNumber,
|
||||||
|
} = mappedAnnotations[0];
|
||||||
|
|
||||||
const instance = displaySet.images.find(
|
const instance = displaySet.images.find(
|
||||||
image => image.SOPInstanceUID === SOPInstanceUID
|
image => image.SOPInstanceUID === SOPInstanceUID
|
||||||
@ -188,7 +198,9 @@ function getDisplayText(mappedAnnotations, displaySet) {
|
|||||||
const instanceText = InstanceNumber ? ` I: ${InstanceNumber}` : '';
|
const instanceText = InstanceNumber ? ` I: ${InstanceNumber}` : '';
|
||||||
const frameText = displaySet.isMultiFrame ? ` F: ${frameNumber}` : '';
|
const frameText = displaySet.isMultiFrame ? ` F: ${frameNumber}` : '';
|
||||||
|
|
||||||
if (length === null || length === undefined) return displayText;
|
if (length === null || length === undefined) {
|
||||||
|
return displayText;
|
||||||
|
}
|
||||||
const roundedLength = utils.roundNumber(length, 2);
|
const roundedLength = utils.roundNumber(length, 2);
|
||||||
displayText.push(
|
displayText.push(
|
||||||
`${roundedLength} mm (S: ${SeriesNumber}${instanceText}${frameText})`
|
`${roundedLength} mm (S: ${SeriesNumber}${instanceText}${frameText})`
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import SUPPORTED_TOOLS from './constants/supportedTools';
|
|||||||
import getSOPInstanceAttributes from './utils/getSOPInstanceAttributes';
|
import getSOPInstanceAttributes from './utils/getSOPInstanceAttributes';
|
||||||
|
|
||||||
const PlanarFreehandROI = {
|
const PlanarFreehandROI = {
|
||||||
toAnnotation: measurement => { },
|
toAnnotation: measurement => {},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maps cornerstone annotation event data to measurement service format.
|
* Maps cornerstone annotation event data to measurement service format.
|
||||||
|
|||||||
@ -25,12 +25,15 @@ const RectangleROI = {
|
|||||||
throw new Error('Tool not supported');
|
throw new Error('Tool not supported');
|
||||||
}
|
}
|
||||||
|
|
||||||
const { SOPInstanceUID, SeriesInstanceUID, StudyInstanceUID } =
|
const {
|
||||||
getSOPInstanceAttributes(
|
SOPInstanceUID,
|
||||||
referencedImageId,
|
SeriesInstanceUID,
|
||||||
CornerstoneViewportService,
|
StudyInstanceUID,
|
||||||
viewportId
|
} = getSOPInstanceAttributes(
|
||||||
);
|
referencedImageId,
|
||||||
|
CornerstoneViewportService,
|
||||||
|
viewportId
|
||||||
|
);
|
||||||
|
|
||||||
let displaySet;
|
let displaySet;
|
||||||
|
|
||||||
@ -95,8 +98,11 @@ function getMappedAnnotations(annotation, DisplaySetService) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const { SOPInstanceUID, SeriesInstanceUID, frameNumber } =
|
const {
|
||||||
getSOPInstanceAttributes(referencedImageId);
|
SOPInstanceUID,
|
||||||
|
SeriesInstanceUID,
|
||||||
|
frameNumber,
|
||||||
|
} = getSOPInstanceAttributes(referencedImageId);
|
||||||
|
|
||||||
const displaySet = DisplaySetService.getDisplaySetForSOPInstanceUID(
|
const displaySet = DisplaySetService.getDisplaySetForSOPInstanceUID(
|
||||||
SOPInstanceUID,
|
SOPInstanceUID,
|
||||||
|
|||||||
@ -46,7 +46,9 @@ function createDicomJSONApi(dicomJsonConfig) {
|
|||||||
|
|
||||||
const implementation = {
|
const implementation = {
|
||||||
initialize: async ({ query, url }) => {
|
initialize: async ({ query, url }) => {
|
||||||
if (!url) url = query.get('url');
|
if (!url) {
|
||||||
|
url = query.get('url');
|
||||||
|
}
|
||||||
let metaData = getMetaDataByURL(url);
|
let metaData = getMetaDataByURL(url);
|
||||||
|
|
||||||
// if we have already cached the data from this specific url
|
// if we have already cached the data from this specific url
|
||||||
@ -212,7 +214,9 @@ function createDicomJSONApi(dicomJsonConfig) {
|
|||||||
return obj;
|
return obj;
|
||||||
});
|
});
|
||||||
storeInstances(instances);
|
storeInstances(instances);
|
||||||
if (index === numberOfSeries - 1) setSuccessFlag();
|
if (index === numberOfSeries - 1) {
|
||||||
|
setSuccessFlag();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@ -12,8 +12,12 @@ const END_MODALITIES = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const compareValue = (v1, v2, def = 0) => {
|
const compareValue = (v1, v2, def = 0) => {
|
||||||
if (v1 === v2) return def;
|
if (v1 === v2) {
|
||||||
if (v1 < v2) return -1;
|
return def;
|
||||||
|
}
|
||||||
|
if (v1 < v2) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
return 1;
|
return 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
export default function (wadoRoot) {
|
export default function(wadoRoot) {
|
||||||
return {
|
return {
|
||||||
series: (StudyInstanceUID, SeriesInstanceUID) => {
|
series: (StudyInstanceUID, SeriesInstanceUID) => {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
@ -15,7 +15,7 @@ export default function (wadoRoot) {
|
|||||||
|
|
||||||
console.log(xhr);
|
console.log(xhr);
|
||||||
|
|
||||||
xhr.onreadystatechange = function () {
|
xhr.onreadystatechange = function() {
|
||||||
//Call a function when the state changes.
|
//Call a function when the state changes.
|
||||||
if (xhr.readyState == 4) {
|
if (xhr.readyState == 4) {
|
||||||
switch (xhr.status) {
|
switch (xhr.status) {
|
||||||
|
|||||||
@ -36,12 +36,16 @@ export default class StaticWadoClient extends api.DICOMwebClient {
|
|||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
async searchForStudies(options) {
|
async searchForStudies(options) {
|
||||||
if (!this.staticWado) return super.searchForStudies(options);
|
if (!this.staticWado) {
|
||||||
|
return super.searchForStudies(options);
|
||||||
|
}
|
||||||
|
|
||||||
const searchResult = await super.searchForStudies(options);
|
const searchResult = await super.searchForStudies(options);
|
||||||
const { queryParams } = options;
|
const { queryParams } = options;
|
||||||
|
|
||||||
if (!queryParams) return searchResult;
|
if (!queryParams) {
|
||||||
|
return searchResult;
|
||||||
|
}
|
||||||
|
|
||||||
const lowerParams = this.toLowerParams(queryParams);
|
const lowerParams = this.toLowerParams(queryParams);
|
||||||
const filtered = searchResult.filter(study => {
|
const filtered = searchResult.filter(study => {
|
||||||
@ -63,11 +67,15 @@ export default class StaticWadoClient extends api.DICOMwebClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async searchForSeries(options) {
|
async searchForSeries(options) {
|
||||||
if (!this.staticWado) return super.searchForSeries(options);
|
if (!this.staticWado) {
|
||||||
|
return super.searchForSeries(options);
|
||||||
|
}
|
||||||
|
|
||||||
const searchResult = await super.searchForSeries(options);
|
const searchResult = await super.searchForSeries(options);
|
||||||
const { queryParams } = options;
|
const { queryParams } = options;
|
||||||
if (!queryParams) return searchResult;
|
if (!queryParams) {
|
||||||
|
return searchResult;
|
||||||
|
}
|
||||||
const lowerParams = this.toLowerParams(queryParams);
|
const lowerParams = this.toLowerParams(queryParams);
|
||||||
|
|
||||||
const filtered = searchResult.filter(series => {
|
const filtered = searchResult.filter(series => {
|
||||||
@ -112,8 +120,12 @@ export default class StaticWadoClient extends api.DICOMwebClient {
|
|||||||
actual = actual.Alphabetic;
|
actual = actual.Alphabetic;
|
||||||
}
|
}
|
||||||
if (typeof actual == 'string') {
|
if (typeof actual == 'string') {
|
||||||
if (actual.length === 0) return true;
|
if (actual.length === 0) {
|
||||||
if (desired.length === 0 || desired === '*') return true;
|
return true;
|
||||||
|
}
|
||||||
|
if (desired.length === 0 || desired === '*') {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
if (desired[0] === '*' && desired[desired.length - 1] === '*') {
|
if (desired[0] === '*' && desired[desired.length - 1] === '*') {
|
||||||
// console.log(`Comparing ${actual} to ${desired.substring(1, desired.length - 1)}`)
|
// console.log(`Comparing ${actual} to ${desired.substring(1, desired.length - 1)}`)
|
||||||
return actual.indexOf(desired.substring(1, desired.length - 1)) != -1;
|
return actual.indexOf(desired.substring(1, desired.length - 1)) != -1;
|
||||||
@ -131,9 +143,13 @@ export default class StaticWadoClient extends api.DICOMwebClient {
|
|||||||
|
|
||||||
/** Compares a pair of dates to see if the value is within the range */
|
/** Compares a pair of dates to see if the value is within the range */
|
||||||
compareDateRange(range, value) {
|
compareDateRange(range, value) {
|
||||||
if (!value) return true;
|
if (!value) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
const dash = range.indexOf('-');
|
const dash = range.indexOf('-');
|
||||||
if (dash === -1) return this.compareValues(range, value);
|
if (dash === -1) {
|
||||||
|
return this.compareValues(range, value);
|
||||||
|
}
|
||||||
const start = range.substring(0, dash);
|
const start = range.substring(0, dash);
|
||||||
const end = range.substring(dash + 1);
|
const end = range.substring(dash + 1);
|
||||||
return (!start || value >= start) && (!end || value <= end);
|
return (!start || value >= start) && (!end || value <= end);
|
||||||
@ -150,11 +166,17 @@ export default class StaticWadoClient extends api.DICOMwebClient {
|
|||||||
*/
|
*/
|
||||||
filterItem(key: string, queryParams, study, sourceFilterMap) {
|
filterItem(key: string, queryParams, study, sourceFilterMap) {
|
||||||
const altKey = sourceFilterMap[key] || key;
|
const altKey = sourceFilterMap[key] || key;
|
||||||
if (!queryParams) return true;
|
if (!queryParams) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
const testValue = queryParams[key] || queryParams[altKey];
|
const testValue = queryParams[key] || queryParams[altKey];
|
||||||
if (!testValue) return true;
|
if (!testValue) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
const valueElem = study[key] || study[altKey];
|
const valueElem = study[key] || study[altKey];
|
||||||
if (!valueElem) return false;
|
if (!valueElem) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (valueElem.vr == 'DA') {
|
if (valueElem.vr == 'DA') {
|
||||||
return this.compareDateRange(testValue, valueElem.Value[0]);
|
return this.compareDateRange(testValue, valueElem.Value[0]);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -276,7 +276,9 @@ function _mapMeasurementToDisplay(measurement, index, types) {
|
|||||||
if (findingSites) {
|
if (findingSites) {
|
||||||
const siteText = [];
|
const siteText = [];
|
||||||
findingSites.forEach(site => {
|
findingSites.forEach(site => {
|
||||||
if (site?.text !== label) siteText.push(site.text);
|
if (site?.text !== label) {
|
||||||
|
siteText.push(site.text);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
displayText = [...siteText, ...displayText];
|
displayText = [...siteText, ...displayText];
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,12 +9,16 @@ function debounce(func, wait, immediate) {
|
|||||||
args = arguments;
|
args = arguments;
|
||||||
var later = function() {
|
var later = function() {
|
||||||
timeout = null;
|
timeout = null;
|
||||||
if (!immediate) func.apply(context, args);
|
if (!immediate) {
|
||||||
|
func.apply(context, args);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
var callNow = immediate && !timeout;
|
var callNow = immediate && !timeout;
|
||||||
clearTimeout(timeout);
|
clearTimeout(timeout);
|
||||||
timeout = setTimeout(later, wait);
|
timeout = setTimeout(later, wait);
|
||||||
if (callNow) func.apply(context, args);
|
if (callNow) {
|
||||||
|
func.apply(context, args);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -40,8 +40,8 @@ NestedMenu.propTypes = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
NestedMenu.defaultProps = {
|
NestedMenu.defaultProps = {
|
||||||
icon: "tool-more-menu",
|
icon: 'tool-more-menu',
|
||||||
label: "More",
|
label: 'More',
|
||||||
};
|
};
|
||||||
|
|
||||||
export default NestedMenu;
|
export default NestedMenu;
|
||||||
|
|||||||
@ -50,7 +50,7 @@ function ViewerLayout({
|
|||||||
// dataSourceIdx === -1
|
// dataSourceIdx === -1
|
||||||
// ? undefined
|
// ? undefined
|
||||||
// : `datasources=${pathname.substring(dataSourceIdx + 1)}`;
|
// : `datasources=${pathname.substring(dataSourceIdx + 1)}`;
|
||||||
|
|
||||||
// Todo: Handle parameters in a better way.
|
// Todo: Handle parameters in a better way.
|
||||||
const query = new URLSearchParams(window.location.search);
|
const query = new URLSearchParams(window.location.search);
|
||||||
const configUrl = query.get('configUrl');
|
const configUrl = query.get('configUrl');
|
||||||
@ -69,7 +69,7 @@ function ViewerLayout({
|
|||||||
|
|
||||||
navigate({
|
navigate({
|
||||||
pathname: '/',
|
pathname: '/',
|
||||||
search: decodeURIComponent(searchQuery.toString())
|
search: decodeURIComponent(searchQuery.toString()),
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -129,13 +129,17 @@ const commandsModule = ({
|
|||||||
stage,
|
stage,
|
||||||
} = hangingProtocolService.getActiveProtocol();
|
} = hangingProtocolService.getActiveProtocol();
|
||||||
const enableListener = button => {
|
const enableListener = button => {
|
||||||
if (!button.id) return;
|
if (!button.id) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
const { commands, items } = button.props || button;
|
const { commands, items } = button.props || button;
|
||||||
if (items) {
|
if (items) {
|
||||||
items.forEach(enableListener);
|
items.forEach(enableListener);
|
||||||
}
|
}
|
||||||
const hpCommand = commands?.find?.(isHangingProtocolCommand);
|
const hpCommand = commands?.find?.(isHangingProtocolCommand);
|
||||||
if (!hpCommand) return;
|
if (!hpCommand) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
const { protocolId, stageIndex, stageId } = hpCommand.commandOptions;
|
const { protocolId, stageIndex, stageId } = hpCommand.commandOptions;
|
||||||
const isActive =
|
const isActive =
|
||||||
(!protocolId || protocolId === protocol.id) &&
|
(!protocolId || protocolId === protocol.id) &&
|
||||||
|
|||||||
@ -22,7 +22,9 @@ export const findOrCreateViewport = (
|
|||||||
options: Record<string, unknown>
|
options: Record<string, unknown>
|
||||||
) => {
|
) => {
|
||||||
const byPositionViewport = viewportsByPosition?.[positionId];
|
const byPositionViewport = viewportsByPosition?.[positionId];
|
||||||
if (byPositionViewport) return { ...byPositionViewport };
|
if (byPositionViewport) {
|
||||||
|
return { ...byPositionViewport };
|
||||||
|
}
|
||||||
const { protocolId, stageIndex } = hangingProtocolService.getState();
|
const { protocolId, stageIndex } = hangingProtocolService.getState();
|
||||||
|
|
||||||
// Setup the initial in display correctly for initial view/select
|
// Setup the initial in display correctly for initial view/select
|
||||||
|
|||||||
@ -83,17 +83,21 @@ export default function getCustomizationModule() {
|
|||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
id: 'ohif.overlayItem',
|
id: 'ohif.overlayItem',
|
||||||
content: function (props) {
|
content: function(props) {
|
||||||
if (this.condition && !this.condition(props)) return null;
|
if (this.condition && !this.condition(props)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
const { instance } = props;
|
const { instance } = props;
|
||||||
const value =
|
const value =
|
||||||
instance && this.attribute
|
instance && this.attribute
|
||||||
? instance[this.attribute]
|
? instance[this.attribute]
|
||||||
: this.contentF && typeof this.contentF === 'function'
|
: this.contentF && typeof this.contentF === 'function'
|
||||||
? this.contentF(props)
|
? this.contentF(props)
|
||||||
: null;
|
: null;
|
||||||
if (!value) return null;
|
if (!value) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<span
|
<span
|
||||||
@ -117,7 +121,7 @@ export default function getCustomizationModule() {
|
|||||||
* This function clones the object and child objects to prevent
|
* This function clones the object and child objects to prevent
|
||||||
* changes to the original customization object.
|
* changes to the original customization object.
|
||||||
*/
|
*/
|
||||||
transform: function (customizationService: CustomizationService) {
|
transform: function(customizationService: CustomizationService) {
|
||||||
// Don't modify the children, as those are copied by reference
|
// Don't modify the children, as those are copied by reference
|
||||||
const clonedObject = { ...this };
|
const clonedObject = { ...this };
|
||||||
clonedObject.menus = this.menus.map(menu => ({ ...menu }));
|
clonedObject.menus = this.menus.map(menu => ({ ...menu }));
|
||||||
|
|||||||
@ -23,9 +23,13 @@ const getDirectURL = (config, params) => {
|
|||||||
singlepart: fetchPart = 'video',
|
singlepart: fetchPart = 'video',
|
||||||
} = params;
|
} = params;
|
||||||
const value = instance[tag];
|
const value = instance[tag];
|
||||||
if (!value) return undefined;
|
if (!value) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
if (value.DirectRetrieveURL) return value.DirectRetrieveURL;
|
if (value.DirectRetrieveURL) {
|
||||||
|
return value.DirectRetrieveURL;
|
||||||
|
}
|
||||||
if (value.InlineBinary) {
|
if (value.InlineBinary) {
|
||||||
const blob = utils.b64toBlob(value.InlineBinary, defaultType);
|
const blob = utils.b64toBlob(value.InlineBinary, defaultType);
|
||||||
value.DirectRetrieveURL = URL.createObjectURL(blob);
|
value.DirectRetrieveURL = URL.createObjectURL(blob);
|
||||||
|
|||||||
@ -47,10 +47,14 @@ const reuseCachedLayout = (
|
|||||||
for (let idx = 0; idx < state.viewports.length; idx++) {
|
for (let idx = 0; idx < state.viewports.length; idx++) {
|
||||||
const viewport = state.viewports[idx];
|
const viewport = state.viewports[idx];
|
||||||
const { displaySetOptions, displaySetInstanceUIDs } = viewport;
|
const { displaySetOptions, displaySetInstanceUIDs } = viewport;
|
||||||
if (!displaySetOptions) continue;
|
if (!displaySetOptions) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
for (let i = 0; i < displaySetOptions.length; i++) {
|
for (let i = 0; i < displaySetOptions.length; i++) {
|
||||||
const displaySetUID = displaySetInstanceUIDs[i];
|
const displaySetUID = displaySetInstanceUIDs[i];
|
||||||
if (!displaySetUID) continue;
|
if (!displaySetUID) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (idx === activeViewportIndex && i === 0) {
|
if (idx === activeViewportIndex && i === 0) {
|
||||||
displaySetSelectorMap[
|
displaySetSelectorMap[
|
||||||
`${activeStudyUID}:activeDisplaySet:0`
|
`${activeStudyUID}:activeDisplaySet:0`
|
||||||
|
|||||||
@ -41,7 +41,9 @@ class DicomMicroscopyViewport extends Component {
|
|||||||
const { microscopyService } = this.props.servicesManager.services;
|
const { microscopyService } = this.props.servicesManager.services;
|
||||||
this.microscopyService = microscopyService;
|
this.microscopyService = microscopyService;
|
||||||
this.debouncedResize = debounce(() => {
|
this.debouncedResize = debounce(() => {
|
||||||
if (this.viewer) this.viewer.resize();
|
if (this.viewer) {
|
||||||
|
this.viewer.resize();
|
||||||
|
}
|
||||||
}, 100);
|
}, 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -107,8 +107,12 @@ const itemGenerator = (props: any) => {
|
|||||||
props.formatTime = formatDICOMTime;
|
props.formatTime = formatDICOMTime;
|
||||||
props.formatPN = formatPN;
|
props.formatPN = formatPN;
|
||||||
props.formatNumberPrecision = formatNumberPrecision;
|
props.formatNumberPrecision = formatNumberPrecision;
|
||||||
if (condition && !condition(props)) return null;
|
if (condition && !condition(props)) {
|
||||||
if (!contents && !valueFunc) return null;
|
return null;
|
||||||
|
}
|
||||||
|
if (!contents && !valueFunc) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
const value = valueFunc && valueFunc(props);
|
const value = valueFunc && valueFunc(props);
|
||||||
const contentsValue = (contents && contents(props)) || [
|
const contentsValue = (contents && contents(props)) || [
|
||||||
{ className: 'mr-1', value: title },
|
{ className: 'mr-1', value: title },
|
||||||
|
|||||||
@ -1,10 +1,16 @@
|
|||||||
const listComponentGenerator = props => {
|
const listComponentGenerator = props => {
|
||||||
const { list, itemGenerator } = props;
|
const { list, itemGenerator } = props;
|
||||||
if (!list) return;
|
if (!list) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
return list.map(item => {
|
return list.map(item => {
|
||||||
if (!item) return;
|
if (!item) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
const generator = item.generator || itemGenerator;
|
const generator = item.generator || itemGenerator;
|
||||||
if (!generator) throw new Error(`No generator for ${item}`);
|
if (!generator) {
|
||||||
|
throw new Error(`No generator for ${item}`);
|
||||||
|
}
|
||||||
return generator({ ...props, item });
|
return generator({ ...props, item });
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@ -22,7 +22,9 @@ export default function getCommandsModule({
|
|||||||
deleteMeasurement: ({ uid }) => {
|
deleteMeasurement: ({ uid }) => {
|
||||||
if (uid) {
|
if (uid) {
|
||||||
const roiAnnotation = microscopyService.getAnnotation(uid);
|
const roiAnnotation = microscopyService.getAnnotation(uid);
|
||||||
if (roiAnnotation) microscopyService.removeAnnotation(roiAnnotation);
|
if (roiAnnotation) {
|
||||||
|
microscopyService.removeAnnotation(roiAnnotation);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -72,7 +74,7 @@ export default function getCommandsModule({
|
|||||||
].indexOf(toolName) >= 0
|
].indexOf(toolName) >= 0
|
||||||
) {
|
) {
|
||||||
// TODO: read from configuration
|
// TODO: read from configuration
|
||||||
let options = {
|
const options = {
|
||||||
geometryType: toolName,
|
geometryType: toolName,
|
||||||
vertexEnabled: true,
|
vertexEnabled: true,
|
||||||
styleOptions: styles.default,
|
styleOptions: styles.default,
|
||||||
@ -140,7 +142,9 @@ export default function getCommandsModule({
|
|||||||
);
|
);
|
||||||
let onoff = false; // true if this will toggle on
|
let onoff = false; // true if this will toggle on
|
||||||
for (let i = 0; i < overlays.length; i++) {
|
for (let i = 0; i < overlays.length; i++) {
|
||||||
if (i === 0) onoff = overlays.item(0).classList.contains('hidden');
|
if (i === 0) {
|
||||||
|
onoff = overlays.item(0).classList.contains('hidden');
|
||||||
|
}
|
||||||
overlays.item(i).classList.toggle('hidden');
|
overlays.item(i).classList.toggle('hidden');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -5,7 +5,9 @@
|
|||||||
* @returns {string} formatted name
|
* @returns {string} formatted name
|
||||||
*/
|
*/
|
||||||
export default function formatDICOMPatientName(name) {
|
export default function formatDICOMPatientName(name) {
|
||||||
if (typeof name !== 'string') return;
|
if (typeof name !== 'string') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert the first ^ to a ', '. String.replace() only affects
|
* Convert the first ^ to a ', '. String.replace() only affects
|
||||||
|
|||||||
@ -56,7 +56,7 @@ export default class MicroscopyService extends PubSubService {
|
|||||||
clear() {
|
clear() {
|
||||||
this.managedViewers.forEach(managedViewer => managedViewer.destroy());
|
this.managedViewers.forEach(managedViewer => managedViewer.destroy());
|
||||||
this.managedViewers.clear();
|
this.managedViewers.clear();
|
||||||
for (var key in this.annotations) {
|
for (const key in this.annotations) {
|
||||||
delete this.annotations[key];
|
delete this.annotations[key];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,7 +124,9 @@ export default class MicroscopyService extends PubSubService {
|
|||||||
_onRoiModified(data) {
|
_onRoiModified(data) {
|
||||||
const { roiGraphic, managedViewer } = data;
|
const { roiGraphic, managedViewer } = data;
|
||||||
const roiAnnotation = this.getAnnotation(roiGraphic.uid);
|
const roiAnnotation = this.getAnnotation(roiGraphic.uid);
|
||||||
if (!roiAnnotation) return;
|
if (!roiAnnotation) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
roiAnnotation.setRoiGraphic(roiGraphic);
|
roiAnnotation.setRoiGraphic(roiGraphic);
|
||||||
roiAnnotation.setViewState(managedViewer.getViewState());
|
roiAnnotation.setViewState(managedViewer.getViewState());
|
||||||
}
|
}
|
||||||
@ -156,7 +158,10 @@ export default class MicroscopyService extends PubSubService {
|
|||||||
_onRoiUpdated(data) {
|
_onRoiUpdated(data) {
|
||||||
const { roiGraphic, managedViewer } = data;
|
const { roiGraphic, managedViewer } = data;
|
||||||
this.synchronizeViewers(managedViewer);
|
this.synchronizeViewers(managedViewer);
|
||||||
this._broadcastEvent(EVENTS.ANNOTATION_UPDATED, this.getAnnotation(roiGraphic.uid));
|
this._broadcastEvent(
|
||||||
|
EVENTS.ANNOTATION_UPDATED,
|
||||||
|
this.getAnnotation(roiGraphic.uid)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -170,8 +175,13 @@ export default class MicroscopyService extends PubSubService {
|
|||||||
_onRoiSelected(data) {
|
_onRoiSelected(data) {
|
||||||
const { roiGraphic } = data;
|
const { roiGraphic } = data;
|
||||||
const selectedAnnotation = this.getAnnotation(roiGraphic.uid);
|
const selectedAnnotation = this.getAnnotation(roiGraphic.uid);
|
||||||
if (selectedAnnotation && selectedAnnotation !== this.getSelectedAnnotation()) {
|
if (
|
||||||
if (this.selectedAnnotation) this.clearSelection();
|
selectedAnnotation &&
|
||||||
|
selectedAnnotation !== this.getSelectedAnnotation()
|
||||||
|
) {
|
||||||
|
if (this.selectedAnnotation) {
|
||||||
|
this.clearSelection();
|
||||||
|
}
|
||||||
this.selectedAnnotation = selectedAnnotation;
|
this.selectedAnnotation = selectedAnnotation;
|
||||||
this._broadcastEvent(EVENTS.ANNOTATION_SELECTED, selectedAnnotation);
|
this._broadcastEvent(EVENTS.ANNOTATION_SELECTED, selectedAnnotation);
|
||||||
}
|
}
|
||||||
@ -183,11 +193,26 @@ export default class MicroscopyService extends PubSubService {
|
|||||||
* @param {ViewerManager} managedViewer The viewer being added
|
* @param {ViewerManager} managedViewer The viewer being added
|
||||||
*/
|
*/
|
||||||
_addManagedViewerSubscriptions(managedViewer) {
|
_addManagedViewerSubscriptions(managedViewer) {
|
||||||
managedViewer._roiAddedSubscription = managedViewer.subscribe(ViewerEvents.ADDED, this._onRoiAdded);
|
managedViewer._roiAddedSubscription = managedViewer.subscribe(
|
||||||
managedViewer._roiModifiedSubscription = managedViewer.subscribe(ViewerEvents.MODIFIED, this._onRoiModified);
|
ViewerEvents.ADDED,
|
||||||
managedViewer._roiRemovedSubscription = managedViewer.subscribe(ViewerEvents.REMOVED, this._onRoiRemoved);
|
this._onRoiAdded
|
||||||
managedViewer._roiUpdatedSubscription = managedViewer.subscribe(ViewerEvents.UPDATED, this._onRoiUpdated);
|
);
|
||||||
managedViewer._roiSelectedSubscription = managedViewer.subscribe(ViewerEvents.UPDATED, this._onRoiSelected);
|
managedViewer._roiModifiedSubscription = managedViewer.subscribe(
|
||||||
|
ViewerEvents.MODIFIED,
|
||||||
|
this._onRoiModified
|
||||||
|
);
|
||||||
|
managedViewer._roiRemovedSubscription = managedViewer.subscribe(
|
||||||
|
ViewerEvents.REMOVED,
|
||||||
|
this._onRoiRemoved
|
||||||
|
);
|
||||||
|
managedViewer._roiUpdatedSubscription = managedViewer.subscribe(
|
||||||
|
ViewerEvents.UPDATED,
|
||||||
|
this._onRoiUpdated
|
||||||
|
);
|
||||||
|
managedViewer._roiSelectedSubscription = managedViewer.subscribe(
|
||||||
|
ViewerEvents.UPDATED,
|
||||||
|
this._onRoiSelected
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -196,11 +221,16 @@ export default class MicroscopyService extends PubSubService {
|
|||||||
* @param {ViewerManager} managedViewer The viewer being removed
|
* @param {ViewerManager} managedViewer The viewer being removed
|
||||||
*/
|
*/
|
||||||
_removeManagedViewerSubscriptions(managedViewer) {
|
_removeManagedViewerSubscriptions(managedViewer) {
|
||||||
managedViewer._roiAddedSubscription && managedViewer._roiAddedSubscription.unsubscribe();
|
managedViewer._roiAddedSubscription &&
|
||||||
managedViewer._roiModifiedSubscription && managedViewer._roiModifiedSubscription.unsubscribe();
|
managedViewer._roiAddedSubscription.unsubscribe();
|
||||||
managedViewer._roiRemovedSubscription && managedViewer._roiRemovedSubscription.unsubscribe();
|
managedViewer._roiModifiedSubscription &&
|
||||||
managedViewer._roiUpdatedSubscription && managedViewer._roiUpdatedSubscription.unsubscribe();
|
managedViewer._roiModifiedSubscription.unsubscribe();
|
||||||
managedViewer._roiSelectedSubscription && managedViewer._roiSelectedSubscription.unsubscribe();
|
managedViewer._roiRemovedSubscription &&
|
||||||
|
managedViewer._roiRemovedSubscription.unsubscribe();
|
||||||
|
managedViewer._roiUpdatedSubscription &&
|
||||||
|
managedViewer._roiUpdatedSubscription.unsubscribe();
|
||||||
|
managedViewer._roiSelectedSubscription &&
|
||||||
|
managedViewer._roiSelectedSubscription.unsubscribe();
|
||||||
|
|
||||||
managedViewer._roiAddedSubscription = null;
|
managedViewer._roiAddedSubscription = null;
|
||||||
managedViewer._roiModifiedSubscription = null;
|
managedViewer._roiModifiedSubscription = null;
|
||||||
@ -460,7 +490,9 @@ export default class MicroscopyService extends PubSubService {
|
|||||||
* @param {RoiAnnotation} roiAnnotation The instance to be selected
|
* @param {RoiAnnotation} roiAnnotation The instance to be selected
|
||||||
*/
|
*/
|
||||||
selectAnnotation(roiAnnotation) {
|
selectAnnotation(roiAnnotation) {
|
||||||
if (this.selectedAnnotation) this.clearSelection();
|
if (this.selectedAnnotation) {
|
||||||
|
this.clearSelection();
|
||||||
|
}
|
||||||
|
|
||||||
this.selectedAnnotation = roiAnnotation;
|
this.selectedAnnotation = roiAnnotation;
|
||||||
this._broadcastEvent(EVENTS.ANNOTATION_SELECTED, roiAnnotation);
|
this._broadcastEvent(EVENTS.ANNOTATION_SELECTED, roiAnnotation);
|
||||||
|
|||||||
@ -83,7 +83,9 @@ export default function constructSR(
|
|||||||
console.debug('[SR] storing evaluations...', evaluations);
|
console.debug('[SR] storing evaluations...', evaluations);
|
||||||
console.debug('[SR] storing presentation state...', presentationState);
|
console.debug('[SR] storing presentation state...', presentationState);
|
||||||
|
|
||||||
if (presentationState) presentationState.marker = marker;
|
if (presentationState) {
|
||||||
|
presentationState.marker = marker;
|
||||||
|
}
|
||||||
|
|
||||||
/** Avoid incompatibility with dcmjs */
|
/** Avoid incompatibility with dcmjs */
|
||||||
measurements = measurements.map((measurement: any) => {
|
measurements = measurements.map((measurement: any) => {
|
||||||
|
|||||||
@ -38,7 +38,9 @@ export default function coordinateFormatScoord3d2Geometry(
|
|||||||
}
|
}
|
||||||
|
|
||||||
function _getPixelSpacing(metadata) {
|
function _getPixelSpacing(metadata) {
|
||||||
if (metadata.PixelSpacing) return metadata.PixelSpacing;
|
if (metadata.PixelSpacing) {
|
||||||
|
return metadata.PixelSpacing;
|
||||||
|
}
|
||||||
const functionalGroup = metadata.SharedFunctionalGroupsSequence[0];
|
const functionalGroup = metadata.SharedFunctionalGroupsSequence[0];
|
||||||
const pixelMeasures = functionalGroup.PixelMeasuresSequence[0];
|
const pixelMeasures = functionalGroup.PixelMeasuresSequence[0];
|
||||||
return pixelMeasures.PixelSpacing;
|
return pixelMeasures.PixelSpacing;
|
||||||
|
|||||||
@ -4,8 +4,8 @@
|
|||||||
* @param filename
|
* @param filename
|
||||||
*/
|
*/
|
||||||
export function saveByteArray(buffer: ArrayBuffer, filename: string) {
|
export function saveByteArray(buffer: ArrayBuffer, filename: string) {
|
||||||
var blob = new Blob([buffer], { type: 'application/dicom' });
|
const blob = new Blob([buffer], { type: 'application/dicom' });
|
||||||
var link = document.createElement('a');
|
const link = document.createElement('a');
|
||||||
link.href = window.URL.createObjectURL(blob);
|
link.href = window.URL.createObjectURL(blob);
|
||||||
link.download = filename;
|
link.download = filename;
|
||||||
link.click();
|
link.click();
|
||||||
|
|||||||
@ -344,7 +344,9 @@ function _mapMeasurementToDisplay(measurement, types, displaySetService) {
|
|||||||
if (findingSites) {
|
if (findingSites) {
|
||||||
const siteText = [];
|
const siteText = [];
|
||||||
findingSites.forEach(site => {
|
findingSites.forEach(site => {
|
||||||
if (site?.text !== label) siteText.push(site.text);
|
if (site?.text !== label) {
|
||||||
|
siteText.push(site.text);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
displayText = [...siteText, ...displayText];
|
displayText = [...siteText, ...displayText];
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1 +1,4 @@
|
|||||||
export default (study, extraData) => Math.max(...(extraData?.displaySets?.map?.(ds => (ds.numImageFrames ?? 0))) || [0]);
|
export default (study, extraData) =>
|
||||||
|
Math.max(
|
||||||
|
...(extraData?.displaySets?.map?.(ds => ds.numImageFrames ?? 0) || [0])
|
||||||
|
);
|
||||||
|
|||||||
@ -1 +1 @@
|
|||||||
export default (study, extraData) => extraData?.displaySets?.length;
|
export default (study, extraData) => extraData?.displaySets?.length;
|
||||||
|
|||||||
@ -4,30 +4,37 @@
|
|||||||
* From 'this', it uses:
|
* From 'this', it uses:
|
||||||
* `sameAttribute` as the attribute name to look for
|
* `sameAttribute` as the attribute name to look for
|
||||||
* `sameDisplaySetId` as the display set id to look for
|
* `sameDisplaySetId` as the display set id to look for
|
||||||
* From `options`, it looks for
|
* From `options`, it looks for
|
||||||
*/
|
*/
|
||||||
export default function (displaySet, options) {
|
export default function(displaySet, options) {
|
||||||
const { sameAttribute, sameDisplaySetId } = this;
|
const { sameAttribute, sameDisplaySetId } = this;
|
||||||
if( !sameAttribute ) {
|
if (!sameAttribute) {
|
||||||
console.log("sameAttribute not defined in", this);
|
console.log('sameAttribute not defined in', this);
|
||||||
return `sameAttribute not defined in ${this.id}`;
|
return `sameAttribute not defined in ${this.id}`;
|
||||||
}
|
}
|
||||||
if( !sameDisplaySetId ) {
|
if (!sameDisplaySetId) {
|
||||||
console.log("sameDisplaySetId not defined in", this);
|
console.log('sameDisplaySetId not defined in', this);
|
||||||
return `sameDisplaySetId not defined in ${this.id}`;
|
return `sameDisplaySetId not defined in ${this.id}`;
|
||||||
}
|
}
|
||||||
const { displaySetMatchDetails, displaySets } = options;
|
const { displaySetMatchDetails, displaySets } = options;
|
||||||
const match = displaySetMatchDetails.get(sameDisplaySetId);
|
const match = displaySetMatchDetails.get(sameDisplaySetId);
|
||||||
if( !match ) {
|
if (!match) {
|
||||||
console.log("No match for display set", sameDisplaySetId);
|
console.log('No match for display set', sameDisplaySetId);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const { displaySetInstanceUID } = match;
|
const { displaySetInstanceUID } = match;
|
||||||
const altDisplaySet = displaySets.find(it => it.displaySetInstanceUID==displaySetInstanceUID);
|
const altDisplaySet = displaySets.find(
|
||||||
if( !altDisplaySet ) {
|
it => it.displaySetInstanceUID == displaySetInstanceUID
|
||||||
console.log("No display set found with", displaySetInstanceUID, "in", displaySets);
|
);
|
||||||
|
if (!altDisplaySet) {
|
||||||
|
console.log(
|
||||||
|
'No display set found with',
|
||||||
|
displaySetInstanceUID,
|
||||||
|
'in',
|
||||||
|
displaySets
|
||||||
|
);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const testValue = altDisplaySet[sameAttribute];
|
const testValue = altDisplaySet[sameAttribute];
|
||||||
return testValue===displaySet[sameAttribute];
|
return testValue === displaySet[sameAttribute];
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,9 +2,11 @@ const codeMenuItem = {
|
|||||||
id: '@ohif/contextMenuAnnotationCode',
|
id: '@ohif/contextMenuAnnotationCode',
|
||||||
|
|
||||||
/** Applies the code value setup for this item */
|
/** Applies the code value setup for this item */
|
||||||
transform: function (customizationService) {
|
transform: function(customizationService) {
|
||||||
const { code: codeRef } = this;
|
const { code: codeRef } = this;
|
||||||
if (!codeRef) throw new Error(`item ${this} has no code ref`);
|
if (!codeRef) {
|
||||||
|
throw new Error(`item ${this} has no code ref`);
|
||||||
|
}
|
||||||
const codingValues = customizationService.get('codingValues');
|
const codingValues = customizationService.get('codingValues');
|
||||||
const code = codingValues[codeRef];
|
const code = codingValues[codeRef];
|
||||||
return {
|
return {
|
||||||
|
|||||||
@ -117,7 +117,7 @@ function calculateSuvPeak(
|
|||||||
const secondaryCircleWorld = vec3.create();
|
const secondaryCircleWorld = vec3.create();
|
||||||
const bottomWorld = vec3.create();
|
const bottomWorld = vec3.create();
|
||||||
const topWorld = vec3.create();
|
const topWorld = vec3.create();
|
||||||
referenceVolumeImageData.indexToWorld(<vec3>maxIJK, secondaryCircleWorld);
|
referenceVolumeImageData.indexToWorld(maxIJK as vec3, secondaryCircleWorld);
|
||||||
vec3.scaleAndAdd(bottomWorld, secondaryCircleWorld, direction, -diameter / 2);
|
vec3.scaleAndAdd(bottomWorld, secondaryCircleWorld, direction, -diameter / 2);
|
||||||
vec3.scaleAndAdd(topWorld, secondaryCircleWorld, direction, diameter / 2);
|
vec3.scaleAndAdd(topWorld, secondaryCircleWorld, direction, diameter / 2);
|
||||||
const suvPeakCirclePoints = [bottomWorld, topWorld] as [
|
const suvPeakCirclePoints = [bottomWorld, topWorld] as [
|
||||||
|
|||||||
@ -78,8 +78,8 @@
|
|||||||
"@babel/preset-react": "^7.16.7",
|
"@babel/preset-react": "^7.16.7",
|
||||||
"@babel/preset-typescript": "^7.13.0",
|
"@babel/preset-typescript": "^7.13.0",
|
||||||
"@types/jest": "^27.5.0",
|
"@types/jest": "^27.5.0",
|
||||||
"@typescript-eslint/eslint-plugin": "^4.19.0",
|
"@typescript-eslint/eslint-plugin": "^6.3.0",
|
||||||
"@typescript-eslint/parser": "^4.19.0",
|
"@typescript-eslint/parser": "^6.3.0",
|
||||||
"autoprefixer": "^10.4.4",
|
"autoprefixer": "^10.4.4",
|
||||||
"babel-eslint": "9.x",
|
"babel-eslint": "9.x",
|
||||||
"babel-loader": "^8.2.4",
|
"babel-loader": "^8.2.4",
|
||||||
|
|||||||
@ -71,6 +71,7 @@ describe('OHIF Cornerstone Toolbar', () => {
|
|||||||
|
|
||||||
it('checks if Levels tool will change the window width and center of an image', () => {
|
it('checks if Levels tool will change the window width and center of an image', () => {
|
||||||
//Click on button and verify if icon is active on toolbar
|
//Click on button and verify if icon is active on toolbar
|
||||||
|
cy.waitDicomImage();
|
||||||
cy.get('@wwwcBtnPrimary')
|
cy.get('@wwwcBtnPrimary')
|
||||||
.click()
|
.click()
|
||||||
.then($wwwcBtn => {
|
.then($wwwcBtn => {
|
||||||
|
|||||||
@ -60,7 +60,7 @@ Cypress.Commands.add(
|
|||||||
cy.location('pathname').then($url => {
|
cy.location('pathname').then($url => {
|
||||||
cy.log($url);
|
cy.log($url);
|
||||||
if (
|
if (
|
||||||
$url == 'blank' ||
|
$url === 'blank' ||
|
||||||
!$url.includes(`/basic-test/${StudyInstanceUID}${otherParams}`)
|
!$url.includes(`/basic-test/${StudyInstanceUID}${otherParams}`)
|
||||||
) {
|
) {
|
||||||
cy.openStudyInViewer(StudyInstanceUID, otherParams);
|
cy.openStudyInViewer(StudyInstanceUID, otherParams);
|
||||||
@ -158,10 +158,10 @@ Cypress.Commands.add('addLine', (viewport, firstClick, secondClick) => {
|
|||||||
|
|
||||||
// TODO: Added a wait which appears necessary in Cornerstone Tools >4?
|
// TODO: Added a wait which appears necessary in Cornerstone Tools >4?
|
||||||
cy.wrap($viewport)
|
cy.wrap($viewport)
|
||||||
.click(x1, y1)
|
.click(x1, y1, { force: true })
|
||||||
.wait(100)
|
.wait(100)
|
||||||
.trigger('mousemove', { clientX: x2, clientY: y2 })
|
.trigger('mousemove', { clientX: x2, clientY: y2 })
|
||||||
.click(x2, y2)
|
.click(x2, y2, { force: true })
|
||||||
.wait(100);
|
.wait(100);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -4,6 +4,8 @@ const originalConsoleError = console.error;
|
|||||||
// JSDom's CSS Parser has limited support for certain features
|
// JSDom's CSS Parser has limited support for certain features
|
||||||
// This supresses error warnings caused by it
|
// This supresses error warnings caused by it
|
||||||
console.error = function(msg) {
|
console.error = function(msg) {
|
||||||
if (_.startsWith(msg, 'Error: Could not parse CSS stylesheet')) return;
|
if (_.startsWith(msg, 'Error: Could not parse CSS stylesheet')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
originalConsoleError(msg);
|
originalConsoleError(msg);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -103,7 +103,9 @@ async function appInit(appConfigOrFunc, defaultExtensions, defaultModes) {
|
|||||||
const modesById = new Set();
|
const modesById = new Set();
|
||||||
for (let i = 0; i < loadedModes.length; i++) {
|
for (let i = 0; i < loadedModes.length; i++) {
|
||||||
let mode = loadedModes[i];
|
let mode = loadedModes[i];
|
||||||
if (!mode) continue;
|
if (!mode) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
const { id } = mode;
|
const { id } = mode;
|
||||||
|
|
||||||
if (mode.modeFactory) {
|
if (mode.modeFactory) {
|
||||||
@ -116,10 +118,14 @@ async function appInit(appConfigOrFunc, defaultExtensions, defaultModes) {
|
|||||||
mode = mode.modeFactory({ modeConfiguration });
|
mode = mode.modeFactory({ modeConfiguration });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (modesById.has(id)) continue;
|
if (modesById.has(id)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
// Prevent duplication
|
// Prevent duplication
|
||||||
modesById.add(id);
|
modesById.add(id);
|
||||||
if (!mode || typeof mode !== 'object') continue;
|
if (!mode || typeof mode !== 'object') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
appConfig.loadedModes.push(mode);
|
appConfig.loadedModes.push(mode);
|
||||||
}
|
}
|
||||||
// Hack alert - don't touch the original modes definition,
|
// Hack alert - don't touch the original modes definition,
|
||||||
|
|||||||
@ -145,7 +145,9 @@ function ViewerViewportGrid(props) {
|
|||||||
const { unsubscribe } = measurementService.subscribe(
|
const { unsubscribe } = measurementService.subscribe(
|
||||||
MeasurementService.EVENTS.JUMP_TO_MEASUREMENT_LAYOUT,
|
MeasurementService.EVENTS.JUMP_TO_MEASUREMENT_LAYOUT,
|
||||||
({ viewportIndex, measurement, isConsumed }) => {
|
({ viewportIndex, measurement, isConsumed }) => {
|
||||||
if (isConsumed) return;
|
if (isConsumed) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
// This occurs when no viewport has elected to consume the event
|
// This occurs when no viewport has elected to consume the event
|
||||||
// so we need to change layouts into a layout which can consume
|
// so we need to change layouts into a layout which can consume
|
||||||
// the event.
|
// the event.
|
||||||
@ -292,7 +294,9 @@ function ViewerViewportGrid(props) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const onInteractionHandler = event => {
|
const onInteractionHandler = event => {
|
||||||
if (isActive) return;
|
if (isActive) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (event) {
|
if (event) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
export default class FileLoader {
|
export default class FileLoader {
|
||||||
fileType;
|
fileType;
|
||||||
loadFile(file, imageId) { }
|
loadFile(file, imageId) {}
|
||||||
getDataset(image, imageId) { }
|
getDataset(image, imageId) {}
|
||||||
getStudies(dataset, imageId) { }
|
getStudies(dataset, imageId) {}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,8 +11,12 @@ type StudyMetadata = Types.StudyMetadata;
|
|||||||
* @returns - compare a and b, returning 1 if a<b -1 if a>b and defaultCompare otherwise
|
* @returns - compare a and b, returning 1 if a<b -1 if a>b and defaultCompare otherwise
|
||||||
*/
|
*/
|
||||||
const compare = (a, b, defaultCompare = 0): number => {
|
const compare = (a, b, defaultCompare = 0): number => {
|
||||||
if (a === b) return defaultCompare;
|
if (a === b) {
|
||||||
if (a < b) return 1;
|
return defaultCompare;
|
||||||
|
}
|
||||||
|
if (a < b) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
return -1;
|
return -1;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -49,7 +53,9 @@ const getStudiesfromDisplaySets = (displaysets): StudyMetadata[] => {
|
|||||||
* in the original order, as specified.
|
* in the original order, as specified.
|
||||||
*/
|
*/
|
||||||
const getStudiesFromUIDs = (studyUids: string[]): StudyMetadata[] => {
|
const getStudiesFromUIDs = (studyUids: string[]): StudyMetadata[] => {
|
||||||
if (!studyUids?.length) return;
|
if (!studyUids?.length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
return studyUids.map(uid => DicomMetadataStore.getStudy(uid));
|
return studyUids.map(uid => DicomMetadataStore.getStudy(uid));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -361,32 +361,35 @@ function WorkList({
|
|||||||
query.append('configUrl', filterValues.configUrl);
|
query.append('configUrl', filterValues.configUrl);
|
||||||
}
|
}
|
||||||
query.append('StudyInstanceUIDs', studyInstanceUid);
|
query.append('StudyInstanceUIDs', studyInstanceUid);
|
||||||
return mode.displayName && (
|
return (
|
||||||
<Link
|
mode.displayName && (
|
||||||
className={isValidMode ? '' : 'cursor-not-allowed'}
|
<Link
|
||||||
key={i}
|
className={isValidMode ? '' : 'cursor-not-allowed'}
|
||||||
to={`${dataPath ? '../../' : ''}${mode.routeName}${dataPath ||
|
key={i}
|
||||||
''}?${query.toString()}`}
|
to={`${dataPath ? '../../' : ''}${
|
||||||
onClick={event => {
|
mode.routeName
|
||||||
// In case any event bubbles up for an invalid mode, prevent the navigation.
|
}${dataPath || ''}?${query.toString()}`}
|
||||||
// For example, the event bubbles up when the icon embedded in the disabled button is clicked.
|
onClick={event => {
|
||||||
if (!isValidMode) {
|
// In case any event bubbles up for an invalid mode, prevent the navigation.
|
||||||
event.preventDefault();
|
// For example, the event bubbles up when the icon embedded in the disabled button is clicked.
|
||||||
}
|
if (!isValidMode) {
|
||||||
}}
|
event.preventDefault();
|
||||||
// to={`${mode.routeName}/dicomweb?StudyInstanceUIDs=${studyInstanceUid}`}
|
}
|
||||||
>
|
}}
|
||||||
{/* TODO revisit the completely rounded style of buttons used for launching a mode from the worklist later - for now use LegacyButton*/}
|
// to={`${mode.routeName}/dicomweb?StudyInstanceUIDs=${studyInstanceUid}`}
|
||||||
<LegacyButton
|
|
||||||
rounded="full"
|
|
||||||
variant={isValidMode ? 'contained' : 'disabled'}
|
|
||||||
disabled={!isValidMode}
|
|
||||||
endIcon={<Icon name="launch-arrow" />} // launch-arrow | launch-info
|
|
||||||
onClick={() => {}}
|
|
||||||
>
|
>
|
||||||
{t(`Modes:${mode.displayName}`)}
|
{/* TODO revisit the completely rounded style of buttons used for launching a mode from the worklist later - for now use LegacyButton*/}
|
||||||
</LegacyButton>
|
<LegacyButton
|
||||||
</Link>
|
rounded="full"
|
||||||
|
variant={isValidMode ? 'contained' : 'disabled'}
|
||||||
|
disabled={!isValidMode}
|
||||||
|
endIcon={<Icon name="launch-arrow" />} // launch-arrow | launch-info
|
||||||
|
onClick={() => {}}
|
||||||
|
>
|
||||||
|
{t(`Modes:${mode.displayName}`)}
|
||||||
|
</LegacyButton>
|
||||||
|
</Link>
|
||||||
|
)
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -10,7 +10,7 @@ import {
|
|||||||
initGit,
|
initGit,
|
||||||
} from './utils/index.js';
|
} from './utils/index.js';
|
||||||
|
|
||||||
const createPackage = async (options) => {
|
const createPackage = async options => {
|
||||||
const { packageType } = options; // extension or mode
|
const { packageType } = options; // extension or mode
|
||||||
|
|
||||||
if (fs.existsSync(options.targetDir)) {
|
if (fs.existsSync(options.targetDir)) {
|
||||||
|
|||||||
@ -22,7 +22,9 @@ const createDirectoryContents = (
|
|||||||
const contents = fs.readFileSync(origFilePath, 'utf8');
|
const contents = fs.readFileSync(origFilePath, 'utf8');
|
||||||
|
|
||||||
// Rename
|
// Rename
|
||||||
if (file === '.npmignore') file = '.gitignore';
|
if (file === '.npmignore') {
|
||||||
|
file = '.gitignore';
|
||||||
|
}
|
||||||
|
|
||||||
const writePath = `${targetDirPath}/${file}`;
|
const writePath = `${targetDirPath}/${file}`;
|
||||||
fs.writeFileSync(writePath, contents, 'utf8');
|
fs.writeFileSync(writePath, contents, 'utf8');
|
||||||
|
|||||||
@ -11,7 +11,7 @@ export default async function findRequiredOhifExtensionsForMode(yarnInfo) {
|
|||||||
const dependencies = [];
|
const dependencies = [];
|
||||||
const ohifExtensions = [];
|
const ohifExtensions = [];
|
||||||
|
|
||||||
Object.keys(peerDependencies).forEach((packageName) => {
|
Object.keys(peerDependencies).forEach(packageName => {
|
||||||
dependencies.push({
|
dependencies.push({
|
||||||
packageName,
|
packageName,
|
||||||
version: peerDependencies[packageName],
|
version: peerDependencies[packageName],
|
||||||
|
|||||||
@ -77,14 +77,14 @@ function getVersion(json, version) {
|
|||||||
const [majorVersion] = version
|
const [majorVersion] = version
|
||||||
.split('^')[1]
|
.split('^')[1]
|
||||||
.split('.')
|
.split('.')
|
||||||
.map((v) => parseInt(v));
|
.map(v => parseInt(v));
|
||||||
|
|
||||||
// Find the version that matches the major version, but is the latest minor version
|
// Find the version that matches the major version, but is the latest minor version
|
||||||
versions
|
versions
|
||||||
.filter((version) => parseInt(version.split('.')[0]) === majorVersion)
|
.filter(version => parseInt(version.split('.')[0]) === majorVersion)
|
||||||
.sort((a, b) => {
|
.sort((a, b) => {
|
||||||
const [majorA, minorA, patchA] = a.split('.').map((v) => parseInt(v));
|
const [majorA, minorA, patchA] = a.split('.').map(v => parseInt(v));
|
||||||
const [majorB, minorB, patchB] = b.split('.').map((v) => parseInt(v));
|
const [majorB, minorB, patchB] = b.split('.').map(v => parseInt(v));
|
||||||
|
|
||||||
if (majorA === majorB) {
|
if (majorA === majorB) {
|
||||||
if (minorA === minorB) {
|
if (minorA === minorB) {
|
||||||
@ -110,13 +110,16 @@ function validate(packageName, version, keyword) {
|
|||||||
|
|
||||||
// Gets the registry of the package. Scoped packages may not be using the global default.
|
// Gets the registry of the package. Scoped packages may not be using the global default.
|
||||||
const registryUrlOfPackage = registryUrl(scope);
|
const registryUrlOfPackage = registryUrl(scope);
|
||||||
let options = {}
|
let options = {};
|
||||||
if (process.env.NPM_TOKEN){
|
if (process.env.NPM_TOKEN) {
|
||||||
options['headers'] = {
|
options['headers'] = {
|
||||||
'Authorization': `Bearer ${process.env.NPM_TOKEN}`,
|
Authorization: `Bearer ${process.env.NPM_TOKEN}`,
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
const response = await fetch(`${registryUrlOfPackage}${packageName}`, options);
|
const response = await fetch(
|
||||||
|
`${registryUrlOfPackage}${packageName}`,
|
||||||
|
options
|
||||||
|
);
|
||||||
const json = await response.json();
|
const json = await response.json();
|
||||||
|
|
||||||
if (json.error && json.error === NOT_FOUND) {
|
if (json.error && json.error === NOT_FOUND) {
|
||||||
|
|||||||
@ -25,10 +25,18 @@ function convertToInt(input) {
|
|||||||
function padFour(input) {
|
function padFour(input) {
|
||||||
const l = input.length;
|
const l = input.length;
|
||||||
|
|
||||||
if (l == 0) return '0000';
|
if (l === 0) {
|
||||||
if (l == 1) return '000' + input;
|
return '0000';
|
||||||
if (l == 2) return '00' + input;
|
}
|
||||||
if (l == 3) return '0' + input;
|
if (l === 1) {
|
||||||
|
return '000' + input;
|
||||||
|
}
|
||||||
|
if (l === 2) {
|
||||||
|
return '00' + input;
|
||||||
|
}
|
||||||
|
if (l === 3) {
|
||||||
|
return '0' + input;
|
||||||
|
}
|
||||||
|
|
||||||
return input;
|
return input;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import 'isomorphic-base64'
|
import 'isomorphic-base64';
|
||||||
import user from '../user';
|
import user from '../user';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -175,7 +175,9 @@ export class CommandsManager {
|
|||||||
toRun: Command | Commands | Command[] | undefined,
|
toRun: Command | Commands | Command[] | undefined,
|
||||||
options?: Record<string, unknown>
|
options?: Record<string, unknown>
|
||||||
): unknown {
|
): unknown {
|
||||||
if (!toRun) return;
|
if (!toRun) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
const commands =
|
const commands =
|
||||||
(Array.isArray(toRun) && toRun) ||
|
(Array.isArray(toRun) && toRun) ||
|
||||||
((toRun as Command).commandName && [toRun]) ||
|
((toRun as Command).commandName && [toRun]) ||
|
||||||
|
|||||||
@ -454,7 +454,9 @@ class MetadataProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getUIDsFromImageID(imageId) {
|
getUIDsFromImageID(imageId) {
|
||||||
if (!imageId) throw new Error('MetadataProvider::Empty imageId');
|
if (!imageId) {
|
||||||
|
throw new Error('MetadataProvider::Empty imageId');
|
||||||
|
}
|
||||||
// TODO: adding csiv here is not really correct. Probably need to use
|
// TODO: adding csiv here is not really correct. Probably need to use
|
||||||
// metadataProvider.addImageIdToUIDs(imageId, {
|
// metadataProvider.addImageIdToUIDs(imageId, {
|
||||||
// StudyInstanceUID,
|
// StudyInstanceUID,
|
||||||
|
|||||||
@ -2,7 +2,9 @@
|
|||||||
function getNestedObject(shallowObject) {
|
function getNestedObject(shallowObject) {
|
||||||
const nestedObject = {};
|
const nestedObject = {};
|
||||||
for (let key in shallowObject) {
|
for (let key in shallowObject) {
|
||||||
if (!shallowObject.hasOwnProperty(key)) continue;
|
if (!shallowObject.hasOwnProperty(key)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
const value = shallowObject[key];
|
const value = shallowObject[key];
|
||||||
const propertyArray = key.split('.');
|
const propertyArray = key.split('.');
|
||||||
let currentObject = nestedObject;
|
let currentObject = nestedObject;
|
||||||
@ -28,7 +30,9 @@ function getShallowObject(nestedObject) {
|
|||||||
const shallowObject = {};
|
const shallowObject = {};
|
||||||
const putValues = (baseKey, nestedObject, resultObject) => {
|
const putValues = (baseKey, nestedObject, resultObject) => {
|
||||||
for (let key in nestedObject) {
|
for (let key in nestedObject) {
|
||||||
if (!nestedObject.hasOwnProperty(key)) continue;
|
if (!nestedObject.hasOwnProperty(key)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
let currentKey = baseKey ? `${baseKey}.${key}` : key;
|
let currentKey = baseKey ? `${baseKey}.${key}` : key;
|
||||||
const currentValue = nestedObject[key];
|
const currentValue = nestedObject[key];
|
||||||
if (typeof currentValue === 'object') {
|
if (typeof currentValue === 'object') {
|
||||||
|
|||||||
@ -11,7 +11,7 @@ const extensionManager = {
|
|||||||
registeredExtensionIds: [],
|
registeredExtensionIds: [],
|
||||||
moduleEntries: {},
|
moduleEntries: {},
|
||||||
|
|
||||||
getModuleEntry: function (id) {
|
getModuleEntry: function(id) {
|
||||||
return this.moduleEntries[id];
|
return this.moduleEntries[id];
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -20,7 +20,7 @@ const commandsManager = {};
|
|||||||
|
|
||||||
const ohifOverlayItem = {
|
const ohifOverlayItem = {
|
||||||
id: 'ohif.overlayItem',
|
id: 'ohif.overlayItem',
|
||||||
content: function (props) {
|
content: function(props) {
|
||||||
return {
|
return {
|
||||||
label: this.label,
|
label: this.label,
|
||||||
value: props[this.attribute],
|
value: props[this.attribute],
|
||||||
|
|||||||
@ -12,8 +12,12 @@ const flattenNestedStrings = (
|
|||||||
strs: NestedStrings | string,
|
strs: NestedStrings | string,
|
||||||
ret?: Record<string, string>
|
ret?: Record<string, string>
|
||||||
): Record<string, string> => {
|
): Record<string, string> => {
|
||||||
if (!ret) ret = {};
|
if (!ret) {
|
||||||
if (!strs) return ret;
|
ret = {};
|
||||||
|
}
|
||||||
|
if (!strs) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
if (Array.isArray(strs)) {
|
if (Array.isArray(strs)) {
|
||||||
for (const val of strs) {
|
for (const val of strs) {
|
||||||
flattenNestedStrings(val, ret);
|
flattenNestedStrings(val, ret);
|
||||||
@ -81,7 +85,9 @@ export default class CustomizationService extends PubSubService {
|
|||||||
this.extensionManager.registeredExtensionIds.forEach(extensionId => {
|
this.extensionManager.registeredExtensionIds.forEach(extensionId => {
|
||||||
const key = `${extensionId}.customizationModule.default`;
|
const key = `${extensionId}.customizationModule.default`;
|
||||||
const defaultCustomizations = this.findExtensionValue(key);
|
const defaultCustomizations = this.findExtensionValue(key);
|
||||||
if (!defaultCustomizations) return;
|
if (!defaultCustomizations) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
const { value } = defaultCustomizations;
|
const { value } = defaultCustomizations;
|
||||||
this.addReference(value, true);
|
this.addReference(value, true);
|
||||||
});
|
});
|
||||||
@ -172,9 +178,13 @@ export default class CustomizationService extends PubSubService {
|
|||||||
* type into the new type, allowing default behaviour to be configured.
|
* type into the new type, allowing default behaviour to be configured.
|
||||||
*/
|
*/
|
||||||
public transform(customization: Customization): Customization {
|
public transform(customization: Customization): Customization {
|
||||||
if (!customization) return customization;
|
if (!customization) {
|
||||||
|
return customization;
|
||||||
|
}
|
||||||
const { customizationType } = customization;
|
const { customizationType } = customization;
|
||||||
if (!customizationType) return customization;
|
if (!customizationType) {
|
||||||
|
return customization;
|
||||||
|
}
|
||||||
const parent = this.getCustomization(customizationType);
|
const parent = this.getCustomization(customizationType);
|
||||||
const result = parent
|
const result = parent
|
||||||
? Object.assign(Object.create(parent), customization)
|
? Object.assign(Object.create(parent), customization)
|
||||||
@ -242,7 +252,9 @@ export default class CustomizationService extends PubSubService {
|
|||||||
* or a customization itself.
|
* or a customization itself.
|
||||||
*/
|
*/
|
||||||
addReference(value?: Obj | string, isGlobal = true, id?: string): void {
|
addReference(value?: Obj | string, isGlobal = true, id?: string): void {
|
||||||
if (!value) return;
|
if (!value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (typeof value === 'string') {
|
if (typeof value === 'string') {
|
||||||
const extensionValue = this.findExtensionValue(value);
|
const extensionValue = this.findExtensionValue(value);
|
||||||
// The child of a reference is only a set of references when an array,
|
// The child of a reference is only a set of references when an array,
|
||||||
@ -265,7 +277,9 @@ export default class CustomizationService extends PubSubService {
|
|||||||
* or customization.
|
* or customization.
|
||||||
*/
|
*/
|
||||||
addReferences(references?: Obj | Obj[], isGlobal = true): void {
|
addReferences(references?: Obj | Obj[], isGlobal = true): void {
|
||||||
if (!references) return;
|
if (!references) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (Array.isArray(references)) {
|
if (Array.isArray(references)) {
|
||||||
references.forEach(item => {
|
references.forEach(item => {
|
||||||
this.addReference(item, isGlobal);
|
this.addReference(item, isGlobal);
|
||||||
|
|||||||
@ -157,7 +157,9 @@ export default class DisplaySetService extends PubSubService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public deleteDisplaySet(displaySetInstanceUID) {
|
public deleteDisplaySet(displaySetInstanceUID) {
|
||||||
if (!displaySetInstanceUID) return;
|
if (!displaySetInstanceUID) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
const { activeDisplaySets, activeDisplaySetsMap } = this;
|
const { activeDisplaySets, activeDisplaySetsMap } = this;
|
||||||
|
|
||||||
const activeDisplaySetsIndex = activeDisplaySets.findIndex(
|
const activeDisplaySetsIndex = activeDisplaySets.findIndex(
|
||||||
@ -314,7 +316,9 @@ export default class DisplaySetService extends PubSubService {
|
|||||||
}
|
}
|
||||||
// This means that all instances already existed or got added to
|
// This means that all instances already existed or got added to
|
||||||
// existing display sets, and had an invalidated event fired
|
// existing display sets, and had an invalidated event fired
|
||||||
if (!instances.length) return allDisplaySets;
|
if (!instances.length) {
|
||||||
|
return allDisplaySets;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!instances.length) {
|
if (!instances.length) {
|
||||||
@ -329,7 +333,9 @@ export default class DisplaySetService extends PubSubService {
|
|||||||
// creating additional display sets using the sop class handler
|
// creating additional display sets using the sop class handler
|
||||||
displaySets = handler.getDisplaySetsFromSeries(instances);
|
displaySets = handler.getDisplaySetsFromSeries(instances);
|
||||||
|
|
||||||
if (!displaySets || !displaySets.length) continue;
|
if (!displaySets || !displaySets.length) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// applying hp-defined viewport settings to the displaysets
|
// applying hp-defined viewport settings to the displaysets
|
||||||
displaySets.forEach(ds => {
|
displaySets.forEach(ds => {
|
||||||
|
|||||||
@ -134,7 +134,7 @@ function checkHpsBestMatch(hps) {
|
|||||||
displaySetOptions: {
|
displaySetOptions: {
|
||||||
id: 'displaySetSelector',
|
id: 'displaySetSelector',
|
||||||
options: {},
|
options: {},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
@ -192,6 +192,6 @@ describe('HangingProtocolService', () => {
|
|||||||
it('matches best image match', () => {
|
it('matches best image match', () => {
|
||||||
checkHpsBestMatch(hangingProtocolService);
|
checkHpsBestMatch(hangingProtocolService);
|
||||||
});
|
});
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|||||||
@ -86,7 +86,9 @@ export default class HangingProtocolService extends PubSubService {
|
|||||||
metadata.ModalitiesInStudy ??
|
metadata.ModalitiesInStudy ??
|
||||||
(metadata.series || []).reduce((prev, curr) => {
|
(metadata.series || []).reduce((prev, curr) => {
|
||||||
const { Modality } = curr;
|
const { Modality } = curr;
|
||||||
if (Modality && prev.indexOf(Modality) == -1) prev.push(Modality);
|
if (Modality && prev.indexOf(Modality) == -1) {
|
||||||
|
prev.push(Modality);
|
||||||
|
}
|
||||||
return prev;
|
return prev;
|
||||||
}, []),
|
}, []),
|
||||||
},
|
},
|
||||||
@ -200,7 +202,9 @@ export default class HangingProtocolService extends PubSubService {
|
|||||||
* protocolId, stageIndex, stageId and activeStudyUID
|
* protocolId, stageIndex, stageId and activeStudyUID
|
||||||
*/
|
*/
|
||||||
public getState(): HangingProtocol.HPInfo {
|
public getState(): HangingProtocol.HPInfo {
|
||||||
if (!this.protocol) return;
|
if (!this.protocol) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
protocolId: this.protocol.id,
|
protocolId: this.protocol.id,
|
||||||
stageIndex: this.stageIndex,
|
stageIndex: this.stageIndex,
|
||||||
@ -257,8 +261,12 @@ export default class HangingProtocolService extends PubSubService {
|
|||||||
* @returns protocol - the protocol with the given id
|
* @returns protocol - the protocol with the given id
|
||||||
*/
|
*/
|
||||||
public getProtocolById(protocolId: string): HangingProtocol.Protocol {
|
public getProtocolById(protocolId: string): HangingProtocol.Protocol {
|
||||||
if (!protocolId) return;
|
if (!protocolId) {
|
||||||
if (protocolId === this.protocol?.id) return this.protocol;
|
return;
|
||||||
|
}
|
||||||
|
if (protocolId === this.protocol?.id) {
|
||||||
|
return this.protocol;
|
||||||
|
}
|
||||||
const protocol = this.protocols.get(protocolId);
|
const protocol = this.protocols.get(protocolId);
|
||||||
if (!protocol) {
|
if (!protocol) {
|
||||||
throw new Error(`No protocol ${protocolId} found`);
|
throw new Error(`No protocol ${protocolId} found`);
|
||||||
@ -697,7 +705,9 @@ export default class HangingProtocolService extends PubSubService {
|
|||||||
const { id } = displaySet;
|
const { id } = displaySet;
|
||||||
const displaySetMatchDetail = displaySetMatchDetails.get(id);
|
const displaySetMatchDetail = displaySetMatchDetails.get(id);
|
||||||
|
|
||||||
const { displaySetInstanceUID: oldDisplaySetInstanceUID } = displaySetMatchDetail;
|
const {
|
||||||
|
displaySetInstanceUID: oldDisplaySetInstanceUID,
|
||||||
|
} = displaySetMatchDetail;
|
||||||
|
|
||||||
const displaySetInstanceUID =
|
const displaySetInstanceUID =
|
||||||
displaySet.id === displaySetSelectorId
|
displaySet.id === displaySetSelectorId
|
||||||
@ -730,8 +740,12 @@ export default class HangingProtocolService extends PubSubService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options === null) return options;
|
if (options === null) {
|
||||||
if (typeof options !== 'object') return options;
|
return options;
|
||||||
|
}
|
||||||
|
if (typeof options !== 'object') {
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
|
||||||
// If options is an object with a custom attribute, compute a new options object
|
// If options is an object with a custom attribute, compute a new options object
|
||||||
if (options.custom) {
|
if (options.custom) {
|
||||||
@ -892,7 +906,9 @@ export default class HangingProtocolService extends PubSubService {
|
|||||||
if (stageId) {
|
if (stageId) {
|
||||||
for (let i = 0; i < stages.length; i++) {
|
for (let i = 0; i < stages.length; i++) {
|
||||||
const stage = stages[i];
|
const stage = stages[i];
|
||||||
if (stage.id === stageId && stage.status !== 'disabled') return i;
|
if (stage.id === stageId && stage.status !== 'disabled') {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -905,7 +921,9 @@ export default class HangingProtocolService extends PubSubService {
|
|||||||
let firstNotDisabled: number;
|
let firstNotDisabled: number;
|
||||||
|
|
||||||
for (let i = 0; i < stages.length; i++) {
|
for (let i = 0; i < stages.length; i++) {
|
||||||
if (stages[i].status === 'enabled') return i;
|
if (stages[i].status === 'enabled') {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
if (firstNotDisabled === undefined && stages[i].status !== 'disabled') {
|
if (firstNotDisabled === undefined && stages[i].status !== 'disabled') {
|
||||||
firstNotDisabled = i;
|
firstNotDisabled = i;
|
||||||
}
|
}
|
||||||
@ -979,7 +997,9 @@ export default class HangingProtocolService extends PubSubService {
|
|||||||
if (stageId !== undefined) {
|
if (stageId !== undefined) {
|
||||||
return protocol.stages.findIndex(it => it.id === stageId);
|
return protocol.stages.findIndex(it => it.id === stageId);
|
||||||
}
|
}
|
||||||
if (stageIndex !== undefined) return stageIndex;
|
if (stageIndex !== undefined) {
|
||||||
|
return stageIndex;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1030,7 +1050,9 @@ export default class HangingProtocolService extends PubSubService {
|
|||||||
const protocol = this.protocol;
|
const protocol = this.protocol;
|
||||||
const stage = protocol.stages[stageIdx];
|
const stage = protocol.stages[stageIdx];
|
||||||
const defaultViewport = stage.defaultViewport || protocol.defaultViewport;
|
const defaultViewport = stage.defaultViewport || protocol.defaultViewport;
|
||||||
if (!defaultViewport) return;
|
if (!defaultViewport) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const useViewport = { ...defaultViewport };
|
const useViewport = { ...defaultViewport };
|
||||||
return this._matchViewport(useViewport, options);
|
return this._matchViewport(useViewport, options);
|
||||||
@ -1152,12 +1174,18 @@ export default class HangingProtocolService extends PubSubService {
|
|||||||
offset: number,
|
offset: number,
|
||||||
options: HangingProtocol.SetProtocolOptions = {}
|
options: HangingProtocol.SetProtocolOptions = {}
|
||||||
): HangingProtocol.DisplaySetMatchDetails {
|
): HangingProtocol.DisplaySetMatchDetails {
|
||||||
if (!matchDetails) return;
|
if (!matchDetails) {
|
||||||
if (offset === 0) return matchDetails;
|
return;
|
||||||
|
}
|
||||||
|
if (offset === 0) {
|
||||||
|
return matchDetails;
|
||||||
|
}
|
||||||
const { matchingScores = [] } = matchDetails;
|
const { matchingScores = [] } = matchDetails;
|
||||||
if (offset === -1) {
|
if (offset === -1) {
|
||||||
const { inDisplay } = options;
|
const { inDisplay } = options;
|
||||||
if (!inDisplay) return matchDetails;
|
if (!inDisplay) {
|
||||||
|
return matchDetails;
|
||||||
|
}
|
||||||
for (let i = 0; i < matchDetails.matchingScores.length; i++) {
|
for (let i = 0; i < matchDetails.matchingScores.length; i++) {
|
||||||
if (
|
if (
|
||||||
inDisplay.indexOf(
|
inDisplay.indexOf(
|
||||||
@ -1184,12 +1212,16 @@ export default class HangingProtocolService extends PubSubService {
|
|||||||
id: string,
|
id: string,
|
||||||
displaySetUID: string
|
displaySetUID: string
|
||||||
): void {
|
): void {
|
||||||
if (match.displaySetInstanceUID === displaySetUID) return;
|
if (match.displaySetInstanceUID === displaySetUID) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (!match.matchingScores) {
|
if (!match.matchingScores) {
|
||||||
throw new Error('No matchingScores found in ' + match);
|
throw new Error('No matchingScores found in ' + match);
|
||||||
}
|
}
|
||||||
for (const subMatch of match.matchingScores) {
|
for (const subMatch of match.matchingScores) {
|
||||||
if (subMatch.displaySetInstanceUID === displaySetUID) return;
|
if (subMatch.displaySetInstanceUID === displaySetUID) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`Reused viewport details ${id} with ds ${displaySetUID} not valid`
|
`Reused viewport details ${id} with ds ${displaySetUID} not valid`
|
||||||
@ -1391,21 +1423,23 @@ export default class HangingProtocolService extends PubSubService {
|
|||||||
const matchActiveOnly = this.protocol.numberOfPriorsReferenced === -1;
|
const matchActiveOnly = this.protocol.numberOfPriorsReferenced === -1;
|
||||||
this.studies.forEach(study => {
|
this.studies.forEach(study => {
|
||||||
// Skip non-active if active only
|
// Skip non-active if active only
|
||||||
if (matchActiveOnly && this.activeStudy !== study) return;
|
if (matchActiveOnly && this.activeStudy !== study) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const studyDisplaySets = this.displaySets.filter(
|
const studyDisplaySets = this.displaySets.filter(
|
||||||
it => it.StudyInstanceUID === study.StudyInstanceUID
|
it => it.StudyInstanceUID === study.StudyInstanceUID
|
||||||
);
|
);
|
||||||
|
|
||||||
const studyMatchDetails = this.protocolEngine.findMatch(
|
const studyMatchDetails = this.protocolEngine.findMatch(
|
||||||
study,
|
study,
|
||||||
studyMatchingRules,
|
studyMatchingRules,
|
||||||
{
|
{
|
||||||
studies: this.studies,
|
studies: this.studies,
|
||||||
displaySets: studyDisplaySets,
|
displaySets: studyDisplaySets,
|
||||||
allDisplaySets: this.displaySets,
|
allDisplaySets: this.displaySets,
|
||||||
displaySetMatchDetails: this.displaySetMatchDetails,
|
displaySetMatchDetails: this.displaySetMatchDetails,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
// Prevent bestMatch from being updated if the matchDetails' required attribute check has failed
|
// Prevent bestMatch from being updated if the matchDetails' required attribute check has failed
|
||||||
@ -1414,10 +1448,10 @@ export default class HangingProtocolService extends PubSubService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.debug(
|
this.debug(
|
||||||
'study',
|
'study',
|
||||||
study.StudyInstanceUID,
|
study.StudyInstanceUID,
|
||||||
'display sets #',
|
'display sets #',
|
||||||
studyDisplaySets.length
|
studyDisplaySets.length
|
||||||
);
|
);
|
||||||
studyDisplaySets.forEach(displaySet => {
|
studyDisplaySets.forEach(displaySet => {
|
||||||
const {
|
const {
|
||||||
@ -1426,15 +1460,15 @@ export default class HangingProtocolService extends PubSubService {
|
|||||||
displaySetInstanceUID,
|
displaySetInstanceUID,
|
||||||
} = displaySet;
|
} = displaySet;
|
||||||
const seriesMatchDetails = this.protocolEngine.findMatch(
|
const seriesMatchDetails = this.protocolEngine.findMatch(
|
||||||
displaySet,
|
displaySet,
|
||||||
seriesMatchingRules,
|
seriesMatchingRules,
|
||||||
// Todo: why we have images here since the matching type does not have it
|
// Todo: why we have images here since the matching type does not have it
|
||||||
{
|
{
|
||||||
studies: this.studies,
|
studies: this.studies,
|
||||||
instance: displaySet.images?.[0],
|
instance: displaySet.images?.[0],
|
||||||
displaySetMatchDetails: this.displaySetMatchDetails,
|
displaySetMatchDetails: this.displaySetMatchDetails,
|
||||||
displaySets: studyDisplaySets,
|
displaySets: studyDisplaySets,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
// Prevent bestMatch from being updated if the matchDetails' required attribute check has failed
|
// Prevent bestMatch from being updated if the matchDetails' required attribute check has failed
|
||||||
|
|||||||
@ -13,7 +13,9 @@ const isDisplaySetFromUrl = (displaySet): boolean => {
|
|||||||
params
|
params
|
||||||
);
|
);
|
||||||
const initialSOPInstanceUID = getSplitParam('initialsopinstanceuid', params);
|
const initialSOPInstanceUID = getSplitParam('initialsopinstanceuid', params);
|
||||||
if (!initialSeriesInstanceUID && !initialSOPInstanceUID) return false;
|
if (!initialSeriesInstanceUID && !initialSOPInstanceUID) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
const isSeriesMatch =
|
const isSeriesMatch =
|
||||||
!initialSeriesInstanceUID ||
|
!initialSeriesInstanceUID ||
|
||||||
initialSeriesInstanceUID.some(
|
initialSeriesInstanceUID.some(
|
||||||
@ -32,9 +34,13 @@ const isDisplaySetFromUrl = (displaySet): boolean => {
|
|||||||
*/
|
*/
|
||||||
function sopInstanceLocation(displaySets) {
|
function sopInstanceLocation(displaySets) {
|
||||||
const displaySet = displaySets?.[0];
|
const displaySet = displaySets?.[0];
|
||||||
if (!displaySet) return;
|
if (!displaySet) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
const initialSOPInstanceUID = getSplitParam('initialsopinstanceuid');
|
const initialSOPInstanceUID = getSplitParam('initialsopinstanceuid');
|
||||||
if (!initialSOPInstanceUID) return;
|
if (!initialSOPInstanceUID) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const index = displaySet.instances.findIndex(instance =>
|
const index = displaySet.instances.findIndex(instance =>
|
||||||
initialSOPInstanceUID.includes(instance.SOPInstanceUID)
|
initialSOPInstanceUID.includes(instance.SOPInstanceUID)
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
export default (study, extraData) => {
|
export default (study, extraData) => {
|
||||||
const ret = extraData?.displaySets?.filter(ds => ds.numImageFrames>0)?.length;
|
const ret = extraData?.displaySets?.filter(ds => ds.numImageFrames > 0)
|
||||||
console.log("number of display sets with images", ret);
|
?.length;
|
||||||
|
console.log('number of display sets with images', ret);
|
||||||
return ret;
|
return ret;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1 +1,2 @@
|
|||||||
export default (study, extraData) => extraData?.displaySets?.map(ds => ds.SeriesDescription);
|
export default (study, extraData) =>
|
||||||
|
extraData?.displaySets?.map(ds => ds.SeriesDescription);
|
||||||
|
|||||||
@ -111,10 +111,12 @@ validate.validators.includes = function(value, options, key) {
|
|||||||
const includedValues = testValue.filter(el => dicomArrayValue.includes(el));
|
const includedValues = testValue.filter(el => dicomArrayValue.includes(el));
|
||||||
if (includedValues.length === 0) {
|
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`;
|
} else {
|
||||||
|
return `${key} ${testValue} must be an array`;
|
||||||
|
}
|
||||||
// else if (!value.includes(testValue)) {
|
// else if (!value.includes(testValue)) {
|
||||||
// return `${key} ${value} must include ${testValue}`;
|
// return `${key} ${value} must include ${testValue}`;
|
||||||
// }
|
// }
|
||||||
@ -151,7 +153,9 @@ validate.validators.doesNotInclude = function(value, options, key) {
|
|||||||
if (includedValues.length > 0) {
|
if (includedValues.length > 0) {
|
||||||
return `${key} must not include the following value: ${includedValues}`;
|
return `${key} must not include the following value: ${includedValues}`;
|
||||||
}
|
}
|
||||||
} else return `${key} ${testValue} must be an array`;
|
} else {
|
||||||
|
return `${key} ${testValue} must be an array`;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
// Ignore case contains.
|
// Ignore case contains.
|
||||||
// options testValue MUST be in lower case already, otherwise it won't match
|
// options testValue MUST be in lower case already, otherwise it won't match
|
||||||
@ -175,31 +179,31 @@ validate.validators.containsI = function(value, options, key) {
|
|||||||
const testValue = getTestValue(options);
|
const testValue = getTestValue(options);
|
||||||
if (Array.isArray(value)) {
|
if (Array.isArray(value)) {
|
||||||
if (
|
if (
|
||||||
value.some(
|
value.some(
|
||||||
item => !validate.validators.containsI(item.toLowerCase(), options, key)
|
item => !validate.validators.containsI(item.toLowerCase(), options, key)
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
return `No item of ${value.join(',')} contains ${JSON.stringify(
|
return `No item of ${value.join(',')} contains ${JSON.stringify(
|
||||||
testValue
|
testValue
|
||||||
)}`;
|
)}`;
|
||||||
}
|
}
|
||||||
if (Array.isArray(testValue)) {
|
if (Array.isArray(testValue)) {
|
||||||
if (
|
if (
|
||||||
testValue.some(
|
testValue.some(
|
||||||
subTest =>
|
subTest =>
|
||||||
!validate.validators.containsI(value, subTest.toLowerCase(), key)
|
!validate.validators.containsI(value, subTest.toLowerCase(), key)
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
return `${key} must contain at least one of ${testValue.join(',')}`;
|
return `${key} must contain at least one of ${testValue.join(',')}`;
|
||||||
}
|
}
|
||||||
if (
|
if (
|
||||||
testValue &&
|
testValue &&
|
||||||
value.indexOf &&
|
value.indexOf &&
|
||||||
value.toLowerCase().indexOf(testValue.toLowerCase()) === -1
|
value.toLowerCase().indexOf(testValue.toLowerCase()) === -1
|
||||||
) {
|
) {
|
||||||
return key + 'must contain any case of' + testValue;
|
return key + 'must contain any case of' + testValue;
|
||||||
}
|
}
|
||||||
@ -227,14 +231,14 @@ validate.validators.contains = function(value, options, key) {
|
|||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
return `No item of ${value.join(',')} contains ${JSON.stringify(
|
return `No item of ${value.join(',')} contains ${JSON.stringify(
|
||||||
testValue
|
testValue
|
||||||
)}`;
|
)}`;
|
||||||
}
|
}
|
||||||
if (Array.isArray(testValue)) {
|
if (Array.isArray(testValue)) {
|
||||||
if (
|
if (
|
||||||
testValue.some(
|
testValue.some(
|
||||||
subTest => !validate.validators.contains(value, subTest, key)
|
subTest => !validate.validators.contains(value, subTest, key)
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -454,11 +458,13 @@ validate.validators.range = function(value, options, key) {
|
|||||||
if (value === undefined || value < min || value > max) {
|
if (value === undefined || value < min || value > max) {
|
||||||
return `${key} with value ${value} must be between ${min} and ${max}`;
|
return `${key} with value ${value} must be between ${min} and ${max}`;
|
||||||
}
|
}
|
||||||
} else return `${key} must be an array of length 2`;
|
} else {
|
||||||
|
return `${key} must be an array of length 2`;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
validate.validators.notNull = value =>
|
validate.validators.notNull = value =>
|
||||||
value === null || value === undefined ? 'Value is null' : undefined;
|
value === null || value === undefined ? 'Value is null' : undefined;
|
||||||
const getTestValue = options => {
|
const getTestValue = options => {
|
||||||
if (Array.isArray(options)) {
|
if (Array.isArray(options)) {
|
||||||
return options.map(option => option?.value ?? option);
|
return options.map(option => option?.value ?? option);
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -40,7 +40,7 @@ export default class StateSyncService extends PubSubService {
|
|||||||
this.configuration = configuration || {};
|
this.configuration = configuration || {};
|
||||||
}
|
}
|
||||||
|
|
||||||
public init(extensionManager: ExtensionManager): void { }
|
public init(extensionManager: ExtensionManager): void {}
|
||||||
|
|
||||||
/** Registers a new sync store called `id`. The state
|
/** Registers a new sync store called `id`. The state
|
||||||
* defines how the state is stored, and any default clearing of the
|
* defines how the state is stored, and any default clearing of the
|
||||||
|
|||||||
@ -66,7 +66,9 @@ export default class ToolbarService extends PubSubService {
|
|||||||
* called with {...commandOptions,...options}
|
* called with {...commandOptions,...options}
|
||||||
*/
|
*/
|
||||||
recordInteraction(interaction, options?: Record<string, unknown>) {
|
recordInteraction(interaction, options?: Record<string, unknown>) {
|
||||||
if (!interaction) return;
|
if (!interaction) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
const commandsManager = this._commandsManager;
|
const commandsManager = this._commandsManager;
|
||||||
const { groupId, itemId, interactionType, commands } = interaction;
|
const { groupId, itemId, interactionType, commands } = interaction;
|
||||||
|
|
||||||
|
|||||||
@ -35,10 +35,16 @@ const addUniqueIndex = (arr, key, viewports, isUpdatingSameViewport) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const getLutId = (ds): string => {
|
const getLutId = (ds): string => {
|
||||||
if (!ds || !ds.options) return DEFAULT;
|
if (!ds || !ds.options) {
|
||||||
if (ds.options.id) return ds.options.id;
|
return DEFAULT;
|
||||||
|
}
|
||||||
|
if (ds.options.id) {
|
||||||
|
return ds.options.id;
|
||||||
|
}
|
||||||
const arr = Object.entries(ds.options).map(([key, val]) => `${key}=${val}`);
|
const arr = Object.entries(ds.options).map(([key, val]) => `${key}=${val}`);
|
||||||
if (!arr.length) return DEFAULT;
|
if (!arr.length) {
|
||||||
|
return DEFAULT;
|
||||||
|
}
|
||||||
return arr.join(JOIN_STR);
|
return arr.join(JOIN_STR);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -93,7 +99,9 @@ export type PresentationIds = {
|
|||||||
* @returns PresentationIds
|
* @returns PresentationIds
|
||||||
*/
|
*/
|
||||||
const getPresentationIds = (viewport, viewports): PresentationIds => {
|
const getPresentationIds = (viewport, viewports): PresentationIds => {
|
||||||
if (!viewport) return;
|
if (!viewport) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
const {
|
const {
|
||||||
viewportOptions,
|
viewportOptions,
|
||||||
displaySetInstanceUIDs,
|
displaySetInstanceUIDs,
|
||||||
@ -108,7 +116,9 @@ const getPresentationIds = (viewport, viewports): PresentationIds => {
|
|||||||
const lutPresentationArr = [lutId];
|
const lutPresentationArr = [lutId];
|
||||||
|
|
||||||
const positionPresentationArr = [orientation || 'acquisition'];
|
const positionPresentationArr = [orientation || 'acquisition'];
|
||||||
if (id) positionPresentationArr.push(id);
|
if (id) {
|
||||||
|
positionPresentationArr.push(id);
|
||||||
|
}
|
||||||
|
|
||||||
for (const uid of displaySetInstanceUIDs) {
|
for (const uid of displaySetInstanceUIDs) {
|
||||||
positionPresentationArr.push(uid);
|
positionPresentationArr.push(uid);
|
||||||
|
|||||||
@ -1,7 +1,9 @@
|
|||||||
const absoluteUrl = path => {
|
const absoluteUrl = path => {
|
||||||
let absolutePath = '/';
|
let absolutePath = '/';
|
||||||
|
|
||||||
if (!path) return absolutePath;
|
if (!path) {
|
||||||
|
return absolutePath;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Find another way to get root url
|
// TODO: Find another way to get root url
|
||||||
const absoluteUrl = window.location.origin;
|
const absoluteUrl = window.location.origin;
|
||||||
|
|||||||
@ -9,12 +9,16 @@ function debounce(func, wait, immediate) {
|
|||||||
args = arguments;
|
args = arguments;
|
||||||
var later = function() {
|
var later = function() {
|
||||||
timeout = null;
|
timeout = null;
|
||||||
if (!immediate) func.apply(context, args);
|
if (!immediate) {
|
||||||
|
func.apply(context, args);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
var callNow = immediate && !timeout;
|
var callNow = immediate && !timeout;
|
||||||
clearTimeout(timeout);
|
clearTimeout(timeout);
|
||||||
timeout = setTimeout(later, wait);
|
timeout = setTimeout(later, wait);
|
||||||
if (callNow) func.apply(context, args);
|
if (callNow) {
|
||||||
|
func.apply(context, args);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -58,6 +58,8 @@ const imagesTypes = [
|
|||||||
* @returns {boolean} - true if it has image data
|
* @returns {boolean} - true if it has image data
|
||||||
*/
|
*/
|
||||||
export const isImage = SOPClassUID => {
|
export const isImage = SOPClassUID => {
|
||||||
if (!SOPClassUID) return false;
|
if (!SOPClassUID) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
return imagesTypes.indexOf(SOPClassUID) !== -1;
|
return imagesTypes.indexOf(SOPClassUID) !== -1;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,4 +1,10 @@
|
|||||||
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) {
|
export default function isLowPriorityModality(Modality) {
|
||||||
return LOW_PRIORITY_MODALITIES.includes(Modality);
|
return LOW_PRIORITY_MODALITIES.includes(Modality);
|
||||||
|
|||||||
@ -2,11 +2,15 @@ export default function makeCancelable(thenable) {
|
|||||||
let isCanceled = false;
|
let isCanceled = false;
|
||||||
const promise = Promise.resolve(thenable).then(
|
const promise = Promise.resolve(thenable).then(
|
||||||
function(result) {
|
function(result) {
|
||||||
if (isCanceled) throw Object.freeze({ isCanceled });
|
if (isCanceled) {
|
||||||
|
throw Object.freeze({ isCanceled });
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
function(error) {
|
function(error) {
|
||||||
if (isCanceled) throw Object.freeze({ isCanceled, error });
|
if (isCanceled) {
|
||||||
|
throw Object.freeze({ isCanceled, error });
|
||||||
|
}
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|||||||
@ -18,8 +18,9 @@ export default function fetchPaletteColorLookupTableData(
|
|||||||
) {
|
) {
|
||||||
const { PaletteColorLookupTableUID } = item;
|
const { PaletteColorLookupTableUID } = item;
|
||||||
const paletteData = item[tag];
|
const paletteData = item[tag];
|
||||||
if (paletteData === undefined && PaletteColorLookupTableUID === undefined)
|
if (paletteData === undefined && PaletteColorLookupTableUID === undefined) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
// performance optimization - read UID and cache by UID
|
// performance optimization - read UID and cache by UID
|
||||||
return _getPaletteColor(item[tag], item[descriptorTag]);
|
return _getPaletteColor(item[tag], item[descriptorTag]);
|
||||||
}
|
}
|
||||||
@ -28,7 +29,9 @@ function _getPaletteColor(paletteColorLookupTableData, lutDescriptor) {
|
|||||||
const numLutEntries = lutDescriptor[0];
|
const numLutEntries = lutDescriptor[0];
|
||||||
const bits = lutDescriptor[2];
|
const bits = lutDescriptor[2];
|
||||||
|
|
||||||
if (!paletteColorLookupTableData) return undefined;
|
if (!paletteColorLookupTableData) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
const arrayBufferToPaletteColorLUT = arraybuffer => {
|
const arrayBufferToPaletteColorLUT = arraybuffer => {
|
||||||
const lut = [];
|
const lut = [];
|
||||||
|
|||||||
@ -124,7 +124,9 @@ function getOverallProgress(list) {
|
|||||||
status.total++;
|
status.total++;
|
||||||
if (isValidProgress(task.progress)) {
|
if (isValidProgress(task.progress)) {
|
||||||
status.partial += task.progress;
|
status.partial += task.progress;
|
||||||
if (task.progress === 1.0 && task.failed) status.failures++;
|
if (task.progress === 1.0 && task.failed) {
|
||||||
|
status.failures++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
task = task.next;
|
task = task.next;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -13,7 +13,9 @@ const compareSeriesDateTime = (a, b) => {
|
|||||||
const defaultSeriesSort = (a, b) => {
|
const defaultSeriesSort = (a, b) => {
|
||||||
const seriesNumberA = a.SeriesNumber ?? a.seriesNumber;
|
const seriesNumberA = a.SeriesNumber ?? a.seriesNumber;
|
||||||
const seriesNumberB = b.SeriesNumber ?? b.seriesNumber;
|
const seriesNumberB = b.SeriesNumber ?? b.seriesNumber;
|
||||||
if (seriesNumberA === seriesNumberB) return compareSeriesDateTime(a, b);
|
if (seriesNumberA === seriesNumberB) {
|
||||||
|
return compareSeriesDateTime(a, b);
|
||||||
|
}
|
||||||
return seriesNumberA - seriesNumberB;
|
return seriesNumberA - seriesNumberB;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -67,8 +69,11 @@ const sortStudySeries = (
|
|||||||
seriesSortingCriteria = seriesSortCriteria.default,
|
seriesSortingCriteria = seriesSortCriteria.default,
|
||||||
sortFunction = null
|
sortFunction = null
|
||||||
) => {
|
) => {
|
||||||
if (typeof sortFunction === 'function') return sortFunction(series);
|
if (typeof sortFunction === 'function') {
|
||||||
else return series.sort(seriesSortingCriteria);
|
return sortFunction(series);
|
||||||
|
} else {
|
||||||
|
return series.sort(seriesSortingCriteria);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -1,6 +1,8 @@
|
|||||||
/** Splits a list of stirngs by commas within the strings */
|
/** Splits a list of stirngs by commas within the strings */
|
||||||
const splitComma = (strings: string[]): string[] => {
|
const splitComma = (strings: string[]): string[] => {
|
||||||
if (!strings) return null;
|
if (!strings) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
for (let i = 0; i < strings.length; i++) {
|
for (let i = 0; i < strings.length; i++) {
|
||||||
const comma = strings[i].indexOf(',');
|
const comma = strings[i].indexOf(',');
|
||||||
if (comma !== -1) {
|
if (comma !== -1) {
|
||||||
@ -24,7 +26,9 @@ const getSplitParam = (
|
|||||||
const sourceKey = [...params.keys()].find(
|
const sourceKey = [...params.keys()].find(
|
||||||
it => it.toLowerCase() === lowerCaseKey
|
it => it.toLowerCase() === lowerCaseKey
|
||||||
);
|
);
|
||||||
if (!sourceKey) return;
|
if (!sourceKey) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
return splitComma(params.getAll(sourceKey));
|
return splitComma(params.getAll(sourceKey));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
// By default, Docusaurus generates a sidebar from the docs folder structure
|
// By default, Docusaurus generates a sidebar from the docs folder structure
|
||||||
tutorialSidebar: [{type: 'autogenerated', dirName: '.'}],
|
tutorialSidebar: [{ type: 'autogenerated', dirName: '.' }],
|
||||||
|
|
||||||
// But you can create a sidebar manually
|
// But you can create a sidebar manually
|
||||||
/*
|
/*
|
||||||
|
|||||||
@ -4,7 +4,15 @@ const debugMode = !!(
|
|||||||
|
|
||||||
const detectionOptions = {
|
const detectionOptions = {
|
||||||
// order and from where user language should be detected
|
// order and from where user language should be detected
|
||||||
order: ['querystring', 'cookie', 'localStorage', 'navigator', 'htmlTag', 'path', 'subdomain'],
|
order: [
|
||||||
|
'querystring',
|
||||||
|
'cookie',
|
||||||
|
'localStorage',
|
||||||
|
'navigator',
|
||||||
|
'htmlTag',
|
||||||
|
'path',
|
||||||
|
'subdomain',
|
||||||
|
],
|
||||||
|
|
||||||
// keys or params to lookup language from
|
// keys or params to lookup language from
|
||||||
lookupQuerystring: 'lng',
|
lookupQuerystring: 'lng',
|
||||||
@ -18,7 +26,7 @@ const detectionOptions = {
|
|||||||
excludeCacheFor: ['cimode'], // languages to not persist (cookie, localStorage)
|
excludeCacheFor: ['cimode'], // languages to not persist (cookie, localStorage)
|
||||||
|
|
||||||
// optional htmlTag with lang attribute, the default is:
|
// optional htmlTag with lang attribute, the default is:
|
||||||
htmlTag: document.documentElement
|
htmlTag: document.documentElement,
|
||||||
};
|
};
|
||||||
|
|
||||||
export { debugMode, detectionOptions };
|
export { debugMode, detectionOptions };
|
||||||
|
|||||||
@ -128,7 +128,7 @@ function initI18n(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return initialized.then(function (t) {
|
return initialized.then(function(t) {
|
||||||
i18n.T = t;
|
i18n.T = t;
|
||||||
customDebug(`T function available.`, 'info');
|
customDebug(`T function available.`, 'info');
|
||||||
});
|
});
|
||||||
@ -140,7 +140,13 @@ i18n.initializing = initI18n();
|
|||||||
i18n.initI18n = initI18n;
|
i18n.initI18n = initI18n;
|
||||||
i18n.addLocales = addLocales;
|
i18n.addLocales = addLocales;
|
||||||
i18n.availableLanguages = getAvailableLanguagesInfo(locales);
|
i18n.availableLanguages = getAvailableLanguagesInfo(locales);
|
||||||
i18n.defaultLanguage = { label: getLanguageLabel(DEFAULT_LANGUAGE), value: DEFAULT_LANGUAGE };
|
i18n.defaultLanguage = {
|
||||||
i18n.currentLanguage = () => ({ label: getLanguageLabel(i18n.language), value: i18n.language });
|
label: getLanguageLabel(DEFAULT_LANGUAGE),
|
||||||
|
value: DEFAULT_LANGUAGE,
|
||||||
|
};
|
||||||
|
i18n.currentLanguage = () => ({
|
||||||
|
label: getLanguageLabel(i18n.language),
|
||||||
|
value: i18n.language,
|
||||||
|
});
|
||||||
|
|
||||||
export default i18n;
|
export default i18n;
|
||||||
|
|||||||
@ -19,5 +19,5 @@ export default {
|
|||||||
...pt_BR,
|
...pt_BR,
|
||||||
...vi,
|
...vi,
|
||||||
...zh,
|
...zh,
|
||||||
...test_lng
|
...test_lng,
|
||||||
};
|
};
|
||||||
|
|||||||
@ -32,6 +32,6 @@ export default {
|
|||||||
PatientInfo,
|
PatientInfo,
|
||||||
Modes,
|
Modes,
|
||||||
SidePanel,
|
SidePanel,
|
||||||
Modals
|
Modals,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@ -57,7 +57,7 @@ const languagesMap = {
|
|||||||
'test-LNG': 'Test Language',
|
'test-LNG': 'Test Language',
|
||||||
};
|
};
|
||||||
|
|
||||||
const getLanguageLabel = (language) => {
|
const getLanguageLabel = language => {
|
||||||
return languagesMap[language];
|
return languagesMap[language];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -21,7 +21,9 @@ const directories = getDirectories(directoryPath);
|
|||||||
|
|
||||||
function writeFile(filepath, name, content) {
|
function writeFile(filepath, name, content) {
|
||||||
fs.writeFile(path.join(filepath, name), content, err => {
|
fs.writeFile(path.join(filepath, name), content, err => {
|
||||||
if (err) throw err;
|
if (err) {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -45,7 +45,7 @@ const renderYearsOptions = () => {
|
|||||||
return options;
|
return options;
|
||||||
};
|
};
|
||||||
|
|
||||||
const DateRange = (props) => {
|
const DateRange = props => {
|
||||||
const { id, onChange, startDate, endDate } = props;
|
const { id, onChange, startDate, endDate } = props;
|
||||||
const [focusedInput, setFocusedInput] = useState(null);
|
const [focusedInput, setFocusedInput] = useState(null);
|
||||||
const renderYearsOptionsCallback = useCallback(renderYearsOptions, []);
|
const renderYearsOptionsCallback = useCallback(renderYearsOptions, []);
|
||||||
@ -81,15 +81,15 @@ const DateRange = (props) => {
|
|||||||
onYearSelect: PropTypes.func,
|
onYearSelect: PropTypes.func,
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleMonthChange = (event) => {
|
const handleMonthChange = event => {
|
||||||
onMonthSelect(month, event.target.value);
|
onMonthSelect(month, event.target.value);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleYearChange = (event) => {
|
const handleYearChange = event => {
|
||||||
onYearSelect(month, event.target.value);
|
onYearSelect(month, event.target.value);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleOnBlur = () => { };
|
const handleOnBlur = () => {};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex justify-center">
|
<div className="flex justify-center">
|
||||||
@ -136,10 +136,10 @@ const DateRange = (props) => {
|
|||||||
onChange({
|
onChange({
|
||||||
startDate: newStartDate ? newStartDate.format('YYYYMMDD') : undefined,
|
startDate: newStartDate ? newStartDate.format('YYYYMMDD') : undefined,
|
||||||
endDate: newEndDate ? newEndDate.format('YYYYMMDD') : undefined,
|
endDate: newEndDate ? newEndDate.format('YYYYMMDD') : undefined,
|
||||||
})
|
});
|
||||||
}}
|
}}
|
||||||
focusedInput={focusedInput}
|
focusedInput={focusedInput}
|
||||||
onFocusChange={(updatedVal) => setFocusedInput(updatedVal)}
|
onFocusChange={updatedVal => setFocusedInput(updatedVal)}
|
||||||
/** OPTIONAL */
|
/** OPTIONAL */
|
||||||
renderCalendarInfo={renderDatePresets}
|
renderCalendarInfo={renderDatePresets}
|
||||||
renderMonthElement={renderMonthElement}
|
renderMonthElement={renderMonthElement}
|
||||||
@ -149,7 +149,7 @@ const DateRange = (props) => {
|
|||||||
closeDatePicker: 'Close',
|
closeDatePicker: 'Close',
|
||||||
clearDates: 'Clear dates',
|
clearDates: 'Clear dates',
|
||||||
}}
|
}}
|
||||||
isOutsideRange={(day) => !isInclusivelyBeforeDay(day, moment())}
|
isOutsideRange={day => !isInclusivelyBeforeDay(day, moment())}
|
||||||
hideKeyboardShortcutsPanel={true}
|
hideKeyboardShortcutsPanel={true}
|
||||||
numberOfMonths={1}
|
numberOfMonths={1}
|
||||||
showClearDates={false}
|
showClearDates={false}
|
||||||
|
|||||||
@ -15,7 +15,14 @@ import { getKeys, formatKeysForInput } from './utils';
|
|||||||
* @param {string} props.className input classes
|
* @param {string} props.className input classes
|
||||||
* @param {Array[]} props.modifierKeys
|
* @param {Array[]} props.modifierKeys
|
||||||
*/
|
*/
|
||||||
const HotkeyField = ({ disabled, keys, onChange, className, modifierKeys, hotkeys }) => {
|
const HotkeyField = ({
|
||||||
|
disabled,
|
||||||
|
keys,
|
||||||
|
onChange,
|
||||||
|
className,
|
||||||
|
modifierKeys,
|
||||||
|
hotkeys,
|
||||||
|
}) => {
|
||||||
const inputValue = formatKeysForInput(keys);
|
const inputValue = formatKeysForInput(keys);
|
||||||
|
|
||||||
const onInputKeyDown = event => {
|
const onInputKeyDown = event => {
|
||||||
@ -55,11 +62,11 @@ HotkeyField.propTypes = {
|
|||||||
unpause: PropTypes.func.isRequired,
|
unpause: PropTypes.func.isRequired,
|
||||||
startRecording: PropTypes.func.isRequired,
|
startRecording: PropTypes.func.isRequired,
|
||||||
record: PropTypes.func.isRequired,
|
record: PropTypes.func.isRequired,
|
||||||
}).isRequired
|
}).isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
HotkeyField.defaultProps = {
|
HotkeyField.defaultProps = {
|
||||||
disabled: false
|
disabled: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default HotkeyField;
|
export default HotkeyField;
|
||||||
|
|||||||
@ -25,7 +25,4 @@ const getKeys = ({ sequence, modifierKeys }) => {
|
|||||||
return [...modifiers, ...keys];
|
return [...modifiers, ...keys];
|
||||||
};
|
};
|
||||||
|
|
||||||
export {
|
export { getKeys, formatKeysForInput };
|
||||||
getKeys,
|
|
||||||
formatKeysForInput
|
|
||||||
};
|
|
||||||
|
|||||||
@ -72,7 +72,9 @@ const disallowedValidator = ({ pressedKeys = [] }) => {
|
|||||||
|
|
||||||
if (hasDisallowedCombinations) {
|
if (hasDisallowedCombinations) {
|
||||||
return {
|
return {
|
||||||
error: `"${formatPressedKeys(pressedKeys)}" shortcut combination is not allowed`,
|
error: `"${formatPressedKeys(
|
||||||
|
pressedKeys
|
||||||
|
)}" shortcut combination is not allowed`,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user