fix: Service consistency typing (#3309)
* Use more consistent type/structure for services * Fix restoring SR so the tests described work * One more typed service * Added types for the Cornerstone library * Couple more type fixes
This commit is contained in:
parent
47c25f4364
commit
6cf271d006
@ -30,17 +30,6 @@ const extension = {
|
||||
*/
|
||||
id,
|
||||
|
||||
/**
|
||||
* Perform any pre-registration tasks here. This is called before the extension
|
||||
* is registered. Usually we run tasks such as: configuring the libraries
|
||||
* (e.g. cornerstone, cornerstoneTools, ...) or registering any services that
|
||||
* this extension is providing.
|
||||
*/
|
||||
preRegistration: ({
|
||||
servicesManager,
|
||||
commandsManager,
|
||||
configuration = {},
|
||||
}) => {},
|
||||
/**
|
||||
* PanelModule should provide a list of panels that will be available in OHIF
|
||||
* for Modes to consume and render. Each panel is defined by a {name,
|
||||
|
||||
@ -32,8 +32,8 @@
|
||||
"test:unit:ci": "jest --ci --runInBand --collectCoverage --passWithNoTests"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@ohif/core": "^3.0.0",
|
||||
"@ohif/extension-cornerstone": "^3.0.0",
|
||||
"@ohif/core": ">=3.0.0",
|
||||
"@ohif/extension-cornerstone": ">=3.0.0",
|
||||
"@ohif/extension-measurement-tracking": "^3.0.0",
|
||||
"@ohif/ui": "^2.0.0",
|
||||
"dcmjs": "^0.29.5",
|
||||
|
||||
@ -2,6 +2,8 @@ import PropTypes from 'prop-types';
|
||||
import React, { useCallback, useContext, useEffect, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import OHIF, { utils, ServicesManager, ExtensionManager } from '@ohif/core';
|
||||
import { CornerstoneServices } from '@ohif/extension-cornerstone/types';
|
||||
|
||||
import { setTrackingUniqueIdentifiersForElement } from '../tools/modules/dicomSRModule';
|
||||
|
||||
import {
|
||||
@ -37,7 +39,7 @@ function OHIFCornerstoneSRViewport(props) {
|
||||
displaySetService,
|
||||
cornerstoneViewportService,
|
||||
measurementService,
|
||||
} = servicesManager.services;
|
||||
} = servicesManager.services as CornerstoneServices;
|
||||
|
||||
// SR viewport will always have a single display set
|
||||
if (displaySets.length > 1) {
|
||||
@ -91,10 +93,12 @@ function OHIFCornerstoneSRViewport(props) {
|
||||
SeriesInstanceUIDs[0]
|
||||
);
|
||||
if (displaySets.length) {
|
||||
viewportGridService.setDisplaySetsForViewport({
|
||||
viewportIndex: activeViewportIndex,
|
||||
displaySetInstanceUIDs: [displaySets[0].displaySetInstanceUID],
|
||||
});
|
||||
viewportGridService.setDisplaySetsForViewports([
|
||||
{
|
||||
viewportIndex: activeViewportIndex,
|
||||
displaySetInstanceUIDs: [displaySets[0].displaySetInstanceUID],
|
||||
},
|
||||
]);
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -422,6 +426,7 @@ OHIFCornerstoneSRViewport.propTypes = {
|
||||
children: PropTypes.node,
|
||||
customProps: PropTypes.object,
|
||||
viewportOptions: PropTypes.object,
|
||||
viewportLabel: PropTypes.string,
|
||||
servicesManager: PropTypes.instanceOf(ServicesManager).isRequired,
|
||||
extensionManager: PropTypes.instanceOf(ExtensionManager).isRequired,
|
||||
};
|
||||
|
||||
@ -7,6 +7,11 @@
|
||||
"repository": "OHIF/Viewers",
|
||||
"main": "dist/index.umd.js",
|
||||
"module": "src/index.tsx",
|
||||
"types": "src/types/index.ts",
|
||||
"exports": {
|
||||
".": "./src/index.tsx",
|
||||
"./types": "./src/types/index.ts"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10",
|
||||
"npm": ">=6",
|
||||
|
||||
@ -10,17 +10,18 @@ import {
|
||||
utilities as csUtils,
|
||||
CONSTANTS,
|
||||
} from '@cornerstonejs/core';
|
||||
import { CinePlayer, useCine, useViewportGrid } from '@ohif/ui';
|
||||
import {
|
||||
IStackViewport,
|
||||
IVolumeViewport,
|
||||
} from '@cornerstonejs/core/dist/esm/types';
|
||||
|
||||
import { setEnabledElement } from '../state';
|
||||
|
||||
import './OHIFCornerstoneViewport.css';
|
||||
import CornerstoneOverlays from './Overlays/CornerstoneOverlays';
|
||||
import {
|
||||
IStackViewport,
|
||||
IVolumeViewport,
|
||||
} from '@cornerstonejs/core/dist/esm/types';
|
||||
import getSOPInstanceAttributes from '../utils/measurementServiceMappings/utils/getSOPInstanceAttributes';
|
||||
import { CinePlayer, useCine, useViewportGrid } from '@ohif/ui';
|
||||
import CornerstoneServices from '../types/CornerstoneServices';
|
||||
|
||||
const STACK = 'stack';
|
||||
|
||||
@ -129,7 +130,7 @@ const OHIFCornerstoneViewport = React.memo(props => {
|
||||
cornerstoneCacheService,
|
||||
viewportGridService,
|
||||
stateSyncService,
|
||||
} = servicesManager.services;
|
||||
} = servicesManager.services as CornerstoneServices;
|
||||
|
||||
const cineHandler = () => {
|
||||
if (!cines || !cines[viewportIndex] || !enabledVPElement) {
|
||||
|
||||
@ -7,7 +7,7 @@ import {
|
||||
imageRetrievalPoolManager,
|
||||
} from '@cornerstonejs/core';
|
||||
import { Enums as cs3DToolsEnums } from '@cornerstonejs/tools';
|
||||
import { Types } from '@ohif/core';
|
||||
import { ServicesManager, Types } from '@ohif/core';
|
||||
|
||||
import init from './init';
|
||||
import getCommandsModule from './commandsModule';
|
||||
@ -16,10 +16,11 @@ import ToolGroupService from './services/ToolGroupService';
|
||||
import SyncGroupService from './services/SyncGroupService';
|
||||
import SegmentationService from './services/SegmentationService';
|
||||
import CornerstoneCacheService from './services/CornerstoneCacheService';
|
||||
import CornerstoneViewportService from './services/ViewportService/CornerstoneViewportService';
|
||||
import * as CornerstoneExtensionTypes from './types';
|
||||
|
||||
import { toolNames } from './initCornerstoneTools';
|
||||
import { getEnabledElement, reset as enabledElementReset } from './state';
|
||||
import CornerstoneViewportService from './services/ViewportService/CornerstoneViewportService';
|
||||
import dicomLoaderService from './utils/dicomLoaderService';
|
||||
import { registerColormap } from './utils/colormap/transferFunctionHelpers';
|
||||
|
||||
@ -72,18 +73,11 @@ const cornerstoneExtension: Types.Extensions.Extension = {
|
||||
props: Types.Extensions.ExtensionParams
|
||||
): Promise<void> {
|
||||
const { servicesManager } = props;
|
||||
// Todo: we should be consistent with how services get registered. Use REGISTRATION static method for all
|
||||
servicesManager.registerService(
|
||||
CornerstoneViewportService(servicesManager)
|
||||
);
|
||||
servicesManager.registerService(
|
||||
ToolGroupService.REGISTRATION(servicesManager)
|
||||
);
|
||||
servicesManager.registerService(SyncGroupService(servicesManager));
|
||||
servicesManager.registerService(SegmentationService(servicesManager));
|
||||
servicesManager.registerService(
|
||||
CornerstoneCacheService.REGISTRATION(servicesManager)
|
||||
);
|
||||
servicesManager.registerService(CornerstoneViewportService.REGISTRATION);
|
||||
servicesManager.registerService(ToolGroupService.REGISTRATION);
|
||||
servicesManager.registerService(SyncGroupService.REGISTRATION);
|
||||
servicesManager.registerService(SegmentationService.REGISTRATION);
|
||||
servicesManager.registerService(CornerstoneCacheService.REGISTRATION);
|
||||
|
||||
return init.call(this, props);
|
||||
},
|
||||
@ -145,5 +139,5 @@ const cornerstoneExtension: Types.Extensions.Extension = {
|
||||
};
|
||||
|
||||
export type { PublicViewportOptions };
|
||||
export { measurementMappingUtils };
|
||||
export { measurementMappingUtils, CornerstoneExtensionTypes };
|
||||
export default cornerstoneExtension;
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { ServicesManager } from '@ohif/core';
|
||||
import { ServicesManager, Types } from '@ohif/core';
|
||||
import { cache as cs3DCache, Enums, volumeLoader } from '@cornerstonejs/core';
|
||||
|
||||
import getCornerstoneViewportType from '../../utils/getCornerstoneViewportType';
|
||||
@ -10,20 +10,21 @@ import {
|
||||
const VOLUME_LOADER_SCHEME = 'cornerstoneStreamingImageVolume';
|
||||
|
||||
class CornerstoneCacheService {
|
||||
static REGISTRATION = (serviceManager: ServicesManager) => {
|
||||
return {
|
||||
name: 'cornerstoneCacheService',
|
||||
altName: 'CornerstoneCacheService',
|
||||
create: ({ configuration = {} }) => {
|
||||
return new CornerstoneCacheService(serviceManager);
|
||||
},
|
||||
};
|
||||
static REGISTRATION = {
|
||||
name: 'cornerstoneCacheService',
|
||||
altName: 'CornerstoneCacheService',
|
||||
create: ({
|
||||
servicesManager,
|
||||
}: Types.Extensions.ExtensionParams): CornerstoneCacheService => {
|
||||
return new CornerstoneCacheService(servicesManager);
|
||||
},
|
||||
};
|
||||
|
||||
stackImageIds: Map<string, string[]> = new Map();
|
||||
volumeImageIds: Map<string, string[]> = new Map();
|
||||
readonly servicesManager: ServicesManager;
|
||||
|
||||
constructor(servicesManager) {
|
||||
constructor(servicesManager: ServicesManager) {
|
||||
this.servicesManager = servicesManager;
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import cloneDeep from 'lodash.clonedeep';
|
||||
|
||||
import { Types as OhifTypes, ServicesManager, PubSubService } from '@ohif/core';
|
||||
import {
|
||||
cache,
|
||||
eventTarget,
|
||||
@ -16,7 +17,6 @@ import {
|
||||
Types as cstTypes,
|
||||
utilities as cstUtils,
|
||||
} from '@cornerstonejs/tools';
|
||||
import { pubSubServiceInterface } from '@ohif/core';
|
||||
import isEqual from 'lodash.isequal';
|
||||
import { easeInOutBell } from '../../utils/transitions';
|
||||
import {
|
||||
@ -47,19 +47,26 @@ const EVENTS = {
|
||||
|
||||
const VALUE_TYPES = {};
|
||||
|
||||
class SegmentationService {
|
||||
listeners = {};
|
||||
class SegmentationService extends PubSubService {
|
||||
static REGISTRATION = {
|
||||
name: 'segmentationService',
|
||||
altName: 'SegmentationService',
|
||||
create: ({
|
||||
servicesManager,
|
||||
}: OhifTypes.Extensions.ExtensionParams): SegmentationService => {
|
||||
return new SegmentationService({ servicesManager });
|
||||
},
|
||||
};
|
||||
|
||||
segmentations: Record<string, Segmentation>;
|
||||
servicesManager = null;
|
||||
readonly servicesManager: ServicesManager;
|
||||
highlightIntervalId = null;
|
||||
_broadcastEvent: (eventName: string, callbackProps: any) => void;
|
||||
readonly EVENTS = EVENTS;
|
||||
|
||||
constructor({ servicesManager }) {
|
||||
super(EVENTS);
|
||||
this.segmentations = {};
|
||||
this.listeners = {};
|
||||
|
||||
Object.assign(this, pubSubServiceInterface);
|
||||
this.servicesManager = servicesManager;
|
||||
|
||||
this._initSegmentationService();
|
||||
|
||||
@ -1,11 +1,3 @@
|
||||
import SegmentationService from './SegmentationService';
|
||||
|
||||
export default function ExtendedSegmentationService(servicesManager) {
|
||||
return {
|
||||
name: 'segmentationService',
|
||||
altName: 'SegmentationService',
|
||||
create: ({ configuration = {} }) => {
|
||||
return new SegmentationService({ servicesManager });
|
||||
},
|
||||
};
|
||||
}
|
||||
export default SegmentationService;
|
||||
|
||||
@ -4,7 +4,7 @@ import {
|
||||
Synchronizer,
|
||||
} from '@cornerstonejs/tools';
|
||||
|
||||
import { pubSubServiceInterface } from '@ohif/core';
|
||||
import { pubSubServiceInterface, Types, ServicesManager } from '@ohif/core';
|
||||
|
||||
const EVENTS = {
|
||||
TOOL_GROUP_CREATED: 'event::cornerstone::syncgroupservice:toolgroupcreated',
|
||||
@ -37,7 +37,17 @@ const asSyncGroup = (syncGroup: string | SyncGroup): SyncGroup =>
|
||||
typeof syncGroup === 'string' ? { type: syncGroup } : syncGroup;
|
||||
|
||||
export default class SyncGroupService {
|
||||
serviceManager: any;
|
||||
static REGISTRATION = {
|
||||
name: 'syncGroupService',
|
||||
altName: 'SyncGroupService',
|
||||
create: ({
|
||||
servicesManager,
|
||||
}: Types.Extensions.ExtensionParams): SyncGroupService => {
|
||||
return new SyncGroupService(servicesManager);
|
||||
},
|
||||
};
|
||||
|
||||
servicesManager: ServicesManager;
|
||||
listeners: { [key: string]: (...args: any[]) => void } = {};
|
||||
EVENTS: { [key: string]: string };
|
||||
synchronizerCreators: Record<string, SyncCreator> = {
|
||||
@ -47,8 +57,8 @@ export default class SyncGroupService {
|
||||
[STACKIMAGE]: synchronizers.createStackImageSynchronizer,
|
||||
};
|
||||
|
||||
constructor(serviceManager) {
|
||||
this.serviceManager = serviceManager;
|
||||
constructor(serviceManager: ServicesManager) {
|
||||
this.servicesManager = serviceManager;
|
||||
this.listeners = {};
|
||||
this.EVENTS = EVENTS;
|
||||
//
|
||||
|
||||
@ -1,11 +1,3 @@
|
||||
import SyncGroupService from './SyncGroupService';
|
||||
|
||||
export default function ExtendedSyncGroupService(serviceManager) {
|
||||
return {
|
||||
altName: 'SyncGroupService',
|
||||
name: 'syncGroupService',
|
||||
create: ({ configuration = {} }) => {
|
||||
return new SyncGroupService(serviceManager);
|
||||
},
|
||||
};
|
||||
}
|
||||
export default SyncGroupService;
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { ToolGroupManager, Enums, Types } from '@cornerstonejs/tools';
|
||||
|
||||
import { pubSubServiceInterface } from '@ohif/core';
|
||||
import { Types as OhifTypes, pubSubServiceInterface } from '@ohif/core';
|
||||
|
||||
const EVENTS = {
|
||||
VIEWPORT_ADDED: 'event::cornerstone::toolgroupservice:viewportadded',
|
||||
@ -20,14 +20,14 @@ type Tools = {
|
||||
};
|
||||
|
||||
export default class ToolGroupService {
|
||||
public static REGISTRATION = serviceManager => {
|
||||
return {
|
||||
name: 'toolGroupService',
|
||||
altName: 'ToolGroupService',
|
||||
create: ({ configuration = {} }) => {
|
||||
return new ToolGroupService(serviceManager);
|
||||
},
|
||||
};
|
||||
public static REGISTRATION = {
|
||||
name: 'toolGroupService',
|
||||
altName: 'ToolGroupService',
|
||||
create: ({
|
||||
servicesManager,
|
||||
}: OhifTypes.Extensions.ExtensionParams): ToolGroupService => {
|
||||
return new ToolGroupService(servicesManager);
|
||||
},
|
||||
};
|
||||
|
||||
serviceManager: any;
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import { PubSubService } from '@ohif/core';
|
||||
import { PubSubService, ServicesManager } from '@ohif/core';
|
||||
import * as OhifTypes from '@ohif/core/types';
|
||||
import {
|
||||
RenderingEngine,
|
||||
StackViewport,
|
||||
@ -43,6 +44,16 @@ const EVENTS = {
|
||||
*/
|
||||
class CornerstoneViewportService extends PubSubService
|
||||
implements IViewportService {
|
||||
static REGISTRATION = {
|
||||
name: 'cornerstoneViewportService',
|
||||
altName: 'CornerstoneViewportService',
|
||||
create: ({
|
||||
servicesManager,
|
||||
}: OhifTypes.Extensions.ExtensionParams): CornerstoneViewportService => {
|
||||
return new CornerstoneViewportService(servicesManager);
|
||||
},
|
||||
};
|
||||
|
||||
renderingEngine: Types.IRenderingEngine | null;
|
||||
viewportsInfo: Map<number, ViewportInfo> = new Map();
|
||||
viewportsById: Map<string, ViewportInfo> = new Map();
|
||||
@ -55,7 +66,7 @@ class CornerstoneViewportService extends PubSubService
|
||||
resizeRefreshMode: 'debounce';
|
||||
servicesManager = null;
|
||||
|
||||
constructor(servicesManager) {
|
||||
constructor(servicesManager: ServicesManager) {
|
||||
super(EVENTS);
|
||||
this.renderingEngine = null;
|
||||
this.viewportGridResizeObserver = null;
|
||||
@ -71,7 +82,7 @@ class CornerstoneViewportService extends PubSubService
|
||||
viewportIndex: number,
|
||||
viewportOptions: PublicViewportOptions,
|
||||
elementRef: HTMLDivElement
|
||||
) {
|
||||
): void {
|
||||
// Use the provided viewportId
|
||||
// Not providing a viewportId is frowned upon because it does weird things
|
||||
// on moving them around, but it does mostly work.
|
||||
@ -855,14 +866,4 @@ class CornerstoneViewportService extends PubSubService
|
||||
}
|
||||
}
|
||||
|
||||
export default function CornerstoneViewportServiceRegistration(serviceManager) {
|
||||
return {
|
||||
name: 'cornerstoneViewportService',
|
||||
altName: 'CornerstoneViewportService',
|
||||
create: ({ configuration = {} }) => {
|
||||
return new CornerstoneViewportService(serviceManager);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export { CornerstoneViewportService, CornerstoneViewportServiceRegistration };
|
||||
export default CornerstoneViewportService;
|
||||
|
||||
16
extensions/cornerstone/src/types/CornerstoneServices.ts
Normal file
16
extensions/cornerstone/src/types/CornerstoneServices.ts
Normal file
@ -0,0 +1,16 @@
|
||||
import { Types } from '@ohif/core';
|
||||
import ToolGroupService from './services/ToolGroupService';
|
||||
import SyncGroupService from './services/SyncGroupService';
|
||||
import SegmentationService from './services/SegmentationService';
|
||||
import CornerstoneCacheService from './services/CornerstoneCacheService';
|
||||
import CornerstoneViewportService from './services/ViewportService/CornerstoneViewportService';
|
||||
|
||||
interface CornerstoneServices extends Types.Services {
|
||||
cornerstoneViewportService: CornerstoneViewportService;
|
||||
toolGroupService: ToolGroupService;
|
||||
syncGroupService: SyncGroupService;
|
||||
segmentationService: SegmentationService;
|
||||
cornerstoneCacheService: CornerstoneCacheService;
|
||||
}
|
||||
|
||||
export default CornerstoneServices;
|
||||
@ -1,5 +1,7 @@
|
||||
import * as CornerstoneCacheService from './CornerstoneCacheService'
|
||||
import CornerstoneServices from './CornerstoneServices';
|
||||
|
||||
export type {
|
||||
CornerstoneCacheService
|
||||
CornerstoneCacheService,
|
||||
CornerstoneServices,
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import ContextMenuController from './ContextMenuController';
|
||||
import ContextMenuItemsBuilder from './ContextMenuItemsBuilder';
|
||||
import * as ContextMenuItemsBuilder from './ContextMenuItemsBuilder';
|
||||
import defaultContextMenu from './defaultContextMenu';
|
||||
import * as CustomizeableContextMenuTypes from './types';
|
||||
|
||||
|
||||
@ -7,6 +7,7 @@
|
||||
"repository": "OHIF/Viewers",
|
||||
"main": "dist/index.umd.js",
|
||||
"module": "src/index.ts",
|
||||
"types": "src/types/index.ts",
|
||||
"sideEffects": "false",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
|
||||
@ -37,9 +37,12 @@ export interface ExtensionParams extends ExtensionConstructor {
|
||||
export interface Extension {
|
||||
id: string;
|
||||
preRegistration?: (p: ExtensionParams) => Promise<void> | void;
|
||||
onModeExit?: () => void;
|
||||
getHangingProtocolModule?: (p: ExtensionParams) => unknown;
|
||||
getCommandsModule?: (p: ExtensionParams) => CommandsModule;
|
||||
getViewportModule?: (p: ExtensionParams) => unknown;
|
||||
getUtilityModule?: (p: ExtensionParams) => unknown;
|
||||
onModeEnter?: () => void;
|
||||
onModeExit?: () => void;
|
||||
}
|
||||
|
||||
export type ExtensionRegister = {
|
||||
|
||||
@ -1,91 +0,0 @@
|
||||
/**
|
||||
* UI Modal
|
||||
*
|
||||
* @typedef {Object} ModalProps
|
||||
* @property {ReactElement|HTMLElement} [content=null] Modal content.
|
||||
* @property {Object} [contentProps=null] Modal content props.
|
||||
* @property {boolean} [shouldCloseOnEsc=false] Modal is dismissible via the esc key.
|
||||
* @property {boolean} [isOpen=true] Make the Modal visible or hidden.
|
||||
* @property {boolean} [closeButton=true] Should the modal body render the close button.
|
||||
* @property {string} [title=null] Should the modal render the title independently of the body content.
|
||||
* @property {string} [customClassName=null] The custom class to style the modal.
|
||||
*/
|
||||
|
||||
const name = 'uiModalService';
|
||||
|
||||
const publicAPI = {
|
||||
name,
|
||||
hide: _hide,
|
||||
show: _show,
|
||||
setServiceImplementation,
|
||||
};
|
||||
|
||||
const serviceImplementation = {
|
||||
_hide: () => console.warn('hide() NOT IMPLEMENTED'),
|
||||
_show: () => console.warn('show() NOT IMPLEMENTED'),
|
||||
};
|
||||
|
||||
/**
|
||||
* Show a new UI modal;
|
||||
*
|
||||
* @param {ModalProps} props { content, contentProps, shouldCloseOnEsc, isOpen, closeButton, title, customClassName }
|
||||
*/
|
||||
function _show({
|
||||
content = null,
|
||||
contentProps = null,
|
||||
shouldCloseOnEsc = true,
|
||||
isOpen = true,
|
||||
closeButton = true,
|
||||
title = null,
|
||||
customClassName = null,
|
||||
}) {
|
||||
return serviceImplementation._show({
|
||||
content,
|
||||
contentProps,
|
||||
shouldCloseOnEsc,
|
||||
isOpen,
|
||||
closeButton,
|
||||
title,
|
||||
customClassName,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Hides/dismisses the modal, if currently shown
|
||||
*
|
||||
* @returns void
|
||||
*/
|
||||
function _hide() {
|
||||
return serviceImplementation._hide();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param {*} {
|
||||
* hide: hideImplementation,
|
||||
* show: showImplementation,
|
||||
* }
|
||||
*/
|
||||
function setServiceImplementation({
|
||||
hide: hideImplementation,
|
||||
show: showImplementation,
|
||||
}) {
|
||||
if (hideImplementation) {
|
||||
serviceImplementation._hide = hideImplementation;
|
||||
}
|
||||
if (showImplementation) {
|
||||
serviceImplementation._show = showImplementation;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO - export TS Type
|
||||
export default {
|
||||
REGISTRATION: {
|
||||
name,
|
||||
altName: 'UIModalService',
|
||||
create: ({ configuration = {} }) => {
|
||||
return publicAPI;
|
||||
},
|
||||
},
|
||||
};
|
||||
87
platform/core/src/services/UIModalService/index.ts
Normal file
87
platform/core/src/services/UIModalService/index.ts
Normal file
@ -0,0 +1,87 @@
|
||||
/**
|
||||
* UI Modal
|
||||
*
|
||||
* @typedef {Object} ModalProps
|
||||
* @property {ReactElement|HTMLElement} [content=null] Modal content.
|
||||
* @property {Object} [contentProps=null] Modal content props.
|
||||
* @property {boolean} [shouldCloseOnEsc=false] Modal is dismissible via the esc key.
|
||||
* @property {boolean} [isOpen=true] Make the Modal visible or hidden.
|
||||
* @property {boolean} [closeButton=true] Should the modal body render the close button.
|
||||
* @property {string} [title=null] Should the modal render the title independently of the body content.
|
||||
* @property {string} [customClassName=null] The custom class to style the modal.
|
||||
*/
|
||||
|
||||
const name = 'uiModalService';
|
||||
|
||||
const serviceImplementation = {
|
||||
_hide: () => console.warn('hide() NOT IMPLEMENTED'),
|
||||
_show: () => console.warn('show() NOT IMPLEMENTED'),
|
||||
};
|
||||
|
||||
class UIModalService {
|
||||
static REGISTRATION = {
|
||||
name,
|
||||
altName: 'UIModalService',
|
||||
create: (): UIModalService => {
|
||||
return new UIModalService();
|
||||
},
|
||||
};
|
||||
|
||||
readonly name = name;
|
||||
|
||||
/**
|
||||
* Show a new UI modal;
|
||||
*
|
||||
* @param {ModalProps} props { content, contentProps, shouldCloseOnEsc, isOpen, closeButton, title, customClassName }
|
||||
*/
|
||||
show({
|
||||
content = null,
|
||||
contentProps = null,
|
||||
shouldCloseOnEsc = true,
|
||||
isOpen = true,
|
||||
closeButton = true,
|
||||
title = null,
|
||||
customClassName = null,
|
||||
}) {
|
||||
return serviceImplementation._show({
|
||||
content,
|
||||
contentProps,
|
||||
shouldCloseOnEsc,
|
||||
isOpen,
|
||||
closeButton,
|
||||
title,
|
||||
customClassName,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Hides/dismisses the modal, if currently shown
|
||||
*
|
||||
* @returns void
|
||||
*/
|
||||
hide() {
|
||||
return serviceImplementation._hide();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param {*} {
|
||||
* hide: hideImplementation,
|
||||
* show: showImplementation,
|
||||
* }
|
||||
*/
|
||||
setServiceImplementation({
|
||||
hide: hideImplementation,
|
||||
show: showImplementation,
|
||||
}) {
|
||||
if (hideImplementation) {
|
||||
serviceImplementation._hide = hideImplementation;
|
||||
}
|
||||
if (showImplementation) {
|
||||
serviceImplementation._show = showImplementation;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default UIModalService;
|
||||
@ -1,101 +0,0 @@
|
||||
/**
|
||||
* A UI Notification
|
||||
*
|
||||
* @typedef {Object} Notification
|
||||
* @property {string} title -
|
||||
* @property {string} message -
|
||||
* @property {number} [duration=5000] - in ms
|
||||
* @property {string} [position="bottomRight"] -"topLeft" | "topCenter | "topRight" | "bottomLeft" | "bottomCenter" | "bottomRight"
|
||||
* @property {string} [type="info"] - "info" | "error" | "warning" | "success"
|
||||
* @property {boolean} [autoClose=true]
|
||||
*/
|
||||
|
||||
const name = 'uiNotificationService';
|
||||
|
||||
const serviceShowRequestQueue = [];
|
||||
|
||||
const publicAPI = {
|
||||
name,
|
||||
hide: _hide,
|
||||
show: _show,
|
||||
setServiceImplementation,
|
||||
};
|
||||
|
||||
const serviceImplementation = {
|
||||
_hide: () => console.warn('hide() NOT IMPLEMENTED'),
|
||||
_show: showArguments => {
|
||||
serviceShowRequestQueue.push(showArguments);
|
||||
|
||||
console.warn('show() NOT IMPLEMENTED');
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* Create and show a new UI notification; returns the
|
||||
* ID of the created notification.
|
||||
*
|
||||
* @param {Notification} notification { title, message, duration, position, type, autoClose}
|
||||
* @returns {number} id
|
||||
*/
|
||||
function _show({
|
||||
title,
|
||||
message,
|
||||
duration = 5000,
|
||||
position = 'bottomRight',
|
||||
type = 'info',
|
||||
autoClose = true,
|
||||
}) {
|
||||
return serviceImplementation._show({
|
||||
title,
|
||||
message,
|
||||
duration,
|
||||
position,
|
||||
type,
|
||||
autoClose,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Hides/dismisses the notification, if currently shown
|
||||
*
|
||||
* @param {number} id - id of the notification to hide/dismiss
|
||||
* @returns undefined
|
||||
*/
|
||||
function _hide(id) {
|
||||
return serviceImplementation._hide({ id });
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param {*} {
|
||||
* hide: hideImplementation,
|
||||
* show: showImplementation,
|
||||
* }
|
||||
*/
|
||||
function setServiceImplementation({
|
||||
hide: hideImplementation,
|
||||
show: showImplementation,
|
||||
}) {
|
||||
if (hideImplementation) {
|
||||
serviceImplementation._hide = hideImplementation;
|
||||
}
|
||||
if (showImplementation) {
|
||||
serviceImplementation._show = showImplementation;
|
||||
|
||||
while (serviceShowRequestQueue.length > 0) {
|
||||
const showArguments = serviceShowRequestQueue.pop();
|
||||
serviceImplementation._show(showArguments);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
REGISTRATION: {
|
||||
name,
|
||||
altName: 'UINotificationService',
|
||||
create: ({ configuration = {} }) => {
|
||||
return publicAPI;
|
||||
},
|
||||
},
|
||||
};
|
||||
94
platform/core/src/services/UINotificationService/index.ts
Normal file
94
platform/core/src/services/UINotificationService/index.ts
Normal file
@ -0,0 +1,94 @@
|
||||
/**
|
||||
* A UI Notification
|
||||
*
|
||||
* @typedef {Object} Notification
|
||||
* @property {string} title -
|
||||
* @property {string} message -
|
||||
* @property {number} [duration=5000] - in ms
|
||||
* @property {string} [position="bottomRight"] -"topLeft" | "topCenter | "topRight" | "bottomLeft" | "bottomCenter" | "bottomRight"
|
||||
* @property {string} [type="info"] - "info" | "error" | "warning" | "success"
|
||||
* @property {boolean} [autoClose=true]
|
||||
*/
|
||||
|
||||
const serviceShowRequestQueue = [];
|
||||
|
||||
const serviceImplementation = {
|
||||
_hide: () => console.warn('hide() NOT IMPLEMENTED'),
|
||||
_show: showArguments => {
|
||||
serviceShowRequestQueue.push(showArguments);
|
||||
|
||||
console.warn('show() NOT IMPLEMENTED');
|
||||
},
|
||||
};
|
||||
|
||||
class UINotificationService {
|
||||
static REGISTRATION = {
|
||||
name: 'uiNotificationService',
|
||||
altName: 'UINotificationService',
|
||||
create: (): UINotificationService => {
|
||||
return new UINotificationService();
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param {*} {
|
||||
* hide: hideImplementation,
|
||||
* show: showImplementation,
|
||||
* }
|
||||
*/
|
||||
public setServiceImplementation({
|
||||
hide: hideImplementation,
|
||||
show: showImplementation,
|
||||
}): void {
|
||||
if (hideImplementation) {
|
||||
serviceImplementation._hide = hideImplementation;
|
||||
}
|
||||
if (showImplementation) {
|
||||
serviceImplementation._show = showImplementation;
|
||||
|
||||
while (serviceShowRequestQueue.length > 0) {
|
||||
const showArguments = serviceShowRequestQueue.pop();
|
||||
serviceImplementation._show(showArguments);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hides/dismisses the notification, if currently shown
|
||||
*
|
||||
* @param {number} id - id of the notification to hide/dismiss
|
||||
* @returns undefined
|
||||
*/
|
||||
public hide(id: string) {
|
||||
return serviceImplementation._hide({ id });
|
||||
}
|
||||
|
||||
/**
|
||||
* Create and show a new UI notification; returns the
|
||||
* ID of the created notification.
|
||||
*
|
||||
* @param {Notification} notification { title, message, duration, position, type, autoClose}
|
||||
* @returns {number} id
|
||||
*/
|
||||
show({
|
||||
title,
|
||||
message,
|
||||
duration = 5000,
|
||||
position = 'bottomRight',
|
||||
type = 'info',
|
||||
autoClose = true,
|
||||
}) {
|
||||
return serviceImplementation._show({
|
||||
title,
|
||||
message,
|
||||
duration,
|
||||
position,
|
||||
type,
|
||||
autoClose,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export default UINotificationService;
|
||||
@ -6,6 +6,8 @@ import {
|
||||
ToolbarService,
|
||||
DisplaySetService,
|
||||
StateSyncService,
|
||||
UINotificationService,
|
||||
UIModalService,
|
||||
} from '../services';
|
||||
|
||||
/**
|
||||
@ -22,8 +24,8 @@ export default interface Services {
|
||||
cornerstoneViewportService?: Record<string, unknown>;
|
||||
uiDialogService?: Record<string, unknown>;
|
||||
toolGroupService?: Record<string, unknown>;
|
||||
uiNotificationService?: Record<string, unknown>;
|
||||
uiModalService?: Record<string, unknown>;
|
||||
uiNotificationService?: UINotificationService;
|
||||
uiModalService?: UIModalService;
|
||||
uiViewportDialogService?: Record<string, unknown>;
|
||||
viewportGridService?: ViewportGridService;
|
||||
syncGroupService?: Record<string, unknown>;
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import ThumbnailType from './ThumbnailType';
|
||||
import { PresentationIds } from '../contextProviders/getPresentationIds';
|
||||
import type { PresentationIds } from '../contextProviders/getPresentationIds';
|
||||
|
||||
// A few miscellaneous types declared inline here.
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user