diff --git a/platform/core/src/studies/retrieveStudiesMetadata.js b/platform/core/src/studies/retrieveStudiesMetadata.js index ebed831cbdc..e6ffd730932 100644 --- a/platform/core/src/studies/retrieveStudiesMetadata.js +++ b/platform/core/src/studies/retrieveStudiesMetadata.js @@ -11,12 +11,15 @@ import { retrieveStudyMetadata } from './retrieveStudyMetadata'; * @param {Array} studyInstanceUIDs The UIDs of the Studies to be retrieved * @param {Object} [filters] - Object containing filters to be applied on retrieve metadata process * @param {string} [filter.seriesInstanceUID] - series instance uid to filter results against + * @param {boolean} [separateSeriesInstanceUIDFilters = false] - If true, split filtered metadata calls into multiple calls, + * as some DICOMWeb implementations only support single filters. * @returns {Promise} that will be resolved with the metadata or rejected with the error */ export default function retrieveStudiesMetadata( server, studyInstanceUIDs, - filters + filters, + separateSeriesInstanceUIDFilters = false ) { // Create an empty array to store the Promises for each metaData retrieval call const promises = []; @@ -24,7 +27,12 @@ export default function retrieveStudiesMetadata( // Loop through the array of studyInstanceUIDs studyInstanceUIDs.forEach(function(StudyInstanceUID) { // Send the call and resolve or reject the related promise based on its outcome - const promise = retrieveStudyMetadata(server, StudyInstanceUID, filters); + const promise = retrieveStudyMetadata( + server, + StudyInstanceUID, + filters, + separateSeriesInstanceUIDFilters + ); // Add the current promise to the array of promises promises.push(promise); diff --git a/platform/core/src/studies/retrieveStudyMetadata.js b/platform/core/src/studies/retrieveStudyMetadata.js index b2d84be9ef5..ad931ef1239 100644 --- a/platform/core/src/studies/retrieveStudyMetadata.js +++ b/platform/core/src/studies/retrieveStudyMetadata.js @@ -11,9 +11,16 @@ const StudyMetaDataPromises = new Map(); * @param {string} StudyInstanceUID The UID of the Study to be retrieved * @param {Object} [filters] - Object containing filters to be applied on retrieve metadata process * @param {string} [filter.seriesInstanceUID] - series instance uid to filter results against + * @param {boolean} [separateSeriesInstanceUIDFilters = false] - If true, split filtered metadata calls into multiple calls, + * as some DICOMWeb implementations only support single filters. * @returns {Promise} that will be resolved with the metadata or rejected with the error */ -export function retrieveStudyMetadata(server, StudyInstanceUID, filters) { +export function retrieveStudyMetadata( + server, + StudyInstanceUID, + filters, + separateSeriesInstanceUIDFilters = false +) { // @TODO: Whenever a study metadata request has failed, its related promise will be rejected once and for all // and further requests for that metadata will always fail. On failure, we probably need to remove the // corresponding promise from the "StudyMetaDataPromises" map... @@ -33,11 +40,29 @@ export function retrieveStudyMetadata(server, StudyInstanceUID, filters) { } // Create a promise to handle the data retrieval - const promise = new Promise((resolve, reject) => { - RetrieveMetadata(server, StudyInstanceUID, filters).then(function(data) { - resolve(data); - }, reject); - }); + let promise; + + if ( + filters && + filters.seriesInstanceUID && + separateSeriesInstanceUIDFilters + ) { + promise = __separateSeriesRequestToAggregatePromiseateSeriesRequestToAggregatePromise( + server, + StudyInstanceUID, + filters + ); + } else { + promise = RetrieveMetadata(server, StudyInstanceUID, filters); + + /* + promise = new Promise((resolve, reject) => { + RetrieveMetadata(server, StudyInstanceUID, filters).then(function(data) { + resolve(data); + }, reject); + }); + */ + } // Store the promise in cache StudyMetaDataPromises.set(StudyInstanceUID, promise); @@ -45,6 +70,49 @@ export function retrieveStudyMetadata(server, StudyInstanceUID, filters) { return promise; } +/** + * Splits up seriesInstanceUID filters to multiple calls for platforms + * @param {Object} server Object with server configuration parameters + * @param {string} StudyInstanceUID The UID of the Study to be retrieved + * @param {Object} filters - Object containing filters to be applied on retrieve metadata process + */ +function __separateSeriesRequestToAggregatePromiseateSeriesRequestToAggregatePromise( + server, + StudyInstanceUID, + filters +) { + const { seriesInstanceUID } = filters; + const seriesInstanceUIDs = seriesInstanceUID.split(','); + + return new Promise((resolve, reject) => { + const promises = []; + + seriesInstanceUIDs.forEach(uid => { + const seriesSpecificFilters = Object.assign({}, filters, { + seriesInstanceUID: uid, + }); + + promises.push( + RetrieveMetadata(server, StudyInstanceUID, seriesSpecificFilters) + ); + }); + + Promise.all(promises).then(results => { + const data = results[0]; + + let series = []; + + results.forEach(result => { + series = [...series, ...result.series]; + }); + + data.series = series; + + resolve(data); + }, reject); + }); +} + /** * Delete the cached study metadata retrieval promise to ensure that the browser will * re-retrieve the study metadata when it is next requested diff --git a/platform/viewer/public/config/idc.js b/platform/viewer/public/config/idc.js index 3077f39709a..9346217fb74 100644 --- a/platform/viewer/public/config/idc.js +++ b/platform/viewer/public/config/idc.js @@ -7,9 +7,11 @@ window.config = function(props) { enableGoogleCloudAdapter: true, enableGoogleCloudAdapterUI: false, showStudyList: true, + filterQueryParam: true, httpErrorHandler: error => { // This is 429 when rejected from the public idc sandbox too often. console.warn(error.status); + // Could use services manager here to bring up a dialog/modal if needed. console.warn('test, navigate to https://ohif.org/'); window.location = 'https://ohif.org/'; diff --git a/platform/viewer/src/connectedComponents/ViewerRetrieveStudyData.js b/platform/viewer/src/connectedComponents/ViewerRetrieveStudyData.js index 1d003cf9e18..b7f7a9dc256 100644 --- a/platform/viewer/src/connectedComponents/ViewerRetrieveStudyData.js +++ b/platform/viewer/src/connectedComponents/ViewerRetrieveStudyData.js @@ -88,6 +88,7 @@ const _isQueryParamApplied = (study, filters = {}, isFilterStrategy) => { const { seriesInstanceUID } = filters; let applied = true; // skip in case no filter or no toast manager + if (!seriesInstanceUID) { return applied; } @@ -340,6 +341,10 @@ function ViewerRetrieveStudyData({ } } + if (appConfig.enableGoogleCloudAdapter) { + retrieveParams.push(true); // Seperate SeriesInstanceUID filter calls. + } + cancelableStudiesPromises[studyInstanceUIDs] = makeCancelable( retrieveStudiesMetadata(...retrieveParams) )