diff --git a/platform/core/src/redux/reducers/servers.js b/platform/core/src/redux/reducers/servers.js
index b834f4fb0..6b11b2310 100644
--- a/platform/core/src/redux/reducers/servers.js
+++ b/platform/core/src/redux/reducers/servers.js
@@ -11,6 +11,16 @@ const servers = (state = defaultState, action) => {
servers.forEach(s => (s.active = true));
return { ...state, servers };
+ case 'ACTIVATE_SERVER': {
+ const newServer = { ...action.server, active: true };
+ const newServers = state.servers;
+ newServers.forEach(s => (s.active = false));
+ return {
+ ...state,
+ servers: uniqBy([...newServers, newServer], 'wadoRoot'),
+ };
+ }
+
case 'SET_SERVERS':
return { ...state, servers: action.servers };
diff --git a/platform/viewer/src/connectedComponents/ConnectedStandaloneRouting.js b/platform/viewer/src/connectedComponents/ConnectedStandaloneRouting.js
new file mode 100644
index 000000000..26d553a93
--- /dev/null
+++ b/platform/viewer/src/connectedComponents/ConnectedStandaloneRouting.js
@@ -0,0 +1,21 @@
+import { connect } from 'react-redux';
+import StandaloneRouting from '../routes/StandaloneRouting';
+
+const mapDispatchToProps = dispatch => {
+ return {
+ activateServer: server => {
+ const action = {
+ type: 'ACTIVATE_SERVER',
+ server,
+ };
+ dispatch(action);
+ },
+ };
+};
+
+const ConnectedStandaloneRouting = connect(
+ null,
+ mapDispatchToProps
+)(StandaloneRouting);
+
+export default ConnectedStandaloneRouting;
diff --git a/platform/viewer/src/connectedComponents/ConnectedViewerRetrieveStudyData.js b/platform/viewer/src/connectedComponents/ConnectedViewerRetrieveStudyData.js
index f3a7e5ee2..d7ffc6ea2 100644
--- a/platform/viewer/src/connectedComponents/ConnectedViewerRetrieveStudyData.js
+++ b/platform/viewer/src/connectedComponents/ConnectedViewerRetrieveStudyData.js
@@ -2,23 +2,21 @@ import { connect } from 'react-redux';
import ViewerRetrieveStudyData from './ViewerRetrieveStudyData.js';
import OHIF from "@ohif/core";
-const {
- clearViewportSpecificData
-} = OHIF.redux.actions;
+const { clearViewportSpecificData } = OHIF.redux.actions;
const isActive = a => a.active === true;
-const mapStateToProps = state => {
+const mapStateToProps = (state, ownProps) => {
const activeServer = state.servers.servers.find(isActive);
return {
- server: activeServer,
+ server: ownProps.server || activeServer,
};
};
const mapDispatchToProps = dispatch => {
return {
clearViewportSpecificData: () => {
dispatch(clearViewportSpecificData());
- }
+ },
};
};
diff --git a/platform/viewer/src/routes/NotFound.js b/platform/viewer/src/routes/NotFound.js
index 2844b35da..41f5e01f1 100644
--- a/platform/viewer/src/routes/NotFound.js
+++ b/platform/viewer/src/routes/NotFound.js
@@ -2,14 +2,16 @@ import React from 'react';
import './NotFound.css';
import { Link } from 'react-router-dom';
-export default function NotFound() {
+export default function NotFound({ message = 'Sorry, this page does not exist.', showGoBackButton = true }) {
return (
-
Sorry, this page does not exist.
-
- Go back to the Study List
-
+ {message}
+ {showGoBackButton && (
+
+ Go back to the Study List
+
+ )}
);
diff --git a/platform/viewer/src/routes/StandaloneRouting.js b/platform/viewer/src/routes/StandaloneRouting.js
index a061f818d..44fa8a7a9 100644
--- a/platform/viewer/src/routes/StandaloneRouting.js
+++ b/platform/viewer/src/routes/StandaloneRouting.js
@@ -1,29 +1,33 @@
import React, { Component } from 'react';
-import { log, metadata, studies, utils } from '@ohif/core';
-
+import { log, metadata, utils } from '@ohif/core';
import PropTypes from 'prop-types';
-import ConnectedViewer from '../connectedComponents/ConnectedViewer';
-import { extensionManager } from './../App.js';
import qs from 'querystring';
-const { OHIFStudyMetadata } = metadata;
-const { retrieveStudiesMetadata } = studies;
+import { extensionManager } from './../App.js';
+import ConnectedViewer from '../connectedComponents/ConnectedViewer';
+import ConnectedViewerRetrieveStudyData from '../connectedComponents/ConnectedViewerRetrieveStudyData';
+import NotFound from '../routes/NotFound';
+
const { studyMetadataManager, updateMetaDataManager } = utils;
+const { OHIFStudyMetadata } = metadata;
class StandaloneRouting extends Component {
state = {
studies: null,
+ server: null,
+ studyInstanceUids: null,
+ seriesInstanceUids: null,
error: null,
+ loading: true,
};
- studyInstanceUids = [];
-
static propTypes = {
location: PropTypes.object,
store: PropTypes.object,
+ setServers: PropTypes.func,
};
- static parseQueryAndFetchStudies(query) {
+ parseQueryAndRetrieveDICOMWebData(query) {
return new Promise((resolve, reject) => {
const url = query.url;
@@ -43,7 +47,11 @@ class StandaloneRouting extends Component {
// When the JSON has been returned, parse it into a JavaScript Object
// and render the OHIF Viewer with this data
- oReq.addEventListener('load', () => {
+ oReq.addEventListener('load', event => {
+ if (event.target.status === 404) {
+ reject(new Error('No JSON data found'));
+ }
+
// Parse the response content
// https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/responseText
if (!oReq.responseText) {
@@ -54,27 +62,24 @@ class StandaloneRouting extends Component {
log.info(JSON.stringify(oReq.responseText, null, 2));
const data = JSON.parse(oReq.responseText);
- if (data.servers && query.studyInstanceUids) {
+ if (data.servers) {
+ if (!query.studyInstanceUids) {
+ log.warn('No study instance uids specified');
+ reject(new Error('No study instance uids specified'));
+ }
+
const server = data.servers.dicomWeb[0];
server.type = 'dicomWeb';
- const studyInstanceUids = query.studyInstanceUids.split(';');
- const seriesInstanceUids = [];
+ log.warn('Activating server', server);
+ this.props.activateServer(server);
- retrieveStudiesMetadata(
- server,
- studyInstanceUids,
- seriesInstanceUids
- ).then(
- studies => {
- resolve(studies);
- },
- error => {
- reject(error);
- }
- );
+ const studyInstanceUids = query.studyInstanceUids.split(';');
+ const seriesInstanceUids = query.seriesInstanceUids ? query.seriesInstanceUids.split(';') : [];
+
+ resolve({ server, studyInstanceUids, seriesInstanceUids });
} else {
- resolve(data.studies);
+ resolve({ studies: data.studies, studyInstanceUids: [] });
}
});
@@ -96,56 +101,80 @@ class StandaloneRouting extends Component {
// Remove ? prefix which is included for some reason
search = search.slice(1, search.length);
-
const query = qs.parse(search);
- const studies = await StandaloneRouting.parseQueryAndFetchStudies(query);
- studyMetadataManager.purge();
+ let {
+ server,
+ studies,
+ studyInstanceUids,
+ seriesInstanceUids,
+ } = await this.parseQueryAndRetrieveDICOMWebData(query);
- // Map studies to new format, update metadata manager?
- const uniqueStudyUids = new Set();
- const updatedStudies = studies.map(study => {
- const studyMetadata = new OHIFStudyMetadata(
- study,
- study.studyInstanceUid
- );
- const sopClassHandlerModules =
- extensionManager.modules['sopClassHandlerModule'];
+ if (studies) {
+ const {
+ studies: updatedStudies,
+ studyInstanceUids: updatedStudiesInstanceUids,
+ } = _mapStudiesToNewFormat(studies);
+ studies = updatedStudies;
+ studyInstanceUids = updatedStudiesInstanceUids;
+ }
- study.displaySets =
- study.displaySets ||
- studyMetadata.createDisplaySets(sopClassHandlerModules);
- studyMetadata.setDisplaySets(study.displaySets);
-
- // Updates WADO-RS metaDataManager
- updateMetaDataManager(study);
-
- studyMetadataManager.add(studyMetadata);
- uniqueStudyUids.add(study.studyInstanceUid);
-
- return study;
+ this.setState({
+ studies,
+ server,
+ studyInstanceUids,
+ seriesInstanceUids,
+ loading: false,
});
-
- this.studyInstanceUids = Array.from(uniqueStudyUids);
- this.setState({ studies: updatedStudies });
} catch (error) {
- this.setState({ error });
+ this.setState({ error: error.message, loading: false });
}
}
render() {
- if (this.state.error) {
- return Error: {JSON.stringify(this.state.error)}
;
- } else if (!this.state.studies) {
- return Loading...
;
+ const message = this.state.error ? `Error: ${JSON.stringify(this.state.error)}` : 'Loading...';
+ if (this.state.error || this.state.loading) {
+ return ;
}
- return (
-
- );
+
+ return this.state.studies ? (
+
+ ) : (
+
+ );
}
}
+const _mapStudiesToNewFormat = studies => {
+ studyMetadataManager.purge();
+
+ /* Map studies to new format, update metadata manager? */
+ const uniqueStudyUids = new Set();
+ const updatedStudies = studies.map(study => {
+ const studyMetadata = new OHIFStudyMetadata(study, study.studyInstanceUid);
+
+ const sopClassHandlerModules = extensionManager.modules['sopClassHandlerModule'];
+ study.displaySets = study.displaySets ||
+ studyMetadata.createDisplaySets(sopClassHandlerModules);
+ studyMetadata.setDisplaySets(study.displaySets);
+
+ /* Updates WADO-RS metaDataManager */
+ updateMetaDataManager(study);
+
+ studyMetadataManager.add(studyMetadata);
+ uniqueStudyUids.add(study.studyInstanceUid);
+
+ return study;
+ });
+
+ return {
+ studies: updatedStudies,
+ studyInstanceUids: Array.from(uniqueStudyUids),
+ };
+};
+
export default StandaloneRouting;
diff --git a/platform/viewer/src/routes/routesUtil.js b/platform/viewer/src/routes/routesUtil.js
index 552eda18a..b0c39a598 100644
--- a/platform/viewer/src/routes/routesUtil.js
+++ b/platform/viewer/src/routes/routesUtil.js
@@ -19,7 +19,7 @@ const StudyListRouting = asyncComponent(() =>
)
);
const StandaloneRouting = asyncComponent(() =>
- import(/* webpackChunkName: "StandaloneRouting" */ './StandaloneRouting.js')
+ import(/* webpackChunkName: "ConnectedStandaloneRouting" */ '../connectedComponents/ConnectedStandaloneRouting.js')
);
const ViewerLocalFileData = asyncComponent(() =>
import(