Files
ohif-viewer/platform/viewer/src/connectedComponents/ViewerMain.js
T
Igor Octaviano 55a580659e feat!: Ability to configure cornerstone tools via extension configuration (#1229)
* Fix ExtensionManager bug and add test to bandaid

* Add tools configuration to extension manager preinit

* Fix reducing of configs

* Merge internal with external configs

* Merge internal with external configs

* Remove dialog from init in measurementstable

* Testing injected configuration

* New way to set config

* Add new prop to dialog provider to allow disabling last position

* Remove code from preinit in cornerstone

* Add new prop to dialog provider to allow disabling last position

* Add centralize to dialogs

* Reorder dialogs when adding them

* Fix draggable styles (cursor)

* Remove repositioning methods from labelling flow and remove overlay from labelling manager

* Fix empty array being set in bringToFront

* Add new command to update table and pass commands manager to modules/preinit hook

* Ad UIContextMenu service / factory

* Use new contextmenu service in measurementspanel extension

* Use dialogs for arrow annotate in default

* Remove positioning funcionality from tool context menu

* Add context menu service

* Pass commandsModule to extension

* Update edit description dialog and simple dialog to position relative

* Remove style code from labelling flow and manager

* Remove eventdata from labelling

* Remove labelling code from measurement init

* Add commandsmanager to provider

* Update contextmenu provider and service

* Add touchstart and mouseclick to hide contextmenu

* Hide labelling if click/touch

* Remove labelling and context menu dead code

* Fix undefined bug if ViewerMain grid has no children

* Fix broken prop on context menu

* Update commandsmodule based on master

* Fix broken configuration

* Update script tag config

* Remove cornerstone from toolcontextmenu

* Remove cornerstone from toolcontextmenu

* Split labelling and context menu providers

* Split labelling and context menu providers

* Update test

* Destructure extensions into new array

* CR Update: Move default arrow config to cornerstone instead of default

* CR Update: Fix app configuration props structure

* CR Update: Fix app configuration prop in script tag and extract commands manager from providers

* CR Update: Create custom providers to use commandsManager

* CR Update: Use services directly in measurementspanel

* CR Update: Pass components to providers

* CR Update: Remove position from dialog

* CR Update: fix dialog prop check

* CR Update: Fix comments

* CR Update: Update documentation

* CR Update: Add test default configuration

* CR Update: Add default empy array to extensions

* CR Update: Update i18n configuration all ot match current function configuration

* CR Update: Add defaults to injected dependencies in configuration and extension configuration

* CR Update: Add defaults to configuration with no args

* Update documentation

* CR Update: Add default for tools

* CR Update: Update config object to i18n

* CR Update: spread defaults

* CR Update: Add tool configuration example to cornerstone extension

* CR Update: Add tool configuration to netlify (testing)

* CR Update: Remove netlify config for tools

* CR Update: Rollback changes to i18n to be fixed later

* CR Update: Update documentation and pass whole cornerstone config object instead of tools key

SEE: https://www.conventionalcommits.org/en/v1.0.0/#commit-message-with-both-and-breaking-change-footer

BREAKING CHANGE: modifies the exposed react <App /> components props. The contract for providing configuration for the app has changed. Please reference updated documentation for guidance.
2019-12-09 12:47:23 -05:00

190 lines
5.3 KiB
JavaScript

import './ViewerMain.css';
import { Component } from 'react';
import { ConnectedViewportGrid } from './../components/ViewportGrid/index.js';
import PropTypes from 'prop-types';
import React from 'react';
class ViewerMain extends Component {
static propTypes = {
activeViewportIndex: PropTypes.number.isRequired,
studies: PropTypes.array,
viewportSpecificData: PropTypes.object.isRequired,
layout: PropTypes.object.isRequired,
setViewportSpecificData: PropTypes.func.isRequired,
clearViewportSpecificData: PropTypes.func.isRequired,
};
constructor(props) {
super(props);
this.state = {
displaySets: [],
};
}
getDisplaySets(studies) {
const displaySets = [];
studies.forEach(study => {
study.displaySets.forEach(dSet => {
if (!dSet.plugin) {
dSet.plugin = 'cornerstone';
}
displaySets.push(dSet);
});
});
return displaySets;
}
findDisplaySet(studies, studyInstanceUid, displaySetInstanceUid) {
const study = studies.find(study => {
return study.studyInstanceUid === studyInstanceUid;
});
if (!study) {
return;
}
return study.displaySets.find(displaySet => {
return displaySet.displaySetInstanceUid === displaySetInstanceUid;
});
}
componentDidMount() {
// Add beforeUnload event handler to check for unsaved changes
//window.addEventListener('beforeunload', unloadHandlers.beforeUnload);
// Get all the display sets for the viewer studies
if (this.props.studies) {
const displaySets = this.getDisplaySets(this.props.studies);
this.setState({ displaySets }, this.fillEmptyViewportPanes);
}
}
componentDidUpdate(prevProps) {
const prevViewportAmount = prevProps.layout.viewports.length;
const viewportAmount = this.props.layout.viewports.length;
const isVtk = this.props.layout.viewports.some(vp => !!vp.vtk);
if (
this.props.studies !== prevProps.studies ||
(viewportAmount !== prevViewportAmount && !isVtk)
) {
const displaySets = this.getDisplaySets(this.props.studies);
this.setState({ displaySets }, this.fillEmptyViewportPanes);
}
}
fillEmptyViewportPanes = () => {
const dirtyViewportPanes = [];
const { layout, viewportSpecificData } = this.props;
const { displaySets } = this.state;
if (!displaySets || !displaySets.length) {
return;
}
for (let i = 0; i < layout.viewports.length; i++) {
const viewportPane = viewportSpecificData[i];
const isNonEmptyViewport =
viewportPane &&
viewportPane.studyInstanceUid &&
viewportPane.displaySetInstanceUid;
if (isNonEmptyViewport) {
dirtyViewportPanes.push({
studyInstanceUid: viewportPane.studyInstanceUid,
displaySetInstanceUid: viewportPane.displaySetInstanceUid,
});
continue;
}
const foundDisplaySet =
displaySets.find(
ds =>
!dirtyViewportPanes.some(
v => v.displaySetInstanceUid === ds.displaySetInstanceUid
)
) || displaySets[displaySets.length - 1];
dirtyViewportPanes.push(foundDisplaySet);
}
dirtyViewportPanes.forEach((vp, i) => {
if (vp && vp.studyInstanceUid) {
this.setViewportData({
viewportIndex: i,
studyInstanceUid: vp.studyInstanceUid,
displaySetInstanceUid: vp.displaySetInstanceUid,
});
}
});
};
setViewportData = ({
viewportIndex,
studyInstanceUid,
displaySetInstanceUid,
}) => {
const displaySet = this.findDisplaySet(
this.props.studies,
studyInstanceUid,
displaySetInstanceUid
);
this.props.setViewportSpecificData(viewportIndex, displaySet);
};
render() {
const { viewportSpecificData } = this.props;
const viewportData = viewportSpecificData
? Object.values(viewportSpecificData)
: [];
return (
<div className="ViewerMain">
{this.state.displaySets.length && (
<ConnectedViewportGrid
studies={this.props.studies}
viewportData={viewportData}
setViewportData={this.setViewportData}
>
{/* Children to add to each viewport that support children */}
</ConnectedViewportGrid>
)}
</div>
);
}
componentWillUnmount() {
// Clear the entire viewport specific data
const { viewportSpecificData } = this.props;
Object.keys(viewportSpecificData).forEach(viewportIndex => {
this.props.clearViewportSpecificData(viewportIndex);
});
// TODO: These don't have to be viewer specific?
// Could qualify for other routes?
// hotkeys.destroy();
// Remove beforeUnload event handler...
//window.removeEventListener('beforeunload', unloadHandlers.beforeUnload);
// Destroy the synchronizer used to update reference lines
//OHIF.viewer.updateImageSynchronizer.destroy();
// TODO: Instruct all plugins to clean up themselves
//
// Clear references to all stacks in the StackManager
//StackManager.clearStacks();
// @TypeSafeStudies
// Clears OHIF.viewer.Studies collection
//OHIF.viewer.Studies.removeAll();
// @TypeSafeStudies
// Clears OHIF.viewer.StudyMetadataList collection
//OHIF.viewer.StudyMetadataList.removeAll();
}
}
export default ViewerMain;