ohif-core --> @ohif/core
This commit is contained in:
parent
8c5bd55f88
commit
755da173ea
@ -197,9 +197,9 @@ would like included at startup.
|
|||||||
_app.js_
|
_app.js_
|
||||||
|
|
||||||
```js
|
```js
|
||||||
import { createStore, combineReducers } from 'redux';
|
import { createStore, combineReducers } from "redux";
|
||||||
import OHIF from 'ohif-core';
|
import OHIF from "@ohif/core";
|
||||||
import OHIFCornerstoneExtension from 'ohif-cornerstone-extension';
|
import OHIFCornerstoneExtension from "ohif-cornerstone-extension";
|
||||||
|
|
||||||
const combined = combineReducers(OHIF.redux.reducers);
|
const combined = combineReducers(OHIF.redux.reducers);
|
||||||
const store = createStore(combined);
|
const store = createStore(combined);
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import CornerstoneViewport from 'react-cornerstone-viewport';
|
import CornerstoneViewport from "react-cornerstone-viewport";
|
||||||
import OHIF from 'ohif-core';
|
import OHIF from "@ohif/core";
|
||||||
import { connect } from 'react-redux';
|
import { connect } from "react-redux";
|
||||||
import throttle from 'lodash.throttle';
|
import throttle from "lodash.throttle";
|
||||||
|
|
||||||
const { setViewportActive, setViewportSpecificData } = OHIF.redux.actions;
|
const { setViewportActive, setViewportSpecificData } = OHIF.redux.actions;
|
||||||
|
|
||||||
@ -37,7 +37,7 @@ const mapStateToProps = (state, ownProps) => {
|
|||||||
enableStackPrefetch: isActive,
|
enableStackPrefetch: isActive,
|
||||||
//stack: viewportSpecificData.stack,
|
//stack: viewportSpecificData.stack,
|
||||||
cineToolData: viewportSpecificData.cine,
|
cineToolData: viewportSpecificData.cine,
|
||||||
viewport: viewportSpecificData.viewport,
|
viewport: viewportSpecificData.viewport
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -64,8 +64,8 @@ const mapDispatchToProps = (dispatch, ownProps) => {
|
|||||||
dispatch(
|
dispatch(
|
||||||
setViewportSpecificData(viewportIndex, {
|
setViewportSpecificData(viewportIndex, {
|
||||||
// TODO: Hack to make sure our plugin info is available from the outset
|
// TODO: Hack to make sure our plugin info is available from the outset
|
||||||
plugin: 'cornerstone',
|
plugin: "cornerstone",
|
||||||
dom: enabledElement,
|
dom: enabledElement
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
@ -74,18 +74,18 @@ const mapDispatchToProps = (dispatch, ownProps) => {
|
|||||||
const {
|
const {
|
||||||
onAdded,
|
onAdded,
|
||||||
onRemoved,
|
onRemoved,
|
||||||
onModified,
|
onModified
|
||||||
} = OHIF.measurements.MeasurementHandlers;
|
} = OHIF.measurements.MeasurementHandlers;
|
||||||
const actions = {
|
const actions = {
|
||||||
added: onAdded,
|
added: onAdded,
|
||||||
removed: onRemoved,
|
removed: onRemoved,
|
||||||
modified: throttle(event => {
|
modified: throttle(event => {
|
||||||
return onModified(event);
|
return onModified(event);
|
||||||
}, 300),
|
}, 300)
|
||||||
};
|
};
|
||||||
|
|
||||||
return actions[action](event);
|
return actions[action](event);
|
||||||
},
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
import React, { Component } from 'react';
|
import React, { Component } from "react";
|
||||||
|
|
||||||
import ConnectedCornerstoneViewport from './ConnectedCornerstoneViewport';
|
import ConnectedCornerstoneViewport from "./ConnectedCornerstoneViewport";
|
||||||
import OHIF from 'ohif-core';
|
import OHIF from "@ohif/core";
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from "prop-types";
|
||||||
import cornerstone from 'cornerstone-core';
|
import cornerstone from "cornerstone-core";
|
||||||
import handleSegmentationStorage from './handleSegmentationStorage.js';
|
import handleSegmentationStorage from "./handleSegmentationStorage.js";
|
||||||
|
|
||||||
const { StackManager } = OHIF.utils;
|
const { StackManager } = OHIF.utils;
|
||||||
|
|
||||||
@ -18,7 +18,7 @@ cornerstone.metaData.addProvider(
|
|||||||
StackManager.setMetadataProvider(metadataProvider);
|
StackManager.setMetadataProvider(metadataProvider);
|
||||||
|
|
||||||
const SOP_CLASSES = {
|
const SOP_CLASSES = {
|
||||||
SEGMENTATION_STORAGE: '1.2.840.10008.5.1.4.1.1.66.4',
|
SEGMENTATION_STORAGE: "1.2.840.10008.5.1.4.1.1.66.4"
|
||||||
};
|
};
|
||||||
|
|
||||||
const specialCaseHandlers = {};
|
const specialCaseHandlers = {};
|
||||||
@ -28,11 +28,11 @@ specialCaseHandlers[
|
|||||||
|
|
||||||
class OHIFCornerstoneViewport extends Component {
|
class OHIFCornerstoneViewport extends Component {
|
||||||
state = {
|
state = {
|
||||||
viewportData: null,
|
viewportData: null
|
||||||
};
|
};
|
||||||
|
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
customProps: {},
|
customProps: {}
|
||||||
};
|
};
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
@ -40,17 +40,17 @@ class OHIFCornerstoneViewport extends Component {
|
|||||||
displaySet: PropTypes.object,
|
displaySet: PropTypes.object,
|
||||||
viewportIndex: PropTypes.number,
|
viewportIndex: PropTypes.number,
|
||||||
children: PropTypes.node,
|
children: PropTypes.node,
|
||||||
customProps: PropTypes.object,
|
customProps: PropTypes.object
|
||||||
};
|
};
|
||||||
|
|
||||||
static id = 'OHIFCornerstoneViewport';
|
static id = "OHIFCornerstoneViewport";
|
||||||
|
|
||||||
static init() {
|
static init() {
|
||||||
console.log('OHIFCornerstoneViewport init()');
|
console.log("OHIFCornerstoneViewport init()");
|
||||||
}
|
}
|
||||||
|
|
||||||
static destroy() {
|
static destroy() {
|
||||||
console.log('OHIFCornerstoneViewport destroy()');
|
console.log("OHIFCornerstoneViewport destroy()");
|
||||||
StackManager.clearStacks();
|
StackManager.clearStacks();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,15 +72,15 @@ class OHIFCornerstoneViewport extends Component {
|
|||||||
frameIndex = 0
|
frameIndex = 0
|
||||||
) {
|
) {
|
||||||
if (!studies || !studies.length) {
|
if (!studies || !studies.length) {
|
||||||
throw new Error('Studies not provided.');
|
throw new Error("Studies not provided.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!studyInstanceUid) {
|
if (!studyInstanceUid) {
|
||||||
throw new Error('StudyInstanceUID not provided.');
|
throw new Error("StudyInstanceUID not provided.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!displaySetInstanceUid) {
|
if (!displaySetInstanceUid) {
|
||||||
throw new Error('StudyInstanceUID not provided.');
|
throw new Error("StudyInstanceUID not provided.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create shortcut to displaySet
|
// Create shortcut to displaySet
|
||||||
@ -89,7 +89,7 @@ class OHIFCornerstoneViewport extends Component {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (!study) {
|
if (!study) {
|
||||||
throw new Error('Study not found.');
|
throw new Error("Study not found.");
|
||||||
}
|
}
|
||||||
|
|
||||||
const displaySet = study.displaySets.find(set => {
|
const displaySet = study.displaySets.find(set => {
|
||||||
@ -97,7 +97,7 @@ class OHIFCornerstoneViewport extends Component {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (!displaySet) {
|
if (!displaySet) {
|
||||||
throw new Error('Display Set not found.');
|
throw new Error("Display Set not found.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get stack from Stack Manager
|
// Get stack from Stack Manager
|
||||||
@ -110,7 +110,7 @@ class OHIFCornerstoneViewport extends Component {
|
|||||||
if (sopInstanceUid) {
|
if (sopInstanceUid) {
|
||||||
const index = stack.imageIds.findIndex(imageId => {
|
const index = stack.imageIds.findIndex(imageId => {
|
||||||
const sopCommonModule = cornerstone.metaData.get(
|
const sopCommonModule = cornerstone.metaData.get(
|
||||||
'sopCommonModule',
|
"sopCommonModule",
|
||||||
imageId
|
imageId
|
||||||
);
|
);
|
||||||
if (!sopCommonModule) {
|
if (!sopCommonModule) {
|
||||||
@ -124,7 +124,7 @@ class OHIFCornerstoneViewport extends Component {
|
|||||||
stack.currentImageIdIndex = index;
|
stack.currentImageIdIndex = index;
|
||||||
} else {
|
} else {
|
||||||
console.warn(
|
console.warn(
|
||||||
'SOPInstanceUID provided was not found in specified DisplaySet'
|
"SOPInstanceUID provided was not found in specified DisplaySet"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -183,7 +183,7 @@ class OHIFCornerstoneViewport extends Component {
|
|||||||
viewportData = {
|
viewportData = {
|
||||||
studyInstanceUid,
|
studyInstanceUid,
|
||||||
displaySetInstanceUid,
|
displaySetInstanceUid,
|
||||||
stack,
|
stack
|
||||||
};
|
};
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -199,12 +199,12 @@ class OHIFCornerstoneViewport extends Component {
|
|||||||
displaySetInstanceUid,
|
displaySetInstanceUid,
|
||||||
sopClassUids,
|
sopClassUids,
|
||||||
sopInstanceUid,
|
sopInstanceUid,
|
||||||
frameIndex,
|
frameIndex
|
||||||
} = displaySet;
|
} = displaySet;
|
||||||
|
|
||||||
if (sopClassUids && sopClassUids.length > 1) {
|
if (sopClassUids && sopClassUids.length > 1) {
|
||||||
console.warn(
|
console.warn(
|
||||||
'More than one SOPClassUid in the same series is not yet supported.'
|
"More than one SOPClassUid in the same series is not yet supported."
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -219,7 +219,7 @@ class OHIFCornerstoneViewport extends Component {
|
|||||||
frameIndex
|
frameIndex
|
||||||
).then(viewportData => {
|
).then(viewportData => {
|
||||||
this.setState({
|
this.setState({
|
||||||
viewportData,
|
viewportData
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -250,7 +250,7 @@ class OHIFCornerstoneViewport extends Component {
|
|||||||
childrenWithProps = this.props.children.map((child, index) => {
|
childrenWithProps = this.props.children.map((child, index) => {
|
||||||
return React.cloneElement(child, {
|
return React.cloneElement(child, {
|
||||||
viewportIndex: this.props.viewportIndex,
|
viewportIndex: this.props.viewportIndex,
|
||||||
key: index,
|
key: index
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
import * as dcmjs from 'dcmjs';
|
import * as dcmjs from "dcmjs";
|
||||||
|
|
||||||
import OHIF from 'ohif-core';
|
import OHIF from "@ohif/core";
|
||||||
import cornerstone from 'cornerstone-core';
|
import cornerstone from "cornerstone-core";
|
||||||
import cornerstoneTools from 'cornerstone-tools';
|
import cornerstoneTools from "cornerstone-tools";
|
||||||
|
|
||||||
const { StackManager } = OHIF.utils;
|
const { StackManager } = OHIF.utils;
|
||||||
|
|
||||||
@ -56,7 +56,7 @@ function retrieveDicomData(wadoUri) {
|
|||||||
// TODO: Authorization header depends on the server. If we ever have multiple servers
|
// TODO: Authorization header depends on the server. If we ever have multiple servers
|
||||||
// we will need to figure out how / when to pass this information in.
|
// we will need to figure out how / when to pass this information in.
|
||||||
return fetch(wadoUri, {
|
return fetch(wadoUri, {
|
||||||
headers: OHIF.DICOMWeb.getAuthorizationHeader(),
|
headers: OHIF.DICOMWeb.getAuthorizationHeader()
|
||||||
}).then(response => response.arrayBuffer());
|
}).then(response => response.arrayBuffer());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,7 +91,7 @@ async function handleSegmentationStorage(
|
|||||||
|
|
||||||
if (displaySets.length > 1) {
|
if (displaySets.length > 1) {
|
||||||
console.warn(
|
console.warn(
|
||||||
'More than one display set with the same seriesInstanceUid. This is not supported yet...'
|
"More than one display set with the same seriesInstanceUid. This is not supported yet..."
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -100,7 +100,7 @@ async function handleSegmentationStorage(
|
|||||||
const results = parseSeg(arrayBuffer, imageIds);
|
const results = parseSeg(arrayBuffer, imageIds);
|
||||||
|
|
||||||
if (!results) {
|
if (!results) {
|
||||||
throw new Error('Fractional segmentations are not supported');
|
throw new Error("Fractional segmentations are not supported");
|
||||||
}
|
}
|
||||||
|
|
||||||
const { segMetadata, toolState } = results;
|
const { segMetadata, toolState } = results;
|
||||||
@ -123,7 +123,7 @@ async function handleSegmentationStorage(
|
|||||||
return {
|
return {
|
||||||
studyInstanceUid,
|
studyInstanceUid,
|
||||||
displaySetInstanceUid,
|
displaySetInstanceUid,
|
||||||
stack,
|
stack
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,14 +1,14 @@
|
|||||||
import { MODULE_TYPES, utils } from 'ohif-core';
|
import { MODULE_TYPES, utils } from "@ohif/core";
|
||||||
|
|
||||||
// TODO: Should probably use dcmjs for this
|
// TODO: Should probably use dcmjs for this
|
||||||
const SOP_CLASS_UIDS = {
|
const SOP_CLASS_UIDS = {
|
||||||
BASIC_TEXT_SR: '1.2.840.10008.5.1.4.1.1.88.11',
|
BASIC_TEXT_SR: "1.2.840.10008.5.1.4.1.1.88.11",
|
||||||
ENHANCED_SR: '1.2.840.10008.5.1.4.1.1.88.22',
|
ENHANCED_SR: "1.2.840.10008.5.1.4.1.1.88.22",
|
||||||
COMPREHENSIVE_SR: '1.2.840.10008.5.1.4.1.1.88.33',
|
COMPREHENSIVE_SR: "1.2.840.10008.5.1.4.1.1.88.33",
|
||||||
PROCEDURE_LOG_STORAGE: '1.2.840.10008.5.1.4.1.1.88.40',
|
PROCEDURE_LOG_STORAGE: "1.2.840.10008.5.1.4.1.1.88.40",
|
||||||
MAMMOGRAPHY_CAD_SR: '1.2.840.10008.5.1.4.1.1.88.50',
|
MAMMOGRAPHY_CAD_SR: "1.2.840.10008.5.1.4.1.1.88.50",
|
||||||
CHEST_CAD_SR: '1.2.840.10008.5.1.4.1.1.88.65',
|
CHEST_CAD_SR: "1.2.840.10008.5.1.4.1.1.88.65",
|
||||||
X_RAY_RADIATION_DOSE_SR: '1.2.840.10008.5.1.4.1.1.88.67'
|
X_RAY_RADIATION_DOSE_SR: "1.2.840.10008.5.1.4.1.1.88.67"
|
||||||
};
|
};
|
||||||
|
|
||||||
const sopClassUids = Object.values(SOP_CLASS_UIDS);
|
const sopClassUids = Object.values(SOP_CLASS_UIDS);
|
||||||
@ -16,14 +16,14 @@ const sopClassUids = Object.values(SOP_CLASS_UIDS);
|
|||||||
// TODO: Handle the case where there is more than one SOP Class Handler for the
|
// TODO: Handle the case where there is more than one SOP Class Handler for the
|
||||||
// same SOP Class
|
// same SOP Class
|
||||||
const OHIFDicomHtmlSopClassHandler = {
|
const OHIFDicomHtmlSopClassHandler = {
|
||||||
id: 'OHIFDicomHtmlSopClassHandler',
|
id: "OHIFDicomHtmlSopClassHandler",
|
||||||
type: MODULE_TYPES.SOP_CLASS_HANDLER,
|
type: MODULE_TYPES.SOP_CLASS_HANDLER,
|
||||||
sopClassUids,
|
sopClassUids,
|
||||||
getDisplaySetFromSeries(series, study, dicomWebClient, authorizationHeaders) {
|
getDisplaySetFromSeries(series, study, dicomWebClient, authorizationHeaders) {
|
||||||
const instance = series.getFirstInstance();
|
const instance = series.getFirstInstance();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
plugin: 'html',
|
plugin: "html",
|
||||||
displaySetInstanceUid: utils.guid(),
|
displaySetInstanceUid: utils.guid(),
|
||||||
wadoRoot: study.getData().wadoRoot,
|
wadoRoot: study.getData().wadoRoot,
|
||||||
wadoUri: instance.getData().wadouri,
|
wadoUri: instance.getData().wadouri,
|
||||||
|
|||||||
@ -1,13 +1,13 @@
|
|||||||
import OHIF from 'ohif-core';
|
import OHIF from "@ohif/core";
|
||||||
|
|
||||||
const { utils } = OHIF;
|
const { utils } = OHIF;
|
||||||
|
|
||||||
const SOP_CLASS_UIDS = {
|
const SOP_CLASS_UIDS = {
|
||||||
VL_WHOLE_SLIDE_MICROSCOPY_IMAGE_STORAGE: '1.2.840.10008.5.1.4.1.1.77.1.6',
|
VL_WHOLE_SLIDE_MICROSCOPY_IMAGE_STORAGE: "1.2.840.10008.5.1.4.1.1.77.1.6"
|
||||||
};
|
};
|
||||||
|
|
||||||
const DicomMicroscopySopClassHandler = {
|
const DicomMicroscopySopClassHandler = {
|
||||||
id: 'DicomMicroscopySopClassHandlerPlugin',
|
id: "DicomMicroscopySopClassHandlerPlugin",
|
||||||
sopClassUids: [SOP_CLASS_UIDS.VL_WHOLE_SLIDE_MICROSCOPY_IMAGE_STORAGE],
|
sopClassUids: [SOP_CLASS_UIDS.VL_WHOLE_SLIDE_MICROSCOPY_IMAGE_STORAGE],
|
||||||
getDisplaySetFromSeries(series, study, dicomWebClient) {
|
getDisplaySetFromSeries(series, study, dicomWebClient) {
|
||||||
const instance = series.getFirstInstance();
|
const instance = series.getFirstInstance();
|
||||||
@ -15,14 +15,14 @@ const DicomMicroscopySopClassHandler = {
|
|||||||
// Note: We are passing the dicomweb client into each viewport!
|
// Note: We are passing the dicomweb client into each viewport!
|
||||||
|
|
||||||
return {
|
return {
|
||||||
plugin: 'microscopy',
|
plugin: "microscopy",
|
||||||
displaySetInstanceUid: utils.guid(),
|
displaySetInstanceUid: utils.guid(),
|
||||||
dicomWebClient,
|
dicomWebClient,
|
||||||
sopInstanceUid: instance.getSOPInstanceUID(),
|
sopInstanceUid: instance.getSOPInstanceUID(),
|
||||||
seriesInstanceUid: series.getSeriesInstanceUID(),
|
seriesInstanceUid: series.getSeriesInstanceUID(),
|
||||||
studyInstanceUid: study.getStudyInstanceUID(),
|
studyInstanceUid: study.getStudyInstanceUID()
|
||||||
};
|
};
|
||||||
},
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export default DicomMicroscopySopClassHandler;
|
export default DicomMicroscopySopClassHandler;
|
||||||
|
|||||||
@ -1,19 +1,19 @@
|
|||||||
import { MODULE_TYPES, utils } from 'ohif-core';
|
import { MODULE_TYPES, utils } from "@ohif/core";
|
||||||
|
|
||||||
// TODO: Should probably use dcmjs for this
|
// TODO: Should probably use dcmjs for this
|
||||||
const SOP_CLASS_UIDS = {
|
const SOP_CLASS_UIDS = {
|
||||||
ENCAPSULATED_PDF: '1.2.840.10008.5.1.4.1.1.104.1'
|
ENCAPSULATED_PDF: "1.2.840.10008.5.1.4.1.1.104.1"
|
||||||
};
|
};
|
||||||
|
|
||||||
const OHIFDicomPDFSopClassHandler = {
|
const OHIFDicomPDFSopClassHandler = {
|
||||||
id: 'OHIFDicomPDFSopClassHandlerPlugin',
|
id: "OHIFDicomPDFSopClassHandlerPlugin",
|
||||||
type: MODULE_TYPES.SOP_CLASS_HANDLER,
|
type: MODULE_TYPES.SOP_CLASS_HANDLER,
|
||||||
sopClassUids: [SOP_CLASS_UIDS.ENCAPSULATED_PDF],
|
sopClassUids: [SOP_CLASS_UIDS.ENCAPSULATED_PDF],
|
||||||
getDisplaySetFromSeries(series, study, dicomWebClient, authorizationHeaders) {
|
getDisplaySetFromSeries(series, study, dicomWebClient, authorizationHeaders) {
|
||||||
const instance = series.getFirstInstance();
|
const instance = series.getFirstInstance();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
plugin: 'pdf',
|
plugin: "pdf",
|
||||||
displaySetInstanceUid: utils.guid(),
|
displaySetInstanceUid: utils.guid(),
|
||||||
wadoRoot: study.getData().wadoRoot,
|
wadoRoot: study.getData().wadoRoot,
|
||||||
wadoUri: instance.getData().wadouri,
|
wadoUri: instance.getData().wadouri,
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
import React, { Component } from 'react';
|
import React, { Component } from "react";
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from "prop-types";
|
||||||
import OHIF from 'ohif-core';
|
import OHIF from "@ohif/core";
|
||||||
import OHIFComponentPlugin from './OHIFComponentPlugin.js';
|
import OHIFComponentPlugin from "./OHIFComponentPlugin.js";
|
||||||
import DicomPDFViewport from './DicomPDFViewport';
|
import DicomPDFViewport from "./DicomPDFViewport";
|
||||||
|
|
||||||
const { DICOMWeb } = OHIF;
|
const { DICOMWeb } = OHIF;
|
||||||
|
|
||||||
@ -18,44 +18,69 @@ class OHIFDicomPDFViewport extends Component {
|
|||||||
error: null
|
error: null
|
||||||
};
|
};
|
||||||
|
|
||||||
static id = 'DicomPDFViewportPDF';
|
static id = "DicomPDFViewportPDF";
|
||||||
|
|
||||||
static init() {
|
static init() {
|
||||||
console.log('DicomPDFViewport init()');
|
console.log("DicomPDFViewport init()");
|
||||||
}
|
}
|
||||||
|
|
||||||
static destroy() {
|
static destroy() {
|
||||||
console.log('DicomPDFViewport destroy()');
|
console.log("DicomPDFViewport destroy()");
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
const { displaySet } = this.props.viewportData;
|
const { displaySet } = this.props.viewportData;
|
||||||
const { studyInstanceUid, seriesInstanceUid, sopInstanceUid, wadoRoot, wadoUri, authorizationHeaders} = displaySet;
|
const {
|
||||||
|
studyInstanceUid,
|
||||||
|
seriesInstanceUid,
|
||||||
|
sopInstanceUid,
|
||||||
|
wadoRoot,
|
||||||
|
wadoUri,
|
||||||
|
authorizationHeaders
|
||||||
|
} = displaySet;
|
||||||
|
|
||||||
this.retrieveDicomData(studyInstanceUid, seriesInstanceUid, sopInstanceUid, wadoRoot, wadoUri, authorizationHeaders).then(byteArray => {
|
this.retrieveDicomData(
|
||||||
this.setState({
|
studyInstanceUid,
|
||||||
byteArray
|
seriesInstanceUid,
|
||||||
});
|
sopInstanceUid,
|
||||||
}, error => {
|
wadoRoot,
|
||||||
this.setState({
|
wadoUri,
|
||||||
error
|
authorizationHeaders
|
||||||
});
|
).then(
|
||||||
|
byteArray => {
|
||||||
|
this.setState({
|
||||||
|
byteArray
|
||||||
|
});
|
||||||
|
},
|
||||||
|
error => {
|
||||||
|
this.setState({
|
||||||
|
error
|
||||||
|
});
|
||||||
|
|
||||||
throw new Error(error);
|
throw new Error(error);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
retrieveDicomData(studyInstanceUid, seriesInstanceUid, sopInstanceUid, wadoRoot, wadoUri, authorizationHeaders) {
|
retrieveDicomData(
|
||||||
|
studyInstanceUid,
|
||||||
|
seriesInstanceUid,
|
||||||
|
sopInstanceUid,
|
||||||
|
wadoRoot,
|
||||||
|
wadoUri,
|
||||||
|
authorizationHeaders
|
||||||
|
) {
|
||||||
// TODO: Passing in a lot of data we aren't using
|
// TODO: Passing in a lot of data we aren't using
|
||||||
|
|
||||||
// TODO: Authorization header depends on the server. If we ever have multiple servers
|
// TODO: Authorization header depends on the server. If we ever have multiple servers
|
||||||
// we will need to figure out how / when to pass this information in.
|
// we will need to figure out how / when to pass this information in.
|
||||||
return fetch(wadoUri, {
|
return fetch(wadoUri, {
|
||||||
headers: authorizationHeaders
|
headers: authorizationHeaders
|
||||||
}).then(response => response.arrayBuffer()).then(arraybuffer => {
|
})
|
||||||
return new Uint8Array(arraybuffer);
|
.then(response => response.arrayBuffer())
|
||||||
});
|
.then(arraybuffer => {
|
||||||
|
return new Uint8Array(arraybuffer);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import OHIF from 'ohif-core';
|
import OHIF from "@ohif/core";
|
||||||
import { View2D } from 'react-vtkjs-viewport';
|
import { View2D } from "react-vtkjs-viewport";
|
||||||
import { connect } from 'react-redux';
|
import { connect } from "react-redux";
|
||||||
|
|
||||||
const { setViewportActive, setViewportSpecificData } = OHIF.redux.actions;
|
const { setViewportActive, setViewportSpecificData } = OHIF.redux.actions;
|
||||||
|
|
||||||
@ -24,7 +24,7 @@ const mapStateToProps = (state, ownProps) => {
|
|||||||
// Hopefully this doesn't break anything under the hood for this one
|
// Hopefully this doesn't break anything under the hood for this one
|
||||||
// activeTool: activeButton && activeButton.command,
|
// activeTool: activeButton && activeButton.command,
|
||||||
...dataFromStore,
|
...dataFromStore,
|
||||||
enableStackPrefetch: isActive,
|
enableStackPrefetch: isActive
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -38,7 +38,7 @@ const mapDispatchToProps = (dispatch, ownProps) => {
|
|||||||
|
|
||||||
setViewportSpecificData: data => {
|
setViewportSpecificData: data => {
|
||||||
dispatch(setViewportSpecificData(viewportIndex, data));
|
dispatch(setViewportSpecificData(viewportIndex, data));
|
||||||
},
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -63,10 +63,10 @@ const mergeProps = (propsFromState, propsFromDispatch, ownProps) => {
|
|||||||
// Store the API details for later
|
// Store the API details for later
|
||||||
//setViewportSpecificData({ vtkApi: api });
|
//setViewportSpecificData({ vtkApi: api });
|
||||||
|
|
||||||
if (afterCreation && typeof afterCreation === 'function') {
|
if (afterCreation && typeof afterCreation === "function") {
|
||||||
afterCreation(api);
|
afterCreation(api);
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
};
|
};
|
||||||
return props;
|
return props;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,16 +1,16 @@
|
|||||||
import React, { Component } from 'react';
|
import React, { Component } from "react";
|
||||||
import { getImageData, loadImageData } from 'react-vtkjs-viewport';
|
import { getImageData, loadImageData } from "react-vtkjs-viewport";
|
||||||
|
|
||||||
import ConnectedVTKViewport from './ConnectedVTKViewport';
|
import ConnectedVTKViewport from "./ConnectedVTKViewport";
|
||||||
import LoadingIndicator from './LoadingIndicator.js';
|
import LoadingIndicator from "./LoadingIndicator.js";
|
||||||
import OHIF from 'ohif-core';
|
import OHIF from "@ohif/core";
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from "prop-types";
|
||||||
import cornerstone from 'cornerstone-core';
|
import cornerstone from "cornerstone-core";
|
||||||
import handleSegmentationStorage from './handleSegmentationStorage.js';
|
import handleSegmentationStorage from "./handleSegmentationStorage.js";
|
||||||
import vtkDataArray from 'vtk.js/Sources/Common/Core/DataArray';
|
import vtkDataArray from "vtk.js/Sources/Common/Core/DataArray";
|
||||||
import vtkImageData from 'vtk.js/Sources/Common/DataModel/ImageData';
|
import vtkImageData from "vtk.js/Sources/Common/DataModel/ImageData";
|
||||||
import vtkVolume from 'vtk.js/Sources/Rendering/Core/Volume';
|
import vtkVolume from "vtk.js/Sources/Rendering/Core/Volume";
|
||||||
import vtkVolumeMapper from 'vtk.js/Sources/Rendering/Core/VolumeMapper';
|
import vtkVolumeMapper from "vtk.js/Sources/Rendering/Core/VolumeMapper";
|
||||||
|
|
||||||
const { StackManager } = OHIF.utils;
|
const { StackManager } = OHIF.utils;
|
||||||
|
|
||||||
@ -24,7 +24,7 @@ cornerstone.metaData.addProvider(
|
|||||||
StackManager.setMetadataProvider(metadataProvider);
|
StackManager.setMetadataProvider(metadataProvider);
|
||||||
|
|
||||||
const SOP_CLASSES = {
|
const SOP_CLASSES = {
|
||||||
SEGMENTATION_STORAGE: '1.2.840.10008.5.1.4.1.1.66.4',
|
SEGMENTATION_STORAGE: "1.2.840.10008.5.1.4.1.1.66.4"
|
||||||
};
|
};
|
||||||
|
|
||||||
const specialCaseHandlers = {};
|
const specialCaseHandlers = {};
|
||||||
@ -42,7 +42,7 @@ const volumeCache = {};
|
|||||||
*/
|
*/
|
||||||
function createLabelMapImageData(backgroundImageData) {
|
function createLabelMapImageData(backgroundImageData) {
|
||||||
const labelMapData = vtkImageData.newInstance(
|
const labelMapData = vtkImageData.newInstance(
|
||||||
backgroundImageData.get('spacing', 'origin', 'direction')
|
backgroundImageData.get("spacing", "origin", "direction")
|
||||||
);
|
);
|
||||||
labelMapData.setDimensions(backgroundImageData.getDimensions());
|
labelMapData.setDimensions(backgroundImageData.getDimensions());
|
||||||
labelMapData.computeTransforms();
|
labelMapData.computeTransforms();
|
||||||
@ -50,7 +50,7 @@ function createLabelMapImageData(backgroundImageData) {
|
|||||||
const values = new Uint8Array(backgroundImageData.getNumberOfPoints());
|
const values = new Uint8Array(backgroundImageData.getNumberOfPoints());
|
||||||
const dataArray = vtkDataArray.newInstance({
|
const dataArray = vtkDataArray.newInstance({
|
||||||
numberOfComponents: 1, // labelmap with single component
|
numberOfComponents: 1, // labelmap with single component
|
||||||
values,
|
values
|
||||||
});
|
});
|
||||||
labelMapData.getPointData().setScalars(dataArray);
|
labelMapData.getPointData().setScalars(dataArray);
|
||||||
|
|
||||||
@ -61,24 +61,24 @@ class OHIFVTKViewport extends Component {
|
|||||||
state = {
|
state = {
|
||||||
volumes: null,
|
volumes: null,
|
||||||
paintFilterLabelMapImageData: null,
|
paintFilterLabelMapImageData: null,
|
||||||
paintFilterBackgroundImageData: null,
|
paintFilterBackgroundImageData: null
|
||||||
};
|
};
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
studies: PropTypes.object,
|
studies: PropTypes.object,
|
||||||
displaySet: PropTypes.object,
|
displaySet: PropTypes.object,
|
||||||
viewportIndex: PropTypes.number,
|
viewportIndex: PropTypes.number,
|
||||||
children: PropTypes.node,
|
children: PropTypes.node
|
||||||
};
|
};
|
||||||
|
|
||||||
static id = 'OHIFVTKViewport';
|
static id = "OHIFVTKViewport";
|
||||||
|
|
||||||
static init() {
|
static init() {
|
||||||
console.log('OHIFVTKViewport init()');
|
console.log("OHIFVTKViewport init()");
|
||||||
}
|
}
|
||||||
|
|
||||||
static destroy() {
|
static destroy() {
|
||||||
console.log('OHIFVTKViewport destroy()');
|
console.log("OHIFVTKViewport destroy()");
|
||||||
StackManager.clearStacks();
|
StackManager.clearStacks();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -109,7 +109,7 @@ class OHIFVTKViewport extends Component {
|
|||||||
} else if (sopInstanceUid) {
|
} else if (sopInstanceUid) {
|
||||||
const index = stack.imageIds.findIndex(imageId => {
|
const index = stack.imageIds.findIndex(imageId => {
|
||||||
const sopCommonModule = cornerstone.metaData.get(
|
const sopCommonModule = cornerstone.metaData.get(
|
||||||
'sopCommonModule',
|
"sopCommonModule",
|
||||||
imageId
|
imageId
|
||||||
);
|
);
|
||||||
if (!sopCommonModule) {
|
if (!sopCommonModule) {
|
||||||
@ -151,7 +151,7 @@ class OHIFVTKViewport extends Component {
|
|||||||
|
|
||||||
switch (sopClassUid) {
|
switch (sopClassUid) {
|
||||||
case SOP_CLASSES.SEGMENTATION_STORAGE:
|
case SOP_CLASSES.SEGMENTATION_STORAGE:
|
||||||
throw new Error('Not yet implemented');
|
throw new Error("Not yet implemented");
|
||||||
|
|
||||||
const data = handleSegmentationStorage(
|
const data = handleSegmentationStorage(
|
||||||
stack.imageIds,
|
stack.imageIds,
|
||||||
@ -164,7 +164,7 @@ class OHIFVTKViewport extends Component {
|
|||||||
return loadImageData(imageDataObject).then(() => {
|
return loadImageData(imageDataObject).then(() => {
|
||||||
return {
|
return {
|
||||||
data: imageDataObject.vtkImageData,
|
data: imageDataObject.vtkImageData,
|
||||||
labelmap: labelmapDataObject,
|
labelmap: labelmapDataObject
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
default:
|
default:
|
||||||
@ -172,7 +172,7 @@ class OHIFVTKViewport extends Component {
|
|||||||
|
|
||||||
return loadImageData(imageDataObject).then(() => {
|
return loadImageData(imageDataObject).then(() => {
|
||||||
return {
|
return {
|
||||||
data: imageDataObject.vtkImageData,
|
data: imageDataObject.vtkImageData
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -201,12 +201,12 @@ class OHIFVTKViewport extends Component {
|
|||||||
displaySetInstanceUid,
|
displaySetInstanceUid,
|
||||||
sopClassUids,
|
sopClassUids,
|
||||||
sopInstanceUid,
|
sopInstanceUid,
|
||||||
frameIndex,
|
frameIndex
|
||||||
} = displaySet;
|
} = displaySet;
|
||||||
|
|
||||||
if (sopClassUids.length > 1) {
|
if (sopClassUids.length > 1) {
|
||||||
console.warn(
|
console.warn(
|
||||||
'More than one SOPClassUid in the same series is not yet supported.'
|
"More than one SOPClassUid in the same series is not yet supported."
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -230,7 +230,7 @@ class OHIFVTKViewport extends Component {
|
|||||||
this.setState({
|
this.setState({
|
||||||
volumes: [volumeActor],
|
volumes: [volumeActor],
|
||||||
paintFilterBackgroundImageData: data,
|
paintFilterBackgroundImageData: data,
|
||||||
paintFilterLabelMapImageData: labelmap,
|
paintFilterLabelMapImageData: labelmap
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -260,12 +260,12 @@ class OHIFVTKViewport extends Component {
|
|||||||
childrenWithProps = this.props.children.map((child, index) => {
|
childrenWithProps = this.props.children.map((child, index) => {
|
||||||
return React.cloneElement(child, {
|
return React.cloneElement(child, {
|
||||||
viewportIndex: this.props.viewportIndex,
|
viewportIndex: this.props.viewportIndex,
|
||||||
key: index,
|
key: index
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const style = { width: '100%', height: '100%', position: 'relative' };
|
const style = { width: "100%", height: "100%", position: "relative" };
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import * as dcmjs from 'dcmjs';
|
import * as dcmjs from "dcmjs";
|
||||||
|
|
||||||
import OHIF from 'ohif-core';
|
import OHIF from "@ohif/core";
|
||||||
import { api } from 'dicomweb-client';
|
import { api } from "dicomweb-client";
|
||||||
|
|
||||||
const { StackManager } = OHIF.utils;
|
const { StackManager } = OHIF.utils;
|
||||||
|
|
||||||
@ -57,14 +57,14 @@ function retrieveDicomData(
|
|||||||
) {
|
) {
|
||||||
const config = {
|
const config = {
|
||||||
url: wadoRoot,
|
url: wadoRoot,
|
||||||
headers: DICOMWeb.getAuthorizationHeader(),
|
headers: DICOMWeb.getAuthorizationHeader()
|
||||||
};
|
};
|
||||||
|
|
||||||
const dicomWeb = new api.DICOMwebClient(config);
|
const dicomWeb = new api.DICOMwebClient(config);
|
||||||
const options = {
|
const options = {
|
||||||
studyInstanceUID,
|
studyInstanceUID,
|
||||||
seriesInstanceUID,
|
seriesInstanceUID,
|
||||||
sopInstanceUID,
|
sopInstanceUID
|
||||||
};
|
};
|
||||||
|
|
||||||
return dicomWeb.retrieveInstance(options);
|
return dicomWeb.retrieveInstance(options);
|
||||||
@ -117,7 +117,7 @@ async function handleSegmentationStorage(
|
|||||||
|
|
||||||
if (displaySets.length > 1) {
|
if (displaySets.length > 1) {
|
||||||
console.warn(
|
console.warn(
|
||||||
'More than one display set with the same seriesInstanceUid. This is not supported yet...'
|
"More than one display set with the same seriesInstanceUid. This is not supported yet..."
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -125,7 +125,7 @@ async function handleSegmentationStorage(
|
|||||||
const imageIds = referenceDisplaySet.images.map(image => image.getImageId());
|
const imageIds = referenceDisplaySet.images.map(image => image.getImageId());
|
||||||
|
|
||||||
if (!results) {
|
if (!results) {
|
||||||
throw new Error('Fractional segmentations are not supported');
|
throw new Error("Fractional segmentations are not supported");
|
||||||
}
|
}
|
||||||
|
|
||||||
const cachedStack = StackManager.findOrCreateStack(
|
const cachedStack = StackManager.findOrCreateStack(
|
||||||
@ -137,13 +137,13 @@ async function handleSegmentationStorage(
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
referenceDataObject,
|
referenceDataObject,
|
||||||
labelmapDataObject,
|
labelmapDataObject
|
||||||
};
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
studyInstanceUid,
|
studyInstanceUid,
|
||||||
displaySetInstanceUid,
|
displaySetInstanceUid,
|
||||||
stack,
|
stack
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { redux } from 'ohif-core';
|
import { redux } from "@ohif/core";
|
||||||
|
|
||||||
const { setViewportLayoutAndData } = redux.actions;
|
const { setViewportLayoutAndData } = redux.actions;
|
||||||
|
|
||||||
|
|||||||
@ -1,26 +1,26 @@
|
|||||||
const path = require('path');
|
const path = require("path");
|
||||||
const webpack = require('webpack');
|
const webpack = require("webpack");
|
||||||
const autoprefixer = require('autoprefixer');
|
const autoprefixer = require("autoprefixer");
|
||||||
// const vtkHtmlRules = require('vtk.js/Utilities/config/dependency.js').webpack
|
// const vtkHtmlRules = require('vtk.js/Utilities/config/dependency.js').webpack
|
||||||
// .core.rules;
|
// .core.rules;
|
||||||
// Optional if you want to load *.css and *.module.css files
|
// Optional if you want to load *.css and *.module.css files
|
||||||
// var cssRules = require('vtk.js/Utilities/config/dependency.js').webpack.css.rules;
|
// var cssRules = require('vtk.js/Utilities/config/dependency.js').webpack.css.rules;
|
||||||
const SRC_DIR = path.join(__dirname, './src');
|
const SRC_DIR = path.join(__dirname, "./src");
|
||||||
const OUTPUT_DIR = path.join(__dirname, './dist');
|
const OUTPUT_DIR = path.join(__dirname, "./dist");
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
mode: 'development',
|
mode: "development",
|
||||||
entry: {
|
entry: {
|
||||||
app: `${SRC_DIR}/index.js`,
|
app: `${SRC_DIR}/index.js`
|
||||||
},
|
},
|
||||||
context: SRC_DIR,
|
context: SRC_DIR,
|
||||||
// ~~~ MODE
|
// ~~~ MODE
|
||||||
output: {
|
output: {
|
||||||
path: OUTPUT_DIR,
|
path: OUTPUT_DIR,
|
||||||
library: 'ohifVtkExtension',
|
library: "ohifVtkExtension",
|
||||||
libraryTarget: 'umd',
|
libraryTarget: "umd",
|
||||||
filename: 'index.umd.js',
|
filename: "index.umd.js",
|
||||||
auxiliaryComment: 'Text VTK Extension Comment',
|
auxiliaryComment: "Text VTK Extension Comment"
|
||||||
},
|
},
|
||||||
stats: {
|
stats: {
|
||||||
colors: true,
|
colors: true,
|
||||||
@ -31,43 +31,43 @@ module.exports = {
|
|||||||
chunkModules: true,
|
chunkModules: true,
|
||||||
modules: true,
|
modules: true,
|
||||||
children: true,
|
children: true,
|
||||||
warnings: true,
|
warnings: true
|
||||||
},
|
},
|
||||||
optimization: {
|
optimization: {
|
||||||
minimize: false,
|
minimize: false,
|
||||||
sideEffects: true,
|
sideEffects: true
|
||||||
},
|
},
|
||||||
// ~~~ END MODE
|
// ~~~ END MODE
|
||||||
resolve: {
|
resolve: {
|
||||||
modules: [
|
modules: [
|
||||||
path.resolve(__dirname, 'node_modules'),
|
path.resolve(__dirname, "node_modules"),
|
||||||
path.resolve(__dirname, '../../node_modules'),
|
path.resolve(__dirname, "../../node_modules"),
|
||||||
SRC_DIR,
|
SRC_DIR
|
||||||
],
|
],
|
||||||
extensions: ['.js', '.jsx', '.json', '*'],
|
extensions: [".js", ".jsx", ".json", "*"],
|
||||||
symlinks: true,
|
symlinks: true
|
||||||
},
|
},
|
||||||
module: {
|
module: {
|
||||||
rules: [
|
rules: [
|
||||||
{
|
{
|
||||||
test: /\.(js|jsx)$/,
|
test: /\.(js|jsx)$/,
|
||||||
exclude: [/node_modules/],
|
exclude: [/node_modules/],
|
||||||
loader: 'babel-loader',
|
loader: "babel-loader",
|
||||||
options: {
|
options: {
|
||||||
// Find babel.config.js in monorepo root
|
// Find babel.config.js in monorepo root
|
||||||
// https://babeljs.io/docs/en/options#rootmode
|
// https://babeljs.io/docs/en/options#rootmode
|
||||||
rootMode: 'upward',
|
rootMode: "upward",
|
||||||
presets: [
|
presets: [
|
||||||
[
|
[
|
||||||
'@babel/preset-env',
|
"@babel/preset-env",
|
||||||
{
|
{
|
||||||
// Do not transform ES6 modules to another format.
|
// Do not transform ES6 modules to another format.
|
||||||
// Webpack will take care of that.
|
// Webpack will take care of that.
|
||||||
modules: false,
|
modules: false
|
||||||
},
|
}
|
||||||
],
|
]
|
||||||
],
|
]
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@ -76,15 +76,15 @@ module.exports = {
|
|||||||
test: /\.css$/,
|
test: /\.css$/,
|
||||||
exclude: /\.module\.css$/,
|
exclude: /\.module\.css$/,
|
||||||
use: [
|
use: [
|
||||||
'style-loader',
|
"style-loader",
|
||||||
'css-loader',
|
"css-loader",
|
||||||
{
|
{
|
||||||
loader: 'postcss-loader',
|
loader: "postcss-loader",
|
||||||
options: {
|
options: {
|
||||||
plugins: () => [autoprefixer('last 2 version', 'ie >= 10')],
|
plugins: () => [autoprefixer("last 2 version", "ie >= 10")]
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
],
|
]
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@ -92,7 +92,7 @@ module.exports = {
|
|||||||
{
|
{
|
||||||
test: /\.glsl$/i,
|
test: /\.glsl$/i,
|
||||||
include: /vtk\.js[\/\\]Sources/,
|
include: /vtk\.js[\/\\]Sources/,
|
||||||
loader: 'shader-loader',
|
loader: "shader-loader"
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@ -102,13 +102,13 @@ module.exports = {
|
|||||||
include: /vtk\.js[\/\\]Sources/,
|
include: /vtk\.js[\/\\]Sources/,
|
||||||
use: [
|
use: [
|
||||||
{
|
{
|
||||||
loader: 'worker-loader',
|
loader: "worker-loader",
|
||||||
options: { inline: true, fallback: false },
|
options: { inline: true, fallback: false }
|
||||||
},
|
}
|
||||||
],
|
]
|
||||||
},
|
}
|
||||||
],
|
]
|
||||||
},
|
}
|
||||||
// externals: [
|
// externals: [
|
||||||
// {
|
// {
|
||||||
// cornerstone: {
|
// cornerstone: {
|
||||||
@ -125,7 +125,7 @@ module.exports = {
|
|||||||
// },
|
// },
|
||||||
// },
|
// },
|
||||||
// '@ohif/i18n',
|
// '@ohif/i18n',
|
||||||
// 'ohif-core',
|
// '@ohif/core',
|
||||||
// 'dcmjs',
|
// 'dcmjs',
|
||||||
// 'react-viewerbase',
|
// 'react-viewerbase',
|
||||||
// 'react', //: 'React',
|
// 'react', //: 'React',
|
||||||
|
|||||||
@ -62,13 +62,13 @@ Usage is dependent on the feature(s) you want to leverage. The bulk of
|
|||||||
_Example: retrieving study metadata from a server_
|
_Example: retrieving study metadata from a server_
|
||||||
|
|
||||||
```js
|
```js
|
||||||
import { studies } from 'ohif-core'
|
import { studies } from "@ohif/core";
|
||||||
|
|
||||||
const studiesMetadata = await studies.retrieveStudiesMetadata(
|
const studiesMetadata = await studies.retrieveStudiesMetadata(
|
||||||
server, // Object
|
server, // Object
|
||||||
studyInstanceUids, // Array
|
studyInstanceUids, // Array
|
||||||
seriesInstanceUids // Array (optional)
|
seriesInstanceUids // Array (optional)
|
||||||
)
|
);
|
||||||
```
|
```
|
||||||
|
|
||||||
### Contributing
|
### Contributing
|
||||||
@ -89,10 +89,10 @@ When creating tests, place the test file "next to" the file you're testing.
|
|||||||
|
|
||||||
```js
|
```js
|
||||||
// File
|
// File
|
||||||
index.js
|
index.js;
|
||||||
|
|
||||||
// Test for file
|
// Test for file
|
||||||
index.test.js
|
index.test.js;
|
||||||
```
|
```
|
||||||
|
|
||||||
As you add and modify code, `jest` will watch for uncommitted changes and run
|
As you add and modify code, `jest` will watch for uncommitted changes and run
|
||||||
|
|||||||
@ -1,46 +1,46 @@
|
|||||||
import './config';
|
import "./config";
|
||||||
// Polyfills
|
// Polyfills
|
||||||
import 'core-js/features/array/flat';
|
import "core-js/features/array/flat";
|
||||||
import 'core-js/stable';
|
import "core-js/stable";
|
||||||
import 'regenerator-runtime/runtime';
|
import "regenerator-runtime/runtime";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
CommandsManager,
|
CommandsManager,
|
||||||
ExtensionManager,
|
ExtensionManager,
|
||||||
HotkeysManager,
|
HotkeysManager,
|
||||||
utils,
|
utils
|
||||||
} from 'ohif-core';
|
} from "@ohif/core";
|
||||||
import React, { Component } from 'react';
|
import React, { Component } from "react";
|
||||||
import {
|
import {
|
||||||
getUserManagerForOpenIdConnectClient,
|
getUserManagerForOpenIdConnectClient,
|
||||||
initWebWorkers,
|
initWebWorkers
|
||||||
} from './utils/index.js';
|
} from "./utils/index.js";
|
||||||
|
|
||||||
import { I18nextProvider } from 'react-i18next';
|
import { I18nextProvider } from "react-i18next";
|
||||||
import initCornerstoneTools from './initCornerstoneTools.js';
|
import initCornerstoneTools from "./initCornerstoneTools.js";
|
||||||
|
|
||||||
// ~~ EXTENSIONS
|
// ~~ EXTENSIONS
|
||||||
import { GenericViewerCommands, MeasurementsPanel } from './appExtensions';
|
import { GenericViewerCommands, MeasurementsPanel } from "./appExtensions";
|
||||||
import OHIFCornerstoneExtension from '@ohif/extension-cornerstone';
|
import OHIFCornerstoneExtension from "@ohif/extension-cornerstone";
|
||||||
import OHIFStandaloneViewer from './OHIFStandaloneViewer';
|
import OHIFStandaloneViewer from "./OHIFStandaloneViewer";
|
||||||
import { OidcProvider } from 'redux-oidc';
|
import { OidcProvider } from "redux-oidc";
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from "prop-types";
|
||||||
import { Provider } from 'react-redux';
|
import { Provider } from "react-redux";
|
||||||
import { BrowserRouter as Router } from 'react-router-dom';
|
import { BrowserRouter as Router } from "react-router-dom";
|
||||||
import WhiteLabellingContext from './WhiteLabellingContext';
|
import WhiteLabellingContext from "./WhiteLabellingContext";
|
||||||
import { getActiveContexts } from './store/layout/selectors.js';
|
import { getActiveContexts } from "./store/layout/selectors.js";
|
||||||
import i18n from '@ohif/i18n';
|
import i18n from "@ohif/i18n";
|
||||||
import setupTools from './setupTools.js';
|
import setupTools from "./setupTools.js";
|
||||||
import store from './store';
|
import store from "./store";
|
||||||
|
|
||||||
// ~~~~ APP SETUP
|
// ~~~~ APP SETUP
|
||||||
initCornerstoneTools({
|
initCornerstoneTools({
|
||||||
globalToolSyncEnabled: true,
|
globalToolSyncEnabled: true
|
||||||
});
|
});
|
||||||
|
|
||||||
const commandsManagerConfig = {
|
const commandsManagerConfig = {
|
||||||
getAppState: () => store.getState(),
|
getAppState: () => store.getState(),
|
||||||
getActiveContexts: () => getActiveContexts(store.getState()),
|
getActiveContexts: () => getActiveContexts(store.getState())
|
||||||
};
|
};
|
||||||
|
|
||||||
const commandsManager = new CommandsManager(commandsManagerConfig);
|
const commandsManager = new CommandsManager(commandsManagerConfig);
|
||||||
@ -64,15 +64,15 @@ class App extends Component {
|
|||||||
whiteLabelling: PropTypes.object,
|
whiteLabelling: PropTypes.object,
|
||||||
extensions: PropTypes.arrayOf(
|
extensions: PropTypes.arrayOf(
|
||||||
PropTypes.shape({
|
PropTypes.shape({
|
||||||
id: PropTypes.string.isRequired,
|
id: PropTypes.string.isRequired
|
||||||
})
|
})
|
||||||
),
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
whiteLabelling: {},
|
whiteLabelling: {},
|
||||||
oidc: [],
|
oidc: [],
|
||||||
extensions: [],
|
extensions: []
|
||||||
};
|
};
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
@ -137,7 +137,7 @@ function _initExtensions(extensions) {
|
|||||||
const defaultExtensions = [
|
const defaultExtensions = [
|
||||||
GenericViewerCommands,
|
GenericViewerCommands,
|
||||||
MeasurementsPanel,
|
MeasurementsPanel,
|
||||||
OHIFCornerstoneExtension,
|
OHIFCornerstoneExtension
|
||||||
];
|
];
|
||||||
const mergedExtensions = defaultExtensions.concat(extensions);
|
const mergedExtensions = defaultExtensions.concat(extensions);
|
||||||
extensionManager.registerExtensions(mergedExtensions);
|
extensionManager.registerExtensions(mergedExtensions);
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { redux } from 'ohif-core';
|
import { redux } from "@ohif/core";
|
||||||
import store from './../../store';
|
import store from "./../../store";
|
||||||
const { setViewportActive } = redux.actions;
|
const { setViewportActive } = redux.actions;
|
||||||
|
|
||||||
const actions = {
|
const actions = {
|
||||||
@ -16,24 +16,24 @@ const actions = {
|
|||||||
newIndex = newIndex < 0 ? maxIndex : newIndex;
|
newIndex = newIndex < 0 ? maxIndex : newIndex;
|
||||||
|
|
||||||
store.dispatch(setViewportActive(newIndex));
|
store.dispatch(setViewportActive(newIndex));
|
||||||
},
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const definitions = {
|
const definitions = {
|
||||||
// Next/Previous active viewport
|
// Next/Previous active viewport
|
||||||
incrementActiveViewport: {
|
incrementActiveViewport: {
|
||||||
commandFn: actions.updateActiveViewport,
|
commandFn: actions.updateActiveViewport,
|
||||||
storeContexts: ['viewports'],
|
storeContexts: ["viewports"],
|
||||||
options: { direction: 1 },
|
options: { direction: 1 }
|
||||||
},
|
},
|
||||||
decrementActiveViewport: {
|
decrementActiveViewport: {
|
||||||
commandFn: actions.updateActiveViewport,
|
commandFn: actions.updateActiveViewport,
|
||||||
storeContexts: ['viewports'],
|
storeContexts: ["viewports"],
|
||||||
options: { direction: -1 },
|
options: { direction: -1 }
|
||||||
},
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
definitions,
|
definitions,
|
||||||
defaultContext: 'VIEWER',
|
defaultContext: "VIEWER"
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,12 +1,12 @@
|
|||||||
import { connect } from 'react-redux';
|
import { connect } from "react-redux";
|
||||||
import { MeasurementTable } from 'react-viewerbase';
|
import { MeasurementTable } from "react-viewerbase";
|
||||||
import OHIF from 'ohif-core';
|
import OHIF from "@ohif/core";
|
||||||
import moment from 'moment';
|
import moment from "moment";
|
||||||
import cornerstone from 'cornerstone-core';
|
import cornerstone from "cornerstone-core";
|
||||||
|
|
||||||
//
|
//
|
||||||
import jumpToRowItem from './jumpToRowItem.js';
|
import jumpToRowItem from "./jumpToRowItem.js";
|
||||||
import getMeasurementLocationCallback from './../../lib/getMeasurementLocationCallback';
|
import getMeasurementLocationCallback from "./../../lib/getMeasurementLocationCallback";
|
||||||
|
|
||||||
const { setViewportSpecificData } = OHIF.redux.actions;
|
const { setViewportSpecificData } = OHIF.redux.actions;
|
||||||
const { MeasurementApi } = OHIF.measurements;
|
const { MeasurementApi } = OHIF.measurements;
|
||||||
@ -30,7 +30,7 @@ function getAllTools() {
|
|||||||
|
|
||||||
function getMeasurementText(measurementData) {
|
function getMeasurementText(measurementData) {
|
||||||
const { location, description } = measurementData;
|
const { location, description } = measurementData;
|
||||||
let text = '...';
|
let text = "...";
|
||||||
if (location) {
|
if (location) {
|
||||||
text = location;
|
text = location;
|
||||||
if (description) {
|
if (description) {
|
||||||
@ -50,7 +50,7 @@ function getDataForEachMeasurementNumber(
|
|||||||
measurementNumberList.forEach(measurement => {
|
measurementNumberList.forEach(measurement => {
|
||||||
timepoints.forEach(timepoint => {
|
timepoints.forEach(timepoint => {
|
||||||
const eachData = {
|
const eachData = {
|
||||||
displayText: '...',
|
displayText: "..."
|
||||||
};
|
};
|
||||||
if (measurement.timepointId === timepoint.timepointId) {
|
if (measurement.timepointId === timepoint.timepointId) {
|
||||||
eachData.displayText = displayFunction(measurement);
|
eachData.displayText = displayFunction(measurement);
|
||||||
@ -71,7 +71,7 @@ function convertMeasurementsToTableData(toolCollections, timepoints) {
|
|||||||
return {
|
return {
|
||||||
groupName: toolGroup.name,
|
groupName: toolGroup.name,
|
||||||
groupId: toolGroup.id,
|
groupId: toolGroup.id,
|
||||||
measurements: [],
|
measurements: []
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -81,7 +81,7 @@ function convertMeasurementsToTableData(toolCollections, timepoints) {
|
|||||||
const { displayFunction } = tool.options.measurementTable;
|
const { displayFunction } = tool.options.measurementTable;
|
||||||
|
|
||||||
// Group by measurementNumber so we can display then all in the same line
|
// Group by measurementNumber so we can display then all in the same line
|
||||||
const groupedMeasurements = groupBy(toolMeasurements, 'measurementNumber');
|
const groupedMeasurements = groupBy(toolMeasurements, "measurementNumber");
|
||||||
|
|
||||||
Object.keys(groupedMeasurements).forEach(groupedMeasurementsIndex => {
|
Object.keys(groupedMeasurements).forEach(groupedMeasurementsIndex => {
|
||||||
const measurementNumberList =
|
const measurementNumberList =
|
||||||
@ -90,7 +90,7 @@ function convertMeasurementsToTableData(toolCollections, timepoints) {
|
|||||||
const {
|
const {
|
||||||
measurementNumber,
|
measurementNumber,
|
||||||
lesionNamingNumber,
|
lesionNamingNumber,
|
||||||
toolType,
|
toolType
|
||||||
} = measurementData;
|
} = measurementData;
|
||||||
const measurementId = measurementData._id;
|
const measurementId = measurementData._id;
|
||||||
|
|
||||||
@ -103,14 +103,14 @@ function convertMeasurementsToTableData(toolCollections, timepoints) {
|
|||||||
lesionNamingNumber,
|
lesionNamingNumber,
|
||||||
toolType,
|
toolType,
|
||||||
hasWarnings: false, //TODO
|
hasWarnings: false, //TODO
|
||||||
warningTitle: '', //TODO
|
warningTitle: "", //TODO
|
||||||
isSplitLesion: false, //TODO
|
isSplitLesion: false, //TODO
|
||||||
warningList: [], //TODO
|
warningList: [], //TODO
|
||||||
data: getDataForEachMeasurementNumber(
|
data: getDataForEachMeasurementNumber(
|
||||||
measurementNumberList,
|
measurementNumberList,
|
||||||
timepoints,
|
timepoints,
|
||||||
displayFunction
|
displayFunction
|
||||||
),
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
// find the group object for the tool
|
// find the group object for the tool
|
||||||
@ -139,9 +139,9 @@ function convertTimepointsToTableData(timepoints) {
|
|||||||
|
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
label: 'Study date:',
|
label: "Study date:",
|
||||||
date: moment(timepoints[0].latestDate).format('DD-MMM-YY'),
|
date: moment(timepoints[0].latestDate).format("DD-MMM-YY")
|
||||||
},
|
}
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -154,7 +154,7 @@ const mapStateToProps = state => {
|
|||||||
timepoints
|
timepoints
|
||||||
),
|
),
|
||||||
timepointManager: state.timepointManager,
|
timepointManager: state.timepointManager,
|
||||||
viewports: state.viewports,
|
viewports: state.viewports
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -166,7 +166,7 @@ const mapDispatchToProps = dispatch => {
|
|||||||
|
|
||||||
const enabledElements = cornerstone.getEnabledElements();
|
const enabledElements = cornerstone.getEnabledElements();
|
||||||
if (!enabledElements || enabledElements.length <= activeViewportIndex) {
|
if (!enabledElements || enabledElements.length <= activeViewportIndex) {
|
||||||
OHIF.log.error('Failed to find the enabled element');
|
OHIF.log.error("Failed to find the enabled element");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -175,9 +175,9 @@ const mapDispatchToProps = dispatch => {
|
|||||||
const eventData = {
|
const eventData = {
|
||||||
event: {
|
event: {
|
||||||
clientX: event.clientX,
|
clientX: event.clientX,
|
||||||
clientY: event.clientY,
|
clientY: event.clientY
|
||||||
},
|
},
|
||||||
element,
|
element
|
||||||
};
|
};
|
||||||
|
|
||||||
const { toolType, measurementId } = measurementData;
|
const { toolType, measurementId } = measurementData;
|
||||||
@ -187,7 +187,7 @@ const mapDispatchToProps = dispatch => {
|
|||||||
|
|
||||||
const options = {
|
const options = {
|
||||||
skipAddLabelButton: true,
|
skipAddLabelButton: true,
|
||||||
editLocation: true,
|
editLocation: true
|
||||||
};
|
};
|
||||||
|
|
||||||
// Clone the tool not to set empty location initially
|
// Clone the tool not to set empty location initially
|
||||||
@ -200,7 +200,7 @@ const mapDispatchToProps = dispatch => {
|
|||||||
|
|
||||||
const enabledElements = cornerstone.getEnabledElements();
|
const enabledElements = cornerstone.getEnabledElements();
|
||||||
if (!enabledElements || enabledElements.length <= activeViewportIndex) {
|
if (!enabledElements || enabledElements.length <= activeViewportIndex) {
|
||||||
OHIF.log.error('Failed to find the enabled element');
|
OHIF.log.error("Failed to find the enabled element");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -209,9 +209,9 @@ const mapDispatchToProps = dispatch => {
|
|||||||
const eventData = {
|
const eventData = {
|
||||||
event: {
|
event: {
|
||||||
clientX: event.clientX,
|
clientX: event.clientX,
|
||||||
clientY: event.clientY,
|
clientY: event.clientY
|
||||||
},
|
},
|
||||||
element,
|
element
|
||||||
};
|
};
|
||||||
|
|
||||||
const { toolType, measurementId } = measurementData;
|
const { toolType, measurementId } = measurementData;
|
||||||
@ -220,7 +220,7 @@ const mapDispatchToProps = dispatch => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const options = {
|
const options = {
|
||||||
editDescriptionOnDialog: true,
|
editDescriptionOnDialog: true
|
||||||
};
|
};
|
||||||
|
|
||||||
getMeasurementLocationCallback(eventData, tool, options);
|
getMeasurementLocationCallback(eventData, tool, options);
|
||||||
@ -285,7 +285,7 @@ const mapDispatchToProps = dispatch => {
|
|||||||
//dispatch(setActiveMeasurement(measurementData.measurementId))
|
//dispatch(setActiveMeasurement(measurementData.measurementId))
|
||||||
|
|
||||||
// (later): Needs to set some property on state.extensions.cornerstone to synchronize viewport scrolling
|
// (later): Needs to set some property on state.extensions.cornerstone to synchronize viewport scrolling
|
||||||
},
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -307,7 +307,7 @@ const mergeProps = (propsFromState, propsFromDispatch, ownProps) => {
|
|||||||
// TODO: childToolKey should come from the measurement table when it supports child tools
|
// TODO: childToolKey should come from the measurement table when it supports child tools
|
||||||
const options = {
|
const options = {
|
||||||
invertViewportTimepointsOrder: false,
|
invertViewportTimepointsOrder: false,
|
||||||
childToolKey: null,
|
childToolKey: null
|
||||||
};
|
};
|
||||||
|
|
||||||
propsFromDispatch.dispatchJumpToRowItem(
|
propsFromDispatch.dispatchJumpToRowItem(
|
||||||
@ -338,11 +338,11 @@ const mergeProps = (propsFromState, propsFromDispatch, ownProps) => {
|
|||||||
measurementData: {
|
measurementData: {
|
||||||
_id: measurementData.measurementId,
|
_id: measurementData.measurementId,
|
||||||
lesionNamingNumber: measurementData.lesionNamingNumber,
|
lesionNamingNumber: measurementData.lesionNamingNumber,
|
||||||
measurementNumber: measurementData.measurementNumber,
|
measurementNumber: measurementData.measurementNumber
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
},
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { measurements, utils } from 'ohif-core';
|
import { measurements, utils } from "@ohif/core";
|
||||||
|
|
||||||
const { MeasurementApi } = measurements;
|
const { MeasurementApi } = measurements;
|
||||||
const { studyMetadataManager } = utils;
|
const { studyMetadataManager } = utils;
|
||||||
@ -82,7 +82,7 @@ export default function jumpToRowItem(
|
|||||||
|
|
||||||
const study = studyMetadataManager.get(data.studyInstanceUid);
|
const study = studyMetadataManager.get(data.studyInstanceUid);
|
||||||
if (!study) {
|
if (!study) {
|
||||||
throw new Error('Study not found.');
|
throw new Error("Study not found.");
|
||||||
}
|
}
|
||||||
|
|
||||||
const displaySet = study.findDisplaySet(displaySet => {
|
const displaySet = study.findDisplaySet(displaySet => {
|
||||||
@ -90,7 +90,7 @@ export default function jumpToRowItem(
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (!displaySet) {
|
if (!displaySet) {
|
||||||
throw new Error('Display set not found.');
|
throw new Error("Display set not found.");
|
||||||
}
|
}
|
||||||
|
|
||||||
displaySet.sopInstanceUid = data.sopInstanceUid;
|
displaySet.sopInstanceUid = data.sopInstanceUid;
|
||||||
@ -100,12 +100,12 @@ export default function jumpToRowItem(
|
|||||||
|
|
||||||
viewportSpecificData.push({
|
viewportSpecificData.push({
|
||||||
viewportIndex,
|
viewportIndex,
|
||||||
displaySet,
|
displaySet
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
viewportSpecificData,
|
viewportSpecificData,
|
||||||
layout: [], // TODO: if we need to change layout, we should return this here
|
layout: [] // TODO: if we need to change layout, we should return this here
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,12 +1,12 @@
|
|||||||
import { Component } from 'react';
|
import { Component } from "react";
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from "prop-types";
|
||||||
import OHIF from 'ohif-core';
|
import OHIF from "@ohif/core";
|
||||||
|
|
||||||
class StudyLoadingMonitor extends Component {
|
class StudyLoadingMonitor extends Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
studies: PropTypes.array.isRequired,
|
studies: PropTypes.array.isRequired,
|
||||||
setStudyLoadingProgress: PropTypes.func.isRequired,
|
setStudyLoadingProgress: PropTypes.func.isRequired,
|
||||||
clearStudyLoadingProgress: PropTypes.func.isRequired,
|
clearStudyLoadingProgress: PropTypes.func.isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
@ -20,7 +20,7 @@ class StudyLoadingMonitor extends Component {
|
|||||||
},
|
},
|
||||||
_clearProgressById: progressId => {
|
_clearProgressById: progressId => {
|
||||||
this.props.clearStudyLoadingProgress(progressId);
|
this.props.clearStudyLoadingProgress(progressId);
|
||||||
},
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const { StudyLoadingListener } = OHIF.classes;
|
const { StudyLoadingListener } = OHIF.classes;
|
||||||
|
|||||||
@ -1,12 +1,12 @@
|
|||||||
import { Component } from 'react';
|
import { Component } from "react";
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from "prop-types";
|
||||||
import OHIF from 'ohif-core';
|
import OHIF from "@ohif/core";
|
||||||
|
|
||||||
const { StudyPrefetcher } = OHIF.classes;
|
const { StudyPrefetcher } = OHIF.classes;
|
||||||
|
|
||||||
class StudyPrefetcherComponent extends Component {
|
class StudyPrefetcherComponent extends Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
studies: PropTypes.array,
|
studies: PropTypes.array
|
||||||
};
|
};
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
|
|||||||
@ -1,12 +1,12 @@
|
|||||||
import OHIF from 'ohif-core';
|
import OHIF from "@ohif/core";
|
||||||
import cornerstone from 'cornerstone-core';
|
import cornerstone from "cornerstone-core";
|
||||||
import cornerstoneWADOImageLoader from 'cornerstone-wado-image-loader';
|
import cornerstoneWADOImageLoader from "cornerstone-wado-image-loader";
|
||||||
import dicomParser from 'dicom-parser';
|
import dicomParser from "dicom-parser";
|
||||||
import version from './version.js';
|
import version from "./version.js";
|
||||||
|
|
||||||
window.info = {
|
window.info = {
|
||||||
version,
|
version,
|
||||||
homepage: `${process.env.PUBLIC_URL}`,
|
homepage: `${process.env.PUBLIC_URL}`
|
||||||
};
|
};
|
||||||
|
|
||||||
// For debugging
|
// For debugging
|
||||||
@ -33,7 +33,7 @@ cornerstoneWADOImageLoader.configure({
|
|||||||
const headers = OHIF.DICOMWeb.getAuthorizationHeader();
|
const headers = OHIF.DICOMWeb.getAuthorizationHeader();
|
||||||
|
|
||||||
if (headers.Authorization) {
|
if (headers.Authorization) {
|
||||||
xhr.setRequestHeader('Authorization', headers.Authorization);
|
xhr.setRequestHeader("Authorization", headers.Authorization);
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@ -1,13 +1,13 @@
|
|||||||
import { connect } from 'react-redux';
|
import { connect } from "react-redux";
|
||||||
import { CineDialog } from 'react-viewerbase';
|
import { CineDialog } from "react-viewerbase";
|
||||||
import OHIF from 'ohif-core';
|
import OHIF from "@ohif/core";
|
||||||
import csTools from 'cornerstone-tools';
|
import csTools from "cornerstone-tools";
|
||||||
// Our target output kills the `as` and "import" throws a keyword error
|
// Our target output kills the `as` and "import" throws a keyword error
|
||||||
// import { import as toolImport, getToolState } from 'cornerstone-tools';
|
// import { import as toolImport, getToolState } from 'cornerstone-tools';
|
||||||
import cloneDeep from 'lodash.clonedeep';
|
import cloneDeep from "lodash.clonedeep";
|
||||||
|
|
||||||
const toolImport = csTools.import;
|
const toolImport = csTools.import;
|
||||||
const scrollToIndex = toolImport('util/scrollToIndex');
|
const scrollToIndex = toolImport("util/scrollToIndex");
|
||||||
const { setViewportSpecificData } = OHIF.redux.actions;
|
const { setViewportSpecificData } = OHIF.redux.actions;
|
||||||
|
|
||||||
// Why do I need or care about any of this info?
|
// Why do I need or care about any of this info?
|
||||||
@ -20,14 +20,14 @@ const mapStateToProps = state => {
|
|||||||
|
|
||||||
const cineData = cine || {
|
const cineData = cine || {
|
||||||
isPlaying: false,
|
isPlaying: false,
|
||||||
cineFrameRate: 24,
|
cineFrameRate: 24
|
||||||
};
|
};
|
||||||
|
|
||||||
// New props we're creating?
|
// New props we're creating?
|
||||||
return {
|
return {
|
||||||
activeEnabledElement: dom,
|
activeEnabledElement: dom,
|
||||||
activeViewportCineData: cineData,
|
activeViewportCineData: cineData,
|
||||||
activeViewportIndex: state.viewports.activeViewportIndex,
|
activeViewportIndex: state.viewports.activeViewportIndex
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -35,7 +35,7 @@ const mapDispatchToProps = dispatch => {
|
|||||||
return {
|
return {
|
||||||
dispatchSetViewportSpecificData: (viewportIndex, data) => {
|
dispatchSetViewportSpecificData: (viewportIndex, data) => {
|
||||||
dispatch(setViewportSpecificData(viewportIndex, data));
|
dispatch(setViewportSpecificData(viewportIndex, data));
|
||||||
},
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -43,7 +43,7 @@ const mergeProps = (propsFromState, propsFromDispatch, ownProps) => {
|
|||||||
const {
|
const {
|
||||||
activeEnabledElement,
|
activeEnabledElement,
|
||||||
activeViewportCineData,
|
activeViewportCineData,
|
||||||
activeViewportIndex,
|
activeViewportIndex
|
||||||
} = propsFromState;
|
} = propsFromState;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -54,7 +54,7 @@ const mergeProps = (propsFromState, propsFromDispatch, ownProps) => {
|
|||||||
cine.isPlaying = !cine.isPlaying;
|
cine.isPlaying = !cine.isPlaying;
|
||||||
|
|
||||||
propsFromDispatch.dispatchSetViewportSpecificData(activeViewportIndex, {
|
propsFromDispatch.dispatchSetViewportSpecificData(activeViewportIndex, {
|
||||||
cine,
|
cine
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
onFrameRateChanged: frameRate => {
|
onFrameRateChanged: frameRate => {
|
||||||
@ -62,34 +62,34 @@ const mergeProps = (propsFromState, propsFromDispatch, ownProps) => {
|
|||||||
cine.cineFrameRate = frameRate;
|
cine.cineFrameRate = frameRate;
|
||||||
|
|
||||||
propsFromDispatch.dispatchSetViewportSpecificData(activeViewportIndex, {
|
propsFromDispatch.dispatchSetViewportSpecificData(activeViewportIndex, {
|
||||||
cine,
|
cine
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
onClickNextButton: () => {
|
onClickNextButton: () => {
|
||||||
const stackData = csTools.getToolState(activeEnabledElement, 'stack');
|
const stackData = csTools.getToolState(activeEnabledElement, "stack");
|
||||||
if (!stackData || !stackData.data || !stackData.data.length) return;
|
if (!stackData || !stackData.data || !stackData.data.length) return;
|
||||||
const { currentImageIdIndex, imageIds } = stackData.data[0];
|
const { currentImageIdIndex, imageIds } = stackData.data[0];
|
||||||
if (currentImageIdIndex >= imageIds.length - 1) return;
|
if (currentImageIdIndex >= imageIds.length - 1) return;
|
||||||
scrollToIndex(activeEnabledElement, currentImageIdIndex + 1);
|
scrollToIndex(activeEnabledElement, currentImageIdIndex + 1);
|
||||||
},
|
},
|
||||||
onClickBackButton: () => {
|
onClickBackButton: () => {
|
||||||
const stackData = csTools.getToolState(activeEnabledElement, 'stack');
|
const stackData = csTools.getToolState(activeEnabledElement, "stack");
|
||||||
if (!stackData || !stackData.data || !stackData.data.length) return;
|
if (!stackData || !stackData.data || !stackData.data.length) return;
|
||||||
const { currentImageIdIndex } = stackData.data[0];
|
const { currentImageIdIndex } = stackData.data[0];
|
||||||
if (currentImageIdIndex === 0) return;
|
if (currentImageIdIndex === 0) return;
|
||||||
scrollToIndex(activeEnabledElement, currentImageIdIndex - 1);
|
scrollToIndex(activeEnabledElement, currentImageIdIndex - 1);
|
||||||
},
|
},
|
||||||
onClickSkipToStart: () => {
|
onClickSkipToStart: () => {
|
||||||
const stackData = csTools.getToolState(activeEnabledElement, 'stack');
|
const stackData = csTools.getToolState(activeEnabledElement, "stack");
|
||||||
if (!stackData || !stackData.data || !stackData.data.length) return;
|
if (!stackData || !stackData.data || !stackData.data.length) return;
|
||||||
scrollToIndex(activeEnabledElement, 0);
|
scrollToIndex(activeEnabledElement, 0);
|
||||||
},
|
},
|
||||||
onClickSkipToEnd: () => {
|
onClickSkipToEnd: () => {
|
||||||
const stackData = csTools.getToolState(activeEnabledElement, 'stack');
|
const stackData = csTools.getToolState(activeEnabledElement, "stack");
|
||||||
if (!stackData || !stackData.data || !stackData.data.length) return;
|
if (!stackData || !stackData.data || !stackData.data.length) return;
|
||||||
const lastIndex = stackData.data[0].imageIds.length - 1;
|
const lastIndex = stackData.data[0].imageIds.length - 1;
|
||||||
scrollToIndex(activeEnabledElement, lastIndex);
|
scrollToIndex(activeEnabledElement, lastIndex);
|
||||||
},
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -1,12 +1,12 @@
|
|||||||
import { LayoutButton } from 'react-viewerbase';
|
import { LayoutButton } from "react-viewerbase";
|
||||||
import OHIF from 'ohif-core';
|
import OHIF from "@ohif/core";
|
||||||
import { connect } from 'react-redux';
|
import { connect } from "react-redux";
|
||||||
|
|
||||||
const { setLayout } = OHIF.redux.actions;
|
const { setLayout } = OHIF.redux.actions;
|
||||||
|
|
||||||
const mapStateToProps = state => {
|
const mapStateToProps = state => {
|
||||||
return {
|
return {
|
||||||
currentLayout: state.viewports.layout,
|
currentLayout: state.viewports.layout
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -21,15 +21,15 @@ const mapDispatchToProps = dispatch => {
|
|||||||
for (let i = 0; i < numViewports; i++) {
|
for (let i = 0; i < numViewports; i++) {
|
||||||
viewports.push({
|
viewports.push({
|
||||||
height: `${100 / rows}%`,
|
height: `${100 / rows}%`,
|
||||||
width: `${100 / columns}%`,
|
width: `${100 / columns}%`
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
const layout = {
|
const layout = {
|
||||||
viewports,
|
viewports
|
||||||
};
|
};
|
||||||
|
|
||||||
dispatch(setLayout(layout));
|
dispatch(setLayout(layout));
|
||||||
},
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import { LayoutManager } from 'react-viewerbase';
|
import { LayoutManager } from "react-viewerbase";
|
||||||
import { MODULE_TYPES } from 'ohif-core';
|
import { MODULE_TYPES } from "@ohif/core";
|
||||||
import { connect } from 'react-redux';
|
import { connect } from "react-redux";
|
||||||
import { extensionManager } from './../App.js';
|
import { extensionManager } from "./../App.js";
|
||||||
|
|
||||||
const mapStateToProps = state => {
|
const mapStateToProps = state => {
|
||||||
const availableViewportModules = {};
|
const availableViewportModules = {};
|
||||||
@ -24,7 +24,7 @@ const mapStateToProps = state => {
|
|||||||
// TODO: rename `availableViewportModules`
|
// TODO: rename `availableViewportModules`
|
||||||
availablePlugins: availableViewportModules,
|
availablePlugins: availableViewportModules,
|
||||||
// TODO: rename `defaultViewportModule`
|
// TODO: rename `defaultViewportModule`
|
||||||
defaultPlugin,
|
defaultPlugin
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import OHIF from 'ohif-core';
|
import OHIF from "@ohif/core";
|
||||||
import PluginSwitch from './PluginSwitch.js';
|
import PluginSwitch from "./PluginSwitch.js";
|
||||||
import { commandsManager } from './../App.js';
|
import { commandsManager } from "./../App.js";
|
||||||
import { connect } from 'react-redux';
|
import { connect } from "react-redux";
|
||||||
|
|
||||||
const { setLayout } = OHIF.redux.actions;
|
const { setLayout } = OHIF.redux.actions;
|
||||||
|
|
||||||
@ -11,7 +11,7 @@ const mapStateToProps = state => {
|
|||||||
return {
|
return {
|
||||||
activeViewportIndex,
|
activeViewportIndex,
|
||||||
viewportSpecificData,
|
viewportSpecificData,
|
||||||
layout,
|
layout
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -19,7 +19,7 @@ const mapDispatchToProps = dispatch => {
|
|||||||
return {
|
return {
|
||||||
setLayout: data => {
|
setLayout: data => {
|
||||||
dispatch(setLayout(data));
|
dispatch(setLayout(data));
|
||||||
},
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -81,16 +81,16 @@ const mergeProps = (propsFromState, propsFromDispatch, ownProps) => {
|
|||||||
},
|
},
|
||||||
},*/
|
},*/
|
||||||
{
|
{
|
||||||
label: '2D MPR',
|
label: "2D MPR",
|
||||||
icon: 'cube',
|
icon: "cube",
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
commandsManager.runCommand('mpr2d');
|
commandsManager.runCommand("mpr2d");
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
return {
|
return {
|
||||||
buttons,
|
buttons
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
import { connect } from 'react-redux';
|
import { connect } from "react-redux";
|
||||||
import StudyLoadingMonitor from '../components/StudyLoadingMonitor.js';
|
import StudyLoadingMonitor from "../components/StudyLoadingMonitor.js";
|
||||||
import OHIF from 'ohif-core';
|
import OHIF from "@ohif/core";
|
||||||
|
|
||||||
const {
|
const {
|
||||||
setStudyLoadingProgress,
|
setStudyLoadingProgress,
|
||||||
clearStudyLoadingProgress,
|
clearStudyLoadingProgress
|
||||||
} = OHIF.redux.actions;
|
} = OHIF.redux.actions;
|
||||||
|
|
||||||
const mapDispatchToProps = dispatch => {
|
const mapDispatchToProps = dispatch => {
|
||||||
@ -14,7 +14,7 @@ const mapDispatchToProps = dispatch => {
|
|||||||
},
|
},
|
||||||
clearStudyLoadingProgress: progressId => {
|
clearStudyLoadingProgress: progressId => {
|
||||||
dispatch(clearStudyLoadingProgress(progressId));
|
dispatch(clearStudyLoadingProgress(progressId));
|
||||||
},
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -1,13 +1,13 @@
|
|||||||
import { connect } from 'react-redux';
|
import { connect } from "react-redux";
|
||||||
import Viewer from './Viewer.js';
|
import Viewer from "./Viewer.js";
|
||||||
import OHIF from 'ohif-core';
|
import OHIF from "@ohif/core";
|
||||||
|
|
||||||
const { setTimepoints, setMeasurements } = OHIF.redux.actions;
|
const { setTimepoints, setMeasurements } = OHIF.redux.actions;
|
||||||
|
|
||||||
const mapStateToProps = (state, ownProps) => {
|
const mapStateToProps = (state, ownProps) => {
|
||||||
return {
|
return {
|
||||||
viewports: state.viewports.viewportSpecificData,
|
viewports: state.viewports.viewportSpecificData,
|
||||||
activeViewportIndex: state.viewports.activeViewportIndex,
|
activeViewportIndex: state.viewports.activeViewportIndex
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -18,7 +18,7 @@ const mapDispatchToProps = dispatch => {
|
|||||||
},
|
},
|
||||||
onMeasurementsUpdated: measurements => {
|
onMeasurementsUpdated: measurements => {
|
||||||
dispatch(setMeasurements(measurements));
|
dispatch(setMeasurements(measurements));
|
||||||
},
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
import OHIF from 'ohif-core';
|
import OHIF from "@ohif/core";
|
||||||
import ViewerMain from './ViewerMain';
|
import ViewerMain from "./ViewerMain";
|
||||||
import { connect } from 'react-redux';
|
import { connect } from "react-redux";
|
||||||
|
|
||||||
const {
|
const {
|
||||||
setViewportSpecificData,
|
setViewportSpecificData,
|
||||||
clearViewportSpecificData,
|
clearViewportSpecificData
|
||||||
} = OHIF.redux.actions;
|
} = OHIF.redux.actions;
|
||||||
|
|
||||||
const mapStateToProps = state => {
|
const mapStateToProps = state => {
|
||||||
@ -14,7 +14,7 @@ const mapStateToProps = state => {
|
|||||||
activeViewportIndex,
|
activeViewportIndex,
|
||||||
layout,
|
layout,
|
||||||
viewportSpecificData,
|
viewportSpecificData,
|
||||||
viewports: state.viewports,
|
viewports: state.viewports
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -25,7 +25,7 @@ const mapDispatchToProps = dispatch => {
|
|||||||
},
|
},
|
||||||
clearViewportSpecificData: () => {
|
clearViewportSpecificData: () => {
|
||||||
dispatch(clearViewportSpecificData());
|
dispatch(clearViewportSpecificData());
|
||||||
},
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -1,18 +1,18 @@
|
|||||||
import './ToolbarRow.css';
|
import "./ToolbarRow.css";
|
||||||
|
|
||||||
import React, { Component } from 'react';
|
import React, { Component } from "react";
|
||||||
import {
|
import {
|
||||||
RoundedButtonGroup,
|
RoundedButtonGroup,
|
||||||
ToolbarButton,
|
ToolbarButton,
|
||||||
ExpandableToolMenu,
|
ExpandableToolMenu
|
||||||
} from 'react-viewerbase';
|
} from "react-viewerbase";
|
||||||
import { commandsManager, extensionManager } from './../App.js';
|
import { commandsManager, extensionManager } from "./../App.js";
|
||||||
|
|
||||||
import ConnectedCineDialog from './ConnectedCineDialog';
|
import ConnectedCineDialog from "./ConnectedCineDialog";
|
||||||
import ConnectedLayoutButton from './ConnectedLayoutButton';
|
import ConnectedLayoutButton from "./ConnectedLayoutButton";
|
||||||
import ConnectedPluginSwitch from './ConnectedPluginSwitch.js';
|
import ConnectedPluginSwitch from "./ConnectedPluginSwitch.js";
|
||||||
import { MODULE_TYPES } from 'ohif-core';
|
import { MODULE_TYPES } from "@ohif/core";
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from "prop-types";
|
||||||
|
|
||||||
class ToolbarRow extends Component {
|
class ToolbarRow extends Component {
|
||||||
// TODO: Simplify these? isOpen can be computed if we say "any" value for selected,
|
// TODO: Simplify these? isOpen can be computed if we say "any" value for selected,
|
||||||
@ -23,7 +23,7 @@ class ToolbarRow extends Component {
|
|||||||
selectedLeftSidePanel: PropTypes.string.isRequired,
|
selectedLeftSidePanel: PropTypes.string.isRequired,
|
||||||
selectedRightSidePanel: PropTypes.string.isRequired,
|
selectedRightSidePanel: PropTypes.string.isRequired,
|
||||||
handleSidePanelChange: PropTypes.func,
|
handleSidePanelChange: PropTypes.func,
|
||||||
activeContexts: PropTypes.arrayOf(PropTypes.string).isRequired,
|
activeContexts: PropTypes.arrayOf(PropTypes.string).isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
@ -41,7 +41,7 @@ class ToolbarRow extends Component {
|
|||||||
this.state = {
|
this.state = {
|
||||||
toolbarButtons: toolbarButtonDefinitions,
|
toolbarButtons: toolbarButtonDefinitions,
|
||||||
activeButtons: [],
|
activeButtons: [],
|
||||||
isCineDialogOpen: false,
|
isCineDialogOpen: false
|
||||||
};
|
};
|
||||||
|
|
||||||
this._handleBuiltIn = _handleBuiltIn.bind(this);
|
this._handleBuiltIn = _handleBuiltIn.bind(this);
|
||||||
@ -51,12 +51,12 @@ class ToolbarRow extends Component {
|
|||||||
left: [
|
left: [
|
||||||
// TODO: This should come from extensions, instead of being baked in
|
// TODO: This should come from extensions, instead of being baked in
|
||||||
{
|
{
|
||||||
value: 'studies',
|
value: "studies",
|
||||||
icon: 'th-large',
|
icon: "th-large",
|
||||||
bottomLabel: 'Series',
|
bottomLabel: "Series"
|
||||||
},
|
}
|
||||||
],
|
],
|
||||||
right: [],
|
right: []
|
||||||
};
|
};
|
||||||
|
|
||||||
panelModules.forEach(panelExtension => {
|
panelModules.forEach(panelExtension => {
|
||||||
@ -74,9 +74,9 @@ class ToolbarRow extends Component {
|
|||||||
const menuOptionEntry = {
|
const menuOptionEntry = {
|
||||||
value: menuOption.target,
|
value: menuOption.target,
|
||||||
icon: menuOption.icon,
|
icon: menuOption.icon,
|
||||||
bottomLabel: menuOption.label,
|
bottomLabel: menuOption.label
|
||||||
};
|
};
|
||||||
const from = menuOption.from || 'right';
|
const from = menuOption.from || "right";
|
||||||
|
|
||||||
this.buttonGroups[from].push(menuOptionEntry);
|
this.buttonGroups[from].push(menuOptionEntry);
|
||||||
}
|
}
|
||||||
@ -90,7 +90,7 @@ class ToolbarRow extends Component {
|
|||||||
|
|
||||||
if (activeContextsChanged) {
|
if (activeContextsChanged) {
|
||||||
this.setState({
|
this.setState({
|
||||||
toolbarButtons: _getVisibleToolbarButtons.call(this),
|
toolbarButtons: _getVisibleToolbarButtons.call(this)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -103,25 +103,25 @@ class ToolbarRow extends Component {
|
|||||||
);
|
);
|
||||||
|
|
||||||
const cineDialogContainerStyle = {
|
const cineDialogContainerStyle = {
|
||||||
display: this.state.isCineDialogOpen ? 'block' : 'none',
|
display: this.state.isCineDialogOpen ? "block" : "none",
|
||||||
position: 'absolute',
|
position: "absolute",
|
||||||
top: '82px',
|
top: "82px",
|
||||||
zIndex: 999,
|
zIndex: 999
|
||||||
};
|
};
|
||||||
|
|
||||||
const onPress = (side, value) => {
|
const onPress = (side, value) => {
|
||||||
this.props.handleSidePanelChange(side, value);
|
this.props.handleSidePanelChange(side, value);
|
||||||
};
|
};
|
||||||
const onPressLeft = onPress.bind(this, 'left');
|
const onPressLeft = onPress.bind(this, "left");
|
||||||
const onPressRight = onPress.bind(this, 'right');
|
const onPressRight = onPress.bind(this, "right");
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="ToolbarRow">
|
<div className="ToolbarRow">
|
||||||
<div className="pull-left m-t-1 p-y-1" style={{ padding: '10px' }}>
|
<div className="pull-left m-t-1 p-y-1" style={{ padding: "10px" }}>
|
||||||
<RoundedButtonGroup
|
<RoundedButtonGroup
|
||||||
options={this.buttonGroups.left}
|
options={this.buttonGroups.left}
|
||||||
value={this.props.selectedLeftSidePanel || ''}
|
value={this.props.selectedLeftSidePanel || ""}
|
||||||
onValueChanged={onPressLeft}
|
onValueChanged={onPressLeft}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@ -130,12 +130,12 @@ class ToolbarRow extends Component {
|
|||||||
<ConnectedPluginSwitch />
|
<ConnectedPluginSwitch />
|
||||||
<div
|
<div
|
||||||
className="pull-right m-t-1 rm-x-1"
|
className="pull-right m-t-1 rm-x-1"
|
||||||
style={{ marginLeft: 'auto' }}
|
style={{ marginLeft: "auto" }}
|
||||||
>
|
>
|
||||||
{this.buttonGroups.right.length && (
|
{this.buttonGroups.right.length && (
|
||||||
<RoundedButtonGroup
|
<RoundedButtonGroup
|
||||||
options={this.buttonGroups.right}
|
options={this.buttonGroups.right}
|
||||||
value={this.props.selectedRightSidePanel || ''}
|
value={this.props.selectedRightSidePanel || ""}
|
||||||
onValueChanged={onPressRight}
|
onValueChanged={onPressRight}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
@ -201,11 +201,11 @@ function _handleToolbarButtonClick(button, evt, props) {
|
|||||||
// TODO: Use Types ENUM
|
// TODO: Use Types ENUM
|
||||||
// TODO: We can update this to be a `getter` on the extension to query
|
// TODO: We can update this to be a `getter` on the extension to query
|
||||||
// For the active tools after we apply our updates?
|
// For the active tools after we apply our updates?
|
||||||
if (button.type === 'setToolActive') {
|
if (button.type === "setToolActive") {
|
||||||
this.setState({
|
this.setState({
|
||||||
activeButtons: [button.id],
|
activeButtons: [button.id]
|
||||||
});
|
});
|
||||||
} else if (button.type === 'builtIn') {
|
} else if (button.type === "builtIn") {
|
||||||
this._handleBuiltIn(button.options);
|
this._handleBuiltIn(button.options);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -232,9 +232,9 @@ function _getVisibleToolbarButtons() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function _handleBuiltIn({ behavior } = {}) {
|
function _handleBuiltIn({ behavior } = {}) {
|
||||||
if (behavior === 'CINE') {
|
if (behavior === "CINE") {
|
||||||
this.setState({
|
this.setState({
|
||||||
isCineDialogOpen: !this.state.isCineDialogOpen,
|
isCineDialogOpen: !this.state.isCineDialogOpen
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,19 +1,19 @@
|
|||||||
import React, { Component } from 'react';
|
import React, { Component } from "react";
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from "prop-types";
|
||||||
import classNames from 'classnames';
|
import classNames from "classnames";
|
||||||
|
|
||||||
import { MODULE_TYPES } from 'ohif-core';
|
import { MODULE_TYPES } from "@ohif/core";
|
||||||
import OHIF from 'ohif-core';
|
import OHIF from "@ohif/core";
|
||||||
import moment from 'moment';
|
import moment from "moment";
|
||||||
import WhiteLabellingContext from '../WhiteLabellingContext.js';
|
import WhiteLabellingContext from "../WhiteLabellingContext.js";
|
||||||
import ConnectedHeader from './ConnectedHeader.js';
|
import ConnectedHeader from "./ConnectedHeader.js";
|
||||||
import ConnectedToolbarRow from './ConnectedToolbarRow.js';
|
import ConnectedToolbarRow from "./ConnectedToolbarRow.js";
|
||||||
import ConnectedLabellingOverlay from './ConnectedLabellingOverlay';
|
import ConnectedLabellingOverlay from "./ConnectedLabellingOverlay";
|
||||||
import ConnectedStudyBrowser from './ConnectedStudyBrowser.js';
|
import ConnectedStudyBrowser from "./ConnectedStudyBrowser.js";
|
||||||
import ConnectedViewerMain from './ConnectedViewerMain.js';
|
import ConnectedViewerMain from "./ConnectedViewerMain.js";
|
||||||
import SidePanel from './../components/SidePanel.js';
|
import SidePanel from "./../components/SidePanel.js";
|
||||||
import { extensionManager } from './../App.js';
|
import { extensionManager } from "./../App.js";
|
||||||
import './Viewer.css';
|
import "./Viewer.css";
|
||||||
/**
|
/**
|
||||||
* Inits OHIF Hanging Protocol's onReady.
|
* Inits OHIF Hanging Protocol's onReady.
|
||||||
* It waits for OHIF Hanging Protocol to be ready to instantiate the ProtocolEngine
|
* It waits for OHIF Hanging Protocol to be ready to instantiate the ProtocolEngine
|
||||||
@ -59,7 +59,7 @@ class Viewer extends Component {
|
|||||||
// window.store.getState().viewports.viewportSpecificData
|
// window.store.getState().viewports.viewportSpecificData
|
||||||
viewports: PropTypes.object.isRequired,
|
viewports: PropTypes.object.isRequired,
|
||||||
// window.store.getState().viewports.activeViewportIndex
|
// window.store.getState().viewports.activeViewportIndex
|
||||||
activeViewportIndex: PropTypes.number.isRequired,
|
activeViewportIndex: PropTypes.number.isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
@ -67,8 +67,8 @@ class Viewer extends Component {
|
|||||||
OHIF.measurements.MeasurementApi.setConfiguration({
|
OHIF.measurements.MeasurementApi.setConfiguration({
|
||||||
dataExchange: {
|
dataExchange: {
|
||||||
retrieve: this.retrieveMeasurements,
|
retrieve: this.retrieveMeasurements,
|
||||||
store: this.storeMeasurements,
|
store: this.storeMeasurements
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
OHIF.measurements.TimepointApi.setConfiguration({
|
OHIF.measurements.TimepointApi.setConfiguration({
|
||||||
@ -77,41 +77,41 @@ class Viewer extends Component {
|
|||||||
store: this.storeTimepoints,
|
store: this.storeTimepoints,
|
||||||
remove: this.removeTimepoint,
|
remove: this.removeTimepoint,
|
||||||
update: this.updateTimepoint,
|
update: this.updateTimepoint,
|
||||||
disassociate: this.disassociateStudy,
|
disassociate: this.disassociateStudy
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
state = {
|
state = {
|
||||||
isLeftSidePanelOpen: true,
|
isLeftSidePanelOpen: true,
|
||||||
isRightSidePanelOpen: false,
|
isRightSidePanelOpen: false,
|
||||||
selectedRightSidePanel: '',
|
selectedRightSidePanel: "",
|
||||||
selectedLeftSidePanel: 'studies', // TODO: Don't hardcode this
|
selectedLeftSidePanel: "studies", // TODO: Don't hardcode this
|
||||||
thumbnails: [],
|
thumbnails: []
|
||||||
};
|
};
|
||||||
|
|
||||||
retrieveMeasurements = (patientId, timepointIds) => {
|
retrieveMeasurements = (patientId, timepointIds) => {
|
||||||
OHIF.log.info('retrieveMeasurements');
|
OHIF.log.info("retrieveMeasurements");
|
||||||
// TODO: Retrieve the measurements from the latest available SR
|
// TODO: Retrieve the measurements from the latest available SR
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
};
|
};
|
||||||
|
|
||||||
storeMeasurements = (measurementData, timepointIds) => {
|
storeMeasurements = (measurementData, timepointIds) => {
|
||||||
OHIF.log.info('storeMeasurements');
|
OHIF.log.info("storeMeasurements");
|
||||||
// TODO: Store the measurements into a new SR sent to the active server
|
// TODO: Store the measurements into a new SR sent to the active server
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
};
|
};
|
||||||
|
|
||||||
retrieveTimepoints = filter => {
|
retrieveTimepoints = filter => {
|
||||||
OHIF.log.info('retrieveTimepoints');
|
OHIF.log.info("retrieveTimepoints");
|
||||||
|
|
||||||
// Get the earliest and latest study date
|
// Get the earliest and latest study date
|
||||||
let earliestDate = new Date().toISOString();
|
let earliestDate = new Date().toISOString();
|
||||||
let latestDate = new Date().toISOString();
|
let latestDate = new Date().toISOString();
|
||||||
if (this.props.studies) {
|
if (this.props.studies) {
|
||||||
latestDate = new Date('1000-01-01').toISOString();
|
latestDate = new Date("1000-01-01").toISOString();
|
||||||
this.props.studies.forEach(study => {
|
this.props.studies.forEach(study => {
|
||||||
const studyDate = moment(study.studyDate, 'YYYYMMDD').toISOString();
|
const studyDate = moment(study.studyDate, "YYYYMMDD").toISOString();
|
||||||
if (studyDate < earliestDate) {
|
if (studyDate < earliestDate) {
|
||||||
earliestDate = studyDate;
|
earliestDate = studyDate;
|
||||||
}
|
}
|
||||||
@ -124,34 +124,34 @@ class Viewer extends Component {
|
|||||||
// Return a generic timepoint
|
// Return a generic timepoint
|
||||||
return Promise.resolve([
|
return Promise.resolve([
|
||||||
{
|
{
|
||||||
timepointType: 'baseline',
|
timepointType: "baseline",
|
||||||
timepointId: 'TimepointId',
|
timepointId: "TimepointId",
|
||||||
studyInstanceUids: this.props.studyInstanceUids,
|
studyInstanceUids: this.props.studyInstanceUids,
|
||||||
patientId: filter.patientId,
|
patientId: filter.patientId,
|
||||||
earliestDate,
|
earliestDate,
|
||||||
latestDate,
|
latestDate,
|
||||||
isLocked: false,
|
isLocked: false
|
||||||
},
|
}
|
||||||
]);
|
]);
|
||||||
};
|
};
|
||||||
|
|
||||||
storeTimepoints = timepointData => {
|
storeTimepoints = timepointData => {
|
||||||
OHIF.log.info('storeTimepoints');
|
OHIF.log.info("storeTimepoints");
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
};
|
};
|
||||||
|
|
||||||
updateTimepoint = (timepointData, query) => {
|
updateTimepoint = (timepointData, query) => {
|
||||||
OHIF.log.info('updateTimepoint');
|
OHIF.log.info("updateTimepoint");
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
};
|
};
|
||||||
|
|
||||||
removeTimepoint = timepointId => {
|
removeTimepoint = timepointId => {
|
||||||
OHIF.log.info('removeTimepoint');
|
OHIF.log.info("removeTimepoint");
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
};
|
};
|
||||||
|
|
||||||
disassociateStudy = (timepointIds, studyInstanceUid) => {
|
disassociateStudy = (timepointIds, studyInstanceUid) => {
|
||||||
OHIF.log.info('disassociateStudy');
|
OHIF.log.info("disassociateStudy");
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -170,14 +170,14 @@ class Viewer extends Component {
|
|||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
const { studies } = this.props;
|
const { studies } = this.props;
|
||||||
const { TimepointApi, MeasurementApi } = OHIF.measurements;
|
const { TimepointApi, MeasurementApi } = OHIF.measurements;
|
||||||
const currentTimepointId = 'TimepointId';
|
const currentTimepointId = "TimepointId";
|
||||||
|
|
||||||
const timepointApi = new TimepointApi(currentTimepointId, {
|
const timepointApi = new TimepointApi(currentTimepointId, {
|
||||||
onTimepointsUpdated: this.onTimepointsUpdated,
|
onTimepointsUpdated: this.onTimepointsUpdated
|
||||||
});
|
});
|
||||||
|
|
||||||
const measurementApi = new MeasurementApi(timepointApi, {
|
const measurementApi = new MeasurementApi(timepointApi, {
|
||||||
onMeasurementsUpdated: this.onMeasurementsUpdated,
|
onMeasurementsUpdated: this.onMeasurementsUpdated
|
||||||
});
|
});
|
||||||
|
|
||||||
this.currentTimepointId = currentTimepointId;
|
this.currentTimepointId = currentTimepointId;
|
||||||
@ -191,7 +191,7 @@ class Viewer extends Component {
|
|||||||
measurementApi.retrieveMeasurements(patientId, [currentTimepointId]);
|
measurementApi.retrieveMeasurements(patientId, [currentTimepointId]);
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
thumbnails: _mapStudiesToThumbnails(studies),
|
thumbnails: _mapStudiesToThumbnails(studies)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -206,7 +206,7 @@ class Viewer extends Component {
|
|||||||
this.measurementApi.retrieveMeasurements(patientId, [currentTimepointId]);
|
this.measurementApi.retrieveMeasurements(patientId, [currentTimepointId]);
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
thumbnails: _mapStudiesToThumbnails(studies),
|
thumbnails: _mapStudiesToThumbnails(studies)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -243,12 +243,12 @@ class Viewer extends Component {
|
|||||||
selectedLeftSidePanel={
|
selectedLeftSidePanel={
|
||||||
this.state.isLeftSidePanelOpen
|
this.state.isLeftSidePanelOpen
|
||||||
? this.state.selectedLeftSidePanel
|
? this.state.selectedLeftSidePanel
|
||||||
: ''
|
: ""
|
||||||
}
|
}
|
||||||
selectedRightSidePanel={
|
selectedRightSidePanel={
|
||||||
this.state.isRightSidePanelOpen
|
this.state.isRightSidePanelOpen
|
||||||
? this.state.selectedRightSidePanel
|
? this.state.selectedRightSidePanel
|
||||||
: ''
|
: ""
|
||||||
}
|
}
|
||||||
handleSidePanelChange={(side, selectedPanel) => {
|
handleSidePanelChange={(side, selectedPanel) => {
|
||||||
const sideClicked = side && side[0].toUpperCase() + side.slice(1);
|
const sideClicked = side && side[0].toUpperCase() + side.slice(1);
|
||||||
@ -291,7 +291,7 @@ class Viewer extends Component {
|
|||||||
</SidePanel>
|
</SidePanel>
|
||||||
|
|
||||||
{/* MAIN */}
|
{/* MAIN */}
|
||||||
<div className={classNames('main-content')}>
|
<div className={classNames("main-content")}>
|
||||||
<ConnectedViewerMain studies={this.props.studies} />
|
<ConnectedViewerMain studies={this.props.studies} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -335,16 +335,16 @@ const _mapStudiesToThumbnails = function(studies) {
|
|||||||
seriesDescription,
|
seriesDescription,
|
||||||
seriesNumber,
|
seriesNumber,
|
||||||
instanceNumber,
|
instanceNumber,
|
||||||
numImageFrames,
|
numImageFrames
|
||||||
} = displaySet;
|
} = displaySet;
|
||||||
|
|
||||||
let imageId;
|
let imageId;
|
||||||
let altImageText = ' '; // modality
|
let altImageText = " "; // modality
|
||||||
|
|
||||||
if (displaySet.images && displaySet.images.length) {
|
if (displaySet.images && displaySet.images.length) {
|
||||||
imageId = displaySet.images[0].getImageId();
|
imageId = displaySet.images[0].getImageId();
|
||||||
} else {
|
} else {
|
||||||
altImageText = 'SR';
|
altImageText = "SR";
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -354,13 +354,13 @@ const _mapStudiesToThumbnails = function(studies) {
|
|||||||
seriesDescription,
|
seriesDescription,
|
||||||
seriesNumber,
|
seriesNumber,
|
||||||
instanceNumber,
|
instanceNumber,
|
||||||
numImageFrames,
|
numImageFrames
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
studyInstanceUid,
|
studyInstanceUid,
|
||||||
thumbnails,
|
thumbnails
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
import React, { Component } from 'react';
|
import React, { Component } from "react";
|
||||||
import { metadata, studies, utils } from 'ohif-core';
|
import { metadata, studies, utils } from "@ohif/core";
|
||||||
|
|
||||||
import ConnectedViewer from './ConnectedViewer.js';
|
import ConnectedViewer from "./ConnectedViewer.js";
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from "prop-types";
|
||||||
import { extensionManager } from './../App.js';
|
import { extensionManager } from "./../App.js";
|
||||||
|
|
||||||
const { OHIFStudyMetadata } = metadata;
|
const { OHIFStudyMetadata } = metadata;
|
||||||
const { retrieveStudiesMetadata } = studies;
|
const { retrieveStudiesMetadata } = studies;
|
||||||
@ -13,12 +13,12 @@ class ViewerRetrieveStudyData extends Component {
|
|||||||
static propTypes = {
|
static propTypes = {
|
||||||
studyInstanceUids: PropTypes.array.isRequired,
|
studyInstanceUids: PropTypes.array.isRequired,
|
||||||
seriesInstanceUids: PropTypes.array,
|
seriesInstanceUids: PropTypes.array,
|
||||||
server: PropTypes.object,
|
server: PropTypes.object
|
||||||
};
|
};
|
||||||
|
|
||||||
state = {
|
state = {
|
||||||
studies: null,
|
studies: null,
|
||||||
error: null,
|
error: null
|
||||||
};
|
};
|
||||||
|
|
||||||
async componentDidMount() {
|
async componentDidMount() {
|
||||||
@ -44,7 +44,7 @@ class ViewerRetrieveStudyData extends Component {
|
|||||||
study.studyInstanceUid
|
study.studyInstanceUid
|
||||||
);
|
);
|
||||||
const sopClassHandlerModules =
|
const sopClassHandlerModules =
|
||||||
extensionManager.modules['sopClassHandlerModule'];
|
extensionManager.modules["sopClassHandlerModule"];
|
||||||
|
|
||||||
study.displaySets =
|
study.displaySets =
|
||||||
study.displaySets ||
|
study.displaySets ||
|
||||||
@ -60,11 +60,11 @@ class ViewerRetrieveStudyData extends Component {
|
|||||||
});
|
});
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
studies: updatedStudies,
|
studies: updatedStudies
|
||||||
});
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this.setState({
|
this.setState({
|
||||||
error: true,
|
error: true
|
||||||
});
|
});
|
||||||
|
|
||||||
// TODO: Handle gracefully instead of throwing?
|
// TODO: Handle gracefully instead of throwing?
|
||||||
|
|||||||
@ -1,11 +1,11 @@
|
|||||||
import OHIF from 'ohif-core';
|
import OHIF from "@ohif/core";
|
||||||
import cornerstone from 'cornerstone-core';
|
import cornerstone from "cornerstone-core";
|
||||||
|
|
||||||
export default function updateTableWithNewMeasurementData({
|
export default function updateTableWithNewMeasurementData({
|
||||||
toolType,
|
toolType,
|
||||||
measurementNumber,
|
measurementNumber,
|
||||||
location,
|
location,
|
||||||
description,
|
description
|
||||||
}) {
|
}) {
|
||||||
// Update all measurements by measurement number
|
// Update all measurements by measurement number
|
||||||
const measurementApi = OHIF.measurements.MeasurementApi.Instance;
|
const measurementApi = OHIF.measurements.MeasurementApi.Instance;
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
import React, { Component } from 'react';
|
import React, { Component } from "react";
|
||||||
import { log, metadata, studies, utils } from 'ohif-core';
|
import { log, metadata, studies, utils } from "@ohif/core";
|
||||||
|
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from "prop-types";
|
||||||
import Viewer from '../connectedComponents/Viewer';
|
import Viewer from "../connectedComponents/Viewer";
|
||||||
import { extensionManager } from './../App.js';
|
import { extensionManager } from "./../App.js";
|
||||||
import qs from 'querystring';
|
import qs from "querystring";
|
||||||
|
|
||||||
const { OHIFStudyMetadata } = metadata;
|
const { OHIFStudyMetadata } = metadata;
|
||||||
const { retrieveStudiesMetadata } = studies;
|
const { retrieveStudiesMetadata } = studies;
|
||||||
@ -13,12 +13,12 @@ const { studyMetadataManager, updateMetaDataManager } = utils;
|
|||||||
class StandaloneRouting extends Component {
|
class StandaloneRouting extends Component {
|
||||||
state = {
|
state = {
|
||||||
studies: null,
|
studies: null,
|
||||||
error: null,
|
error: null
|
||||||
};
|
};
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
location: PropTypes.object,
|
location: PropTypes.object,
|
||||||
store: PropTypes.object,
|
store: PropTypes.object
|
||||||
};
|
};
|
||||||
|
|
||||||
static parseQueryAndFetchStudies(query) {
|
static parseQueryAndFetchStudies(query) {
|
||||||
@ -26,7 +26,7 @@ class StandaloneRouting extends Component {
|
|||||||
const url = query.url;
|
const url = query.url;
|
||||||
|
|
||||||
if (!url) {
|
if (!url) {
|
||||||
reject(new Error('No URL was specified. Use ?url=$yourURL'));
|
reject(new Error("No URL was specified. Use ?url=$yourURL"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Define a request to the server to retrieve the study data
|
// Define a request to the server to retrieve the study data
|
||||||
@ -34,19 +34,19 @@ class StandaloneRouting extends Component {
|
|||||||
const oReq = new XMLHttpRequest();
|
const oReq = new XMLHttpRequest();
|
||||||
|
|
||||||
// Add event listeners for request failure
|
// Add event listeners for request failure
|
||||||
oReq.addEventListener('error', error => {
|
oReq.addEventListener("error", error => {
|
||||||
log.warn('An error occurred while retrieving the JSON data');
|
log.warn("An error occurred while retrieving the JSON data");
|
||||||
reject(error);
|
reject(error);
|
||||||
});
|
});
|
||||||
|
|
||||||
// When the JSON has been returned, parse it into a JavaScript Object
|
// When the JSON has been returned, parse it into a JavaScript Object
|
||||||
// and render the OHIF Viewer with this data
|
// and render the OHIF Viewer with this data
|
||||||
oReq.addEventListener('load', () => {
|
oReq.addEventListener("load", () => {
|
||||||
// Parse the response content
|
// Parse the response content
|
||||||
// https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/responseText
|
// https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/responseText
|
||||||
if (!oReq.responseText) {
|
if (!oReq.responseText) {
|
||||||
log.warn('Response was undefined');
|
log.warn("Response was undefined");
|
||||||
reject(new Error('Response was undefined'));
|
reject(new Error("Response was undefined"));
|
||||||
}
|
}
|
||||||
|
|
||||||
log.info(JSON.stringify(oReq.responseText, null, 2));
|
log.info(JSON.stringify(oReq.responseText, null, 2));
|
||||||
@ -54,9 +54,9 @@ class StandaloneRouting extends Component {
|
|||||||
const data = JSON.parse(oReq.responseText);
|
const data = JSON.parse(oReq.responseText);
|
||||||
if (data.servers && query.studyInstanceUids) {
|
if (data.servers && query.studyInstanceUids) {
|
||||||
const server = data.servers.dicomWeb[0];
|
const server = data.servers.dicomWeb[0];
|
||||||
server.type = 'dicomWeb';
|
server.type = "dicomWeb";
|
||||||
|
|
||||||
const studyInstanceUids = query.studyInstanceUids.split(';');
|
const studyInstanceUids = query.studyInstanceUids.split(";");
|
||||||
const seriesInstanceUids = [];
|
const seriesInstanceUids = [];
|
||||||
|
|
||||||
retrieveStudiesMetadata(
|
retrieveStudiesMetadata(
|
||||||
@ -80,8 +80,8 @@ class StandaloneRouting extends Component {
|
|||||||
// In this case we have a server-side route called /api/
|
// In this case we have a server-side route called /api/
|
||||||
// which responds to GET requests with the study data
|
// which responds to GET requests with the study data
|
||||||
log.info(`Sending Request to: ${url}`);
|
log.info(`Sending Request to: ${url}`);
|
||||||
oReq.open('GET', url);
|
oReq.open("GET", url);
|
||||||
oReq.setRequestHeader('Accept', 'application/json');
|
oReq.setRequestHeader("Accept", "application/json");
|
||||||
|
|
||||||
// Fire the request to the server
|
// Fire the request to the server
|
||||||
oReq.send();
|
oReq.send();
|
||||||
@ -102,7 +102,7 @@ class StandaloneRouting extends Component {
|
|||||||
study.studyInstanceUid
|
study.studyInstanceUid
|
||||||
);
|
);
|
||||||
const sopClassHandlerModules =
|
const sopClassHandlerModules =
|
||||||
extensionManager.modules['sopClassHandlerModule'];
|
extensionManager.modules["sopClassHandlerModule"];
|
||||||
|
|
||||||
study.displaySets =
|
study.displaySets =
|
||||||
study.displaySets ||
|
study.displaySets ||
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
import OHIF from 'ohif-core';
|
import OHIF from "@ohif/core";
|
||||||
import updateTableWithNewMeasurementData from './lib/updateTableWithNewMeasurementData';
|
import updateTableWithNewMeasurementData from "./lib/updateTableWithNewMeasurementData";
|
||||||
|
|
||||||
function getToolLabellingFlowCallback(store) {
|
function getToolLabellingFlowCallback(store) {
|
||||||
const setLabellingFlowDataAction = labellingFlowData => ({
|
const setLabellingFlowDataAction = labellingFlowData => ({
|
||||||
type: 'SET_LABELLING_FLOW_DATA',
|
type: "SET_LABELLING_FLOW_DATA",
|
||||||
labellingFlowData,
|
labellingFlowData
|
||||||
});
|
});
|
||||||
|
|
||||||
const setLabellingFlowData = labellingFlowData => {
|
const setLabellingFlowData = labellingFlowData => {
|
||||||
@ -47,7 +47,7 @@ function getToolLabellingFlowCallback(store) {
|
|||||||
editResponse: options.editResponse,
|
editResponse: options.editResponse,
|
||||||
editDescriptionOnDialog: options.editDescriptionOnDialog,
|
editDescriptionOnDialog: options.editDescriptionOnDialog,
|
||||||
labellingDoneCallback,
|
labellingDoneCallback,
|
||||||
updateLabelling,
|
updateLabelling
|
||||||
};
|
};
|
||||||
|
|
||||||
setLabellingFlowData(labellingFlowData);
|
setLabellingFlowData(labellingFlowData);
|
||||||
@ -55,14 +55,14 @@ function getToolLabellingFlowCallback(store) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const resetLabellingAndContextMenuAction = state => ({
|
const resetLabellingAndContextMenuAction = state => ({
|
||||||
type: 'RESET_LABELLING_AND_CONTEXT_MENU',
|
type: "RESET_LABELLING_AND_CONTEXT_MENU",
|
||||||
state,
|
state
|
||||||
});
|
});
|
||||||
|
|
||||||
const setToolContextMenuDataAction = (viewportIndex, toolContextMenuData) => ({
|
const setToolContextMenuDataAction = (viewportIndex, toolContextMenuData) => ({
|
||||||
type: 'SET_TOOL_CONTEXT_MENU_DATA',
|
type: "SET_TOOL_CONTEXT_MENU_DATA",
|
||||||
viewportIndex,
|
viewportIndex,
|
||||||
toolContextMenuData,
|
toolContextMenuData
|
||||||
});
|
});
|
||||||
|
|
||||||
function getOnRightClickCallback(store) {
|
function getOnRightClickCallback(store) {
|
||||||
@ -76,7 +76,7 @@ function getOnRightClickCallback(store) {
|
|||||||
const getOnCloseCallback = viewportIndex => {
|
const getOnCloseCallback = viewportIndex => {
|
||||||
return function onClose() {
|
return function onClose() {
|
||||||
const toolContextMenuData = {
|
const toolContextMenuData = {
|
||||||
visible: false,
|
visible: false
|
||||||
};
|
};
|
||||||
|
|
||||||
store.dispatch(
|
store.dispatch(
|
||||||
@ -92,7 +92,7 @@ function getOnRightClickCallback(store) {
|
|||||||
const toolContextMenuData = {
|
const toolContextMenuData = {
|
||||||
eventData,
|
eventData,
|
||||||
isTouchEvent: false,
|
isTouchEvent: false,
|
||||||
onClose: getOnCloseCallback(viewportIndex),
|
onClose: getOnCloseCallback(viewportIndex)
|
||||||
};
|
};
|
||||||
|
|
||||||
setToolContextMenuData(viewportIndex, toolContextMenuData);
|
setToolContextMenuData(viewportIndex, toolContextMenuData);
|
||||||
@ -110,7 +110,7 @@ function getOnTouchPressCallback(store) {
|
|||||||
const getOnCloseCallback = viewportIndex => {
|
const getOnCloseCallback = viewportIndex => {
|
||||||
return function onClose() {
|
return function onClose() {
|
||||||
const toolContextMenuData = {
|
const toolContextMenuData = {
|
||||||
visible: false,
|
visible: false
|
||||||
};
|
};
|
||||||
|
|
||||||
store.dispatch(
|
store.dispatch(
|
||||||
@ -126,7 +126,7 @@ function getOnTouchPressCallback(store) {
|
|||||||
const toolContextMenuData = {
|
const toolContextMenuData = {
|
||||||
eventData,
|
eventData,
|
||||||
isTouchEvent: true,
|
isTouchEvent: true,
|
||||||
onClose: getOnCloseCallback(viewportIndex),
|
onClose: getOnCloseCallback(viewportIndex)
|
||||||
};
|
};
|
||||||
|
|
||||||
setToolContextMenuData(viewportIndex, toolContextMenuData);
|
setToolContextMenuData(viewportIndex, toolContextMenuData);
|
||||||
@ -142,78 +142,78 @@ function getResetLabellingAndContextMenu(store) {
|
|||||||
export default function setupTools(store) {
|
export default function setupTools(store) {
|
||||||
const toolLabellingFlowCallback = getToolLabellingFlowCallback(store);
|
const toolLabellingFlowCallback = getToolLabellingFlowCallback(store);
|
||||||
const availableTools = [
|
const availableTools = [
|
||||||
{ name: 'Pan', mouseButtonMasks: [1, 4] },
|
{ name: "Pan", mouseButtonMasks: [1, 4] },
|
||||||
{ name: 'Zoom', mouseButtonMasks: [1, 2] },
|
{ name: "Zoom", mouseButtonMasks: [1, 2] },
|
||||||
{ name: 'Wwwc', mouseButtonMasks: [1] },
|
{ name: "Wwwc", mouseButtonMasks: [1] },
|
||||||
{
|
{
|
||||||
name: 'Bidirectional',
|
name: "Bidirectional",
|
||||||
props: {
|
props: {
|
||||||
configuration: {
|
configuration: {
|
||||||
getMeasurementLocationCallback: toolLabellingFlowCallback,
|
getMeasurementLocationCallback: toolLabellingFlowCallback
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
mouseButtonMasks: [1],
|
mouseButtonMasks: [1]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Length',
|
name: "Length",
|
||||||
props: {
|
props: {
|
||||||
configuration: {
|
configuration: {
|
||||||
getMeasurementLocationCallback: toolLabellingFlowCallback,
|
getMeasurementLocationCallback: toolLabellingFlowCallback
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
mouseButtonMasks: [1],
|
mouseButtonMasks: [1]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Angle',
|
name: "Angle",
|
||||||
props: {
|
props: {
|
||||||
configuration: {
|
configuration: {
|
||||||
getMeasurementLocationCallback: toolLabellingFlowCallback,
|
getMeasurementLocationCallback: toolLabellingFlowCallback
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
mouseButtonMasks: [1],
|
mouseButtonMasks: [1]
|
||||||
},
|
},
|
||||||
{ name: 'StackScroll', mouseButtonMasks: [1] },
|
{ name: "StackScroll", mouseButtonMasks: [1] },
|
||||||
{ name: 'Brush', mouseButtonMasks: [1] },
|
{ name: "Brush", mouseButtonMasks: [1] },
|
||||||
{
|
{
|
||||||
name: 'FreehandMouse',
|
name: "FreehandMouse",
|
||||||
configuration: {
|
configuration: {
|
||||||
configuration: {
|
configuration: {
|
||||||
getMeasurementLocationCallback: toolLabellingFlowCallback,
|
getMeasurementLocationCallback: toolLabellingFlowCallback
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
mouseButtonMasks: [1],
|
mouseButtonMasks: [1]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'EllipticalRoi',
|
name: "EllipticalRoi",
|
||||||
props: {
|
props: {
|
||||||
configuration: {
|
configuration: {
|
||||||
getMeasurementLocationCallback: toolLabellingFlowCallback,
|
getMeasurementLocationCallback: toolLabellingFlowCallback
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
mouseButtonMasks: [1],
|
mouseButtonMasks: [1]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'CircleRoi',
|
name: "CircleRoi",
|
||||||
props: {
|
props: {
|
||||||
configuration: {
|
configuration: {
|
||||||
getMeasurementLocationCallback: toolLabellingFlowCallback,
|
getMeasurementLocationCallback: toolLabellingFlowCallback
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
mouseButtonMasks: [1],
|
mouseButtonMasks: [1]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'RectangleRoi',
|
name: "RectangleRoi",
|
||||||
props: {
|
props: {
|
||||||
configuration: {
|
configuration: {
|
||||||
getMeasurementLocationCallback: toolLabellingFlowCallback,
|
getMeasurementLocationCallback: toolLabellingFlowCallback
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
mouseButtonMasks: [1],
|
mouseButtonMasks: [1]
|
||||||
},
|
},
|
||||||
{ name: 'PanMultiTouch' },
|
{ name: "PanMultiTouch" },
|
||||||
{ name: 'ZoomTouchPinch' },
|
{ name: "ZoomTouchPinch" },
|
||||||
{ name: 'StackScrollMouseWheel' },
|
{ name: "StackScrollMouseWheel" },
|
||||||
{ name: 'StackScrollMultiTouch' },
|
{ name: "StackScrollMultiTouch" }
|
||||||
];
|
];
|
||||||
|
|
||||||
const onRightClick = getOnRightClickCallback(store);
|
const onRightClick = getOnRightClickCallback(store);
|
||||||
@ -221,13 +221,13 @@ export default function setupTools(store) {
|
|||||||
const onNewImage = getResetLabellingAndContextMenu(store);
|
const onNewImage = getResetLabellingAndContextMenu(store);
|
||||||
const onMouseClick = getResetLabellingAndContextMenu(store);
|
const onMouseClick = getResetLabellingAndContextMenu(store);
|
||||||
const onTouchStart = getResetLabellingAndContextMenu(store);
|
const onTouchStart = getResetLabellingAndContextMenu(store);
|
||||||
const toolAction = OHIF.redux.actions.setExtensionData('cornerstone', {
|
const toolAction = OHIF.redux.actions.setExtensionData("cornerstone", {
|
||||||
availableTools,
|
availableTools,
|
||||||
onNewImage,
|
onNewImage,
|
||||||
onRightClick,
|
onRightClick,
|
||||||
onTouchPress,
|
onTouchPress,
|
||||||
onTouchStart,
|
onTouchStart,
|
||||||
onMouseClick,
|
onMouseClick
|
||||||
});
|
});
|
||||||
|
|
||||||
store.dispatch(toolAction);
|
store.dispatch(toolAction);
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
import { applyMiddleware, combineReducers, createStore } from 'redux';
|
import { applyMiddleware, combineReducers, createStore } from "redux";
|
||||||
|
|
||||||
// import { createLogger } from 'redux-logger';
|
// import { createLogger } from 'redux-logger';
|
||||||
import layoutReducers from './layout/reducers.js';
|
import layoutReducers from "./layout/reducers.js";
|
||||||
import { reducer as oidcReducer } from 'redux-oidc';
|
import { reducer as oidcReducer } from "redux-oidc";
|
||||||
import { redux } from 'ohif-core';
|
import { redux } from "@ohif/core";
|
||||||
import thunkMiddleware from 'redux-thunk';
|
import thunkMiddleware from "redux-thunk";
|
||||||
|
|
||||||
// Combine our ohif-core, ui, and oidc reducers
|
// Combine our ohif-core, ui, and oidc reducers
|
||||||
// Set init data, using values found in localStorage
|
// Set init data, using values found in localStorage
|
||||||
@ -28,7 +28,7 @@ const store = createStore(
|
|||||||
// Update our cached preferences in localStorage
|
// Update our cached preferences in localStorage
|
||||||
store.subscribe(() => {
|
store.subscribe(() => {
|
||||||
localStorage.saveState({
|
localStorage.saveState({
|
||||||
preferences: store.getState().preferences,
|
preferences: store.getState().preferences
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -1,31 +1,31 @@
|
|||||||
import React, { Component } from 'react';
|
import React, { Component } from "react";
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from "prop-types";
|
||||||
import OHIF from 'ohif-core';
|
import OHIF from "@ohif/core";
|
||||||
import { withRouter } from 'react-router-dom';
|
import { withRouter } from "react-router-dom";
|
||||||
import { StudyList } from 'react-viewerbase';
|
import { StudyList } from "react-viewerbase";
|
||||||
import ConnectedHeader from '../connectedComponents/ConnectedHeader.js';
|
import ConnectedHeader from "../connectedComponents/ConnectedHeader.js";
|
||||||
import moment from 'moment';
|
import moment from "moment";
|
||||||
|
|
||||||
class StudyListWithData extends Component {
|
class StudyListWithData extends Component {
|
||||||
state = {
|
state = {
|
||||||
searchData: {},
|
searchData: {},
|
||||||
studies: null,
|
studies: null,
|
||||||
error: null,
|
error: null
|
||||||
};
|
};
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
patientId: PropTypes.string,
|
patientId: PropTypes.string,
|
||||||
server: PropTypes.object,
|
server: PropTypes.object,
|
||||||
user: PropTypes.object,
|
user: PropTypes.object,
|
||||||
history: PropTypes.object,
|
history: PropTypes.object
|
||||||
};
|
};
|
||||||
|
|
||||||
static rowsPerPage = 25;
|
static rowsPerPage = 25;
|
||||||
static defaultSort = { field: 'patientName', order: 'desc' };
|
static defaultSort = { field: "patientName", order: "desc" };
|
||||||
|
|
||||||
static studyListDateFilterNumDays = 25000; // TODO: put this in the settings
|
static studyListDateFilterNumDays = 25000; // TODO: put this in the settings
|
||||||
static defaultStudyDateFrom = moment()
|
static defaultStudyDateFrom = moment()
|
||||||
.subtract(StudyListWithData.studyListDateFilterNumDays, 'days')
|
.subtract(StudyListWithData.studyListDateFilterNumDays, "days")
|
||||||
.toDate();
|
.toDate();
|
||||||
static defaultStudyDateTo = new Date();
|
static defaultStudyDateTo = new Date();
|
||||||
|
|
||||||
@ -42,7 +42,7 @@ class StudyListWithData extends Component {
|
|||||||
rowsPerPage: StudyListWithData.rowsPerPage,
|
rowsPerPage: StudyListWithData.rowsPerPage,
|
||||||
studyDateFrom: StudyListWithData.defaultStudyDateFrom,
|
studyDateFrom: StudyListWithData.defaultStudyDateFrom,
|
||||||
studyDateTo: StudyListWithData.defaultStudyDateTo,
|
studyDateTo: StudyListWithData.defaultStudyDateTo,
|
||||||
sortData: StudyListWithData.defaultSort,
|
sortData: StudyListWithData.defaultSort
|
||||||
}
|
}
|
||||||
) => {
|
) => {
|
||||||
const { server } = this.props;
|
const { server } = this.props;
|
||||||
@ -55,7 +55,7 @@ class StudyListWithData extends Component {
|
|||||||
studyDateFrom: searchData.studyDateFrom,
|
studyDateFrom: searchData.studyDateFrom,
|
||||||
studyDateTo: searchData.studyDateTo,
|
studyDateTo: searchData.studyDateTo,
|
||||||
limit: searchData.rowsPerPage,
|
limit: searchData.rowsPerPage,
|
||||||
offset: searchData.currentPage * searchData.rowsPerPage,
|
offset: searchData.currentPage * searchData.rowsPerPage
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: add sorting
|
// TODO: add sorting
|
||||||
@ -70,9 +70,9 @@ class StudyListWithData extends Component {
|
|||||||
|
|
||||||
const { field, order } = searchData.sortData;
|
const { field, order } = searchData.sortData;
|
||||||
let sortedStudies = studies.map(study => {
|
let sortedStudies = studies.map(study => {
|
||||||
if (!moment(study.studyDate, 'MMM DD, YYYY', true).isValid()) {
|
if (!moment(study.studyDate, "MMM DD, YYYY", true).isValid()) {
|
||||||
study.studyDate = moment(study.studyDate, 'YYYYMMDD').format(
|
study.studyDate = moment(study.studyDate, "YYYYMMDD").format(
|
||||||
'MMM DD, YYYY'
|
"MMM DD, YYYY"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return study;
|
return study;
|
||||||
@ -81,11 +81,11 @@ class StudyListWithData extends Component {
|
|||||||
sortedStudies.sort(function(a, b) {
|
sortedStudies.sort(function(a, b) {
|
||||||
let fieldA = a[field];
|
let fieldA = a[field];
|
||||||
let fieldB = b[field];
|
let fieldB = b[field];
|
||||||
if (field === 'studyDate') {
|
if (field === "studyDate") {
|
||||||
fieldA = moment(fieldA).toISOString();
|
fieldA = moment(fieldA).toISOString();
|
||||||
fieldB = moment(fieldB).toISOString();
|
fieldB = moment(fieldB).toISOString();
|
||||||
}
|
}
|
||||||
if (order === 'desc') {
|
if (order === "desc") {
|
||||||
if (fieldA < fieldB) {
|
if (fieldA < fieldB) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -105,12 +105,12 @@ class StudyListWithData extends Component {
|
|||||||
});
|
});
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
studies: sortedStudies,
|
studies: sortedStudies
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
this.setState({
|
this.setState({
|
||||||
error: true,
|
error: true
|
||||||
});
|
});
|
||||||
|
|
||||||
throw new Error(error);
|
throw new Error(error);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user