Merge branch 'master' into IDC-1801

This commit is contained in:
Igor Octaviano 2021-01-21 09:31:17 -03:00 committed by GitHub
commit 0f736bd294
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 135 additions and 53 deletions

View File

@ -72,7 +72,7 @@ class OHIFVTKViewport extends Component {
}; };
static defaultProps = { static defaultProps = {
onScroll: () => { }, onScroll: () => {},
}; };
static id = 'OHIFVTKViewport'; static id = 'OHIFVTKViewport';
@ -138,6 +138,8 @@ class OHIFVTKViewport extends Component {
SOPInstanceUID, SOPInstanceUID,
frameIndex frameIndex
) => { ) => {
const { UINotificationService } = this.props.servicesManager.services;
const stack = OHIFVTKViewport.getCornerstoneStack( const stack = OHIFVTKViewport.getCornerstoneStack(
studies, studies,
StudyInstanceUID, StudyInstanceUID,
@ -159,11 +161,14 @@ class OHIFVTKViewport extends Component {
const { activeLabelmapIndex } = brushStackState; const { activeLabelmapIndex } = brushStackState;
const labelmap3D = brushStackState.labelmaps3D[activeLabelmapIndex]; const labelmap3D = brushStackState.labelmaps3D[activeLabelmapIndex];
if (brushStackState.labelmaps3D.length > 1 && this.props.viewportIndex === 0) { if (
const { UINotificationService } = this.props.servicesManager.services; brushStackState.labelmaps3D.length > 1 &&
this.props.viewportIndex === 0
) {
UINotificationService.show({ UINotificationService.show({
title: 'Overlapping Segmentation Found', title: 'Overlapping Segmentation Found',
message: 'Overlapping segmentations cannot be displayed when in MPR mode', message:
'Overlapping segmentations cannot be displayed when in MPR mode',
type: 'info', type: 'info',
}); });
} }
@ -305,52 +310,79 @@ class OHIFVTKViewport extends Component {
seriesDescription: displaySet.seriesDescription, seriesDescription: displaySet.seriesDescription,
}; };
const { try {
imageDataObject, const {
labelmapDataObject, imageDataObject,
labelmapColorLUT, labelmapDataObject,
} = this.getViewportData( labelmapColorLUT,
studies, } = this.getViewportData(
StudyInstanceUID, studies,
displaySetInstanceUID, StudyInstanceUID,
SOPInstanceUID, displaySetInstanceUID,
frameIndex SOPInstanceUID,
); frameIndex
);
this.imageDataObject = imageDataObject; this.imageDataObject = imageDataObject;
/* TODO: Not currently used until we have drawing tools in vtkjs. /* TODO: Not currently used until we have drawing tools in vtkjs.
if (!labelmap) { if (!labelmap) {
labelmap = createLabelMapImageData(data); labelmap = createLabelMapImageData(data);
} */ } */
const volumeActor = this.getOrCreateVolume( const volumeActor = this.getOrCreateVolume(
imageDataObject, imageDataObject,
displaySetInstanceUID displaySetInstanceUID
); );
this.setState( this.setState(
{ {
percentComplete: 0, percentComplete: 0,
dataDetails, dataDetails,
}, },
() => { () => {
this.loadProgressively(imageDataObject); this.loadProgressively(imageDataObject);
// TODO: There must be a better way to do this. // TODO: There must be a better way to do this.
// We do this so that if all the data is available the react-vtkjs-viewport // We do this so that if all the data is available the react-vtkjs-viewport
// Will render _something_ before the volumes are set and the volume // Will render _something_ before the volumes are set and the volume
// Construction that happens in react-vtkjs-viewport locks up the CPU. // Construction that happens in react-vtkjs-viewport locks up the CPU.
setTimeout(() => { setTimeout(() => {
this.setState({ this.setState({
volumes: [volumeActor], volumes: [volumeActor],
paintFilterLabelMapImageData: labelmapDataObject, paintFilterLabelMapImageData: labelmapDataObject,
paintFilterBackgroundImageData: imageDataObject.vtkImageData, paintFilterBackgroundImageData: imageDataObject.vtkImageData,
labelmapColorLUT, labelmapColorLUT,
}); });
}, 200); }, 200);
}
);
} catch (error) {
const errorTitle = 'Failed to load 2D MPR';
console.error(errorTitle, error);
const { UINotificationService } = this.props.servicesManager.services;
if (this.props.viewportIndex === 0) {
const message = error.message.includes('buffer')
? 'Dataset is too big to display in MPR'
: error.message;
console.error(errorTitle, error);
UINotificationService.show({
title: errorTitle,
message,
type: 'error',
autoClose: false,
action: {
label: 'Exit 2D MPR',
onClick: ({ close }) => {
// context: 'ACTIVE_VIEWPORT::VTK',
close();
this.props.commandsManager.runCommand('setCornerstoneLayout');
},
},
});
} }
); this.setState({ isLoaded: true });
}
} }
componentDidMount() { componentDidMount() {
@ -363,7 +395,7 @@ class OHIFVTKViewport extends Component {
if ( if (
displaySet.displaySetInstanceUID !== displaySet.displaySetInstanceUID !==
prevDisplaySet.displaySetInstanceUID || prevDisplaySet.displaySetInstanceUID ||
displaySet.SOPInstanceUID !== prevDisplaySet.SOPInstanceUID || displaySet.SOPInstanceUID !== prevDisplaySet.SOPInstanceUID ||
displaySet.frameIndex !== prevDisplaySet.frameIndex displaySet.frameIndex !== prevDisplaySet.frameIndex
) { ) {

View File

@ -9,7 +9,9 @@ import { version } from '../package.json';
// import loadLocales from './loadLocales'; // import loadLocales from './loadLocales';
const OHIFVTKViewport = asyncComponent(() => const OHIFVTKViewport = asyncComponent(() =>
retryImport(() => import(/* webpackChunkName: "OHIFVTKViewport" */ './OHIFVTKViewport.js')) retryImport(() =>
import(/* webpackChunkName: "OHIFVTKViewport" */ './OHIFVTKViewport.js')
)
); );
const vtkExtension = { const vtkExtension = {
@ -21,7 +23,11 @@ const vtkExtension = {
getViewportModule({ commandsManager, servicesManager }) { getViewportModule({ commandsManager, servicesManager }) {
const ExtendedVTKViewport = props => ( const ExtendedVTKViewport = props => (
<OHIFVTKViewport {...props} servicesManager={servicesManager} /> <OHIFVTKViewport
{...props}
servicesManager={servicesManager}
commandsManager={commandsManager}
/>
); );
return withCommandsManager(ExtendedVTKViewport, commandsManager); return withCommandsManager(ExtendedVTKViewport, commandsManager);
}, },

View File

@ -8,6 +8,7 @@
* @property {string} [position="bottomRight"] -"topLeft" | "topCenter | "topRight" | "bottomLeft" | "bottomCenter" | "bottomRight" * @property {string} [position="bottomRight"] -"topLeft" | "topCenter | "topRight" | "bottomLeft" | "bottomCenter" | "bottomRight"
* @property {string} [type="info"] - "info" | "error" | "warning" | "success" * @property {string} [type="info"] - "info" | "error" | "warning" | "success"
* @property {boolean} [autoClose=true] * @property {boolean} [autoClose=true]
* @property {object} [action=null]
*/ */
const name = 'UINotificationService'; const name = 'UINotificationService';
@ -34,7 +35,7 @@ const serviceImplementation = {
* Create and show a new UI notification; returns the * Create and show a new UI notification; returns the
* ID of the created notification. * ID of the created notification.
* *
* @param {Notification} notification { title, message, duration, position, type, autoClose} * @param {Notification} notification { title, message, duration, position, type, autoClose, action}
* @returns {number} id * @returns {number} id
*/ */
function _show({ function _show({
@ -44,6 +45,7 @@ function _show({
position = 'bottomRight', position = 'bottomRight',
type = 'info', type = 'info',
autoClose = true, autoClose = true,
action = null,
}) { }) {
return serviceImplementation._show({ return serviceImplementation._show({
title, title,
@ -52,6 +54,7 @@ function _show({
position, position,
type, type,
autoClose, autoClose,
action,
}); });
} }

View File

@ -156,19 +156,50 @@
transition: all 300ms ease; transition: all 300ms ease;
} }
.sb-success { .sb-item .sb-action,
.sb-error .sb-action,
.sb-warning .sb-action,
.sb-info .sb-action,
.sb-success .sb-action {
margin-top: 10px;
display: inline-block;
padding: 6px 12px;
margin-bottom: 0;
font-size: 14px;
font-weight: 400;
line-height: 1.42857143;
text-align: center;
white-space: nowrap;
vertical-align: middle;
-ms-touch-action: manipulation;
touch-action: manipulation;
cursor: pointer;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
background-image: none;
border: none;
color: white;
}
.sb-success,
.sb-success .sb-action {
background-color: var(--snackbar-success); background-color: var(--snackbar-success);
} }
.sb-error { .sb-error,
.sb-error .sb-action {
background-color: var(--snackbar-error); background-color: var(--snackbar-error);
} }
.sb-warning { .sb-warning,
.sb-warning .sb-action {
background-color: var(--snackbar-warning); background-color: var(--snackbar-warning);
} }
.sb-info { .sb-info,
.sb-info .sb-action {
background-color: var(--snackbar-info); background-color: var(--snackbar-info);
} }

View File

@ -1,10 +1,14 @@
import React, { useState, useEffect } from 'react'; import React, { useEffect } from 'react';
const SnackbarItem = ({ options, onClose }) => { const SnackbarItem = ({ options, onClose }) => {
const handleClose = () => { const handleClose = () => {
onClose(options.id); onClose(options.id);
}; };
const handleClick = () => {
options.action.onClick({ ...options, close: handleClose });
};
useEffect(() => { useEffect(() => {
if (options.autoClose) { if (options.autoClose) {
setTimeout(() => { setTimeout(() => {
@ -24,6 +28,11 @@ const SnackbarItem = ({ options, onClose }) => {
</span> </span>
{options.title && <div className="sb-title">{options.title}</div>} {options.title && <div className="sb-title">{options.title}</div>}
{options.message && <div className="sb-message">{options.message}</div>} {options.message && <div className="sb-message">{options.message}</div>}
{options.action && (
<button className="sb-action" onClick={handleClick}>
{options.action.label}
</button>
)}
</div> </div>
); );
}; };

View File

@ -22,6 +22,7 @@ const SnackbarProvider = ({ children, service }) => {
autoClose: true, autoClose: true,
position: 'bottomRight', position: 'bottomRight',
type: SnackbarTypes.INFO, type: SnackbarTypes.INFO,
action: null,
}; };
const [count, setCount] = useState(1); const [count, setCount] = useState(1);