import React, { Component } from 'react'; import OHIF from '@ohif/core'; import PropTypes from 'prop-types'; import qs from 'querystring'; import { extensionManager } from './../App.js'; import ConnectedViewer from '../connectedComponents/ConnectedViewer'; import ConnectedViewerRetrieveStudyData from '../connectedComponents/ConnectedViewerRetrieveStudyData'; import NotFound from '../routes/NotFound'; const { log, metadata, utils } = OHIF; const { studyMetadataManager } = utils; const { OHIFStudyMetadata } = metadata; class StandaloneRouting extends Component { state = { studies: null, server: null, studyInstanceUIDs: null, seriesInstanceUIDs: null, error: null, loading: true, }; static propTypes = { location: PropTypes.object, store: PropTypes.object, setServers: PropTypes.func, }; parseQueryAndRetrieveDICOMWebData(query) { return new Promise((resolve, reject) => { const url = query.url; if (!url) { return 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 => { 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', 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) { log.warn('Response was undefined'); reject(new Error('Response was undefined')); } log.info(JSON.stringify(oReq.responseText, null, 2)); const data = JSON.parse(oReq.responseText); 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'; log.warn('Activating server', server); this.props.activateServer(server); const studyInstanceUIDs = query.studyInstanceUIDs.split(';'); const seriesInstanceUIDs = query.seriesInstanceUIDs ? query.seriesInstanceUIDs.split(';') : []; resolve({ server, studyInstanceUIDs, seriesInstanceUIDs }); } else { // Parse data here and add to metadata provider. const metadataProvider = OHIF.cornerstone.metadataProvider; let StudyInstanceUID; let SeriesInstanceUID; data.studies.forEach(study => { StudyInstanceUID = study.StudyInstanceUID; study.series.forEach(series => { SeriesInstanceUID = series.SeriesInstanceUID; series.instances.forEach(instance => { const { url: imageId, metadata: naturalizedDicom } = instance; // Add instance to metadata provider. metadataProvider.addInstance(naturalizedDicom); // Add imageId specific mapping to this data as the URL isn't necessarliy WADO-URI. metadataProvider.addImageIdToUIDs(imageId, { StudyInstanceUID, SeriesInstanceUID, SOPInstanceUID: naturalizedDicom.SOPInstanceUID, }); }); }); }); resolve({ studies: data.studies, studyInstanceUIDs: [] }); } }); // 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 log.info(`Sending Request to: ${url}`); oReq.open('GET', url); oReq.setRequestHeader('Accept', 'application/json'); // Fire the request to the server oReq.send(); }); } async componentDidMount() { try { let { search } = this.props.location; // Remove ? prefix which is included for some reason search = search.slice(1, search.length); const query = qs.parse(search); let { server, studies, studyInstanceUIDs, seriesInstanceUIDs, } = await this.parseQueryAndRetrieveDICOMWebData(query); if (studies) { const { studies: updatedStudies, studyInstanceUIDs: updatedStudiesInstanceUIDs, } = _mapStudiesToNewFormat(studies); studies = updatedStudies; studyInstanceUIDs = updatedStudiesInstanceUIDs; } this.setState({ studies, server, studyInstanceUIDs, seriesInstanceUIDs, loading: false, }); } catch (error) { this.setState({ error: error.message, loading: false }); } } render() { const message = this.state.error ? `Error: ${JSON.stringify(this.state.error)}` : 'Loading...'; if (this.state.error || this.state.loading) { 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); studyMetadataManager.add(studyMetadata); uniqueStudyUIDs.add(study.StudyInstanceUID); return study; }); return { studies: updatedStudies, studyInstanceUIDs: Array.from(uniqueStudyUIDs), }; }; export default StandaloneRouting;