Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4293c073f0 | ||
|
|
62a2cd5ff3 | ||
|
|
2d827c2a49 | ||
|
|
a8305772d0 | ||
|
|
eab115e70c | ||
|
|
c02b232b0c | ||
|
|
f01640d009 | ||
|
|
63fd65690c |
@ -3,6 +3,28 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [2.8.1](https://github.com/OHIF/Viewers/compare/@ohif/extension-cornerstone@2.8.0...@ohif/extension-cornerstone@2.8.1) (2020-06-04)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 🐛 Infinite frame index change when quickly jumping between ([#1734](https://github.com/OHIF/Viewers/issues/1734)) ([a830577](https://github.com/OHIF/Viewers/commit/a8305772d0fbec506549ad7ea08504a8bc3a4f39)), closes [#1733](https://github.com/OHIF/Viewers/issues/1733)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [2.8.0](https://github.com/OHIF/Viewers/compare/@ohif/extension-cornerstone@2.7.3...@ohif/extension-cornerstone@2.8.0) (2020-06-04)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* 🎸 1729 - error boundary wrapper ([#1764](https://github.com/OHIF/Viewers/issues/1764)) ([c02b232](https://github.com/OHIF/Viewers/commit/c02b232b0cc24f38af5d5e3831d987d048e60ada))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [2.7.3](https://github.com/OHIF/Viewers/compare/@ohif/extension-cornerstone@2.7.2...@ohif/extension-cornerstone@2.7.3) (2020-05-12)
|
||||
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ohif/extension-cornerstone",
|
||||
"version": "2.7.3",
|
||||
"version": "2.8.1",
|
||||
"description": "OHIF extension for Cornerstone",
|
||||
"author": "OHIF",
|
||||
"license": "MIT",
|
||||
@ -51,6 +51,6 @@
|
||||
"classnames": "^2.2.6",
|
||||
"lodash.merge": "^4.6.2",
|
||||
"lodash.throttle": "^4.1.1",
|
||||
"react-cornerstone-viewport": "2.3.8"
|
||||
"react-cornerstone-viewport": "2.3.9"
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,7 +4,6 @@ import ConnectedCornerstoneViewport from './ConnectedCornerstoneViewport';
|
||||
import OHIF from '@ohif/core';
|
||||
import PropTypes from 'prop-types';
|
||||
import cornerstone from 'cornerstone-core';
|
||||
import debounce from 'lodash.debounce';
|
||||
|
||||
const { StackManager } = OHIF.utils;
|
||||
|
||||
@ -216,9 +215,10 @@ class OHIFCornerstoneViewport extends Component {
|
||||
});
|
||||
}
|
||||
|
||||
const debouncedNewImageHandler = debounce(({ currentImageIdIndex, sopInstanceUid }) => {
|
||||
const newImageHandler = ({ currentImageIdIndex, sopInstanceUid }) => {
|
||||
const { displaySet } = this.props.viewportData;
|
||||
const { StudyInstanceUID } = displaySet;
|
||||
|
||||
if (currentImageIdIndex > 0) {
|
||||
this.props.onNewImage({
|
||||
StudyInstanceUID,
|
||||
@ -227,7 +227,7 @@ class OHIFCornerstoneViewport extends Component {
|
||||
activeViewportIndex: viewportIndex,
|
||||
});
|
||||
}
|
||||
}, 700);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
@ -235,7 +235,8 @@ class OHIFCornerstoneViewport extends Component {
|
||||
viewportIndex={viewportIndex}
|
||||
imageIds={imageIds}
|
||||
imageIdIndex={currentImageIdIndex}
|
||||
onNewImage={debouncedNewImageHandler}
|
||||
onNewImage={newImageHandler}
|
||||
onNewImageDebounceTime={700}
|
||||
// ~~ Connected (From REDUX)
|
||||
// frameRate={frameRate}
|
||||
// isPlaying={false}
|
||||
|
||||
@ -39,7 +39,9 @@ export default {
|
||||
const onNewImageHandler = jumpData => {
|
||||
commandsManager.runCommand('jumpToImage', jumpData);
|
||||
};
|
||||
return <OHIFCornerstoneViewport {...props} onNewImage={onNewImageHandler} />;
|
||||
return (
|
||||
<OHIFCornerstoneViewport {...props} onNewImage={onNewImageHandler} />
|
||||
);
|
||||
};
|
||||
|
||||
return ExtendedOHIFCornerstoneViewport;
|
||||
|
||||
@ -3,6 +3,17 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [0.51.0](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-microscopy@0.50.9...@ohif/extension-dicom-microscopy@0.51.0) (2020-06-04)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* 🎸 1729 - error boundary wrapper ([#1764](https://github.com/OHIF/Viewers/issues/1764)) ([c02b232](https://github.com/OHIF/Viewers/commit/c02b232b0cc24f38af5d5e3831d987d048e60ada))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [0.50.9](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-microscopy@0.50.8...@ohif/extension-dicom-microscopy@0.50.9) (2020-04-02)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-dicom-microscopy
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ohif/extension-dicom-microscopy",
|
||||
"version": "0.50.9",
|
||||
"version": "0.51.0",
|
||||
"description": "OHIF extension for Dicom Microscopy",
|
||||
"author": "OHIF",
|
||||
"license": "MIT",
|
||||
|
||||
@ -92,8 +92,8 @@ class DicomMicroscopyViewport extends Component {
|
||||
{this.state.error ? (
|
||||
<h2>{JSON.stringify(this.state.error)}</h2>
|
||||
) : (
|
||||
<div style={style} ref={this.container} />
|
||||
)}
|
||||
<div style={style} ref={this.container} />
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@ -3,6 +3,14 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [0.1.1](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-p10-downloader@0.1.0...@ohif/extension-dicom-p10-downloader@0.1.1) (2020-06-04)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-dicom-p10-downloader
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [0.1.0](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-p10-downloader@0.0.2...@ohif/extension-dicom-p10-downloader@0.1.0) (2020-04-23)
|
||||
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ohif/extension-dicom-p10-downloader",
|
||||
"version": "0.1.0",
|
||||
"version": "0.1.1",
|
||||
"description": "OHIF extension for downloading DICOM P10 files",
|
||||
"author": "OHIF",
|
||||
"license": "MIT",
|
||||
|
||||
@ -2,6 +2,7 @@ import OHIF from '@ohif/core';
|
||||
import {
|
||||
save,
|
||||
getDicomWebClientFromContext,
|
||||
getStudyInstanceUIDFromStudies,
|
||||
getSOPInstanceReferenceFromActiveViewport,
|
||||
getSOPInstanceReferencesFromViewports,
|
||||
} from './utils';
|
||||
@ -41,6 +42,14 @@ export function getCommands(context) {
|
||||
listOfUIDs
|
||||
);
|
||||
},
|
||||
downloadAndZipStudy({ servers, studies, progress }) {
|
||||
const dicomWebClient = getDicomWebClientFromContext(context, servers);
|
||||
const listOfUIDs = getStudyInstanceUIDFromStudies(studies);
|
||||
return save(
|
||||
_downloadAndZip(dicomWebClient, listOfUIDs, { progress }),
|
||||
listOfUIDs
|
||||
);
|
||||
},
|
||||
downloadAndZipSeriesOnViewports({ servers, viewports, progress }) {
|
||||
const dicomWebClient = getDicomWebClientFromContext(context, servers);
|
||||
const listOfUIDs = getSOPInstanceReferencesFromViewports(viewports);
|
||||
@ -64,6 +73,11 @@ export function getCommands(context) {
|
||||
commandFn: queue.bindSafe(actions.downloadAndZip, error),
|
||||
storeContexts: ['servers'],
|
||||
},
|
||||
downloadAndZipStudy: {
|
||||
commandFn: queue.bindSafe(actions.downloadAndZipStudy, error),
|
||||
storeContexts: ['servers', 'studies'],
|
||||
options: { progress },
|
||||
},
|
||||
downloadAndZipSeriesOnViewports: {
|
||||
commandFn: queue.bindSafe(actions.downloadAndZipSeriesOnViewports, error),
|
||||
storeContexts: ['servers', 'viewports'],
|
||||
|
||||
@ -100,11 +100,16 @@ function save(promise, listOfUIDs) {
|
||||
});
|
||||
}
|
||||
|
||||
function getStudyInstanceUIDFromStudies(studies) {
|
||||
return Object.keys(Object(Object(studies).studyData)).slice(0, 1);
|
||||
}
|
||||
|
||||
export {
|
||||
save,
|
||||
validDicomUid,
|
||||
getDicomWebClientFromConfig,
|
||||
getDicomWebClientFromContext,
|
||||
getStudyInstanceUIDFromStudies,
|
||||
getSOPInstanceReferenceFromActiveViewport,
|
||||
getSOPInstanceReferencesFromViewports,
|
||||
};
|
||||
|
||||
@ -3,6 +3,17 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [0.2.0](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-rt@0.1.4...@ohif/extension-dicom-rt@0.2.0) (2020-06-04)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* 🎸 1729 - error boundary wrapper ([#1764](https://github.com/OHIF/Viewers/issues/1764)) ([c02b232](https://github.com/OHIF/Viewers/commit/c02b232b0cc24f38af5d5e3831d987d048e60ada))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [0.1.4](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-rt@0.1.3...@ohif/extension-dicom-rt@0.1.4) (2020-05-14)
|
||||
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ohif/extension-dicom-rt",
|
||||
"version": "0.1.4",
|
||||
"version": "0.2.0",
|
||||
"description": "OHIF extension for rendering DICOM RTSTRUCTs on top of cornerstone images.",
|
||||
"author": "OHIF",
|
||||
"license": "MIT",
|
||||
|
||||
@ -31,7 +31,18 @@ const refreshViewport = () => {
|
||||
* @param {number} props.isOpen - isOpen
|
||||
* @returns component
|
||||
*/
|
||||
const RTPanel = ({ studies, viewports, activeIndex, isOpen, onContourItemClick }) => {
|
||||
const RTPanel = ({
|
||||
studies,
|
||||
viewports,
|
||||
activeIndex,
|
||||
isOpen,
|
||||
onContourItemClick,
|
||||
activeContexts = [],
|
||||
contexts = {}
|
||||
}) => {
|
||||
const isVTK = () => activeContexts.includes(contexts.VTK);
|
||||
const isCornerstone = () => activeContexts.includes(contexts.CORNERSTONE);
|
||||
|
||||
const [selectedContour, setSelectedContour] = useState();
|
||||
const DEFAULT_SET_INDEX = 0;
|
||||
const DEFAULT_STATE = {
|
||||
@ -119,33 +130,35 @@ const RTPanel = ({ studies, viewports, activeIndex, isOpen, onContourItemClick }
|
||||
onClick={() => {
|
||||
setSelectedContour(isSameContour ? null : ROINumber);
|
||||
|
||||
const enabledElements = cornerstone.getEnabledElements();
|
||||
const element = enabledElements[activeIndex].element;
|
||||
const toolState = cornerstoneTools.getToolState(element, 'stack');
|
||||
if (isCornerstone()) {
|
||||
const enabledElements = cornerstone.getEnabledElements();
|
||||
const element = enabledElements[activeIndex].element;
|
||||
const toolState = cornerstoneTools.getToolState(element, 'stack');
|
||||
|
||||
if (!toolState) {
|
||||
return;
|
||||
if (!toolState) {
|
||||
return;
|
||||
}
|
||||
|
||||
const imageIds = toolState.data[0].imageIds;
|
||||
|
||||
const module = cornerstoneTools.getModule('rtstruct');
|
||||
const imageId = module.getters.imageIdOfCenterFrameOfROIContour(
|
||||
state.selectedSet.SeriesInstanceUID,
|
||||
ROINumber,
|
||||
imageIds
|
||||
);
|
||||
|
||||
const frameIndex = imageIds.indexOf(imageId);
|
||||
const SOPInstanceUID = cornerstone.metaData.get('SOPInstanceUID', imageId);
|
||||
const StudyInstanceUID = cornerstone.metaData.get('StudyInstanceUID', imageId);
|
||||
|
||||
onContourItemClick({
|
||||
StudyInstanceUID,
|
||||
SOPInstanceUID,
|
||||
frameIndex,
|
||||
activeViewportIndex: activeIndex
|
||||
});
|
||||
}
|
||||
|
||||
const imageIds = toolState.data[0].imageIds;
|
||||
|
||||
const module = cornerstoneTools.getModule('rtstruct');
|
||||
const imageId = module.getters.imageIdOfCenterFrameOfROIContour(
|
||||
state.selectedSet.SeriesInstanceUID,
|
||||
ROINumber,
|
||||
imageIds
|
||||
);
|
||||
|
||||
const frameIndex = imageIds.indexOf(imageId);
|
||||
const SOPInstanceUID = cornerstone.metaData.get('SOPInstanceUID', imageId);
|
||||
const StudyInstanceUID = cornerstone.metaData.get('StudyInstanceUID', imageId);
|
||||
|
||||
onContourItemClick({
|
||||
StudyInstanceUID,
|
||||
SOPInstanceUID,
|
||||
frameIndex,
|
||||
activeViewportIndex: activeIndex
|
||||
});
|
||||
}}
|
||||
label={`${ROIName} ${interpretedType}`}
|
||||
index={ROINumber}
|
||||
|
||||
@ -20,14 +20,21 @@ export default {
|
||||
preRegistration({ servicesManager, configuration = {} }) {
|
||||
init({ servicesManager, configuration });
|
||||
},
|
||||
getPanelModule({ commandsManager }) {
|
||||
getPanelModule({ commandsManager, api }) {
|
||||
const ExtendedRTPanel = props => {
|
||||
const { activeContexts } = api.hooks.useAppContext();
|
||||
|
||||
const contourItemClickHandler = contourData => {
|
||||
commandsManager.runCommand('jumpToImage', contourData);
|
||||
};
|
||||
|
||||
return (
|
||||
<RTPanel {...props} onContourItemClick={contourItemClickHandler} />
|
||||
<RTPanel
|
||||
{...props}
|
||||
onContourItemClick={contourItemClickHandler}
|
||||
activeContexts={activeContexts}
|
||||
contexts={api.contexts}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@ -3,6 +3,17 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [0.3.0](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-segmentation@0.2.6...@ohif/extension-dicom-segmentation@0.3.0) (2020-06-04)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* 🎸 1729 - error boundary wrapper ([#1764](https://github.com/OHIF/Viewers/issues/1764)) ([c02b232](https://github.com/OHIF/Viewers/commit/c02b232b0cc24f38af5d5e3831d987d048e60ada))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [0.2.6](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-segmentation@0.2.5...@ohif/extension-dicom-segmentation@0.2.6) (2020-05-12)
|
||||
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ohif/extension-dicom-segmentation",
|
||||
"version": "0.2.6",
|
||||
"version": "0.3.0",
|
||||
"description": "OHIF extension for viewing segmentations in the 2D MPR view",
|
||||
"author": "OHIF",
|
||||
"license": "MIT",
|
||||
|
||||
@ -49,8 +49,8 @@ const SegmentationPanel = ({
|
||||
onConfigurationChange,
|
||||
onDisplaySetLoadFailure,
|
||||
onSelectedSegmentationChange,
|
||||
activeContexts,
|
||||
contexts,
|
||||
activeContexts = [],
|
||||
contexts = {},
|
||||
}) => {
|
||||
const isVTK = () => activeContexts.includes(contexts.VTK);
|
||||
const isCornerstone = () => activeContexts.includes(contexts.CORNERSTONE);
|
||||
|
||||
@ -46,7 +46,7 @@ export default {
|
||||
const onSegmentVisibilityChangeHandler = (segmentNumber, visible) => {
|
||||
commandsManager.runCommand('setSegmentConfiguration', {
|
||||
segmentNumber,
|
||||
visible
|
||||
visible,
|
||||
});
|
||||
};
|
||||
|
||||
@ -55,7 +55,7 @@ export default {
|
||||
globalOpacity: configuration.fillAlpha,
|
||||
outlineThickness: configuration.outlineWidth,
|
||||
renderOutline: configuration.renderOutline,
|
||||
visible: configuration.renderFill
|
||||
visible: configuration.renderFill,
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@ -3,6 +3,25 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.6.1](https://github.com/OHIF/Viewers/compare/@ohif/extension-vtk@1.6.0...@ohif/extension-vtk@1.6.1) (2020-06-04)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-vtk
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [1.6.0](https://github.com/OHIF/Viewers/compare/@ohif/extension-vtk@1.5.6...@ohif/extension-vtk@1.6.0) (2020-06-04)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* 🎸 1729 - error boundary wrapper ([#1764](https://github.com/OHIF/Viewers/issues/1764)) ([c02b232](https://github.com/OHIF/Viewers/commit/c02b232b0cc24f38af5d5e3831d987d048e60ada))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [1.5.6](https://github.com/OHIF/Viewers/compare/@ohif/extension-vtk@1.5.5...@ohif/extension-vtk@1.5.6) (2020-05-14)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-vtk
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ohif/extension-vtk",
|
||||
"version": "1.5.6",
|
||||
"version": "1.6.1",
|
||||
"description": "OHIF extension for VTK.js",
|
||||
"author": "OHIF",
|
||||
"license": "MIT",
|
||||
@ -53,8 +53,8 @@
|
||||
"react-vtkjs-viewport": "^0.9.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@ohif/core": "^2.9.6",
|
||||
"@ohif/ui": "^1.4.4",
|
||||
"@ohif/core": "^2.9.7",
|
||||
"@ohif/ui": "^1.5.0",
|
||||
"cornerstone-tools": "4.15.1",
|
||||
"cornerstone-wado-image-loader": "^3.1.0",
|
||||
"dicom-parser": "^1.8.3",
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import React from 'react';
|
||||
import asyncComponent from './asyncComponent.js';
|
||||
import commandsModule from './commandsModule.js';
|
||||
import toolbarModule from './toolbarModule.js';
|
||||
@ -16,7 +17,8 @@ const vtkExtension = {
|
||||
id: 'vtk',
|
||||
|
||||
getViewportModule({ commandsManager }) {
|
||||
return withCommandsManager(OHIFVTKViewport, commandsManager);
|
||||
const ExtendedVTKViewport = props => <OHIFVTKViewport {...props} />;
|
||||
return withCommandsManager(ExtendedVTKViewport, commandsManager);
|
||||
},
|
||||
getToolbarModule() {
|
||||
return toolbarModule;
|
||||
|
||||
@ -3,6 +3,14 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [2.9.7](https://github.com/OHIF/Viewers/compare/@ohif/core@2.9.6...@ohif/core@2.9.7) (2020-06-04)
|
||||
|
||||
**Note:** Version bump only for package @ohif/core
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [2.9.6](https://github.com/OHIF/Viewers/compare/@ohif/core@2.9.5...@ohif/core@2.9.6) (2020-05-14)
|
||||
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ohif/core",
|
||||
"version": "2.9.6",
|
||||
"version": "2.9.7",
|
||||
"description": "Generic business logic for web-based medical imaging applications",
|
||||
"author": "OHIF Core Team",
|
||||
"license": "MIT",
|
||||
|
||||
@ -13,7 +13,7 @@ const findMostRecentStructuredReport = studies => {
|
||||
// Skip series that may not have instances yet
|
||||
// This can happen if we have retrieved just the initial
|
||||
// details about the series via QIDO-RS, but not the full metadata
|
||||
if (!series.instances.length) {
|
||||
if (!series.instances || !series.instances.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@ -6,11 +6,12 @@ const defaultState = {
|
||||
|
||||
const servers = (state = defaultState, action) => {
|
||||
switch (action.type) {
|
||||
case 'SET_STUDY_DATA':
|
||||
const updatedStudyData = cloneDeep(state).studyData;
|
||||
updatedStudyData[action.StudyInstanceUID] = action.data;
|
||||
case 'SET_STUDY_DATA': {
|
||||
const updatedStudyData = cloneDeep(state.studyData);
|
||||
updatedStudyData[action.StudyInstanceUID] = cloneDeep(action.data);
|
||||
|
||||
return Object.assign({}, state, { studyData: updatedStudyData });
|
||||
}
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
|
||||
@ -3,6 +3,17 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [1.5.0](https://github.com/OHIF/Viewers/compare/@ohif/ui@1.4.4...@ohif/ui@1.5.0) (2020-06-04)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* 🎸 1729 - error boundary wrapper ([#1764](https://github.com/OHIF/Viewers/issues/1764)) ([c02b232](https://github.com/OHIF/Viewers/commit/c02b232b0cc24f38af5d5e3831d987d048e60ada))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [1.4.4](https://github.com/OHIF/Viewers/compare/@ohif/ui@1.4.3...@ohif/ui@1.4.4) (2020-05-04)
|
||||
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ohif/ui",
|
||||
"version": "1.4.4",
|
||||
"version": "1.5.0",
|
||||
"description": "A set of React components for Medical Imaging Viewers",
|
||||
"author": "OHIF Contributors",
|
||||
"license": "MIT",
|
||||
@ -53,6 +53,7 @@
|
||||
"react-dnd-html5-backend": "^9.4.0",
|
||||
"react-dnd-touch-backend": "^9.4.0",
|
||||
"react-draggable": "^4.1.0",
|
||||
"react-error-boundary": "^2.2.1",
|
||||
"react-i18next": "^10.11.0",
|
||||
"react-modal": "^3.11.1",
|
||||
"react-with-direction": "1.3.0"
|
||||
|
||||
51
platform/ui/src/components/errorBoundary/ErrorBoundary.js
Normal file
51
platform/ui/src/components/errorBoundary/ErrorBoundary.js
Normal file
@ -0,0 +1,51 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { ErrorBoundary } from 'react-error-boundary';
|
||||
import './ErrorFallback.css';
|
||||
|
||||
const ErrorFallback = ({ error, componentStack, resetErrorBoundary }) => {
|
||||
return (
|
||||
<div className="ErrorFallback" role="alert">
|
||||
<p>Something went wrong.</p>
|
||||
<pre>{error.message}</pre>
|
||||
<pre>{componentStack}</pre>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const OHIFErrorBoundary = ({
|
||||
context = 'OHIF',
|
||||
onReset = () => {},
|
||||
onError = () => {},
|
||||
fallbackComponent,
|
||||
children,
|
||||
}) => {
|
||||
const onErrorHandler = (error, componentStack) => {
|
||||
console.error(`${context} Error Boundary`, error, componentStack);
|
||||
onError(error, componentStack);
|
||||
};
|
||||
|
||||
const onResetHandler = () => {
|
||||
onReset();
|
||||
};
|
||||
|
||||
return (
|
||||
<ErrorBoundary
|
||||
FallbackComponent={fallbackComponent || ErrorFallback}
|
||||
onReset={onResetHandler}
|
||||
onError={onErrorHandler}
|
||||
>
|
||||
{children}
|
||||
</ErrorBoundary>
|
||||
);
|
||||
};
|
||||
|
||||
OHIFErrorBoundary.propTypes = {
|
||||
context: PropTypes.string,
|
||||
onReset: PropTypes.func,
|
||||
onError: PropTypes.func,
|
||||
children: PropTypes.node.isRequired,
|
||||
fallbackComponent: PropTypes.element,
|
||||
};
|
||||
|
||||
export default OHIFErrorBoundary;
|
||||
@ -0,0 +1,4 @@
|
||||
.ErrorFallback {
|
||||
padding: 10px;
|
||||
color: var(--active-color);
|
||||
}
|
||||
1
platform/ui/src/components/errorBoundary/index.js
Normal file
1
platform/ui/src/components/errorBoundary/index.js
Normal file
@ -0,0 +1 @@
|
||||
export { default as ErrorBoundary } from './ErrorBoundary';
|
||||
@ -7,7 +7,6 @@ import { AboutContent } from './content/aboutContent/AboutContent';
|
||||
import { TabComponents, TabFooter } from './tabComponents';
|
||||
import { HotkeyField } from './customForm';
|
||||
import { LanguageSwitcher } from './languageSwitcher';
|
||||
|
||||
import { Checkbox } from './checkbox';
|
||||
import { CineDialog } from './cineDialog';
|
||||
import { ViewportDownloadForm } from './content/viewportDownloadForm';
|
||||
@ -25,8 +24,10 @@ import {
|
||||
} from './studyList';
|
||||
import { ToolbarSection } from './toolbarSection';
|
||||
import { Tooltip } from './tooltip';
|
||||
import { ErrorBoundary } from './errorBoundary';
|
||||
|
||||
export {
|
||||
ErrorBoundary,
|
||||
ContextMenu,
|
||||
Checkbox,
|
||||
CineDialog,
|
||||
|
||||
@ -29,6 +29,7 @@ import {
|
||||
Tooltip,
|
||||
AboutContent,
|
||||
OHIFModal,
|
||||
ErrorBoundary
|
||||
} from './components';
|
||||
import { useDebounce, useMedia } from './hooks';
|
||||
|
||||
@ -123,6 +124,7 @@ export {
|
||||
DialogProvider,
|
||||
withDialog,
|
||||
useDialog,
|
||||
ErrorBoundary,
|
||||
// Hooks
|
||||
useDebounce,
|
||||
useMedia,
|
||||
|
||||
@ -3,6 +3,44 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [4.2.2](https://github.com/OHIF/Viewers/compare/@ohif/viewer@4.2.1...@ohif/viewer@4.2.2) (2020-06-04)
|
||||
|
||||
**Note:** Version bump only for package @ohif/viewer
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [4.2.1](https://github.com/OHIF/Viewers/compare/@ohif/viewer@4.2.0...@ohif/viewer@4.2.1) (2020-06-04)
|
||||
|
||||
**Note:** Version bump only for package @ohif/viewer
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [4.2.0](https://github.com/OHIF/Viewers/compare/@ohif/viewer@4.1.0...@ohif/viewer@4.2.0) (2020-06-04)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* 🎸 1729 - error boundary wrapper ([#1764](https://github.com/OHIF/Viewers/issues/1764)) ([c02b232](https://github.com/OHIF/Viewers/commit/c02b232b0cc24f38af5d5e3831d987d048e60ada))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [4.1.0](https://github.com/OHIF/Viewers/compare/@ohif/viewer@4.0.0...@ohif/viewer@4.1.0) (2020-05-15)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* expose some app internals as window.app ([#1735](https://github.com/OHIF/Viewers/issues/1735)) ([63fd656](https://github.com/OHIF/Viewers/commit/63fd65690cba450721870a6222e0fb3ad71bb291))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [4.0.0](https://github.com/OHIF/Viewers/compare/@ohif/viewer@3.11.11...@ohif/viewer@4.0.0) (2020-05-14)
|
||||
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
describe('OHIF Microscopy Extension', () => {
|
||||
before(() => {
|
||||
cy.openStudyModality('SM');
|
||||
cy.expectMinimumThumbnails(6);
|
||||
cy.expectMinimumThumbnails(2);
|
||||
});
|
||||
|
||||
it('checks if series thumbnails are being displayed', () => {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ohif/viewer",
|
||||
"version": "4.0.0",
|
||||
"version": "4.2.2",
|
||||
"description": "OHIF Viewer",
|
||||
"author": "OHIF Contributors",
|
||||
"license": "MIT",
|
||||
@ -48,18 +48,18 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.5.5",
|
||||
"@ohif/core": "^2.9.6",
|
||||
"@ohif/extension-cornerstone": "^2.7.3",
|
||||
"@ohif/core": "^2.9.7",
|
||||
"@ohif/extension-cornerstone": "^2.8.1",
|
||||
"@ohif/extension-dicom-html": "^1.2.2",
|
||||
"@ohif/extension-dicom-microscopy": "^0.50.9",
|
||||
"@ohif/extension-dicom-p10-downloader": "^0.1.0",
|
||||
"@ohif/extension-dicom-microscopy": "^0.51.0",
|
||||
"@ohif/extension-dicom-p10-downloader": "^0.1.1",
|
||||
"@ohif/extension-dicom-pdf": "^1.0.3",
|
||||
"@ohif/extension-dicom-rt": "^0.1.4",
|
||||
"@ohif/extension-dicom-segmentation": "^0.2.6",
|
||||
"@ohif/extension-dicom-rt": "^0.2.0",
|
||||
"@ohif/extension-dicom-segmentation": "^0.3.0",
|
||||
"@ohif/extension-lesion-tracker": "^0.2.0",
|
||||
"@ohif/extension-vtk": "^1.5.6",
|
||||
"@ohif/extension-vtk": "^1.6.1",
|
||||
"@ohif/i18n": "^0.52.8",
|
||||
"@ohif/ui": "^1.4.4",
|
||||
"@ohif/ui": "^1.5.0",
|
||||
"@tanem/react-nprogress": "^1.1.25",
|
||||
"classnames": "^2.2.6",
|
||||
"core-js": "^3.2.1",
|
||||
|
||||
@ -13,6 +13,7 @@ import {
|
||||
ModalProvider,
|
||||
DialogProvider,
|
||||
OHIFModal,
|
||||
ErrorBoundary
|
||||
} from '@ohif/ui';
|
||||
|
||||
import {
|
||||
@ -71,6 +72,14 @@ let extensionManager;
|
||||
// TODO[react] Use a provider when the whole tree is React
|
||||
window.store = store;
|
||||
|
||||
window.ohif = window.ohif || {};
|
||||
window.ohif.app = {
|
||||
commandsManager,
|
||||
hotkeysManager,
|
||||
servicesManager,
|
||||
extensionManager,
|
||||
};
|
||||
|
||||
class App extends Component {
|
||||
static propTypes = {
|
||||
config: PropTypes.oneOfType([
|
||||
@ -159,53 +168,57 @@ class App extends Component {
|
||||
|
||||
if (this._userManager) {
|
||||
return (
|
||||
<Provider store={store}>
|
||||
<AppProvider config={this._appConfig}>
|
||||
<I18nextProvider i18n={i18n}>
|
||||
<OidcProvider store={store} userManager={this._userManager}>
|
||||
<UserManagerContext.Provider value={this._userManager}>
|
||||
<Router basename={routerBasename}>
|
||||
<WhiteLabelingContext.Provider value={whiteLabeling}>
|
||||
<SnackbarProvider service={UINotificationService}>
|
||||
<DialogProvider service={UIDialogService}>
|
||||
<ModalProvider
|
||||
modal={OHIFModal}
|
||||
service={UIModalService}
|
||||
>
|
||||
<OHIFStandaloneViewer
|
||||
userManager={this._userManager}
|
||||
/>
|
||||
</ModalProvider>
|
||||
</DialogProvider>
|
||||
</SnackbarProvider>
|
||||
</WhiteLabelingContext.Provider>
|
||||
</Router>
|
||||
</UserManagerContext.Provider>
|
||||
</OidcProvider>
|
||||
</I18nextProvider>
|
||||
</AppProvider>
|
||||
</Provider>
|
||||
<ErrorBoundary context='App'>
|
||||
<Provider store={store}>
|
||||
<AppProvider config={this._appConfig}>
|
||||
<I18nextProvider i18n={i18n}>
|
||||
<OidcProvider store={store} userManager={this._userManager}>
|
||||
<UserManagerContext.Provider value={this._userManager}>
|
||||
<Router basename={routerBasename}>
|
||||
<WhiteLabelingContext.Provider value={whiteLabeling}>
|
||||
<SnackbarProvider service={UINotificationService}>
|
||||
<DialogProvider service={UIDialogService}>
|
||||
<ModalProvider
|
||||
modal={OHIFModal}
|
||||
service={UIModalService}
|
||||
>
|
||||
<OHIFStandaloneViewer
|
||||
userManager={this._userManager}
|
||||
/>
|
||||
</ModalProvider>
|
||||
</DialogProvider>
|
||||
</SnackbarProvider>
|
||||
</WhiteLabelingContext.Provider>
|
||||
</Router>
|
||||
</UserManagerContext.Provider>
|
||||
</OidcProvider>
|
||||
</I18nextProvider>
|
||||
</AppProvider>
|
||||
</Provider>
|
||||
</ErrorBoundary>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Provider store={store}>
|
||||
<AppProvider config={this._appConfig}>
|
||||
<I18nextProvider i18n={i18n}>
|
||||
<Router basename={routerBasename}>
|
||||
<WhiteLabelingContext.Provider value={whiteLabeling}>
|
||||
<SnackbarProvider service={UINotificationService}>
|
||||
<DialogProvider service={UIDialogService}>
|
||||
<ModalProvider modal={OHIFModal} service={UIModalService}>
|
||||
<OHIFStandaloneViewer />
|
||||
</ModalProvider>
|
||||
</DialogProvider>
|
||||
</SnackbarProvider>
|
||||
</WhiteLabelingContext.Provider>
|
||||
</Router>
|
||||
</I18nextProvider>
|
||||
</AppProvider>
|
||||
</Provider>
|
||||
<ErrorBoundary context='App'>
|
||||
<Provider store={store}>
|
||||
<AppProvider config={this._appConfig}>
|
||||
<I18nextProvider i18n={i18n}>
|
||||
<Router basename={routerBasename}>
|
||||
<WhiteLabelingContext.Provider value={whiteLabeling}>
|
||||
<SnackbarProvider service={UINotificationService}>
|
||||
<DialogProvider service={UIDialogService}>
|
||||
<ModalProvider modal={OHIFModal} service={UIModalService}>
|
||||
<OHIFStandaloneViewer />
|
||||
</ModalProvider>
|
||||
</DialogProvider>
|
||||
</SnackbarProvider>
|
||||
</WhiteLabelingContext.Provider>
|
||||
</Router>
|
||||
</I18nextProvider>
|
||||
</AppProvider>
|
||||
</Provider>
|
||||
</ErrorBoundary>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@ import { Route, Switch } from 'react-router-dom';
|
||||
import { NProgress } from '@tanem/react-nprogress';
|
||||
import { CSSTransition } from 'react-transition-group';
|
||||
import { connect } from 'react-redux';
|
||||
import { ViewerbaseDragDropContext } from '@ohif/ui';
|
||||
import { ViewerbaseDragDropContext, ErrorBoundary } from '@ohif/ui';
|
||||
import { SignoutCallbackComponent } from 'redux-oidc';
|
||||
import asyncComponent from './components/AsyncComponent.js';
|
||||
import * as RoutesUtil from './routes/routesUtil';
|
||||
@ -191,7 +191,9 @@ class OHIFStandaloneViewer extends Component {
|
||||
{match === null ? (
|
||||
<></>
|
||||
) : (
|
||||
<Component match={match} location={this.props.location} />
|
||||
<ErrorBoundary context={match.url}>
|
||||
<Component match={match} location={this.props.location} />
|
||||
</ErrorBoundary>
|
||||
)}
|
||||
</CSSTransition>
|
||||
)}
|
||||
|
||||
@ -0,0 +1,52 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { ErrorBoundary } from '@ohif/ui';
|
||||
import { servicesManager } from './../../App';
|
||||
|
||||
const { UIModalService } = servicesManager.services;
|
||||
|
||||
const ErrorBoundaryDialog = ({ context, children }) => {
|
||||
const handleOnError = (error, componentStack) => {
|
||||
const ErrorDialog = () => (
|
||||
<div className="ErrorFallback" role="alert">
|
||||
<div>
|
||||
<h3>
|
||||
{context}: <span>{error.message}</span>
|
||||
</h3>
|
||||
</div>
|
||||
<pre>{componentStack}</pre>
|
||||
</div>
|
||||
);
|
||||
|
||||
UIModalService.show({
|
||||
content: ErrorDialog,
|
||||
title: `${context}: ${error.message}`,
|
||||
});
|
||||
};
|
||||
|
||||
const fallbackComponent = () => (
|
||||
<div className="ErrorFallback" role="alert">
|
||||
<p>
|
||||
Error rendering {context}. <br /> Check the browser console for more
|
||||
details.
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
|
||||
return (
|
||||
<ErrorBoundary
|
||||
fallbackComponent={fallbackComponent}
|
||||
context={context}
|
||||
onError={handleOnError}
|
||||
>
|
||||
{children}
|
||||
</ErrorBoundary>
|
||||
);
|
||||
};
|
||||
|
||||
ErrorBoundaryDialog.propTypes = {
|
||||
context: PropTypes.string.isRequired,
|
||||
children: PropTypes.node.isRequired,
|
||||
};
|
||||
|
||||
export default ErrorBoundaryDialog;
|
||||
@ -0,0 +1,3 @@
|
||||
import ErrorBoundaryDialog from './ErrorBoundaryDialog';
|
||||
|
||||
export default ErrorBoundaryDialog;
|
||||
@ -12,7 +12,7 @@ import EmptyViewport from './EmptyViewport.js';
|
||||
|
||||
const { loadAndCacheDerivedDisplaySets } = utils;
|
||||
|
||||
const ViewportGrid = function (props) {
|
||||
const ViewportGrid = function(props) {
|
||||
const {
|
||||
activeViewportIndex,
|
||||
availablePlugins,
|
||||
@ -24,7 +24,7 @@ const ViewportGrid = function (props) {
|
||||
studies,
|
||||
viewportData,
|
||||
children,
|
||||
isStudyLoaded
|
||||
isStudyLoaded,
|
||||
} = props;
|
||||
|
||||
const rowSize = 100 / numRows;
|
||||
@ -54,7 +54,7 @@ const ViewportGrid = function (props) {
|
||||
});
|
||||
});
|
||||
}
|
||||
}, [studies, viewportData, isStudyLoaded]);
|
||||
}, [studies, viewportData, isStudyLoaded, snackbar]);
|
||||
|
||||
const getViewportPanes = () =>
|
||||
layout.viewports.map((layout, viewportIndex) => {
|
||||
|
||||
@ -4,7 +4,7 @@ import PropTypes from 'prop-types';
|
||||
import classNames from 'classnames';
|
||||
import './ViewportPane.css';
|
||||
|
||||
const ViewportPane = function(props) {
|
||||
const ViewportPane = function (props) {
|
||||
const { children, onDrop, viewportIndex, className: propClassName } = props;
|
||||
const [{ hovered, highlighted }, drop] = useDrop({
|
||||
accept: 'thumbnail',
|
||||
|
||||
@ -2,7 +2,7 @@ import { connect } from 'react-redux';
|
||||
import ViewerRetrieveStudyData from './ViewerRetrieveStudyData.js';
|
||||
import OHIF from '@ohif/core';
|
||||
|
||||
const { clearViewportSpecificData } = OHIF.redux.actions;
|
||||
const { clearViewportSpecificData, setStudyData } = OHIF.redux.actions;
|
||||
const isActive = a => a.active === true;
|
||||
|
||||
const mapStateToProps = (state, ownProps) => {
|
||||
@ -14,6 +14,9 @@ const mapStateToProps = (state, ownProps) => {
|
||||
};
|
||||
const mapDispatchToProps = dispatch => {
|
||||
return {
|
||||
setStudyData: (StudyInstanceUID, data) => {
|
||||
dispatch(setStudyData(StudyInstanceUID, data));
|
||||
},
|
||||
clearViewportSpecificData: () => {
|
||||
dispatch(clearViewportSpecificData());
|
||||
},
|
||||
|
||||
@ -2,8 +2,7 @@ import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import classNames from 'classnames';
|
||||
|
||||
import { MODULE_TYPES } from '@ohif/core';
|
||||
import OHIF, { DICOMSR } from '@ohif/core';
|
||||
import OHIF, { MODULE_TYPES, DICOMSR } from '@ohif/core';
|
||||
import { withDialog } from '@ohif/ui';
|
||||
import moment from 'moment';
|
||||
import ConnectedHeader from './ConnectedHeader.js';
|
||||
@ -11,6 +10,7 @@ import ToolbarRow from './ToolbarRow.js';
|
||||
import ConnectedStudyBrowser from './ConnectedStudyBrowser.js';
|
||||
import ConnectedViewerMain from './ConnectedViewerMain.js';
|
||||
import SidePanel from './../components/SidePanel.js';
|
||||
import ErrorBoundaryDialog from './../components/ErrorBoundaryDialog';
|
||||
import { extensionManager } from './../App.js';
|
||||
|
||||
// Contexts
|
||||
@ -26,6 +26,7 @@ class Viewer extends Component {
|
||||
PropTypes.shape({
|
||||
StudyInstanceUID: PropTypes.string.isRequired,
|
||||
StudyDate: PropTypes.string,
|
||||
PatientID: PropTypes.string,
|
||||
displaySets: PropTypes.arrayOf(
|
||||
PropTypes.shape({
|
||||
displaySetInstanceUID: PropTypes.string.isRequired,
|
||||
@ -256,42 +257,44 @@ class Viewer extends Component {
|
||||
</WhiteLabelingContext.Consumer>
|
||||
|
||||
{/* TOOLBAR */}
|
||||
<ToolbarRow
|
||||
isLeftSidePanelOpen={this.state.isLeftSidePanelOpen}
|
||||
isRightSidePanelOpen={this.state.isRightSidePanelOpen}
|
||||
selectedLeftSidePanel={
|
||||
this.state.isLeftSidePanelOpen
|
||||
? this.state.selectedLeftSidePanel
|
||||
: ''
|
||||
}
|
||||
selectedRightSidePanel={
|
||||
this.state.isRightSidePanelOpen
|
||||
? this.state.selectedRightSidePanel
|
||||
: ''
|
||||
}
|
||||
handleSidePanelChange={(side, selectedPanel) => {
|
||||
const sideClicked = side && side[0].toUpperCase() + side.slice(1);
|
||||
const openKey = `is${sideClicked}SidePanelOpen`;
|
||||
const selectedKey = `selected${sideClicked}SidePanel`;
|
||||
const updatedState = Object.assign({}, this.state);
|
||||
|
||||
const isOpen = updatedState[openKey];
|
||||
const prevSelectedPanel = updatedState[selectedKey];
|
||||
// RoundedButtonGroup returns `null` if selected button is clicked
|
||||
const isSameSelectedPanel =
|
||||
prevSelectedPanel === selectedPanel || selectedPanel === null;
|
||||
|
||||
updatedState[selectedKey] = selectedPanel || prevSelectedPanel;
|
||||
|
||||
const isClosedOrShouldClose = !isOpen || isSameSelectedPanel;
|
||||
if (isClosedOrShouldClose) {
|
||||
updatedState[openKey] = !updatedState[openKey];
|
||||
<ErrorBoundaryDialog context="ToolbarRow">
|
||||
<ToolbarRow
|
||||
isLeftSidePanelOpen={this.state.isLeftSidePanelOpen}
|
||||
isRightSidePanelOpen={this.state.isRightSidePanelOpen}
|
||||
selectedLeftSidePanel={
|
||||
this.state.isLeftSidePanelOpen
|
||||
? this.state.selectedLeftSidePanel
|
||||
: ''
|
||||
}
|
||||
selectedRightSidePanel={
|
||||
this.state.isRightSidePanelOpen
|
||||
? this.state.selectedRightSidePanel
|
||||
: ''
|
||||
}
|
||||
handleSidePanelChange={(side, selectedPanel) => {
|
||||
const sideClicked = side && side[0].toUpperCase() + side.slice(1);
|
||||
const openKey = `is${sideClicked}SidePanelOpen`;
|
||||
const selectedKey = `selected${sideClicked}SidePanel`;
|
||||
const updatedState = Object.assign({}, this.state);
|
||||
|
||||
this.setState(updatedState);
|
||||
}}
|
||||
studies={this.props.studies}
|
||||
/>
|
||||
const isOpen = updatedState[openKey];
|
||||
const prevSelectedPanel = updatedState[selectedKey];
|
||||
// RoundedButtonGroup returns `null` if selected button is clicked
|
||||
const isSameSelectedPanel =
|
||||
prevSelectedPanel === selectedPanel || selectedPanel === null;
|
||||
|
||||
updatedState[selectedKey] = selectedPanel || prevSelectedPanel;
|
||||
|
||||
const isClosedOrShouldClose = !isOpen || isSameSelectedPanel;
|
||||
if (isClosedOrShouldClose) {
|
||||
updatedState[openKey] = !updatedState[openKey];
|
||||
}
|
||||
|
||||
this.setState(updatedState);
|
||||
}}
|
||||
studies={this.props.studies}
|
||||
/>
|
||||
</ErrorBoundaryDialog>
|
||||
|
||||
{/*<ConnectedStudyLoadingMonitor studies={this.props.studies} />*/}
|
||||
{/*<StudyPrefetcher studies={this.props.studies} />*/}
|
||||
@ -299,37 +302,46 @@ class Viewer extends Component {
|
||||
{/* VIEWPORTS + SIDEPANELS */}
|
||||
<div className="FlexboxLayout">
|
||||
{/* LEFT */}
|
||||
<SidePanel from="left" isOpen={this.state.isLeftSidePanelOpen}>
|
||||
{VisiblePanelLeft ? (
|
||||
<VisiblePanelLeft
|
||||
viewports={this.props.viewports}
|
||||
studies={this.props.studies}
|
||||
activeIndex={this.props.activeViewportIndex}
|
||||
/>
|
||||
) : (
|
||||
<ErrorBoundaryDialog context="LeftSidePanel">
|
||||
<SidePanel from="left" isOpen={this.state.isLeftSidePanelOpen}>
|
||||
{VisiblePanelLeft ? (
|
||||
<VisiblePanelLeft
|
||||
viewports={this.props.viewports}
|
||||
studies={this.props.studies}
|
||||
activeIndex={this.props.activeViewportIndex}
|
||||
/>
|
||||
) : (
|
||||
<ConnectedStudyBrowser
|
||||
studies={this.state.thumbnails}
|
||||
studyMetadata={this.props.studies}
|
||||
/>
|
||||
)}
|
||||
</SidePanel>
|
||||
</SidePanel>
|
||||
</ErrorBoundaryDialog>
|
||||
|
||||
{/* MAIN */}
|
||||
<div className={classNames('main-content')}>
|
||||
<ConnectedViewerMain studies={this.props.studies} isStudyLoaded={this.props.isStudyLoaded} />
|
||||
<ErrorBoundaryDialog context="ViewerMain">
|
||||
<ConnectedViewerMain
|
||||
studies={this.props.studies}
|
||||
isStudyLoaded={this.props.isStudyLoaded}
|
||||
/>
|
||||
</ErrorBoundaryDialog>
|
||||
</div>
|
||||
|
||||
{/* RIGHT */}
|
||||
<SidePanel from="right" isOpen={this.state.isRightSidePanelOpen}>
|
||||
{VisiblePanelRight && (
|
||||
<VisiblePanelRight
|
||||
isOpen={this.state.isRightSidePanelOpen}
|
||||
viewports={this.props.viewports}
|
||||
studies={this.props.studies}
|
||||
activeIndex={this.props.activeViewportIndex}
|
||||
/>
|
||||
)}
|
||||
</SidePanel>
|
||||
<ErrorBoundaryDialog context="RightSidePanel">
|
||||
<SidePanel from="right" isOpen={this.state.isRightSidePanelOpen}>
|
||||
{VisiblePanelRight && (
|
||||
<VisiblePanelRight
|
||||
isOpen={this.state.isRightSidePanelOpen}
|
||||
viewports={this.props.viewports}
|
||||
studies={this.props.studies}
|
||||
activeIndex={this.props.activeViewportIndex}
|
||||
/>
|
||||
)}
|
||||
</SidePanel>
|
||||
</ErrorBoundaryDialog>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
@ -349,7 +361,7 @@ export default withDialog(Viewer);
|
||||
* @param {Study[]} studies
|
||||
* @param {DisplaySet[]} studies[].displaySets
|
||||
*/
|
||||
const _mapStudiesToThumbnails = function (studies) {
|
||||
const _mapStudiesToThumbnails = function(studies) {
|
||||
return studies.map(study => {
|
||||
const { StudyInstanceUID } = study;
|
||||
|
||||
|
||||
@ -154,11 +154,21 @@ const _sortStudyDisplaySet = (study, studyMetadata) => {
|
||||
studyMetadata.sortDisplaySets(study.displaySets);
|
||||
};
|
||||
|
||||
const _thinStudyData = study => {
|
||||
return {
|
||||
StudyInstanceUID: study.StudyInstanceUID,
|
||||
series: study.series.map(item => ({
|
||||
SeriesInstanceUID: item.SeriesInstanceUID
|
||||
})),
|
||||
}
|
||||
};
|
||||
|
||||
function ViewerRetrieveStudyData({
|
||||
server,
|
||||
studyInstanceUIDs,
|
||||
seriesInstanceUIDs,
|
||||
clearViewportSpecificData,
|
||||
setStudyData,
|
||||
}) {
|
||||
// hooks
|
||||
const [error, setError] = useState(false);
|
||||
@ -220,6 +230,7 @@ function ViewerRetrieveStudyData({
|
||||
if (Array.isArray(studiesData) && studiesData.length > 0) {
|
||||
// Map studies to new format, update metadata manager?
|
||||
const studies = studiesData.map(study => {
|
||||
setStudyData(study.StudyInstanceUID, _thinStudyData(study));
|
||||
const studyMetadata = new OHIFStudyMetadata(
|
||||
study,
|
||||
study.StudyInstanceUID
|
||||
@ -369,6 +380,7 @@ ViewerRetrieveStudyData.propTypes = {
|
||||
seriesInstanceUIDs: PropTypes.array,
|
||||
server: PropTypes.object,
|
||||
clearViewportSpecificData: PropTypes.func.isRequired,
|
||||
setStudyData: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
export default ViewerRetrieveStudyData;
|
||||
|
||||
17
yarn.lock
17
yarn.lock
@ -1247,7 +1247,7 @@
|
||||
pirates "^4.0.0"
|
||||
source-map-support "^0.5.9"
|
||||
|
||||
"@babel/runtime@7.1.2", "@babel/runtime@7.5.5", "@babel/runtime@7.6.0", "@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.2.0", "@babel/runtime@^7.3.1", "@babel/runtime@^7.4.0", "@babel/runtime@^7.4.2", "@babel/runtime@^7.4.4", "@babel/runtime@^7.4.5", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.0", "@babel/runtime@^7.6.3", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7":
|
||||
"@babel/runtime@7.1.2", "@babel/runtime@7.5.5", "@babel/runtime@7.6.0", "@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.2.0", "@babel/runtime@^7.3.1", "@babel/runtime@^7.4.0", "@babel/runtime@^7.4.2", "@babel/runtime@^7.4.4", "@babel/runtime@^7.4.5", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.0", "@babel/runtime@^7.6.3", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.6":
|
||||
version "7.5.5"
|
||||
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.5.5.tgz#74fba56d35efbeca444091c7850ccd494fd2f132"
|
||||
integrity sha512-28QvEGyQyNkB0/m2B4FU7IEZGK2NUrcMtT6BZEFALTguLk+AUT6ofsHtPk5QyjAdUkpMJ+/Em+quwz4HOt30AQ==
|
||||
@ -15603,10 +15603,10 @@ react-codemirror2@^6.0.0:
|
||||
resolved "https://registry.yarnpkg.com/react-codemirror2/-/react-codemirror2-6.0.0.tgz#180065df57a64026026cde569a9708fdf7656525"
|
||||
integrity sha512-D7y9qZ05FbUh9blqECaJMdDwKluQiO3A9xB+fssd5jKM7YAXucRuEOlX32mJQumUvHUkHRHqXIPBjm6g0FW0Ag==
|
||||
|
||||
react-cornerstone-viewport@2.3.8:
|
||||
version "2.3.8"
|
||||
resolved "https://registry.yarnpkg.com/react-cornerstone-viewport/-/react-cornerstone-viewport-2.3.8.tgz#7af8360f29bca986ae4e36b4e503269b88ddc52f"
|
||||
integrity sha512-aiG2uVNrDY6SQx4t/HBxIA3zsMsCwT+6TpcXK9qSSoXhs+X6OTmYEKncWUqL0jtxU1yfh6JTUz8ARTg03gtF+A==
|
||||
react-cornerstone-viewport@2.3.9:
|
||||
version "2.3.9"
|
||||
resolved "https://registry.yarnpkg.com/react-cornerstone-viewport/-/react-cornerstone-viewport-2.3.9.tgz#f9761da8e536f0a217137c6ca1a983f5882249f9"
|
||||
integrity sha512-qrhq8CbX/jq6b93cQjV2qC/mhHOvFBpxzxcHlvHzEQZt/rmRMcaYxCqjpNaNbUmmBu61wNkxesUVsggkPTTcqg==
|
||||
dependencies:
|
||||
classnames "^2.2.6"
|
||||
date-fns "^2.2.1"
|
||||
@ -15796,6 +15796,13 @@ react-dropzone@^10.1.7:
|
||||
file-selector "^0.1.11"
|
||||
prop-types "^15.7.2"
|
||||
|
||||
react-error-boundary@^2.2.1:
|
||||
version "2.2.1"
|
||||
resolved "https://registry.yarnpkg.com/react-error-boundary/-/react-error-boundary-2.2.1.tgz#32ed74386a90482060cc2fea948bb7135465c4cb"
|
||||
integrity sha512-8SZMkJRFUb0JuluHKwuUtkh5vvVWBg3O/bJIWgNMhMJv529aG//TmcphR3cSMhCWjz1vFZDb4taJd6pmwP5mEQ==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.9.6"
|
||||
|
||||
react-error-overlay@^4.0.1:
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-4.0.1.tgz#417addb0814a90f3a7082eacba7cee588d00da89"
|
||||
|
||||
Loading…
Reference in New Issue
Block a user