Segmentation UI for VTKjs (#1685)

* Add single viewport configuration

* Multiple viewport configuration

* Improve performance by using independent set methods

* Add jump to slice command

* Add context configuration

* Cache panel visibility

* Fix sync between vtk and cornerstone

* Remove apis index

* Add approach

* Add loading to update volumes

* Fix broken configuration

* Bump vtk version

* Use loading label

* Update cy tests after vtk loading label changed

* Remove loading for segs
This commit is contained in:
Igor Octaviano authored and GitHub committed 2020-05-06 19:17:44 +02:00
1 parent 19a8e71317
commit 42c22df1b6
22 files changed
+516 -173

No files matched your search

@@ -21,8 +21,8 @@ describe('OHIF VTK Extension', () => {
//Select 2D MPR button
cy.get('[data-cy="2d mpr"]').click();
//Wait Reformatting Images
cy.waitVTKReformatting();
//Wait waitVTKLoading Images
cy.waitVTKLoading();
});
beforeEach(() => {
@@ -18,8 +18,8 @@ describe('Visual Regression - OHIF VTK Extension', () => {
//Select 2D MPR button
cy.get('[data-cy="2d mpr"]').click();
//Wait Reformatting Images
cy.waitVTKReformatting();
//Wait waitVTKLoading Images
cy.waitVTKwaitVTKLoading();
});
beforeEach(() => {
+5 -5
View File
@@ -107,15 +107,15 @@ Cypress.Commands.add('waitStudyList', () => {
});
});
Cypress.Commands.add('waitVTKReformatting', () => {
// Wait for start reformatting
Cypress.Commands.add('waitVTKLoading', () => {
// Wait for start loading
cy.get('[data-cy="viewprt-grid"]', { timeout: 10000 }).should($grid => {
expect($grid).to.contain.text('Reform');
expect($grid).to.contain.text('Loading');
});
// Wait for finish reformatting
// Wait for finish loading
cy.get('[data-cy="viewprt-grid"]', { timeout: 30000 }).should($grid => {
expect($grid).not.to.contain.text('Reform');
expect($grid).not.to.contain.text('Loading');
});
});
+15 -9
View File
@@ -53,7 +53,7 @@ import store from './store';
/** Contexts */
import WhiteLabelingContext from './context/WhiteLabelingContext';
import UserManagerContext from './context/UserManagerContext';
import AppContext from './context/AppContext';
import { AppProvider, useAppContext, CONTEXTS } from './context/AppContext';
/** ~~~~~~~~~~~~~ Application Setup */
const commandsManagerConfig = {
@@ -159,8 +159,8 @@ class App extends Component {
if (this._userManager) {
return (
<AppContext.Provider value={{ appConfig: this._appConfig }}>
<Provider store={store}>
<Provider store={store}>
<AppProvider config={this._appConfig}>
<I18nextProvider i18n={i18n}>
<OidcProvider store={store} userManager={this._userManager}>
<UserManagerContext.Provider value={this._userManager}>
@@ -183,14 +183,14 @@ class App extends Component {
</UserManagerContext.Provider>
</OidcProvider>
</I18nextProvider>
</Provider>
</AppContext.Provider>
</AppProvider>
</Provider>
);
}
return (
<AppContext.Provider value={{ appConfig: this._appConfig }}>
<Provider store={store}>
<Provider store={store}>
<AppProvider config={this._appConfig}>
<I18nextProvider i18n={i18n}>
<Router basename={routerBasename}>
<WhiteLabelingContext.Provider value={whiteLabeling}>
@@ -204,8 +204,8 @@ class App extends Component {
</WhiteLabelingContext.Provider>
</Router>
</I18nextProvider>
</Provider>
</AppContext.Provider>
</AppProvider>
</Provider>
);
}
@@ -255,6 +255,12 @@ function _initExtensions(extensions, cornerstoneExtensionConfig, appConfig) {
commandsManager,
servicesManager,
appConfig,
api: {
contexts: CONTEXTS,
hooks: {
useAppContext
}
}
});
const requiredExtensions = [
+2 -2
View File
@@ -191,8 +191,8 @@ class OHIFStandaloneViewer extends Component {
{match === null ? (
<></>
) : (
<Component match={match} location={this.props.location} />
)}
<Component match={match} location={this.props.location} />
)}
</CSSTransition>
)}
</Route>
@@ -1,15 +0,0 @@
// TODO: REPLACE THIS WITH A CONTEXT PROVIDER
// EVERYTHING IN `VIEWER.JS` COULD USE THIS FOR APPROPRIATE CONTEXT
import ToolbarRow from './ToolbarRow';
import { connect } from 'react-redux';
import { getActiveContexts } from './../store/layout/selectors.js';
const mapStateToProps = state => {
return {
activeContexts: getActiveContexts(state),
};
};
const ConnectedToolbarRow = connect(mapStateToProps)(ToolbarRow);
export default ConnectedToolbarRow;
@@ -16,6 +16,7 @@ import { commandsManager, extensionManager } from './../App.js';
import ConnectedCineDialog from './ConnectedCineDialog';
import ConnectedLayoutButton from './ConnectedLayoutButton';
import { withAppContext } from '../context/AppContext';
class ToolbarRow extends Component {
// TODO: Simplify these? isOpen can be computed if we say "any" value for selected,
@@ -381,5 +382,5 @@ function _handleBuiltIn(button) {
}
export default withTranslation(['Common', 'ViewportDownloadForm'])(
withModal(withDialog(ToolbarRow))
withModal(withDialog(withAppContext(ToolbarRow)))
);
@@ -7,7 +7,7 @@ import OHIF, { DICOMSR } from '@ohif/core';
import { withDialog } from '@ohif/ui';
import moment from 'moment';
import ConnectedHeader from './ConnectedHeader.js';
import ConnectedToolbarRow from './ConnectedToolbarRow.js';
import ToolbarRow from './ToolbarRow.js';
import ConnectedStudyBrowser from './ConnectedStudyBrowser.js';
import ConnectedViewerMain from './ConnectedViewerMain.js';
import SidePanel from './../components/SidePanel.js';
@@ -256,7 +256,7 @@ class Viewer extends Component {
</WhiteLabelingContext.Consumer>
{/* TOOLBAR */}
<ConnectedToolbarRow
<ToolbarRow
isLeftSidePanelOpen={this.state.isLeftSidePanelOpen}
isRightSidePanelOpen={this.state.isRightSidePanelOpen}
selectedLeftSidePanel={
@@ -307,11 +307,11 @@ class Viewer extends Component {
activeIndex={this.props.activeViewportIndex}
/>
) : (
<ConnectedStudyBrowser
studies={this.state.thumbnails}
studyMetadata={this.props.studies}
/>
)}
<ConnectedStudyBrowser
studies={this.state.thumbnails}
studyMetadata={this.props.studies}
/>
)}
</SidePanel>
{/* MAIN */}
@@ -349,7 +349,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;
+29 -1
View File
@@ -1,5 +1,33 @@
import React from 'react';
import React, { useContext } from 'react';
import { useSelector } from 'react-redux';
import { getActiveContexts } from '../store/layout/selectors.js';
let AppContext = React.createContext({});
export const CONTEXTS = {
CORNERSTONE: 'ACTIVE_VIEWPORT::CORNERSTONE',
VTK: 'ACTIVE_VIEWPORT::VTK'
};
export const useAppContext = () => useContext(AppContext);
export const AppProvider = ({ children, config }) => {
const activeContexts = useSelector(state => getActiveContexts(state));
return (
<AppContext.Provider value={{ appConfig: config, activeContexts }}>
{children}
</AppContext.Provider>
);
};
export const withAppContext = Component => {
return function WrappedComponent(props) {
const { appConfig, activeContexts } = useAppContext();
return (
<Component {...props} appConfig={appConfig} activeContexts={activeContexts} />
);
};
};
export default AppContext;