diff --git a/OHIFViewer-react/package.json b/OHIFViewer-react/package.json index 1fc076514..4d9ee8dad 100644 --- a/OHIFViewer-react/package.json +++ b/OHIFViewer-react/package.json @@ -15,6 +15,7 @@ "moment": "^2.22.2", "ohif-core": "^0.1.0", "prop-types": "^15.6.2", + "query-string": "^6.2.0", "react": "^16.4.1", "react-cornerstone-viewport": "^0.1.1", "react-dom": "^16.4.1", diff --git a/OHIFViewer-react/src/App.js b/OHIFViewer-react/src/App.js index edcece569..d418d7fc3 100644 --- a/OHIFViewer-react/src/App.js +++ b/OHIFViewer-react/src/App.js @@ -2,6 +2,7 @@ import React, { Component } from 'react'; import { withRouter } from 'react-router'; import { Route, Switch } from 'react-router-dom'; import ViewerRouting from "./ViewerRouting.js"; +import StandaloneRouting from './StandaloneRouting.js'; import IHEInvokeImageDisplay from './IHEInvokeImageDisplay.js'; import './App.css'; import { StudyList } from 'react-viewerbase'; @@ -50,6 +51,13 @@ class App extends Component { /*auth={this.props.auth}*/ store={this.props.store} /> + { + const url = query.url; + + if (!url) { + reject(new Error('No URL was specified. Use ?url=$yourURL')); + } + + // Define a request to the server to retrieve the study data + // as JSON, given a URL that was in the Route + const oReq = new XMLHttpRequest(); + + // Add event listeners for request failure + oReq.addEventListener('error', (error) => { + OHIF.log.warn('An error occurred while retrieving the JSON data'); + reject(error) + }); + + // When the JSON has been returned, parse it into a JavaScript Object + // and render the OHIF Viewer with this data + oReq.addEventListener('load', () => { + // Parse the response content + // https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/responseText + if (!oReq.responseText) { + OHIF.log.warn('Response was undefined'); + reject(new Error('Response was undefined')); + } + + OHIF.log.info(JSON.stringify(oReq.responseText, null, 2)); + + const data = JSON.parse(oReq.responseText); + if (data.servers && query.studyInstanceUids) { + const server = data.servers.dicomWeb[0]; + server.type = 'dicomWeb'; + + const studyInstanceUids = query.studyInstanceUids.split(';'); + const seriesInstanceUids = []; + + OHIF.studies.retrieveStudiesMetadata(server, studyInstanceUids, seriesInstanceUids).then(studies => { + resolve(studies); + }, error => { + reject(error); + }); + } else { + resolve(data.studies); + } + }); + + // Open the Request to the server for the JSON data + // In this case we have a server-side route called /api/ + // which responds to GET requests with the study data + OHIF.log.info(`Sending Request to: ${url}`); + oReq.open('GET', url); + oReq.setRequestHeader('Accept', 'application/json') + + // Fire the request to the server + oReq.send(); + }); +} + +class StandaloneRouting extends Component { + constructor(props) { + super(props); + + this.state = { + studies: null, + error: null + }; + } + + componentDidMount() { + const query = qs.parse(this.props.location.search); + parseQueryAndFetchStudies(query).then(studies => { + const updatedStudies = createDisplaySets(studies); + + this.setState({ studies: updatedStudies }); + }, error => { + this.setState({ error }); + }); + } + + render() { + if (this.state.error) { + return (
Error: {JSON.stringify(this.state.error)}
); + } else if (!this.state.studies) { + return (
Loading...
); + } + + return ( + + ); + } +} + +export default StandaloneRouting; diff --git a/OHIFViewer-react/src/ViewerFromStudyData.js b/OHIFViewer-react/src/ViewerFromStudyData.js index 60be80296..84f34c10b 100644 --- a/OHIFViewer-react/src/ViewerFromStudyData.js +++ b/OHIFViewer-react/src/ViewerFromStudyData.js @@ -1,50 +1,8 @@ import React, {Component} from "react"; import PropTypes from "prop-types"; -import Viewer from "./viewer/viewer.js"; import OHIF from 'ohif-core'; -import { sortingManager } from './lib/sortingManager.js'; -import { updateMetaDataManager } from './lib/updateMetaDataManager.js'; - -// TODO: Move to react-viewerbase -function createDisplaySets(studies) { - // Define the OHIF.viewer.data global object - // TODO: Save all data that is currently in OHIF.viewer in redux instead - //OHIF.viewer.data = OHIF.viewer.data || {}; - - // @TypeSafeStudies - // Clears OHIF.viewer.Studies collection - //OHIF.viewer.Studies.removeAll(); - - // @TypeSafeStudies - // Clears OHIF.viewer.StudyMetadataList collection - //OHIF.viewer.StudyMetadataList.removeAll(); - - //OHIF.viewer.data.studyInstanceUids = []; - - const updatedStudies = studies.map(study => { - const studyMetadata = new OHIF.metadata.OHIFStudyMetadata(study, study.studyInstanceUid); - let displaySets = study.displaySets; - - if (!study.displaySets) { - displaySets = sortingManager.getDisplaySets(studyMetadata); - study.displaySets = displaySets; - } - - studyMetadata.setDisplaySets(displaySets); - - study.selected = true; - //OHIF.viewer.Studies.insert(study); - //OHIF.viewer.StudyMetadataList.insert(studyMetadata); - //OHIF.viewer.data.studyInstanceUids.push(study.studyInstanceUid); - - // Updates WADO-RS metaDataManager - updateMetaDataManager(study); - - return study; - }); - - return updatedStudies; -} +import Viewer from "./viewer/viewer.js"; +import createDisplaySets from './lib/createDisplaySets.js'; class ViewerFromStudyData extends Component { constructor(props) { diff --git a/OHIFViewer-react/src/lib/createDisplaySets.js b/OHIFViewer-react/src/lib/createDisplaySets.js new file mode 100644 index 000000000..6360a59ca --- /dev/null +++ b/OHIFViewer-react/src/lib/createDisplaySets.js @@ -0,0 +1,44 @@ +import OHIF from 'ohif-core'; +import { sortingManager } from './sortingManager.js'; +import { updateMetaDataManager } from './updateMetaDataManager.js'; + +// TODO: Move to react-viewerbase +export default function createDisplaySets(studies) { + // Define the OHIF.viewer.data global object + // TODO: Save all data that is currently in OHIF.viewer in redux instead + //OHIF.viewer.data = OHIF.viewer.data || {}; + + // @TypeSafeStudies + // Clears OHIF.viewer.Studies collection + //OHIF.viewer.Studies.removeAll(); + + // @TypeSafeStudies + // Clears OHIF.viewer.StudyMetadataList collection + //OHIF.viewer.StudyMetadataList.removeAll(); + + //OHIF.viewer.data.studyInstanceUids = []; + + const updatedStudies = studies.map(study => { + const studyMetadata = new OHIF.metadata.OHIFStudyMetadata(study, study.studyInstanceUid); + let displaySets = study.displaySets; + + if (!study.displaySets) { + displaySets = sortingManager.getDisplaySets(studyMetadata); + study.displaySets = displaySets; + } + + studyMetadata.setDisplaySets(displaySets); + + study.selected = true; + //OHIF.viewer.Studies.insert(study); + //OHIF.viewer.StudyMetadataList.insert(studyMetadata); + //OHIF.viewer.data.studyInstanceUids.push(study.studyInstanceUid); + + // Updates WADO-RS metaDataManager + updateMetaDataManager(study); + + return study; + }); + + return updatedStudies; +} diff --git a/OHIFViewer-react/src/sha.js b/OHIFViewer-react/src/sha.js index 79b206e73..fd953bc87 100644 --- a/OHIFViewer-react/src/sha.js +++ b/OHIFViewer-react/src/sha.js @@ -1 +1 @@ -export default 'fc5bd73c1ed247b233bfc7ebed1fb00c990f98d5'; +export default 'cd6f177bca2cf2258d3cd5a148500715ac759b04'; diff --git a/OHIFViewer-react/yarn.lock b/OHIFViewer-react/yarn.lock index c4fbf3ef2..a13eb2837 100644 --- a/OHIFViewer-react/yarn.lock +++ b/OHIFViewer-react/yarn.lock @@ -6832,9 +6832,10 @@ obuf@^1.0.0, obuf@^1.1.1: resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e" integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg== -"ohif-core@git://github.com/OHIF/ohif-core#master": +ohif-core@^0.1.0: version "0.1.0" - resolved "git://github.com/OHIF/ohif-core#130e621cf3c13817c1c120f91f0e9378b3eba993" + resolved "https://registry.yarnpkg.com/ohif-core/-/ohif-core-0.1.0.tgz#5de7a7e51abb3c895ed1479cf4b607f1f162cf8a" + integrity sha512-4jICzpSTM8Nfq8rY1JjKk/hWRGLWO3eq154PGX8fqYcQuTx8DxDlQLlKQoKbgRqNH2LBGBtOfDWjCZaBp7cDfg== dependencies: cornerstone-math "^0.1.7" isomorphic-base64 "^1.0.2" @@ -8040,6 +8041,14 @@ qs@6.5.2, qs@~6.5.2: resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== +query-string@^6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/query-string/-/query-string-6.2.0.tgz#468edeb542b7e0538f9f9b1aeb26f034f19c86e1" + integrity sha512-5wupExkIt8RYL4h/FE+WTg3JHk62e6fFPWtAZA9J5IWK1PfTfKkMS93HBUHcFpeYi9KsY5pFbh+ldvEyaz5MyA== + dependencies: + decode-uri-component "^0.2.0" + strict-uri-encode "^2.0.0" + querystring-es3@^0.2.0: version "0.2.1" resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73" @@ -8279,9 +8288,10 @@ react-scripts@^2.1.1: optionalDependencies: fsevents "1.2.4" -"react-viewerbase@git://github.com/OHIF/react-viewerbase#master": - version "0.1.2" - resolved "git://github.com/OHIF/react-viewerbase#851631857f037f8db32534a1d2a74dfa945429e4" +react-viewerbase@^0.1.2: + version "0.1.3" + resolved "https://registry.yarnpkg.com/react-viewerbase/-/react-viewerbase-0.1.3.tgz#0a1861149ef5d8116e68f2d375147edf942ce1aa" + integrity sha512-xuMTxgXa+E3lXLeI7mn8MVSiVw8C+HwjYbxItMues5cmeRrUvpjZ0VVx8Qcvr/9XwDmKShHj4mdyKhLL0koi/Q== dependencies: classnames "^2.2.6" @@ -9245,6 +9255,11 @@ stream-shift@^1.0.0: resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.0.tgz#d5c752825e5367e786f78e18e445ea223a155952" integrity sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI= +strict-uri-encode@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz#b9c7330c7042862f6b142dc274bbcc5866ce3546" + integrity sha1-ucczDHBChi9rFC3CdLvMWGbONUY= + string-length@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/string-length/-/string-length-2.0.0.tgz#d40dbb686a3ace960c1cffca562bf2c45f8363ed"