From 13c8599f068e504103af1856b47aee736ee2eec4 Mon Sep 17 00:00:00 2001 From: Evren Ozkan Date: Mon, 4 Feb 2019 20:46:15 -0500 Subject: [PATCH] feat(react-measurements): Integrate Timepoint API and Measurement API from ohif-core package - WIP --- Packages-react/ohif-viewer/src/App.js | 2 + .../ConnectedMeasurementTable.js | 4 +- .../connectedComponents/ConnectedViewer.js | 21 +++ .../src/connectedComponents/FlexboxLayout.js | 2 +- .../src/connectedComponents/Viewer.js | 177 +++++++++--------- .../ViewerRetrieveStudyData.js | 6 +- .../ohif-viewer/src/redux/actions.js | 14 +- .../ohif-viewer/src/redux/timepointManager.js | 17 ++ 8 files changed, 153 insertions(+), 90 deletions(-) create mode 100644 Packages-react/ohif-viewer/src/connectedComponents/ConnectedViewer.js create mode 100644 Packages-react/ohif-viewer/src/redux/timepointManager.js diff --git a/Packages-react/ohif-viewer/src/App.js b/Packages-react/ohif-viewer/src/App.js index 134c91a3e..e91486965 100644 --- a/Packages-react/ohif-viewer/src/App.js +++ b/Packages-react/ohif-viewer/src/App.js @@ -18,6 +18,7 @@ import { createUserManager, reducer as oidcReducer } from 'redux-oidc'; +import timepointManager from './redux/timepointManager'; import cornerstoneWADOImageLoader from 'cornerstone-wado-image-loader'; import './App.css'; @@ -29,6 +30,7 @@ const Icons = '/icons.svg'; const { reducers, localStorage } = OHIF.redux; reducers.ui = ui; reducers.oidc = oidcReducer; +reducers.timepointManager = timepointManager; const combined = combineReducers(reducers); const store = createStore(combined, localStorage.loadState()); diff --git a/Packages-react/ohif-viewer/src/connectedComponents/ConnectedMeasurementTable.js b/Packages-react/ohif-viewer/src/connectedComponents/ConnectedMeasurementTable.js index d3759194d..ed7c410ba 100644 --- a/Packages-react/ohif-viewer/src/connectedComponents/ConnectedMeasurementTable.js +++ b/Packages-react/ohif-viewer/src/connectedComponents/ConnectedMeasurementTable.js @@ -33,9 +33,9 @@ function convertMeasurementsToTableData(measurements) { } const mapStateToProps = state => { - const { timepoints, measurements } = state; + const { timepoints, measurements } = state.timepointManager; return { - timepoints: convertTimepointsToTableData(timepoints.timepoints), + timepoints: convertTimepointsToTableData(timepoints), measurementCollection: convertMeasurementsToTableData(measurements) }; }; diff --git a/Packages-react/ohif-viewer/src/connectedComponents/ConnectedViewer.js b/Packages-react/ohif-viewer/src/connectedComponents/ConnectedViewer.js new file mode 100644 index 000000000..aeee34b36 --- /dev/null +++ b/Packages-react/ohif-viewer/src/connectedComponents/ConnectedViewer.js @@ -0,0 +1,21 @@ +import { connect } from 'react-redux'; +import Viewer from './Viewer.js'; +import actions from '../redux/actions.js'; + +const mapDispatchToProps = dispatch => { + return { + onTimepointsUpdated: timepoints => { + dispatch(actions.setTimepoints(timepoints)); + }, + onMeasurementsUpdated: measurements => { + dispatch(actions.setMeasurements(measurements)); + } + }; +}; + +const ConnectedViewer = connect( + null, + mapDispatchToProps +)(Viewer); + +export default ConnectedViewer; diff --git a/Packages-react/ohif-viewer/src/connectedComponents/FlexboxLayout.js b/Packages-react/ohif-viewer/src/connectedComponents/FlexboxLayout.js index a0618960d..ead9bc3e1 100644 --- a/Packages-react/ohif-viewer/src/connectedComponents/FlexboxLayout.js +++ b/Packages-react/ohif-viewer/src/connectedComponents/FlexboxLayout.js @@ -76,7 +76,7 @@ class FlexboxLayout extends Component { mainContentClassName += ' sidebar-right-open'; } - // TODO[react]: Add measurementLightTable + // TODO[react]: Make ConnectedMeasurementTable extension with state.timepointManager return (
{ - OHIF.log.info('retrieveMeasurements'); - // TODO: Retrieve the measurements from the latest available SR - return Promise.resolve(); - }; - - const storeMeasurements = (measurementData, timepointIds) => { - OHIF.log.info('storeMeasurements'); - // TODO: Store the measurements into a new SR sent to the active server - return Promise.resolve(); - }; - - const retrieveTimepoints = filter => { - OHIF.log.info('retrieveTimepoints'); - - // Get the earliest and latest study date - let earliestDate = new Date().toISOString(); - let latestDate = new Date().toISOString(); - if (props.studies) { - latestDate = new Date('1000-01-01').toISOString(); - props.studies.forEach(study => { - const studyDate = moment(study.studyDate, 'YYYYMMDD').toISOString(); - if (studyDate < earliestDate) { - earliestDate = studyDate; - } - if (studyDate > latestDate) { - latestDate = studyDate; - } - }); - } - - // Return a generic timepoint - return Promise.resolve([ - { - timepointType: 'baseline', - timepointId: 'TimepointId', - studyInstanceUids: props.studyInstanceUids, - patientId: filter.patientId, - earliestDate, - latestDate, - isLocked: false - } - ]); - }; - - const storeTimepoints = timepointData => { - OHIF.log.info('storeTimepoints'); - return Promise.resolve(); - }; - - const updateTimepoint = (timepointData, query) => { - OHIF.log.info('updateTimepoint'); - return Promise.resolve(); - }; - - const removeTimepoint = timepointId => { - OHIF.log.info('removeTimepoint'); - return Promise.resolve(); - }; - - const disassociateStudy = (timepointIds, studyInstanceUid) => { - OHIF.log.info('disassociateStudy'); - return Promise.resolve(); - }; - OHIF.measurements.MeasurementApi.setConfiguration({ measurementTools, dataExchange: { - retrieve: retrieveMeasurements, - store: storeMeasurements + retrieve: this.retrieveMeasurements, + store: this.storeMeasurements } }); OHIF.measurements.TimepointApi.setConfiguration({ dataExchange: { - retrieve: retrieveTimepoints, - store: storeTimepoints, - remove: removeTimepoint, - update: updateTimepoint, - disassociate: disassociateStudy + retrieve: this.retrieveTimepoints, + store: this.storeTimepoints, + remove: this.removeTimepoint, + update: this.updateTimepoint, + disassociate: this.disassociateStudy } }); } + retrieveMeasurements = (patientId, timepointIds) => { + OHIF.log.info('retrieveMeasurements'); + // TODO: Retrieve the measurements from the latest available SR + return Promise.resolve(); + }; + + storeMeasurements = (measurementData, timepointIds) => { + OHIF.log.info('storeMeasurements'); + // TODO: Store the measurements into a new SR sent to the active server + return Promise.resolve(); + }; + + retrieveTimepoints = filter => { + OHIF.log.info('retrieveTimepoints'); + + // Get the earliest and latest study date + let earliestDate = new Date().toISOString(); + let latestDate = new Date().toISOString(); + if (this.props.studies) { + latestDate = new Date('1000-01-01').toISOString(); + this.props.studies.forEach(study => { + const studyDate = moment(study.studyDate, 'YYYYMMDD').toISOString(); + if (studyDate < earliestDate) { + earliestDate = studyDate; + } + if (studyDate > latestDate) { + latestDate = studyDate; + } + }); + } + + // Return a generic timepoint + return Promise.resolve([ + { + timepointType: 'baseline', + timepointId: 'TimepointId', + studyInstanceUids: this.props.studyInstanceUids, + patientId: filter.patientId, + earliestDate, + latestDate, + isLocked: false + } + ]); + }; + + storeTimepoints = timepointData => { + OHIF.log.info('storeTimepoints'); + return Promise.resolve(); + }; + + updateTimepoint = (timepointData, query) => { + OHIF.log.info('updateTimepoint'); + return Promise.resolve(); + }; + + removeTimepoint = timepointId => { + OHIF.log.info('removeTimepoint'); + return Promise.resolve(); + }; + + disassociateStudy = (timepointIds, studyInstanceUid) => { + OHIF.log.info('disassociateStudy'); + return Promise.resolve(); + }; + + onTimepointsUpdated = timepoints => { + if (this.props.onTimepointsUpdated) { + this.props.onTimepointsUpdated(timepoints); + } + }; + + onMeasurementsUpdated = measurements => { + if (this.props.onMeasurementsUpdated) { + this.props.onMeasurementsUpdated(measurements); + } + }; + componentDidMount() { const { studies } = this.props; const { TimepointApi, MeasurementApi } = OHIF.measurements; - // TODO: Get the Redux store from somewhere else - const { store } = window; - - const timepointApi = new TimepointApi(store, 'TimepointId'); - const measurementApi = new MeasurementApi(store, timepointApi); - const apis = { - timepointApi, - measurementApi - }; - - Object.assign(OHIF.viewer, apis); + const timepointApi = new TimepointApi('TimepointId', { + onTimepointsUpdated: this.onTimepointsUpdated + }); + const measurementApi = new MeasurementApi(timepointApi, { + onMeasurementsUpdated: this.onMeasurementsUpdated + }); const patientId = studies[0] && studies[0].patientId; timepointApi.retrieveTimepoints({ patientId }); diff --git a/Packages-react/ohif-viewer/src/connectedComponents/ViewerRetrieveStudyData.js b/Packages-react/ohif-viewer/src/connectedComponents/ViewerRetrieveStudyData.js index 538b01e51..343e50bf1 100644 --- a/Packages-react/ohif-viewer/src/connectedComponents/ViewerRetrieveStudyData.js +++ b/Packages-react/ohif-viewer/src/connectedComponents/ViewerRetrieveStudyData.js @@ -1,7 +1,7 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; import OHIF from 'ohif-core'; -import Viewer from './Viewer.js'; +import ConnectedViewer from './ConnectedViewer.js'; const { createDisplaySets } = OHIF.utils; @@ -18,6 +18,8 @@ class ViewerRetrieveStudyData extends Component { }; componentDidMount() { + // TODO: Avoid using timepoints here + //const params = { studyInstanceUids, seriesInstanceUids, timepointId, timepointsFilter={} }; const { studyInstanceUids, seriesInstanceUids, server } = this.props; const promise = OHIF.studies.retrieveStudiesMetadata( server, @@ -50,7 +52,7 @@ class ViewerRetrieveStudyData extends Component { return
Loading...
; } - return ; + return ; } } diff --git a/Packages-react/ohif-viewer/src/redux/actions.js b/Packages-react/ohif-viewer/src/redux/actions.js index d68e9a57e..7e7971a4b 100644 --- a/Packages-react/ohif-viewer/src/redux/actions.js +++ b/Packages-react/ohif-viewer/src/redux/actions.js @@ -13,10 +13,22 @@ export const setUserPreferencesModalOpen = state => ({ state }); +export const setTimepoints = state => ({ + type: 'SET_TIMEPOINTS', + state +}); + +export const setMeasurements = state => ({ + type: 'SET_MEASUREMENTS', + state +}); + const actions = { setLeftSidebarOpen, setRightSidebarOpen, - setUserPreferencesModalOpen + setUserPreferencesModalOpen, + setTimepoints, + setMeasurements }; export default actions; diff --git a/Packages-react/ohif-viewer/src/redux/timepointManager.js b/Packages-react/ohif-viewer/src/redux/timepointManager.js new file mode 100644 index 000000000..a1d9605c0 --- /dev/null +++ b/Packages-react/ohif-viewer/src/redux/timepointManager.js @@ -0,0 +1,17 @@ +const defaultState = { + timepoints: [], + measurements: [] +}; + +const timepointManager = (state = defaultState, action) => { + switch (action.type) { + case 'SET_TIMEPOINTS': + return Object.assign({}, state, { timepoints: action.state }); + case 'SET_MEASUREMENTS': + return Object.assign({}, state, { measurements: action.state }); + default: + return state; + } +}; + +export default timepointManager;