feat(DataSource): Allow for dynamic data source configuration and creation (#3543)

This commit is contained in:
Joe Boccanfuso authored and GitHub committed 2023-07-20 11:43:05 -04:00
1 parent 6d88978710
commit 7bbc213f58
36 files changed
+640 -298

No files matched your search

+5 -4
View File
@@ -13,10 +13,10 @@ window.config = {
defaultDataSourceName: 'dicomweb',
dataSources: [
{
friendlyName: 'dcmjs DICOMWeb Server',
namespace: '@ohif/extension-default.dataSourcesModule.dicomweb',
sourceName: 'dicomweb',
configuration: {
friendlyName: 'dcmjs DICOMWeb Server',
name: 'DCM4CHEE',
// Something here to check build
wadoUriRoot: 'https://myserver.com/dicomweb',
@@ -34,18 +34,19 @@ window.config = {
},
},
{
friendlyName: 'dicom json',
namespace: '@ohif/extension-default.dataSourcesModule.dicomjson',
sourceName: 'dicomjson',
configuration: {
friendlyName: 'dicom json',
name: 'json',
},
},
{
friendlyName: 'dicom local',
namespace: '@ohif/extension-default.dataSourcesModule.dicomlocal',
sourceName: 'dicomlocal',
configuration: {},
configuration: {
friendlyName: 'dicom local',
},
},
],
httpErrorHandler: error => {
+6 -5
View File
@@ -36,10 +36,10 @@ window.config = {
// },
dataSources: [
{
friendlyName: 'dcmjs DICOMWeb Server',
namespace: '@ohif/extension-default.dataSourcesModule.dicomweb',
sourceName: 'dicomweb',
configuration: {
friendlyName: 'dcmjs DICOMWeb Server',
name: 'aws',
// old server
// wadoUriRoot: 'https://server.dcmjs.org/dcm4chee-arc/aets/DCM4CHEE/wado',
@@ -70,26 +70,27 @@ window.config = {
},
},
{
friendlyName: 'dicomweb delegating proxy',
namespace: '@ohif/extension-default.dataSourcesModule.dicomwebproxy',
sourceName: 'dicomwebproxy',
configuration: {
friendlyName: 'dicomweb delegating proxy',
name: 'dicomwebproxy',
},
},
{
friendlyName: 'dicom json',
namespace: '@ohif/extension-default.dataSourcesModule.dicomjson',
sourceName: 'dicomjson',
configuration: {
friendlyName: 'dicom json',
name: 'json',
},
},
{
friendlyName: 'dicom local',
namespace: '@ohif/extension-default.dataSourcesModule.dicomlocal',
sourceName: 'dicomlocal',
configuration: {},
configuration: {
friendlyName: 'dicom local',
},
},
],
httpErrorHandler: error => {
+1 -1
View File
@@ -10,10 +10,10 @@ window.config = {
defaultDataSourceName: 'dicomweb',
dataSources: [
{
friendlyName: 'DCM4CHEE Server',
namespace: '@ohif/extension-default.dataSourcesModule.dicomweb',
sourceName: 'dicomweb',
configuration: {
friendlyName: 'DCM4CHEE Server',
name: 'DCM4CHEE',
wadoUriRoot: 'https://d33do7qe4w26qo.cloudfront.net/dicomweb',
qidoRoot: 'https://d33do7qe4w26qo.cloudfront.net/dicomweb',
@@ -12,10 +12,10 @@ window.config = {
defaultDataSourceName: 'dicomweb',
dataSources: [
{
friendlyName: 'dcmjs DICOMWeb Server',
namespace: '@ohif/extension-default.dataSourcesModule.dicomweb',
sourceName: 'dicomweb',
configuration: {
friendlyName: 'dcmjs DICOMWeb Server',
name: 'DCM4CHEE',
wadoUriRoot: 'http://localhost:5985',
qidoRoot: 'http://localhost:5985',
@@ -31,18 +31,19 @@ window.config = {
},
},
{
friendlyName: 'dicom json',
namespace: '@ohif/extension-default.dataSourcesModule.dicomjson',
sourceName: 'dicomjson',
configuration: {
friendlyName: 'dicom json',
name: 'json',
},
},
{
friendlyName: 'dicom local',
namespace: '@ohif/extension-default.dataSourcesModule.dicomlocal',
sourceName: 'dicomlocal',
configuration: {},
configuration: {
friendlyName: 'dicom local',
},
},
],
};
@@ -13,10 +13,10 @@ window.config = {
defaultDataSourceName: 'dicomweb',
dataSources: [
{
friendlyName: 'Static WADO Local Data',
namespace: '@ohif/extension-default.dataSourcesModule.dicomweb',
sourceName: 'dicomweb',
configuration: {
friendlyName: 'Static WADO Local Data',
name: 'DCM4CHEE',
wadoUriRoot: '/dicomweb',
qidoRoot: '/dicomweb',
@@ -34,18 +34,19 @@ window.config = {
},
},
{
friendlyName: 'dicom json',
namespace: '@ohif/extension-default.dataSourcesModule.dicomjson',
sourceName: 'dicomjson',
configuration: {
friendlyName: 'dicom json',
name: 'json',
},
},
{
friendlyName: 'dicom local',
namespace: '@ohif/extension-default.dataSourcesModule.dicomlocal',
sourceName: 'dicomlocal',
configuration: {},
configuration: {
friendlyName: 'dicom local',
},
},
],
httpErrorHandler: error => {
@@ -11,10 +11,10 @@ window.config = {
defaultDataSourceName: 'dicomweb',
dataSources: [
{
friendlyName: 'Orthanc Server',
namespace: '@ohif/extension-default.dataSourcesModule.dicomweb',
sourceName: 'dicomweb',
configuration: {
friendlyName: 'Orthanc Server',
name: 'Orthanc',
wadoUriRoot: '/wado',
qidoRoot: '/dicom-web',
@@ -26,18 +26,19 @@ window.config = {
},
},
{
friendlyName: 'dicom json',
namespace: '@ohif/extension-default.dataSourcesModule.dicomjson',
sourceName: 'dicomjson',
configuration: {
friendlyName: 'dicom json',
name: 'json',
},
},
{
friendlyName: 'dicom local',
namespace: '@ohif/extension-default.dataSourcesModule.dicomlocal',
sourceName: 'dicomlocal',
configuration: {},
configuration: {
friendlyName: 'dicom local',
},
},
],
};
@@ -12,10 +12,10 @@ window.config = {
defaultDataSourceName: 'dicomweb',
dataSources: [
{
friendlyName: 'Orthanc Server',
namespace: '@ohif/extension-default.dataSourcesModule.dicomweb',
sourceName: 'dicomweb',
configuration: {
friendlyName: 'Orthanc Server',
name: 'Orthanc',
wadoUriRoot: 'http://127.0.0.1/pacs/wado',
qidoRoot: 'http://127.0.0.1/pacs/dicom-web',
@@ -27,18 +27,19 @@ window.config = {
},
},
{
friendlyName: 'dicom json',
namespace: '@ohif/extension-default.dataSourcesModule.dicomjson',
sourceName: 'dicomjson',
configuration: {
friendlyName: 'dicom json',
name: 'json',
},
},
{
friendlyName: 'dicom local',
namespace: '@ohif/extension-default.dataSourcesModule.dicomlocal',
sourceName: 'dicomlocal',
configuration: {},
configuration: {
friendlyName: 'dicom local',
},
},
],
};
+7 -6
View File
@@ -12,10 +12,10 @@ window.config = {
defaultDataSourceName: 'e2e',
dataSources: [
{
friendlyName: 'StaticWado test data',
namespace: '@ohif/extension-default.dataSourcesModule.dicomweb',
sourceName: 'e2e',
configuration: {
friendlyName: 'StaticWado test data',
// The most important field to set for static WADO
staticWado: true,
name: 'StaticWADO',
@@ -34,10 +34,10 @@ window.config = {
},
},
{
friendlyName: 'Static WADO Local Data',
namespace: '@ohif/extension-default.dataSourcesModule.dicomweb',
sourceName: 'local',
configuration: {
friendlyName: 'Static WADO Local Data',
name: 'DCM4CHEE',
qidoRoot: '/dicomweb',
wadoRoot: '/dicomweb',
@@ -54,10 +54,10 @@ window.config = {
},
},
{
friendlyName: 'dcmjs DICOMWeb Server',
namespace: '@ohif/extension-default.dataSourcesModule.dicomweb',
sourceName: 'ohif',
configuration: {
friendlyName: 'dcmjs DICOMWeb Server',
name: 'aws',
// old server
// wadoUriRoot: 'https://server.dcmjs.org/dcm4chee-arc/aets/DCM4CHEE/wado',
@@ -98,18 +98,19 @@ window.config = {
// },
// },
{
friendlyName: 'dicom json',
namespace: '@ohif/extension-default.dataSourcesModule.dicomjson',
sourceName: 'dicomjson',
configuration: {
friendlyName: 'dicom json',
name: 'json',
},
},
{
friendlyName: 'dicom local',
namespace: '@ohif/extension-default.dataSourcesModule.dicomlocal',
sourceName: 'dicomlocal',
configuration: {},
configuration: {
friendlyName: 'dicom local',
},
},
],
httpErrorHandler: error => {
+5 -4
View File
@@ -36,10 +36,10 @@ window.config = {
defaultDataSourceName: 'dicomweb',
dataSources: [
{
friendlyName: 'dcmjs DICOMWeb Server',
namespace: '@ohif/extension-default.dataSourcesModule.dicomweb',
sourceName: 'dicomweb',
configuration: {
friendlyName: 'dcmjs DICOMWeb Server',
name: 'GCP',
wadoUriRoot:
'https://healthcare.googleapis.com/v1/projects/ohif-cloud-healthcare/locations/us-east4/datasets/ohif-qa-dataset/dicomStores/ohif-qa-2/dicomWeb',
@@ -58,18 +58,19 @@ window.config = {
},
},
{
friendlyName: 'dicom json',
namespace: '@ohif/extension-default.dataSourcesModule.dicomjson',
sourceName: 'dicomjson',
configuration: {
friendlyName: 'dicom json',
name: 'json',
},
},
{
friendlyName: 'dicom local',
namespace: '@ohif/extension-default.dataSourcesModule.dicomlocal',
sourceName: 'dicomlocal',
configuration: {},
configuration: {
friendlyName: 'dicom local',
},
},
],
};
+5 -4
View File
@@ -15,10 +15,10 @@ window.config = {
defaultDataSourceName: 'dicomweb',
dataSources: [
{
friendlyName: 'DCM4CHEE Server',
namespace: '@ohif/extension-default.dataSourcesModule.dicomweb',
sourceName: 'dicomweb',
configuration: {
friendlyName: 'DCM4CHEE Server',
name: 'DCM4CHEE',
wadoUriRoot: 'http://localhost:8080/dcm4chee-arc/aets/DCM4CHEE/wado',
qidoRoot: 'http://localhost:8080/dcm4chee-arc/aets/DCM4CHEE/rs',
@@ -42,18 +42,19 @@ window.config = {
},
},
{
friendlyName: 'dicom json',
namespace: '@ohif/extension-default.dataSourcesModule.dicomjson',
sourceName: 'dicomjson',
configuration: {
friendlyName: 'dicom json',
name: 'json',
},
},
{
friendlyName: 'dicom local',
namespace: '@ohif/extension-default.dataSourcesModule.dicomlocal',
sourceName: 'dicomlocal',
configuration: {},
configuration: {
friendlyName: 'dicom local',
},
},
],
studyListFunctionsEnabled: true,
+5 -4
View File
@@ -16,10 +16,10 @@ window.config = {
defaultDataSourceName: 'dicomweb',
dataSources: [
{
friendlyName: 'dcmjs DICOMWeb Server',
namespace: '@ohif/extension-default.dataSourcesModule.dicomweb',
sourceName: 'dicomweb',
configuration: {
friendlyName: 'dcmjs DICOMWeb Server',
name: 'DCM4CHEE',
wadoUriRoot: 'http://localhost/dicom-web',
qidoRoot: 'http://localhost/dicom-web',
@@ -38,18 +38,19 @@ window.config = {
},
},
{
friendlyName: 'dicom json',
namespace: '@ohif/extension-default.dataSourcesModule.dicomjson',
sourceName: 'dicomjson',
configuration: {
friendlyName: 'dicom json',
name: 'json',
},
},
{
friendlyName: 'dicom local',
namespace: '@ohif/extension-default.dataSourcesModule.dicomlocal',
sourceName: 'dicomlocal',
configuration: {},
configuration: {
friendlyName: 'dicom local',
},
},
],
httpErrorHandler: error => {
+5 -4
View File
@@ -16,10 +16,10 @@ window.config = {
defaultDataSourceName: 'dicomweb',
dataSources: [
{
friendlyName: 'Static WADO Local Data',
namespace: '@ohif/extension-default.dataSourcesModule.dicomweb',
sourceName: 'dicomweb',
configuration: {
friendlyName: 'Static WADO Local Data',
name: 'DCM4CHEE',
qidoRoot: '/dicomweb',
wadoRoot: '/dicomweb',
@@ -36,18 +36,19 @@ window.config = {
},
},
{
friendlyName: 'dicom json',
namespace: '@ohif/extension-default.dataSourcesModule.dicomjson',
sourceName: 'dicomjson',
configuration: {
friendlyName: 'dicom json',
name: 'json',
},
},
{
friendlyName: 'dicom local',
namespace: '@ohif/extension-default.dataSourcesModule.dicomlocal',
sourceName: 'dicomlocal',
configuration: {},
configuration: {
friendlyName: 'dicom local',
},
},
],
httpErrorHandler: error => {
+8 -7
View File
@@ -24,10 +24,10 @@ window.config = {
defaultDataSourceName: 'default',
dataSources: [
{
friendlyName: 'Static WADO Local Data',
namespace: '@ohif/extension-default.dataSourcesModule.dicomweb',
sourceName: 'default',
configuration: {
friendlyName: 'Static WADO Local Data',
name: 'DCM4CHEE',
qidoRoot: '/dicomweb',
wadoRoot: '/dicomweb',
@@ -45,10 +45,10 @@ window.config = {
},
},
{
friendlyName: 'dcmjs DICOMWeb Server',
namespace: '@ohif/extension-default.dataSourcesModule.dicomweb',
sourceName: 'ohif',
configuration: {
friendlyName: 'dcmjs DICOMWeb Server',
name: 'aws',
// old server
// wadoUriRoot: 'https://server.dcmjs.org/dcm4chee-arc/aets/DCM4CHEE/wado',
@@ -70,10 +70,10 @@ window.config = {
},
},
{
friendlyName: 'AWS S3 OHIF',
namespace: '@ohif/extension-default.dataSourcesModule.dicomweb',
sourceName: 'aws',
configuration: {
friendlyName: 'AWS S3 OHIF',
name: 'aws',
qidoRoot: 'https://dd32w2rfebxel.cloudfront.net/dicomweb',
wadoRoot: 'https://dd32w2rfebxel.cloudfront.net/dicomweb',
@@ -90,10 +90,10 @@ window.config = {
},
},
{
friendlyName: 'E2E Test Data',
namespace: '@ohif/extension-default.dataSourcesModule.dicomweb',
sourceName: 'e2e',
configuration: {
friendlyName: 'E2E Test Data',
name: 'DCM4CHEE',
wadoUriRoot: '/viewer-testdata',
qidoRoot: '/viewer-testdata',
@@ -111,18 +111,19 @@ window.config = {
},
},
{
friendlyName: 'dicom json',
namespace: '@ohif/extension-default.dataSourcesModule.dicomjson',
sourceName: 'dicomjson',
configuration: {
friendlyName: 'dicom json',
name: 'json',
},
},
{
friendlyName: 'dicom local',
namespace: '@ohif/extension-default.dataSourcesModule.dicomlocal',
sourceName: 'dicomlocal',
configuration: {},
configuration: {
friendlyName: 'dicom local',
},
},
],
httpErrorHandler: error => {
+5 -4
View File
@@ -12,10 +12,10 @@ window.config = {
defaultDataSourceName: 'dicomweb',
dataSources: [
{
friendlyName: 'dcmjs DICOMWeb Server',
namespace: '@ohif/extension-default.dataSourcesModule.dicomweb',
sourceName: 'dicomweb',
configuration: {
friendlyName: 'dcmjs DICOMWeb Server',
name: 'aws',
wadoUriRoot: 'https://d33do7qe4w26qo.cloudfront.net/dicomweb',
qidoRoot: 'https://d33do7qe4w26qo.cloudfront.net/dicomweb',
@@ -41,18 +41,19 @@ window.config = {
},
},
{
friendlyName: 'dicom json',
namespace: '@ohif/extension-default.dataSourcesModule.dicomjson',
sourceName: 'dicomjson',
configuration: {
friendlyName: 'dicom json',
name: 'json',
},
},
{
friendlyName: 'dicom local',
namespace: '@ohif/extension-default.dataSourcesModule.dicomlocal',
sourceName: 'dicomlocal',
configuration: {},
configuration: {
friendlyName: 'dicom local',
},
},
],
httpErrorHandler: error => {
+2 -3
View File
@@ -1,5 +1,4 @@
import useDebounce from './useDebounce.js';
import useQuery from './useQuery.js';
import useSearchParams from './useSearchParams.js';
import useSearchParams from './useSearchParams';
export { useDebounce, useQuery, useSearchParams };
export { useDebounce, useSearchParams };
-5
View File
@@ -1,5 +0,0 @@
import { useLocation } from 'react-router-dom';
export default function useQuery() {
return new URLSearchParams(useLocation().search);
}
-17
View File
@@ -1,17 +0,0 @@
import useQuery from './useQuery';
/**
* It returns a Map of the query parameters in the URL, where the keys are
* lowercase
* @returns A function that returns a Map of the query parameters.
*/
export default function useSearchParams() {
const query = useQuery();
// make query params case-insensitive
const searchParams = new Map();
for (const [key, value] of query) {
searchParams.set(key.toLowerCase(), value);
}
return searchParams;
}
+24
View File
@@ -0,0 +1,24 @@
import { useLocation } from 'react-router';
/**
* It returns a URLSearchParams of the query parameters in the URL, where the keys are
* either lowercase or maintain their case based on the lowerCaseKeys parameter.
* @param {lowerCaseKeys:boolean} true to return lower case keys; false (default) to maintain casing;
* @returns {URLSearchParams}
*/
export default function useSearchParams(options = { lowerCaseKeys: false }) {
const { lowerCaseKeys } = options;
const searchParams = new URLSearchParams(useLocation().search);
if (!lowerCaseKeys) {
return searchParams;
}
const lowerCaseSearchParams = new URLSearchParams();
for (const [key, value] of searchParams) {
lowerCaseSearchParams.set(key.toLowerCase(), value);
}
return lowerCaseSearchParams;
}
+125 -36
View File
@@ -1,10 +1,22 @@
/* eslint-disable react/jsx-props-no-spreading */
import React, { useEffect, useState } from 'react';
import React, { useCallback, useEffect, useState } from 'react';
import PropTypes from 'prop-types';
import { MODULE_TYPES } from '@ohif/core';
import { ExtensionManager, MODULE_TYPES } from '@ohif/core';
//
import { extensionManager } from '../App.tsx';
import { useParams, useLocation } from 'react-router';
import useSearchParams from '../hooks/useSearchParams.ts';
/**
* Determines if two React Router location objects are the same.
*/
const areLocationsTheSame = (location0, location1) => {
return (
location0.pathname === location1.pathname &&
location0.search === location1.search &&
location0.hash === location1.hash
);
};
/**
* Uses route properties to determine the data source that should be passed
@@ -18,37 +30,8 @@ function DataSourceWrapper(props) {
const { children: LayoutTemplate, ...rest } = props;
const params = useParams();
const location = useLocation();
// TODO - get the variable from the props all the time...
let dataSourceName = new URLSearchParams(location.search).get('datasources');
const dataPath = dataSourceName ? `/${dataSourceName}` : '';
if (!dataSourceName && window.config.defaultDataSourceName) {
dataSourceName = window.config.defaultDataSourceName;
} else if (!dataSourceName) {
// Gets the first defined datasource with the right name
// Mostly for historical reasons - new configs should use the defaultDataSourceName
const dataSourceModules =
extensionManager.modules[MODULE_TYPES.DATA_SOURCE];
// TODO: Good usecase for flatmap?
const webApiDataSources = dataSourceModules.reduce((acc, curr) => {
const mods = [];
curr.module.forEach(mod => {
if (mod.type === 'webApi') {
mods.push(mod);
}
});
return acc.concat(mods);
}, []);
dataSourceName = webApiDataSources
.map(ds => ds.name)
.find(it => extensionManager.getDataSources(it)?.[0] !== undefined);
}
const dataSource = extensionManager.getDataSources(dataSourceName)?.[0];
if (!dataSource) {
throw new Error(`No data source found for ${dataSourceName}`);
}
const lowerCaseSearchParams = useSearchParams({ lowerCaseKeys: true });
const query = useSearchParams();
// Route props --> studies.mapParams
// mapParams --> studies.search
// studies.search --> studies.processResults
@@ -63,10 +46,102 @@ function DataSourceWrapper(props) {
pageNumber: 1,
location: 'Not a valid location, causes first load to occur',
};
const getInitialDataSourceName = useCallback(() => {
// TODO - get the variable from the props all the time...
let dataSourceName = lowerCaseSearchParams.get('datasources');
if (!dataSourceName && window.config.defaultDataSourceName) {
return '';
}
if (!dataSourceName) {
// Gets the first defined datasource with the right name
// Mostly for historical reasons - new configs should use the defaultDataSourceName
const dataSourceModules =
extensionManager.modules[MODULE_TYPES.DATA_SOURCE];
// TODO: Good usecase for flatmap?
const webApiDataSources = dataSourceModules.reduce((acc, curr) => {
const mods = [];
curr.module.forEach(mod => {
if (mod.type === 'webApi') {
mods.push(mod);
}
});
return acc.concat(mods);
}, []);
dataSourceName = webApiDataSources
.map(ds => ds.name)
.find(it => extensionManager.getDataSources(it)?.[0] !== undefined);
}
return dataSourceName;
}, []);
const [isDataSourceInitialized, setIsDataSourceInitialized] = useState(false);
// The path to the data source to be used in the URL for a mode (e.g. mode/dataSourcePath?StudyIntanceUIDs=1.2.3)
const [dataSourcePath, setDataSourcePath] = useState(() => {
const dataSourceName = getInitialDataSourceName();
return dataSourceName ? `/${dataSourceName}` : '';
});
const [dataSource, setDataSource] = useState(() => {
const dataSourceName = getInitialDataSourceName();
if (!dataSourceName) {
return extensionManager.getActiveDataSource()[0];
}
const dataSource = extensionManager.getDataSources(dataSourceName)?.[0];
if (!dataSource) {
throw new Error(`No data source found for ${dataSourceName}`);
}
return dataSource;
});
const [data, setData] = useState(DEFAULT_DATA);
const [isLoading, setIsLoading] = useState(false);
/**
* The effect to initialize the data source whenever it changes. Similar to
* whenever a different Mode is entered, the Mode's data source is initialized, so
* too this DataSourceWrapper must initialize its data source whenever a different
* data source is activated. Furthermore, a data source might be initialized
* several times as it gets activated/deactivated because the location URL
* might change and data sources initialize based on the URL.
*/
useEffect(() => {
const initializeDataSource = async () => {
await dataSource.initialize({ params, query });
setIsDataSourceInitialized(true);
};
initializeDataSource();
}, [dataSource]);
useEffect(() => {
const dataSourceChangedCallback = () => {
setIsDataSourceInitialized(false);
setDataSourcePath('');
setDataSource(extensionManager.getActiveDataSource()[0]);
// Setting data to DEFAULT_DATA triggers a new query just like it does for the initial load.
setData(DEFAULT_DATA);
};
const sub = extensionManager.subscribe(
ExtensionManager.EVENTS.ACTIVE_DATA_SOURCE_CHANGED,
dataSourceChangedCallback
);
return () => sub.unsubscribe();
}, []);
useEffect(() => {
if (!isDataSourceInitialized) {
return;
}
const queryFilterValues = _getQueryFilterValues(
location.search,
STUDIES_LIMIT
@@ -75,6 +150,7 @@ function DataSourceWrapper(props) {
// 204: no content
async function getData() {
setIsLoading(true);
const studies = await dataSource.query.studies.search(queryFilterValues);
setData({
@@ -102,7 +178,12 @@ function DataSourceWrapper(props) {
STUDIES_LIMIT
) *
(STUDIES_LIMIT - 1);
const isLocationUpdated = data.location !== location;
// Simply checking data.location !== location is not sufficient because even though the location href (i.e. entire URL)
// has not changed, the React Router still provides a new location reference and would result in two study queries
// on initial load. Alternatively, window.location.href could be used.
const isLocationUpdated =
typeof data.location === 'string' ||
!areLocationsTheSame(data.location, location);
const isDataInvalid =
!isSamePage ||
(!isLoading && (newOffset !== previousOffset || isLocationUpdated));
@@ -114,7 +195,15 @@ function DataSourceWrapper(props) {
console.warn(ex);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [data, location, params, isLoading, setIsLoading]);
}, [
data,
location,
params,
isLoading,
setIsLoading,
dataSource,
isDataSourceInitialized,
]);
// queryFilterValues
// TODO: Better way to pass DataSource?
@@ -122,7 +211,7 @@ function DataSourceWrapper(props) {
<LayoutTemplate
{...rest}
data={data.studies}
dataPath={dataPath}
dataPath={dataSourcePath}
dataTotal={data.total}
dataSource={dataSource}
isLoadingData={isLoading}
+16 -11
View File
@@ -4,7 +4,7 @@ import PropTypes from 'prop-types';
// TODO: DicomMetadataStore should be injected?
import { DicomMetadataStore, ServicesManager, utils } from '@ohif/core';
import { DragAndDropProvider, ImageViewerProvider } from '@ohif/ui';
import { useQuery, useSearchParams } from '@hooks';
import { useSearchParams } from '@hooks';
import ViewportGrid from '@components/ViewportGrid';
import Compose from './Compose';
import getStudies from './studiesList';
@@ -95,9 +95,13 @@ export default function ModeRoute({
}) {
// Parse route params/querystring
const location = useLocation();
const query = useQuery();
// The react router DOM placeholder map (see https://reactrouter.com/en/main/hooks/use-params).
const params = useParams();
const searchParams = useSearchParams();
// The URL's query search parameters where the keys casing is maintained
const query = useSearchParams();
// The URL's query search parameters where the keys are all lower case.
const lowerCaseSearchParams = useSearchParams({ lowerCaseKeys: true });
const [studyInstanceUIDs, setStudyInstanceUIDs] = useState();
@@ -132,8 +136,10 @@ export default function ModeRoute({
hangingProtocol,
} = mode;
const runTimeHangingProtocolId = searchParams.get('hangingprotocolid');
const token = searchParams.get('token');
const runTimeHangingProtocolId = lowerCaseSearchParams.get(
'hangingprotocolid'
);
const token = lowerCaseSearchParams.get('token');
if (token) {
// if a token is passed in, set the userAuthenticationService to use it
@@ -163,12 +169,11 @@ export default function ModeRoute({
const hotkeys = Array.isArray(hotkeyObj) ? hotkeyObj : hotkeyObj?.hotkeys;
const hotkeyName = hotkeyObj?.name || 'hotkey-definitions-v2';
if (dataSourceName === undefined) {
dataSourceName = extensionManager.defaultDataSourceName;
// An undefined dataSourceName implies that the active data source that is already set in the ExtensionManager should be used.
if (dataSourceName !== undefined) {
extensionManager.setActiveDataSource(dataSourceName);
}
extensionManager.setActiveDataSource(dataSourceName);
const dataSource = extensionManager.getActiveDataSource()[0];
// Only handling one route per mode for now
@@ -232,11 +237,11 @@ export default function ModeRoute({
// Todo: this should not be here, data source should not care about params
const initializeDataSource = async (params, query) => {
const studyInstanceUIDs = await dataSource.initialize({
await dataSource.initialize({
params,
query,
});
setStudyInstanceUIDs(studyInstanceUIDs);
setStudyInstanceUIDs(dataSource.getStudyInstanceUIDs({ params, query }));
};
initializeDataSource(params, query);
@@ -459,7 +459,7 @@ function WorkList({
const { component: dicomUploadComponent } =
customizationService.get('dicomUploadComponent') ?? {};
const uploadProps =
dicomUploadComponent && dataSource.getConfig().dicomUploadEnabled
dicomUploadComponent && dataSource.getConfig()?.dicomUploadEnabled
? {
title: 'Upload files',
closeButton: true,
+2 -4
View File
@@ -63,16 +63,14 @@ export default function buildModeRoutes({
});
});
const defaultDataSourceName = extensionManager.defaultDataSourceName;
// Add default DataSource route.
// Add active DataSource route.
// This is the DataSource route for the active data source defined in ExtensionManager.getActiveDataSource
const path = `/${mode.routeName}`;
// TODO move up.
const children = () => (
<ModeRoute
mode={mode}
dataSourceName={defaultDataSourceName}
extensionManager={extensionManager}
servicesManager={servicesManager}
commandsManager={commandsManager}
+1 -1
View File
@@ -56,7 +56,7 @@ const createRoutes = ({
path: '/',
children: DataSourceWrapper,
private: true,
props: { children: WorkList, servicesManager },
props: { children: WorkList, servicesManager, extensionManager },
};
const customRoutes = customizationService.getGlobalCustomization(