fix: Create typed services and allow lower case access to agree with naming conventions (#3141)

* fix: Add typed services

* fix: Typed services - PR changes

* remaining of the cineService and toolbarService renaming

---------

Co-authored-by: Alireza <ar.sedghi@gmail.com>
This commit is contained in:
Bill Wallace 2023-02-07 14:31:55 -05:00 committed by GitHub
parent 0e1a58da79
commit 7f799b8e3d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
55 changed files with 302 additions and 233 deletions

View File

@ -118,7 +118,7 @@ const OHIFCornerstoneViewport = React.memo(props => {
const {
MeasurementService,
DisplaySetService,
ToolBarService,
toolbarService,
ToolGroupService,
SyncGroupService,
CornerstoneViewportService,
@ -355,7 +355,7 @@ const OHIFCornerstoneViewport = React.memo(props => {
></div>
<CornerstoneOverlays
viewportIndex={viewportIndex}
ToolBarService={ToolBarService}
toolbarService={toolbarService}
element={elementRef.current}
scrollbarHeight={scrollbarHeight}
servicesManager={servicesManager}

View File

@ -3,6 +3,7 @@ import PropTypes from 'prop-types';
import { Enums, Types, utilities } from '@cornerstonejs/core';
import { utilities as csToolsUtils } from '@cornerstonejs/tools';
import { ImageScrollbar } from '@ohif/ui';
import { ServicesManger } from '@ohif/core';
function CornerstoneImageScrollbar({
viewportData,
@ -13,7 +14,10 @@ function CornerstoneImageScrollbar({
scrollbarHeight,
servicesManager,
}) {
const { CineService, CornerstoneViewportService } = servicesManager.services;
const {
cineService,
CornerstoneViewportService,
} = (servicesManager as ServicesManger).services;
const onImageScrollbarChange = (imageIndex, viewportIndex) => {
const viewportInfo = CornerstoneViewportService.getViewportInfoByIndex(
@ -25,12 +29,12 @@ function CornerstoneImageScrollbar({
viewportId
);
const { isCineEnabled } = CineService.getState();
const { isCineEnabled } = cineService.getState();
if (isCineEnabled) {
// on image scrollbar change, stop the CINE if it is playing
CineService.stopClip(element);
CineService.setCine({ id: viewportIndex, isPlaying: false });
cineService.stopClip(element);
cineService.setCine({ id: viewportIndex, isPlaying: false });
}
csToolsUtils.jumpToSlice(viewport.element, {
@ -144,6 +148,7 @@ CornerstoneImageScrollbar.propTypes = {
scrollbarHeight: PropTypes.string,
imageSliceData: PropTypes.object.isRequired,
setImageSliceData: PropTypes.func.isRequired,
servicesManager: PropTypes.object.isRequired,
};
export default CornerstoneImageScrollbar;

View File

@ -3,6 +3,7 @@ import { vec3 } from 'gl-matrix';
import PropTypes from 'prop-types';
import { metaData, Enums, utilities } from '@cornerstonejs/core';
import { ViewportOverlay } from '@ohif/ui';
import { ServicesManager } from '@ohif/core';
const EPSILON = 1e-4;
@ -15,7 +16,7 @@ function CornerstoneViewportOverlay({
}) {
const {
CornerstoneViewportService,
ToolBarService,
toolbarService,
} = servicesManager.services;
const [voi, setVOI] = useState({ windowCenter: null, windowWidth: null });
const [scale, setScale] = useState(1);
@ -25,19 +26,19 @@ function CornerstoneViewportOverlay({
* Initial toolbar state
*/
useEffect(() => {
setActiveTools(ToolBarService.getActiveTools());
setActiveTools(toolbarService.getActiveTools());
}, []);
useEffect(() => {
let isMounted = true;
const { unsubscribe } = ToolBarService.subscribe(
ToolBarService.EVENTS.TOOL_BAR_STATE_MODIFIED,
const { unsubscribe } = toolbarService.subscribe(
toolbarService.EVENTS.TOOL_BAR_STATE_MODIFIED,
() => {
if (!isMounted) {
return;
}
setActiveTools(ToolBarService.getActiveTools());
setActiveTools(toolbarService.getActiveTools());
}
);
@ -287,6 +288,7 @@ CornerstoneViewportOverlay.propTypes = {
viewportData: PropTypes.object,
imageIndex: PropTypes.number,
viewportIndex: PropTypes.number,
servicesManager: ServicesManager,
};
export default CornerstoneViewportOverlay;

View File

@ -10,6 +10,7 @@ import {
utilities as cstUtils,
ReferenceLinesTool,
} from '@cornerstonejs/tools';
import { ServicesManager } from '@ohif/core';
import { getEnabledElement as OHIFgetEnabledElement } from './state';
import CornerstoneViewportDownloadForm from './utils/CornerstoneViewportDownloadForm';
@ -22,13 +23,13 @@ const commandsModule = ({ servicesManager }) => {
const {
ViewportGridService,
ToolGroupService,
CineService,
ToolBarService,
cineService,
toolbarService,
UIDialogService,
CornerstoneViewportService,
HangingProtocolService,
UINotificationService,
} = servicesManager.services;
} = (servicesManager as ServicesManager).services;
function _getActiveViewportEnabledElement() {
const { activeViewportIndex } = ViewportGridService.getState();
@ -92,11 +93,11 @@ const commandsModule = ({ servicesManager }) => {
},
toggleCine: () => {
const { viewports } = ViewportGridService.getState();
const { isCineEnabled } = CineService.getState();
CineService.setIsCineEnabled(!isCineEnabled);
ToolBarService.setButton('Cine', { props: { isActive: !isCineEnabled } });
const { isCineEnabled } = cineService.getState();
cineService.setIsCineEnabled(!isCineEnabled);
toolbarService.setButton('Cine', { props: { isActive: !isCineEnabled } });
viewports.forEach((_, index) =>
CineService.setCine({ id: index, isPlaying: false })
cineService.setCine({ id: index, isPlaying: false })
);
},
setWindowLevel({ window, level, toolGroupId }) {

View File

@ -87,12 +87,12 @@ const cornerstoneExtension = {
// const onNewImageHandler = jumpData => {
// commandsManager.runCommand('jumpToImage', jumpData);
// };
const { ToolBarService } = servicesManager.services;
const { ToolbarService } = servicesManager.services;
return (
<OHIFCornerstoneViewport
{...props}
ToolBarService={ToolBarService}
ToolbarService={ToolbarService}
servicesManager={servicesManager}
commandsManager={commandsManager}
/>

View File

@ -68,7 +68,7 @@ export default async function init({
UIDialogService,
UIModalService,
UINotificationService,
CineService,
cineService,
CornerstoneViewportService,
HangingProtocolService,
ToolGroupService,
@ -137,7 +137,7 @@ export default async function init({
CornerstoneViewportService
);
initCineService(CineService);
initCineService(cineService);
const _getDefaultPosition = event => ({
x: (event && event.currentPoints.client[0]) || 0,

View File

@ -1,6 +1,6 @@
import { utilities } from '@cornerstonejs/tools';
function initCineService(CineService) {
function initCineService(cineService) {
const playClip = (element, playClipOptions) => {
return utilities.cine.playClip(element, playClipOptions);
};
@ -9,7 +9,7 @@ function initCineService(CineService) {
return utilities.cine.stopClip(element);
};
CineService.setServiceImplementation({ playClip, stopClip });
cineService.setServiceImplementation({ playClip, stopClip });
}
export default initCineService;

View File

@ -760,7 +760,8 @@ class CornerstoneViewportService implements IViewportService {
export default function ExtendedCornerstoneViewportService(serviceManager) {
return {
name: 'CornerstoneViewportService',
name: 'cornerstoneViewportService',
altName: 'CornerstoneViewportService',
create: ({ configuration = {} }) => {
return new CornerstoneViewportService(serviceManager);
},

View File

@ -42,7 +42,7 @@ export default function toggleMPRHangingProtocol({
UINotificationService,
HangingProtocolService,
ViewportGridService,
ToolBarService,
toolbarService,
} = servicesManager.services;
// TODO Introduce a service to persist the state of the current hanging protocol/app.
@ -185,7 +185,7 @@ export default function toggleMPRHangingProtocol({
}
});
ToolBarService.recordInteraction({
toolbarService.recordInteraction({
groupId: 'WindowLevel',
itemId: 'WindowLevel',
interactionType: 'tool',

View File

@ -2,7 +2,7 @@ import React, { useEffect, useState } from 'react';
import classnames from 'classnames';
export default function Toolbar({ servicesManager }) {
const { ToolBarService } = servicesManager.services;
const { toolbarService } = servicesManager.services;
const [toolbarButtons, setToolbarButtons] = useState([]);
const [buttonState, setButtonState] = useState({
primaryToolId: '',
@ -12,20 +12,20 @@ export default function Toolbar({ servicesManager }) {
// Could track buttons and state separately...?
useEffect(() => {
const { unsubscribe: unsub1 } = ToolBarService.subscribe(
ToolBarService.EVENTS.TOOL_BAR_MODIFIED,
() => setToolbarButtons(ToolBarService.getButtonSection('primary'))
const { unsubscribe: unsub1 } = toolbarService.subscribe(
toolbarService.EVENTS.TOOL_BAR_MODIFIED,
() => setToolbarButtons(toolbarService.getButtonSection('primary'))
);
const { unsubscribe: unsub2 } = ToolBarService.subscribe(
ToolBarService.EVENTS.TOOL_BAR_STATE_MODIFIED,
() => setButtonState({ ...ToolBarService.state })
const { unsubscribe: unsub2 } = toolbarService.subscribe(
toolbarService.EVENTS.TOOL_BAR_STATE_MODIFIED,
() => setButtonState({ ...toolbarService.state })
);
return () => {
unsub1();
unsub2();
};
}, [ToolBarService]);
}, [toolbarService]);
return (
<>
@ -55,7 +55,7 @@ export default function Toolbar({ servicesManager }) {
{...componentProps}
bState={buttonState}
isActive={isActive}
onInteraction={args => ToolBarService.recordInteraction(args)}
onInteraction={args => toolbarService.recordInteraction(args)}
servicesManager={servicesManager}
/>
</div>

View File

@ -6,6 +6,8 @@ import {
useViewportGrid,
} from '@ohif/ui';
import { ServicesManager } from '@ohif/core';
function LayoutSelector({
rows,
columns,
@ -17,7 +19,10 @@ function LayoutSelector({
const [disableSelector, setDisableSelector] = useState(false);
const [viewportGridState, viewportGridService] = useViewportGrid();
const { HangingProtocolService, ToolBarService } = servicesManager.services;
const {
HangingProtocolService,
toolbarService,
} = (servicesManager as ServicesManager).services;
const closeOnOutsideClick = () => {
if (isOpen) {
@ -61,7 +66,7 @@ function LayoutSelector({
// TODO Here the layout change will amount to a change of hanging protocol as specified by the extension for this layout selector tool
// followed by the change of the grid itself.
if (HangingProtocolService.getActiveProtocol().protocol.id === 'mpr') {
ToolBarService.recordInteraction({
toolbarService.recordInteraction({
groupId: 'MPR',
itemId: 'MPR',
interactionType: 'toggle',
@ -104,6 +109,7 @@ LayoutSelector.propTypes = {
rows: PropTypes.number,
columns: PropTypes.number,
onLayoutChange: PropTypes.func,
servicesManager: PropTypes.instanceOf(ServicesManager),
};
LayoutSelector.defaultProps = {

View File

@ -4,8 +4,6 @@ import ToolbarLayoutSelector from './Toolbar/ToolbarLayoutSelector.tsx';
import ToolbarSplitButton from './Toolbar/ToolbarSplitButton.tsx';
export default function getToolbarModule({ commandsManager, servicesManager }) {
const toolbarService = servicesManager.services.ToolBarService;
return [
{
name: 'ohif.divider',

View File

@ -1,7 +1,7 @@
import React, { useEffect, useState, useCallback } from 'react';
import React, { useEffect, useState } from 'react';
import PropTypes from 'prop-types';
import { Input, Button } from '@ohif/ui';
import { DicomMetadataStore } from '@ohif/core';
import { DicomMetadataStore, ServicesManager } from '@ohif/core';
import { useTranslation } from 'react-i18next';
const DEFAULT_MEATADATA = {
@ -27,9 +27,9 @@ export default function PanelPetSUV({ servicesManager, commandsManager }) {
const {
DisplaySetService,
ToolGroupService,
ToolBarService,
toolbarService,
HangingProtocolService,
} = servicesManager.services;
} = (servicesManager as ServicesManager).services;
const [metadata, setMetadata] = useState(DEFAULT_MEATADATA);
const [ptDisplaySet, setPtDisplaySet] = useState(null);
@ -126,9 +126,9 @@ export default function PanelPetSUV({ servicesManager, commandsManager }) {
});
});
ToolBarService.state.toggles['Crosshairs'] = false;
ToolBarService._broadcastEvent(
ToolBarService.EVENTS.TOOL_BAR_STATE_MODIFIED
toolbarService.state.toggles['Crosshairs'] = false;
toolbarService._broadcastEvent(
toolbarService.EVENTS.TOOL_BAR_STATE_MODIFIED
);
// metadata should be dcmjs naturalized

View File

@ -1,5 +1,5 @@
import toolbarButtons from './toolbarButtons.js';
import { hotkeys } from '@ohif/core';
import { hotkeys, ServicesManager } from '@ohif/core';
import { id } from './id';
const configs = {
@ -53,7 +53,7 @@ function modeFactory({ modeConfiguration }) {
* Lifecycle hooks
*/
onModeEnter: ({ servicesManager, extensionManager }) => {
const { ToolBarService, ToolGroupService } = servicesManager.services;
const { toolbarService, ToolGroupService } = servicesManager.services;
const utilityModule = extensionManager.getModuleEntry(
'@ohif/extension-cornerstone.utilityModule.tools'
);
@ -94,7 +94,7 @@ function modeFactory({ modeConfiguration }) {
let unsubscribe;
const activateTool = () => {
ToolBarService.recordInteraction({
toolbarService.recordInteraction({
groupId: 'WindowLevel',
itemId: 'WindowLevel',
interactionType: 'tool',
@ -121,9 +121,9 @@ function modeFactory({ modeConfiguration }) {
activateTool
));
ToolBarService.init(extensionManager);
ToolBarService.addButtons(toolbarButtons);
ToolBarService.createButtonSection('primary', [
toolbarService.init(extensionManager);
toolbarService.addButtons(toolbarButtons);
toolbarService.createButtonSection('primary', [
'MeasurementTools',
'Zoom',
'WindowLevel',
@ -136,10 +136,10 @@ function modeFactory({ modeConfiguration }) {
const {
ToolGroupService,
MeasurementService,
ToolBarService,
toolbarService,
} = servicesManager.services;
ToolBarService.reset();
toolbarService.reset();
ToolGroupService.destroy();
},
validationTags: {

View File

@ -69,7 +69,7 @@ function modeFactory() {
onModeEnter: ({ servicesManager, extensionManager, commandsManager }) => {
const {
MeasurementService,
ToolBarService,
toolbarService,
ToolGroupService,
} = servicesManager.services;
@ -81,7 +81,7 @@ function modeFactory() {
let unsubscribe;
const activateTool = () => {
ToolBarService.recordInteraction({
toolbarService.recordInteraction({
groupId: 'WindowLevel',
itemId: 'WindowLevel',
interactionType: 'tool',
@ -108,9 +108,9 @@ function modeFactory() {
activateTool
));
ToolBarService.init(extensionManager);
ToolBarService.addButtons(toolbarButtons);
ToolBarService.createButtonSection('primary', [
toolbarService.init(extensionManager);
toolbarService.addButtons(toolbarButtons);
toolbarService.createButtonSection('primary', [
'MeasurementTools',
'Zoom',
'WindowLevel',
@ -126,12 +126,12 @@ function modeFactory() {
const {
ToolGroupService,
SyncGroupService,
ToolBarService,
toolbarService,
SegmentationService,
CornerstoneViewportService,
} = servicesManager.services;
ToolBarService.reset();
toolbarService.reset();
ToolGroupService.destroy();
SyncGroupService.destroy();
SegmentationService.destroy();

View File

@ -69,7 +69,7 @@ function modeFactory() {
onModeEnter: ({ servicesManager, extensionManager, commandsManager }) => {
const {
MeasurementService,
ToolBarService,
toolbarService,
ToolGroupService,
} = servicesManager.services;
@ -81,7 +81,7 @@ function modeFactory() {
let unsubscribe;
const activateTool = () => {
ToolBarService.recordInteraction({
toolbarService.recordInteraction({
groupId: 'WindowLevel',
itemId: 'WindowLevel',
interactionType: 'tool',
@ -108,9 +108,9 @@ function modeFactory() {
activateTool
));
ToolBarService.init(extensionManager);
ToolBarService.addButtons(toolbarButtons);
ToolBarService.createButtonSection('primary', [
toolbarService.init(extensionManager);
toolbarService.addButtons(toolbarButtons);
toolbarService.createButtonSection('primary', [
'MeasurementTools',
'Zoom',
'WindowLevel',
@ -126,12 +126,12 @@ function modeFactory() {
const {
ToolGroupService,
SyncGroupService,
ToolBarService,
toolbarService,
SegmentationService,
CornerstoneViewportService,
} = servicesManager.services;
ToolBarService.reset();
toolbarService.reset();
ToolGroupService.destroy();
SyncGroupService.destroy();
SegmentationService.destroy();

View File

@ -42,7 +42,7 @@ function modeFactory({ modeConfiguration }) {
*/
onModeEnter: ({ servicesManager, extensionManager, commandsManager }) => {
const {
ToolBarService,
toolbarService,
ToolGroupService,
HangingProtocolService,
DisplaySetService,
@ -58,7 +58,7 @@ function modeFactory({ modeConfiguration }) {
initToolGroups(toolNames, Enums, ToolGroupService, commandsManager);
const setWindowLevelActive = () => {
ToolBarService.recordInteraction({
toolbarService.recordInteraction({
groupId: 'WindowLevel',
itemId: 'WindowLevel',
interactionType: 'tool',
@ -120,9 +120,9 @@ function modeFactory({ modeConfiguration }) {
);
unsubscriptions.push(unsubscribe);
ToolBarService.init(extensionManager);
ToolBarService.addButtons(toolbarButtons);
ToolBarService.createButtonSection('primary', [
toolbarService.init(extensionManager);
toolbarService.addButtons(toolbarButtons);
toolbarService.createButtonSection('primary', [
'MeasurementTools',
'Zoom',
'WindowLevel',
@ -136,13 +136,13 @@ function modeFactory({ modeConfiguration }) {
const {
ToolGroupService,
SyncGroupService,
ToolBarService,
toolbarService,
SegmentationService,
CornerstoneViewportService,
} = servicesManager.services;
unsubscriptions.forEach(unsubscribe => unsubscribe());
ToolBarService.reset();
toolbarService.reset();
ToolGroupService.destroy();
SyncGroupService.destroy();
SegmentationService.destroy();

View File

@ -1,4 +1,4 @@
import CommandsManager from './CommandsManager.js';
import CommandsManager from './CommandsManager';
import log from './../log.js';
jest.mock('./../log.js');

View File

@ -1,12 +1,12 @@
import CommandsManager from './CommandsManager.js';
import HotkeysManager from './HotkeysManager.js';
import CommandsManager from './CommandsManager';
import HotkeysManager from './HotkeysManager';
import hotkeys from './../utils/hotkeys';
import log from './../log.js';
import log from './../log';
import objectHash from 'object-hash';
jest.mock('./CommandsManager.js');
jest.mock('./CommandsManager');
jest.mock('./../utils/hotkeys');
jest.mock('./../log.js');
jest.mock('./../log');
describe('HotkeysManager', () => {
let hotkeysManager, commandsManager;

View File

@ -1,14 +1,9 @@
import CommandsManager from './CommandsManager.js';
import HotkeysManager from './HotkeysManager.js';
import CommandsManager from './CommandsManager';
import HotkeysManager from './HotkeysManager';
import ImageSet from './ImageSet';
import MetadataProvider from './MetadataProvider';
export {
MetadataProvider,
CommandsManager,
HotkeysManager,
ImageSet,
};
export { MetadataProvider, CommandsManager, HotkeysManager, ImageSet };
const classes = {
MetadataProvider,

View File

@ -24,14 +24,14 @@ describe('Top level exports', () => {
'OHIF',
//
'CineService',
'CustomizationServiceRegistration',
'CustomizationService',
'UIDialogService',
'UIModalService',
'UINotificationService',
'UIViewportDialogService',
'DisplaySetService',
'MeasurementService',
'ToolBarService',
'ToolbarService',
'Types',
'ViewportGridService',
'HangingProtocolService',
@ -39,6 +39,7 @@ describe('Top level exports', () => {
'IWebApiDataSource',
'DicomMetadataStore',
'pubSubServiceInterface',
'PubSubService',
].sort();
const exports = Object.keys(OHIF).sort();

View File

@ -21,13 +21,14 @@ import {
//
DicomMetadataStore,
DisplaySetService,
ToolBarService,
ToolbarService,
MeasurementService,
ViewportGridService,
HangingProtocolService,
pubSubServiceInterface,
PubSubService,
UserAuthenticationService,
CustomizationServiceRegistration,
CustomizationService,
} from './services';
import IWebApiDataSource from './DataSources/IWebApiDataSource';
@ -58,20 +59,21 @@ const OHIF = {
viewer: {},
//
CineService,
CustomizationServiceRegistration,
CustomizationService,
UIDialogService,
UIModalService,
UINotificationService,
UIViewportDialogService,
DisplaySetService,
MeasurementService,
ToolBarService, // TODO: TYPO
ToolbarService,
ViewportGridService,
HangingProtocolService,
UserAuthenticationService,
IWebApiDataSource,
DicomMetadataStore,
pubSubServiceInterface,
PubSubService,
};
export {
@ -94,20 +96,21 @@ export {
DICOMWeb,
//
CineService,
CustomizationServiceRegistration,
CustomizationService,
UIDialogService,
UIModalService,
UINotificationService,
UIViewportDialogService,
DisplaySetService,
MeasurementService,
ToolBarService,
ToolbarService,
ViewportGridService,
HangingProtocolService,
UserAuthenticationService,
IWebApiDataSource,
DicomMetadataStore,
pubSubServiceInterface,
PubSubService,
Types,
};

View File

@ -64,9 +64,14 @@ function setServiceImplementation({
}
}
export default {
name,
create: ({ configuration = {} }) => {
return publicAPI;
const CineService = {
REGISTRATION: {
altName: name,
name: 'cineService',
create: ({ configuration = {} }) => {
return publicAPI;
},
},
};
export default CineService;

View File

@ -1,6 +1,7 @@
import merge from 'lodash.merge';
import { PubSubService } from '../_shared/pubSubServiceInterface';
import { Customization, NestedStrings, Obj } from './types';
import { CommandsManager } from '../../classes';
const EVENTS = {
MODE_CUSTOMIZATION_MODIFIED: 'event::CustomizationService:modeModified',
@ -50,7 +51,14 @@ const flattenNestedStrings = (
* every module for the given id and to load it/add it to the extensions.
*/
export default class CustomizationService extends PubSubService {
commandsManager: Record<string, unknown>;
public static REGISTRATION = {
name: 'customizationService',
create: ({ configuration = {}, commandsManager }) => {
return new CustomizationService({ configuration, commandsManager });
},
};
commandsManager: CommandsManager;
extensionManager: Record<string, unknown>;
modeCustomizations: Record<string, Customization> = {};

View File

@ -1,11 +1,3 @@
import CustomizationService from './CustomizationService';
const CustomizationServiceRegistration = {
name: 'customizationService',
create: ({ configuration = {}, commandsManager }) => {
return new CustomizationService({ configuration, commandsManager });
},
};
export default CustomizationServiceRegistration;
export { CustomizationService, CustomizationServiceRegistration };
export default CustomizationService;

View File

@ -1,4 +1,4 @@
import pubSubServiceInterface from '../_shared/pubSubServiceInterface';
import { PubSubService } from '../_shared/pubSubServiceInterface';
import EVENTS from './EVENTS';
const displaySetCache = [];
@ -28,16 +28,21 @@ const findInstance = (instance, displaySets) => {
return false;
};
export default class DisplaySetService {
constructor() {
this.activeDisplaySets = [];
this.listeners = {};
this.EVENTS = EVENTS;
export default class DisplaySetService extends PubSubService {
public static REGISTRATION = {
altName: 'DisplaySetService',
name: 'displaySetService',
create: ({ configuration = {} }) => {
return new DisplaySetService();
},
};
Object.assign(this, pubSubServiceInterface);
public activeDisplaySets = [];
constructor() {
super(EVENTS);
}
init(extensionManager, SOPClassHandlerIds) {
public init(extensionManager, SOPClassHandlerIds): void {
this.extensionManager = extensionManager;
this.SOPClassHandlerIds = SOPClassHandlerIds;
this.activeDisplaySets = [];

View File

@ -1,8 +0,0 @@
import DisplaySetService from './DisplaySetService';
export default {
name: 'DisplaySetService',
create: ({ configuration = {} }) => {
return new DisplaySetService();
},
};

View File

@ -0,0 +1,3 @@
import DisplaySetService from './DisplaySetService';
export default DisplaySetService;

View File

@ -19,6 +19,14 @@ const EVENTS = {
type Protocol = HangingProtocol.Protocol | HangingProtocol.ProtocolGenerator;
class HangingProtocolService {
public static REGISTRATION = {
name: 'hangingProtocolService',
altName: 'HangingProtocolService',
create: ({ configuration = {}, commandsManager, servicesManager }) => {
return new HangingProtocolService(commandsManager, servicesManager);
},
};
studies: StudyMetadata[];
// stores all the protocols (object or function that returns an object) in a map
protocols: Map<string, Protocol>;

View File

@ -1,8 +0,0 @@
import HangingProtocolService from './HangingProtocolService';
export default {
name: 'HangingProtocolService',
create: ({ configuration = {}, commandsManager, servicesManager }) => {
return new HangingProtocolService(commandsManager, servicesManager);
},
};

View File

@ -0,0 +1,3 @@
import HangingProtocolService from './HangingProtocolService';
export default HangingProtocolService;

View File

@ -1,7 +1,7 @@
import MeasurementService from './MeasurementService.js';
import MeasurementService from './MeasurementService';
import log from '../../log';
jest.mock('../../log.js', () => ({
jest.mock('../../log', () => ({
info: jest.fn(),
warn: jest.fn(),
error: jest.fn(),

View File

@ -1,6 +1,6 @@
import log from '../../log';
import guid from '../../utils/guid';
import pubSubServiceInterface from '../_shared/pubSubServiceInterface';
import { PubSubService } from '../_shared/pubSubServiceInterface';
/**
* Measurement source schema
@ -94,27 +94,27 @@ const VALUE_TYPES = {
* Note and Todo: We should be able to support measurements that are composed of multiple
* annotations, but that is not the case at the moment.
*/
class MeasurementService {
class MeasurementService extends PubSubService {
public static REGISTRATION = {
name: 'measurementService',
altName: 'MeasurementService',
create: ({ configuration = {} }) => {
return new MeasurementService();
},
};
constructor() {
super(EVENTS);
this.sources = {};
this.mappings = {};
this.measurements = {};
this.listeners = {};
this._jumpToMeasurementCache = {};
Object.defineProperty(this, 'EVENTS', {
value: EVENTS,
writable: false,
enumerable: true,
configurable: false,
});
Object.defineProperty(this, 'VALUE_TYPES', {
value: VALUE_TYPES,
writable: false,
enumerable: true,
configurable: false,
});
Object.assign(this, pubSubServiceInterface);
}
/**

View File

@ -1,8 +0,0 @@
import MeasurementService from './MeasurementService';
export default {
name: 'MeasurementService',
create: ({ configuration = {} }) => {
return new MeasurementService();
},
};

View File

@ -0,0 +1,3 @@
import MeasurementService from './MeasurementService';
export default MeasurementService;

View File

@ -1,9 +1,9 @@
import ServicesManager from './ServicesManager.js';
import log from '../log.js';
import ServicesManager from './ServicesManager';
import log from '../log';
jest.mock('./../log.js');
jest.mock('./../log');
describe('ServicesManager.js', () => {
describe('ServicesManager', () => {
let servicesManager, commandsManager;
beforeEach(() => {

View File

@ -1,6 +1,9 @@
import log from './../log.js';
import Services from '../types/Services';
export default class ServicesManager {
public services: Services = {};
constructor(commandsManager) {
this._commandsManager = commandsManager;
this.services = {};
@ -39,6 +42,10 @@ export default class ServicesManager {
commandsManager: this._commandsManager,
servicesManager: this,
});
if (service.altName) {
console.log('Registering old name', service.altName);
this.services[service.altName] = this.services[service.name];
}
} else {
log.warn(`Service create factory function not defined. Exiting early.`);
return;

View File

@ -1,17 +1,25 @@
import merge from 'lodash.merge';
import pubSubServiceInterface from '../_shared/pubSubServiceInterface';
import { PubSubService } from '../_shared/pubSubServiceInterface';
const EVENTS = {
TOOL_BAR_MODIFIED: 'event::toolBarService:toolBarModified',
TOOL_BAR_STATE_MODIFIED: 'event::toolBarService:toolBarStateModified',
};
export default class ToolBarService {
export default class ToolbarService extends PubSubService {
public static REGISTRATION = {
name: 'toolbarService',
// Note the old name is ToolBarService, with an upper B
altName: 'ToolBarService',
create: ({ commandsManager }) => {
return new ToolbarService(commandsManager);
},
};
constructor(commandsManager) {
super(EVENTS);
this._commandsManager = commandsManager;
//
this.EVENTS = EVENTS;
this.listeners = {};
this.buttons = {};
this.unsubscriptions = []; // if tools need to unsubscribe from events
this.buttonSections = {
@ -32,8 +40,6 @@ export default class ToolBarService {
/* track most recent click per group...? */
},
};
Object.assign(this, pubSubServiceInterface);
}
init(extensionManager) {

View File

@ -1,8 +1,3 @@
import ToolBarService from './ToolBarService';
import ToolbarService from './ToolbarService';
export default {
name: 'ToolBarService',
create: ({ configuration = {}, commandsManager }) => {
return new ToolBarService(commandsManager);
},
};
export default ToolbarService;

View File

@ -25,7 +25,7 @@
* @property {Function} onDrag Called while dragging.
*/
const name = 'UIDialogService';
const name = 'uiDialogService';
const publicAPI = {
name,
@ -119,9 +119,13 @@ function setServiceImplementation({
}
}
// TODO - export type here
export default {
name,
create: ({ configuration = {} }) => {
return publicAPI;
REGISTRATION: {
name,
altName: 'UIDialogService',
create: ({ configuration = {} }) => {
return publicAPI;
},
},
};

View File

@ -11,7 +11,7 @@
* @property {string} [customClassName=null] The custom class to style the modal.
*/
const name = 'UIModalService';
const name = 'uiModalService';
const publicAPI = {
name,
@ -79,9 +79,13 @@ function setServiceImplementation({
}
}
// TODO - export TS Type
export default {
name,
create: ({ configuration = {} }) => {
return publicAPI;
REGISTRATION: {
name,
altName: 'UIModalService',
create: ({ configuration = {} }) => {
return publicAPI;
},
},
};

View File

@ -10,7 +10,7 @@
* @property {boolean} [autoClose=true]
*/
const name = 'UINotificationService';
const name = 'uiNotificationService';
const serviceShowRequestQueue = [];
@ -91,8 +91,11 @@ function setServiceImplementation({
}
export default {
name,
create: ({ configuration = {} }) => {
return publicAPI;
REGISTRATION: {
name,
altName: 'UINotificationService',
create: ({ configuration = {} }) => {
return publicAPI;
},
},
};

View File

@ -75,8 +75,10 @@ function setServiceImplementation({
}
export default {
name,
create: ({ configuration = {} }) => {
return publicAPI;
REGISTRATION: {
name,
create: ({ configuration = {} }) => {
return publicAPI;
},
},
};

View File

@ -1,4 +1,4 @@
const name = 'UserAuthenticationService';
const name = 'userAuthenticationService';
const publicAPI = {
name,
@ -85,8 +85,11 @@ function setServiceImplementation({
}
export default {
name,
create: ({ configuration = {} }) => {
return publicAPI;
REGISTRATION: {
name,
altName: 'UserAuthenticationService',
create: ({ configuration = {} }) => {
return publicAPI;
},
},
};

View File

@ -1,21 +1,26 @@
import pubSubServiceInterface from './../_shared/pubSubServiceInterface';
import { PubSubService } from '../_shared/pubSubServiceInterface';
const EVENTS = {
ACTIVE_VIEWPORT_INDEX_CHANGED: 'event::activeviewportindexchanged',
};
class ViewportGridService {
class ViewportGridService extends PubSubService {
public static REGISTRATION = {
name: 'viewportGridService',
altName: 'ViewportGridService',
create: ({ configuration = {} }) => {
return new ViewportGridService();
},
};
serviceImplementation = {};
EVENTS: { [key: string]: string };
listeners = {};
constructor() {
Object.assign(this, pubSubServiceInterface);
super(EVENTS);
this.serviceImplementation = {};
this.EVENTS = EVENTS;
}
setServiceImplementation({
public setServiceImplementation({
getState: getStateImplementation,
setActiveViewportIndex: setActiveViewportIndexImplementation,
setDisplaySetsForViewport: setDisplaySetsForViewportImplementation,
@ -26,7 +31,7 @@ class ViewportGridService {
reset: resetImplementation,
onModeExit: onModeExitImplementation,
set: setImplementation,
}) {
}): void {
if (getStateImplementation) {
this.serviceImplementation._getState = getStateImplementation;
}
@ -119,9 +124,4 @@ class ViewportGridService {
}
}
export default {
name: 'ViewportGridService',
create: ({ configuration = {} }) => {
return new ViewportGridService();
},
};
export default ViewportGridService;

View File

@ -1,12 +1,12 @@
import MeasurementService from './MeasurementService';
import ServicesManager from './ServicesManager.js';
import ServicesManager from './ServicesManager';
import UIDialogService from './UIDialogService';
import UIModalService from './UIModalService';
import UINotificationService from './UINotificationService';
import UIViewportDialogService from './UIViewportDialogService';
import DicomMetadataStore from './DicomMetadataStore';
import DisplaySetService from './DisplaySetService';
import ToolBarService from './ToolBarService';
import ToolbarService from './ToolBarService';
import ViewportGridService from './ViewportGridService';
import CineService from './CineService';
import HangingProtocolService from './HangingProtocolService';
@ -14,23 +14,22 @@ import pubSubServiceInterface, {
PubSubService,
} from './_shared/pubSubServiceInterface';
import UserAuthenticationService from './UserAuthenticationService';
import {
CustomizationService,
CustomizationServiceRegistration,
} from './CustomizationService';
import CustomizationService from './CustomizationService';
import Services from '../types/Services';
export {
Services,
MeasurementService,
ServicesManager,
CustomizationService,
CustomizationServiceRegistration,
UIDialogService,
UIModalService,
UINotificationService,
UIViewportDialogService,
DicomMetadataStore,
DisplaySetService,
ToolBarService,
ToolbarService,
ViewportGridService,
HangingProtocolService,
CineService,

View File

@ -0,0 +1,27 @@
import {
HangingProtocolService,
CustomizationService,
MeasurementService,
ViewportGridService,
ToolbarService,
DisplaySetService,
} from '../services';
/**
* The interface for the services object
*/
export default interface Services {
hangingProtocolService?: HangingProtocolService;
customizationService?: CustomizationService;
measurementService?: MeasurementService;
displaySetService?: DisplaySetService;
cineService?: Record<string, unknown>;
toolbarService?: ToolbarService;
cornerstoneViewportService?: Record<string, unknown>;
uiDialogService?: Record<string, unknown>;
toolGroupService?: Record<string, unknown>;
uiNotificationService?: Record<string, unknown>;
viewportGridService?: ViewportGridService;
syncGroupService?: Record<string, unknown>;
cornerstoneCacheService?: Record<string, unknown>;
}

View File

@ -9,6 +9,8 @@ import { ExtensionManager } from '../extensions';
import { CustomizationService, PubSubService } from '../services';
import * as HangingProtocol from './HangingProtocol';
import Command from './Command';
import Services from './Services';
import { CommandsManager } from '../classes';
export * from '../services/CustomizationService/types';
@ -22,4 +24,6 @@ export type {
PubSubService,
CustomizationService,
Command,
Services,
CommandsManager,
};

View File

@ -92,7 +92,7 @@ const SplitButton = ({
}) => {
const { t } = useTranslation('Buttons');
const { ToolBarService } = servicesManager.services;
const { toolbarService } = servicesManager.services;
const { primaryToolId, toggles } = bState;
/* Bubbles up individual item clicks */
@ -146,7 +146,7 @@ const SplitButton = ({
(isPrimaryToggle && toggles[state.primary.id] === true);
const PrimaryButtonComponent =
ToolBarService.getButtonComponentForUIType(state.primary.uiType) ??
toolbarService.getButtonComponentForUIType(state.primary.uiType) ??
ToolbarButton;
const primaryButtonClassName = classes.Primary({
@ -197,7 +197,7 @@ const SplitButton = ({
{...state.primary}
bState={bState}
isActive={isPrimaryActive}
onInteraction={args => ToolBarService.recordInteraction(args)}
onInteraction={args => toolbarService.recordInteraction(args)}
servicesManager={servicesManager}
// All rounding is taken care of by className
rounded="none"
@ -295,7 +295,7 @@ SplitButton.propTypes = {
isActive: PropTypes.bool,
})
),
/** Callback function to inform ToolBarService of important events */
/** Callback function to inform toolbarService of important events */
onInteraction: PropTypes.func.isRequired,
};

View File

@ -9,13 +9,13 @@ import {
UIViewportDialogService,
MeasurementService,
DisplaySetService,
ToolBarService,
ToolbarService,
ViewportGridService,
HangingProtocolService,
CineService,
UserAuthenticationService,
errorHandler,
CustomizationServiceRegistration,
CustomizationService,
// utils,
} from '@ohif/core';
@ -45,18 +45,18 @@ async function appInit(appConfigOrFunc, defaultExtensions, defaultModes) {
});
servicesManager.registerServices([
UINotificationService,
UIModalService,
UIDialogService,
UIViewportDialogService,
MeasurementService,
DisplaySetService,
[CustomizationServiceRegistration, appConfig.customizationService],
ToolBarService,
ViewportGridService,
HangingProtocolService,
CineService,
UserAuthenticationService,
UINotificationService.REGISTRATION,
UIModalService.REGISTRATION,
UIDialogService.REGISTRATION,
UIViewportDialogService.REGISTRATION,
MeasurementService.REGISTRATION,
DisplaySetService.REGISTRATION,
[CustomizationService.REGISTRATION, appConfig.customizationService],
ToolbarService.REGISTRATION,
ViewportGridService.REGISTRATION,
HangingProtocolService.REGISTRATION,
CineService.REGISTRATION,
UserAuthenticationService.REGISTRATION,
]);
errorHandler.getHTTPErrorHandler = () => {