fix(datasource): configurability of additional data source extensions (#2931)
* feat(dataSource):Support more than one data source type. * Add consumer type
This commit is contained in:
parent
55a1704e4a
commit
3900e62641
@ -6,7 +6,7 @@
|
|||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"repository": "OHIF/Viewers",
|
"repository": "OHIF/Viewers",
|
||||||
"main": "dist/index.umd.js",
|
"main": "dist/index.umd.js",
|
||||||
"module": "src/index.js",
|
"module": "src/index.ts",
|
||||||
"sideEffects": "false",
|
"sideEffects": "false",
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
"access": "public"
|
"access": "public"
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import * as OHIF from './index.js';
|
import * as OHIF from './index';
|
||||||
|
|
||||||
describe('Top level exports', () => {
|
describe('Top level exports', () => {
|
||||||
test('have not changed', () => {
|
test('have not changed', () => {
|
||||||
@ -31,6 +31,7 @@ describe('Top level exports', () => {
|
|||||||
'DisplaySetService',
|
'DisplaySetService',
|
||||||
'MeasurementService',
|
'MeasurementService',
|
||||||
'ToolBarService',
|
'ToolBarService',
|
||||||
|
'Types',
|
||||||
'ViewportGridService',
|
'ViewportGridService',
|
||||||
'SegmentationService',
|
'SegmentationService',
|
||||||
'HangingProtocolService',
|
'HangingProtocolService',
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { ExtensionManager, MODULE_TYPES } from './extensions';
|
import { ExtensionManager, MODULE_TYPES } from './extensions';
|
||||||
import { ServicesManager } from './services';
|
import { ServicesManager } from './services';
|
||||||
import classes, { CommandsManager, HotkeysManager } from './classes/';
|
import classes, { CommandsManager, HotkeysManager } from './classes';
|
||||||
|
|
||||||
import DICOMWeb from './DICOMWeb';
|
import DICOMWeb from './DICOMWeb';
|
||||||
import errorHandler from './errorHandler.js';
|
import errorHandler from './errorHandler.js';
|
||||||
@ -8,8 +8,9 @@ import log from './log.js';
|
|||||||
import object from './object.js';
|
import object from './object.js';
|
||||||
import string from './string.js';
|
import string from './string.js';
|
||||||
import user from './user.js';
|
import user from './user.js';
|
||||||
import utils from './utils/';
|
import utils from './utils';
|
||||||
import defaults from './defaults';
|
import defaults from './defaults';
|
||||||
|
import * as Types from './types';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
CineService,
|
CineService,
|
||||||
@ -107,6 +108,7 @@ export {
|
|||||||
IWebApiDataSource,
|
IWebApiDataSource,
|
||||||
DicomMetadataStore,
|
DicomMetadataStore,
|
||||||
pubSubServiceInterface,
|
pubSubServiceInterface,
|
||||||
|
Types,
|
||||||
};
|
};
|
||||||
|
|
||||||
export { OHIF };
|
export { OHIF };
|
||||||
@ -1,7 +0,0 @@
|
|||||||
/** Defines a typescript type for study metadata */
|
|
||||||
interface StudyMetadata {
|
|
||||||
readonly StudyInstanceUID: string;
|
|
||||||
StudyDescription?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export default StudyMetadata;
|
|
||||||
@ -1,7 +1,7 @@
|
|||||||
import pubSubServiceInterface from '../_shared/pubSubServiceInterface';
|
import pubSubServiceInterface from '../_shared/pubSubServiceInterface';
|
||||||
import sortBy from '../../utils/sortBy';
|
import sortBy from '../../utils/sortBy';
|
||||||
import ProtocolEngine from './ProtocolEngine';
|
import ProtocolEngine from './ProtocolEngine';
|
||||||
import StudyMetadata from '../DicomMetadataStore/StudyMetadata';
|
import StudyMetadata from '../../types/StudyMetadata';
|
||||||
import IDisplaySet from '../DisplaySetService/IDisplaySet';
|
import IDisplaySet from '../DisplaySetService/IDisplaySet';
|
||||||
|
|
||||||
const EVENTS = {
|
const EVENTS = {
|
||||||
|
|||||||
5
platform/core/src/types/Consumer.ts
Normal file
5
platform/core/src/types/Consumer.ts
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
/**
|
||||||
|
* Just a function that consumes a single argument, with no return.
|
||||||
|
*/
|
||||||
|
type Consumer = (props: Record<string, unknown>) => void;
|
||||||
|
export default Consumer;
|
||||||
12
platform/core/src/types/IPubSub.ts
Normal file
12
platform/core/src/types/IPubSub.ts
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import { Consumer } from './Consumer';
|
||||||
|
|
||||||
|
|
||||||
|
export default interface IPubSub {
|
||||||
|
subscribe: (eventName: string, callback: Consumer) => void;
|
||||||
|
_broadcastEvent: (
|
||||||
|
eventName: string,
|
||||||
|
callbackProps: Record<string, unknown>
|
||||||
|
) => void;
|
||||||
|
_unsubscribe: (eventName: string, listenerId: string) => void;
|
||||||
|
_isValidEvent: (eventName: string) => boolean;
|
||||||
|
}
|
||||||
23
platform/core/src/types/StudyMetadata.ts
Normal file
23
platform/core/src/types/StudyMetadata.ts
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
/** Defines a typescript type for study metadata */
|
||||||
|
|
||||||
|
export interface PatientMetadata extends Record<string, unknown> {
|
||||||
|
PatientName?: string;
|
||||||
|
PatientId?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface StudyMetadata extends Record<string, unknown> {
|
||||||
|
readonly StudyInstanceUID?: string;
|
||||||
|
StudyDescription?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SeriesMetadata extends StudyMetadata {
|
||||||
|
readonly SeriesInstanceUID?: string;
|
||||||
|
SeriesDescription?: string;
|
||||||
|
SeriesNumber?: string | number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface InstanceMetadata extends SeriesMetadata {
|
||||||
|
readonly SOPInstanceUID: string;
|
||||||
|
InstanceNumber?: string | number;
|
||||||
|
}
|
||||||
|
export default StudyMetadata;
|
||||||
9
platform/core/src/types/index.ts
Normal file
9
platform/core/src/types/index.ts
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
import {
|
||||||
|
StudyMetadata,
|
||||||
|
SeriesMetadata,
|
||||||
|
InstanceMetadata,
|
||||||
|
} from './StudyMetadata';
|
||||||
|
|
||||||
|
import Consumer from './Consumer';
|
||||||
|
|
||||||
|
export { StudyMetadata, SeriesMetadata, InstanceMetadata, Consumer };
|
||||||
@ -4,7 +4,7 @@ import classnames from 'classnames';
|
|||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
import { ButtonGroup, Button, StudyItem, ThumbnailList } from '../';
|
import { ButtonGroup, Button, StudyItem, ThumbnailList } from '../';
|
||||||
import { StringNumber } from '../../Types';
|
import { StringNumber } from '../../types';
|
||||||
|
|
||||||
const buttonClasses = 'text-white text-base border-none p-2 min-w-18';
|
const buttonClasses = 'text-white text-base border-none p-2 min-w-18';
|
||||||
|
|
||||||
|
|||||||
@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
|
|||||||
import classnames from 'classnames';
|
import classnames from 'classnames';
|
||||||
import { useDrag } from 'react-dnd';
|
import { useDrag } from 'react-dnd';
|
||||||
import { Icon } from '../';
|
import { Icon } from '../';
|
||||||
import { StringNumber } from '../../Types';
|
import { StringNumber } from '../../types';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import React from 'react';
|
|||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
import { Thumbnail, ThumbnailNoImage, ThumbnailTracked } from '../';
|
import { Thumbnail, ThumbnailNoImage, ThumbnailTracked } from '../';
|
||||||
import * as Types from '../../Types';
|
import * as Types from '../../types';
|
||||||
|
|
||||||
const ThumbnailList = ({
|
const ThumbnailList = ({
|
||||||
thumbnails,
|
thumbnails,
|
||||||
|
|||||||
@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
|
|||||||
import classnames from 'classnames';
|
import classnames from 'classnames';
|
||||||
|
|
||||||
import { Icon, Thumbnail, Tooltip } from '../';
|
import { Icon, Thumbnail, Tooltip } from '../';
|
||||||
import { StringNumber } from '../../Types';
|
import { StringNumber } from '../../types';
|
||||||
|
|
||||||
const ThumbnailTracked = ({
|
const ThumbnailTracked = ({
|
||||||
displaySetInstanceUID,
|
displaySetInstanceUID,
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import classnames from 'classnames';
|
|||||||
import { Icon, ButtonGroup, Button, Tooltip, CinePlayer } from '../';
|
import { Icon, ButtonGroup, Button, Tooltip, CinePlayer } from '../';
|
||||||
import useOnClickOutside from '../../utils/useOnClickOutside';
|
import useOnClickOutside from '../../utils/useOnClickOutside';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { StringNumber } from '../../Types';
|
import { StringNumber } from '../../types';
|
||||||
|
|
||||||
const classes = {
|
const classes = {
|
||||||
infoHeader: 'text-base text-primary-light',
|
infoHeader: 'text-base text-primary-light',
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
/** CONTEXT/HOOKS */
|
/** CONTEXT/HOOKS */
|
||||||
// Export types - need to do as two lines due to a bug in babel
|
// Export types - need to do as two lines due to a bug in babel
|
||||||
import * as Types from './Types';
|
import * as Types from './types';
|
||||||
|
|
||||||
export {
|
export {
|
||||||
useCine,
|
useCine,
|
||||||
|
|||||||
7
platform/ui/src/types/ThumbnailType.ts
Normal file
7
platform/ui/src/types/ThumbnailType.ts
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
|
export default PropTypes.oneOf([
|
||||||
|
'thumbnail',
|
||||||
|
'thumbnailTracked',
|
||||||
|
'thumbnailNoImage',
|
||||||
|
]);
|
||||||
@ -1,4 +1,7 @@
|
|||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
import ThumbnailType from './ThumbnailType';
|
||||||
|
|
||||||
|
// A few miscellaneous types declared inline here.
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* StringNumber often comes back from DICOMweb for integer valued items.
|
* StringNumber often comes back from DICOMweb for integer valued items.
|
||||||
@ -11,10 +14,4 @@ const StringNumber = PropTypes.oneOfType([PropTypes.string, PropTypes.number]);
|
|||||||
*/
|
*/
|
||||||
const StringArray = PropTypes.oneOfType([PropTypes.string, PropTypes.array]);
|
const StringArray = PropTypes.oneOfType([PropTypes.string, PropTypes.array]);
|
||||||
|
|
||||||
const ThumbnailType = PropTypes.oneOf([
|
|
||||||
'thumbnail',
|
|
||||||
'thumbnailTracked',
|
|
||||||
'thumbnailNoImage',
|
|
||||||
]);
|
|
||||||
|
|
||||||
export { StringNumber, StringArray, ThumbnailType };
|
export { StringNumber, StringArray, ThumbnailType };
|
||||||
@ -32,11 +32,16 @@ function DataSourceWrapper(props) {
|
|||||||
return acc.concat(mods);
|
return acc.concat(mods);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
// Grabbing first for now - should get active?
|
// Grabbing first defined for now - should get active
|
||||||
const name = webApiDataSources[0].name;
|
|
||||||
// TODO: Why does this return an array?
|
// TODO: Why does this return an array?
|
||||||
const dataSource = extensionManager.getDataSources(name)[0];
|
const dataSource = webApiDataSources
|
||||||
|
.map(ds => extensionManager.getDataSources(ds.name)?.[0])
|
||||||
|
.find(it => it !== undefined);
|
||||||
|
if (!dataSource) {
|
||||||
|
throw new Error(
|
||||||
|
`No data source found for any of ${webApiDataSources.map(it => it.name)}`
|
||||||
|
);
|
||||||
|
}
|
||||||
// Route props --> studies.mapParams
|
// Route props --> studies.mapParams
|
||||||
// mapParams --> studies.search
|
// mapParams --> studies.search
|
||||||
// studies.search --> studies.processResults
|
// studies.search --> studies.processResults
|
||||||
@ -168,7 +173,7 @@ function _getQueryFilterValues(query, queryLimit) {
|
|||||||
return queryFilterValues;
|
return queryFilterValues;
|
||||||
|
|
||||||
function _tryParseInt(str, defaultValue) {
|
function _tryParseInt(str, defaultValue) {
|
||||||
var retValue = defaultValue;
|
let retValue = defaultValue;
|
||||||
if (str !== null) {
|
if (str !== null) {
|
||||||
if (str.length > 0) {
|
if (str.length > 0) {
|
||||||
if (!isNaN(str)) {
|
if (!isNaN(str)) {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user