feat(DataSource): Allow for dynamic data source configuration and creation (#3543)
This commit is contained in:
1 parent
6d88978710
commit
7bbc213f58
36 files changed
+640
-298
No files matched your search
@@ -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 => {
|
||||
|
||||
@@ -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 => {
|
||||
|
||||
@@ -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',
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
@@ -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 => {
|
||||
|
||||
@@ -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',
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
@@ -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,
|
||||
|
||||
@@ -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 => {
|
||||
|
||||
@@ -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 => {
|
||||
|
||||
@@ -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 => {
|
||||
|
||||
@@ -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 => {
|
||||
|
||||
@@ -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 };
|
||||
@@ -1,5 +0,0 @@
|
||||
import { useLocation } from 'react-router-dom';
|
||||
|
||||
export default function useQuery() {
|
||||
return new URLSearchParams(useLocation().search);
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -56,7 +56,7 @@ const createRoutes = ({
|
||||
path: '/',
|
||||
children: DataSourceWrapper,
|
||||
private: true,
|
||||
props: { children: WorkList, servicesManager },
|
||||
props: { children: WorkList, servicesManager, extensionManager },
|
||||
};
|
||||
|
||||
const customRoutes = customizationService.getGlobalCustomization(
|
||||
|
||||
Reference in new issue
Block a user