feat(typings): Enhance typing support with withAppTypes and custom services throughout OHIF (#4090)

This commit is contained in:
Ibrahim authored and GitHub committed 2024-05-08 12:12:49 -04:00
1 parent b2cd0172d6
commit 374065bc3b
153 files changed
+842 -657

No files matched your search

+2 -3
View File
@@ -2,7 +2,6 @@ import objectHash from 'object-hash';
import { hotkeys } from '../utils';
import isequal from 'lodash.isequal';
import Hotkey from './Hotkey';
import ServicesManager from '../services/ServicesManager';
/**
*
@@ -15,9 +14,9 @@ import ServicesManager from '../services/ServicesManager';
*/
export class HotkeysManager {
private _servicesManager: ServicesManager;
private _servicesManager: AppTypes.ServicesManager;
constructor(commandsManager, servicesManager) {
constructor(commandsManager, servicesManager: AppTypes.ServicesManager) {
this.hotkeyDefinitions = {};
this.hotkeyDefaults = [];
this.isEnabled = true;
@@ -1,7 +1,7 @@
import MODULE_TYPES from './MODULE_TYPES';
import log from '../log';
import { AppConfig } from '../types/AppConfig';
import { PubSubService, ServiceProvidersManager, ServicesManager } from '../services';
import { PubSubService, ServiceProvidersManager } from '../services';
import { HotkeysManager, CommandsManager } from '../classes';
import { DataSourceDefinition } from '../types';
@@ -9,7 +9,7 @@ import { DataSourceDefinition } from '../types';
* This is the arguments given to create the extension.
*/
export interface ExtensionConstructor {
servicesManager: ServicesManager;
servicesManager: AppTypes.ServicesManager;
serviceProvidersManager: ServiceProvidersManager;
commandsManager: CommandsManager;
hotkeysManager: HotkeysManager;
@@ -28,7 +28,7 @@ export type ExtensionConfiguration = Record<string, unknown>;
*/
export interface ExtensionParams extends ExtensionConstructor {
extensionManager: ExtensionManager;
servicesManager: ServicesManager;
servicesManager: AppTypes.ServicesManager;
serviceProvidersManager: ServiceProvidersManager;
configuration?: ExtensionConfiguration;
}
@@ -72,7 +72,7 @@ export default class ExtensionManager extends PubSubService {
public static readonly MODULE_TYPES = MODULE_TYPES;
private _commandsManager: CommandsManager;
private _servicesManager: ServicesManager;
private _servicesManager: AppTypes.ServicesManager;
private _hotkeysManager: HotkeysManager;
private _serviceProvidersManager: ServiceProvidersManager;
private modulesMap: Record<string, unknown>;
+1 -1
View File
@@ -1,6 +1,6 @@
import { useCallback, useEffect, useState } from 'react';
export function useToolbar({ servicesManager, buttonSection = 'primary' }) {
export function useToolbar({ servicesManager, buttonSection = 'primary' }: withAppTypes) {
const { toolbarService, viewportGridService } = servicesManager.services;
const { EVENTS } = toolbarService;
@@ -6,7 +6,6 @@ import ProtocolEngine from './ProtocolEngine';
import { StudyMetadata } from '../../types/StudyMetadata';
import IDisplaySet from '../DisplaySetService/IDisplaySet';
import { CommandsManager } from '../../classes';
import ServicesManager from '../ServicesManager';
import * as HangingProtocol from '../../types/HangingProtocol';
import { isDisplaySetFromUrl, sopInstanceLocation } from './custom-attribute/isDisplaySetFromUrl';
import numberOfDisplaySetsWithImages from './custom-attribute/numberOfDisplaySetsWithImages';
@@ -60,7 +59,7 @@ export default class HangingProtocolService extends PubSubService {
stageIndex = 0;
_commandsManager: CommandsManager;
_servicesManager: ServicesManager;
_servicesManager: AppTypes.ServicesManager;
protocolEngine: ProtocolEngine;
customViewportSettings = [];
displaySets: IDisplaySet[] = [];
@@ -136,7 +135,7 @@ export default class HangingProtocolService extends PubSubService {
HangingProtocol.ViewportMatchDetails
> = new Map();
constructor(commandsManager: CommandsManager, servicesManager) {
constructor(commandsManager: CommandsManager, servicesManager: AppTypes.ServicesManager) {
super(HangingProtocolService.EVENTS);
this._commandsManager = commandsManager;
this._servicesManager = servicesManager;
@@ -1,10 +1,9 @@
import log from './../log.js';
import Services from '../types/Services';
import CommandsManager from '../classes/CommandsManager';
import ExtensionManager from '../extensions/ExtensionManager';
export default class ServicesManager {
public services: Services = {};
public services: AppTypes.Services = {};
public registeredServiceNames: string[] = [];
private _commandsManager: CommandsManager;
private _extensionManager: ExtensionManager;
@@ -2,7 +2,6 @@ import { CommandsManager } from '../../classes';
import { ExtensionManager } from '../../extensions';
import { PubSubService } from '../_shared/pubSubServiceInterface';
import type { RunCommand } from '../../types/Command';
import ServicesManager from '../ServicesManager';
import { Button, ButtonProps, EvaluateFunction, EvaluatePublic, NestedButtonProps } from './types';
const EVENTS = {
@@ -52,14 +51,14 @@ export default class ToolbarService extends PubSubService {
_commandsManager: CommandsManager;
_extensionManager: ExtensionManager;
_servicesManager: ServicesManager;
_servicesManager: AppTypes.ServicesManager;
_evaluateFunction: Record<string, EvaluateFunction> = {};
_serviceSubscriptions = [];
constructor(
commandsManager: CommandsManager,
extensionManager: ExtensionManager,
servicesManager: ServicesManager
servicesManager: AppTypes.ServicesManager
) {
super(EVENTS);
this._commandsManager = commandsManager;
@@ -0,0 +1,80 @@
import { PubSubService } from '../_shared/pubSubServiceInterface';
class UIDialogService extends PubSubService {
public static readonly EVENTS = {};
public static REGISTRATION = {
name: 'uiDialogService',
altName: 'UIDialogService',
create: ({ configuration = {} }) => {
return new UIDialogService();
},
};
serviceImplementation = {
_dismiss: () => console.warn('dismiss() NOT IMPLEMENTED'),
_dismissAll: () => console.warn('dismissAll() NOT IMPLEMENTED'),
_create: () => console.warn('create() NOT IMPLEMENTED'),
};
constructor() {
super(UIDialogService.EVENTS);
this.serviceImplementation = {
...this.serviceImplementation,
};
}
public create({
id,
content,
contentProps,
onStart,
onDrag,
onStop,
centralize = false,
preservePosition = true,
isDraggable = true,
showOverlay = false,
defaultPosition,
}) {
return this.serviceImplementation._create({
id,
content,
contentProps,
onStart,
onDrag,
onStop,
centralize,
preservePosition,
isDraggable,
showOverlay,
defaultPosition,
});
}
public dismiss({ id }) {
return this.serviceImplementation._dismiss({ id });
}
public dismissAll() {
return this.serviceImplementation._dismissAll();
}
public setServiceImplementation({
dismiss: dismissImplementation,
dismissAll: dismissAllImplementation,
create: createImplementation,
}) {
if (dismissImplementation) {
this.serviceImplementation._dismiss = dismissImplementation;
}
if (dismissAllImplementation) {
this.serviceImplementation._dismissAll = dismissAllImplementation;
}
if (createImplementation) {
this.serviceImplementation._create = createImplementation;
}
}
}
export default UIDialogService;
@@ -1,131 +0,0 @@
/**
* A UI Element Position
*
* @typedef {Object} ElementPosition
* @property {number} top -
* @property {number} left -
* @property {number} right -
* @property {number} bottom -
*/
/**
* UI Dialog
*
* @typedef {Object} DialogProps
* @property {string} id The dialog id.
* @property {ReactElement|HTMLElement} content The dialog content.
* @property {Object} contentProps The dialog content props.
* @property {boolean} [isDraggable=true] Controls if dialog content is draggable or not.
* @property {boolean} [showOverlay=false] Controls dialog overlay.
* @property {boolean} [centralize=false] Center the dialog on the screen.
* @property {boolean} [preservePosition=true] Use last position instead of default.
* @property {ElementPosition} defaultPosition Specifies the `x` and `y` that the dragged item should start at.
* @property {Function} onStart Called when dragging starts. If `false` is returned any handler, the action will cancel.
* @property {Function} onStop Called when dragging stops.
* @property {Function} onDrag Called while dragging.
*/
const name = 'uiDialogService';
const publicAPI = {
name,
dismiss: _dismiss,
dismissAll: _dismissAll,
create: _create,
setServiceImplementation,
};
const serviceImplementation = {
_dismiss: () => console.warn('dismiss() NOT IMPLEMENTED'),
_dismissAll: () => console.warn('dismissAll() NOT IMPLEMENTED'),
_create: () => console.warn('create() NOT IMPLEMENTED'),
};
/**
* Show a new UI dialog;
*
* @param {DialogProps} props { id, content, contentProps, onStart, onDrag, onStop, centralize, isDraggable, showOverlay, preservePosition, defaultPosition }
*/
function _create({
id,
content,
contentProps,
onStart,
onDrag,
onStop,
centralize = false,
preservePosition = true,
isDraggable = true,
showOverlay = false,
onClickOutside,
defaultPosition,
}) {
return serviceImplementation._create({
id,
content,
contentProps,
onStart,
onDrag,
onStop,
centralize,
preservePosition,
isDraggable,
onClickOutside,
showOverlay,
defaultPosition,
});
}
/**
* Destroys all dialogs, if any
*
* @returns void
*/
function _dismissAll() {
return serviceImplementation._dismissAll();
}
/**
* Destroy the dialog, if currently created
*
* @returns void
*/
function _dismiss({ id }) {
return serviceImplementation._dismiss({ id });
}
/**
*
*
* @param {*} {
* dismiss: dismissImplementation,
* dismissAll: dismissAllImplementation,
* create: createImplementation,
* }
*/
function setServiceImplementation({
dismiss: dismissImplementation,
dismissAll: dismissAllImplementation,
create: createImplementation,
}) {
if (dismissImplementation) {
serviceImplementation._dismiss = dismissImplementation;
}
if (dismissAllImplementation) {
serviceImplementation._dismissAll = dismissAllImplementation;
}
if (createImplementation) {
serviceImplementation._create = createImplementation;
}
}
// TODO - export type here
export default {
REGISTRATION: {
name,
altName: 'UIDialogService',
create: ({ configuration = {} }) => {
return publicAPI;
},
},
};
@@ -0,0 +1,3 @@
import UIDialogService from './UIDialogService';
export default UIDialogService;
@@ -0,0 +1,52 @@
import { PubSubService } from '../_shared/pubSubServiceInterface';
class UIViewportDialogService extends PubSubService {
public static readonly EVENTS = {};
public static REGISTRATION = {
name: 'uiViewportDialogService',
altName: 'UIViewportDialogService',
create: ({ configuration = {} }) => {
return new UIViewportDialogService();
},
};
serviceImplementation = {
_hide: () => console.warn('hide() NOT IMPLEMENTED'),
_show: () => console.warn('show() NOT IMPLEMENTED'),
};
constructor() {
super(UIViewportDialogService.EVENTS);
this.serviceImplementation = {
...this.serviceImplementation,
};
}
public show({ viewportId, id, type, message, actions, onSubmit, onOutsideClick, onKeyPress }) {
return this.serviceImplementation._show({
viewportId,
id,
type,
message,
actions,
onSubmit,
onOutsideClick,
onKeyPress,
});
}
public hide() {
return this.serviceImplementation._hide();
}
public setServiceImplementation({ hide: hideImplementation, show: showImplementation }) {
if (hideImplementation) {
this.serviceImplementation._hide = hideImplementation;
}
if (showImplementation) {
this.serviceImplementation._show = showImplementation;
}
}
}
export default UIViewportDialogService;
@@ -1,75 +0,0 @@
/**
* Viewport Dialog
*
* @typedef {Object} ViewportDialogProps
* @property {ReactElement|HTMLElement} [content=null] Modal content.
* @property {Object} [contentProps=null] Modal content props.
* @property {boolean} [viewportId=false] Modal is dismissible via the esc key.
*/
const name = 'uiViewportDialogService';
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 viewport dialog on the specified viewportId;
*
* @param {ViewportDialogProps} props { content, contentProps, viewportId }
*/
function _show({ viewportId, id, type, message, actions, onSubmit, onOutsideClick, onKeyPress }) {
return serviceImplementation._show({
viewportId,
id,
type,
message,
actions,
onSubmit,
onOutsideClick,
onKeyPress,
});
}
/**
* Hides/dismisses the viewport dialog, if currently shown
*/
function _hide() {
return serviceImplementation._hide();
}
/**
*
*
* @param {*} {
* hide: hideImplementation,
* show: showImplementation,
* viewportId,
* }
*/
function setServiceImplementation({ hide: hideImplementation, show: showImplementation }) {
if (hideImplementation) {
serviceImplementation._hide = hideImplementation;
}
if (showImplementation) {
serviceImplementation._show = showImplementation;
}
}
export default {
REGISTRATION: {
name,
altName: 'UIViewportDialogService',
create: ({ configuration = {} }) => {
return publicAPI;
},
},
};
@@ -0,0 +1,3 @@
import UIViewportDialogService from './UIViewportDialogService';
export default UIViewportDialogService;
@@ -1,94 +0,0 @@
const name = 'userAuthenticationService';
const publicAPI = {
name,
getState: _getState,
setUser: _setUser,
getUser: _getUser,
getAuthorizationHeader: _getAuthorizationHeader,
handleUnauthenticated: _handleUnauthenticated,
setServiceImplementation,
reset: _reset,
set: _set,
};
const serviceImplementation = {
_getState: () => console.warn('getState() NOT IMPLEMENTED'),
_setUser: () => console.warn('_setUser() NOT IMPLEMENTED'),
_getUser: () => console.warn('_setUser() NOT IMPLEMENTED'),
_getAuthorizationHeader: () => {}, // TODO: have enabled/disabled state?
//console.warn('_getAuthorizationHeader() NOT IMPLEMENTED'),
_handleUnauthenticated: () => console.warn('_handleUnauthenticated() NOT IMPLEMENTED'),
_reset: () => console.warn('reset() NOT IMPLEMENTED'),
_set: () => console.warn('set() NOT IMPLEMENTED'),
};
function _getState() {
return serviceImplementation._getState();
}
function _setUser(user) {
return serviceImplementation._setUser(user);
}
function _getUser() {
return serviceImplementation._getUser();
}
function _getAuthorizationHeader() {
return serviceImplementation._getAuthorizationHeader();
}
function _handleUnauthenticated() {
return serviceImplementation._handleUnauthenticated();
}
function _set(state) {
return serviceImplementation._set(state);
}
function _reset() {
return serviceImplementation._reset({});
}
function setServiceImplementation({
getState: getStateImplementation,
setUser: setUserImplementation,
getUser: getUserImplementation,
getAuthorizationHeader: getAuthorizationHeaderImplementation,
handleUnauthenticated: handleUnauthenticatedImplementation,
reset: resetImplementation,
set: setImplementation,
}) {
if (getStateImplementation) {
serviceImplementation._getState = getStateImplementation;
}
if (setUserImplementation) {
serviceImplementation._setUser = setUserImplementation;
}
if (getUserImplementation) {
serviceImplementation._getUser = getUserImplementation;
}
if (getAuthorizationHeaderImplementation) {
serviceImplementation._getAuthorizationHeader = getAuthorizationHeaderImplementation;
}
if (handleUnauthenticatedImplementation) {
serviceImplementation._handleUnauthenticated = handleUnauthenticatedImplementation;
}
if (resetImplementation) {
serviceImplementation._reset = resetImplementation;
}
if (setImplementation) {
serviceImplementation._set = setImplementation;
}
}
export default {
REGISTRATION: {
name,
altName: 'UserAuthenticationService',
create: ({ configuration = {} }) => {
return publicAPI;
},
},
};
@@ -0,0 +1,92 @@
import { PubSubService } from '../_shared/pubSubServiceInterface';
class UserAuthenticationService extends PubSubService {
public static readonly EVENTS = {};
public static REGISTRATION = {
name: 'userAuthenticationService',
altName: 'UserAuthenticationService',
create: ({ configuration = {} }) => {
return new UserAuthenticationService();
},
};
serviceImplementation = {
_getState: () => console.warn('getState() NOT IMPLEMENTED'),
_setUser: () => console.warn('_setUser() NOT IMPLEMENTED'),
_getUser: () => console.warn('_getUser() NOT IMPLEMENTED'),
_getAuthorizationHeader: () => {}, // TODO: Implement this method
_handleUnauthenticated: () => console.warn('_handleUnauthenticated() NOT IMPLEMENTED'),
_reset: () => console.warn('reset() NOT IMPLEMENTED'),
_set: () => console.warn('set() NOT IMPLEMENTED'),
};
constructor() {
super(UserAuthenticationService.EVENTS);
this.serviceImplementation = {
...this.serviceImplementation,
};
}
public getState() {
return this.serviceImplementation._getState();
}
public setUser(user) {
return this.serviceImplementation._setUser(user);
}
public getUser() {
return this.serviceImplementation._getUser();
}
public getAuthorizationHeader() {
return this.serviceImplementation._getAuthorizationHeader();
}
public handleUnauthenticated() {
return this.serviceImplementation._handleUnauthenticated();
}
public reset() {
return this.serviceImplementation._reset();
}
public set(state) {
return this.serviceImplementation._set(state);
}
public setServiceImplementation({
getState: getStateImplementation,
setUser: setUserImplementation,
getUser: getUserImplementation,
getAuthorizationHeader: getAuthorizationHeaderImplementation,
handleUnauthenticated: handleUnauthenticatedImplementation,
reset: resetImplementation,
set: setImplementation,
}) {
if (getStateImplementation) {
this.serviceImplementation._getState = getStateImplementation;
}
if (setUserImplementation) {
this.serviceImplementation._setUser = setUserImplementation;
}
if (getUserImplementation) {
this.serviceImplementation._getUser = getUserImplementation;
}
if (getAuthorizationHeaderImplementation) {
this.serviceImplementation._getAuthorizationHeader = getAuthorizationHeaderImplementation;
}
if (handleUnauthenticatedImplementation) {
this.serviceImplementation._handleUnauthenticated = handleUnauthenticatedImplementation;
}
if (resetImplementation) {
this.serviceImplementation._reset = resetImplementation;
}
if (setImplementation) {
this.serviceImplementation._set = setImplementation;
}
}
}
export default UserAuthenticationService;
@@ -1,6 +1,5 @@
import { CommandsManager } from '../../classes';
import { ExtensionManager } from '../../extensions';
import { ServicesManager } from '../../services';
import { PubSubService } from '../_shared/pubSubServiceInterface';
export const EVENTS = {
@@ -82,7 +81,7 @@ export type WorkflowStep = {
class WorkflowStepsService extends PubSubService {
private _extensionManager: ExtensionManager;
private _servicesManager: ServicesManager;
private _servicesManager: AppTypes.ServicesManager;
private _commandsManager: CommandsManager;
private _workflowSteps: WorkflowStep[];
private _activeWorkflowStep: WorkflowStep;
@@ -90,7 +89,7 @@ class WorkflowStepsService extends PubSubService {
constructor(
extensionManager: ExtensionManager,
commandsManager: CommandsManager,
servicesManager: ServicesManager
servicesManager: AppTypes.ServicesManager
) {
super(EVENTS);
this._workflowSteps = [];
+14
View File
@@ -4,4 +4,18 @@ export interface AppConfig {
extensions?: string[];
defaultDataSourceName?: string;
hotkeys?: Record<string, Hotkey> | Hotkey[];
useSharedArrayBuffer?: string;
preferSizeOverAccuracy?: boolean;
useNorm16Texture?: boolean;
useCPURendering?: boolean;
strictZSpacingForVolumeViewport?: boolean;
useCursors?: boolean;
maxCacheSize?: number;
showWarningMessageForCrossOrigin?: boolean;
showCPUFallbackMessage?: boolean;
maxNumRequests?: {
interaction?: number;
prefetch?: number;
thumbnail?: number;
};
}
+73
View File
@@ -0,0 +1,73 @@
/* eslint-disable @typescript-eslint/no-namespace */
import HangingProtocolServiceType from '../services/HangingProtocolService';
import CustomizationServiceType from '../services/CustomizationService';
import MeasurementServiceType from '../services/MeasurementService';
import ViewportGridServiceType from '../services/ViewportGridService';
import ToolbarServiceType from '../services/ToolBarService';
import DisplaySetServiceType from '../services/DisplaySetService';
import StateSyncServiceType from '../services/StateSyncService';
import UINotificationServiceType from '../services/UINotificationService';
import UIModalServiceType from '../services/UIModalService';
import WorkflowStepsServiceType from '../services/WorkflowStepsService';
import CineServiceType from '../services/CineService';
import UserAuthenticationServiceType from '../services/UserAuthenticationService';
import PanelServiceType from '../services/PanelService';
import UIDialogServiceType from '../services/UIDialogService';
import UIViewportDialogServiceType from '../services/UIViewportDialogService';
import ServicesManagerType from '../services/ServicesManager';
import CommandsManagerType from '../classes/CommandsManager';
import ExtensionManagerType from '../extensions/ExtensionManager';
declare global {
namespace AppTypes {
export type ServicesManager = ServicesManagerType;
export type CommandsManager = CommandsManagerType;
export type ExtensionManager = ExtensionManagerType;
export type HangingProtocolService = HangingProtocolServiceType;
export type CustomizationService = CustomizationServiceType;
export type MeasurementService = MeasurementServiceType;
export type DisplaySetService = DisplaySetServiceType;
export type ToolbarService = ToolbarServiceType;
export type ViewportGridService = ViewportGridServiceType;
export type UIModalService = UIModalServiceType;
export type UINotificationService = UINotificationServiceType;
export type StateSyncService = StateSyncServiceType;
export type WorkflowStepsService = WorkflowStepsServiceType;
export type CineService = CineServiceType;
export type UserAuthenticationService = UserAuthenticationServiceType;
export type UIDialogService = UIDialogServiceType;
export type UIViewportDialogService = UIViewportDialogServiceType;
export type PanelService = PanelServiceType;
export interface Managers {
servicesManager?: ServicesManager;
commandsManager?: CommandsManager;
extensionManager?: ExtensionManager;
}
export interface Services {
hangingProtocolService?: HangingProtocolServiceType;
customizationService?: CustomizationServiceType;
measurementService?: MeasurementServiceType;
displaySetService?: DisplaySetServiceType;
toolbarService?: ToolbarServiceType;
viewportGridService?: ViewportGridServiceType;
uiModalService?: UIModalServiceType;
uiNotificationService?: UINotificationServiceType;
stateSyncService?: StateSyncServiceType;
workflowStepsService?: WorkflowStepsServiceType;
cineService?: CineServiceType;
userAuthenticationService?: UserAuthenticationServiceType;
uiDialogService?: UIDialogServiceType;
uiViewportDialogService?: UIViewportDialogServiceType;
panelService?: PanelServiceType;
}
}
export type withAppTypes<T = object> = T &
AppTypes.Services &
AppTypes.Managers & {
[key: string]: any;
};
}
+1 -1
View File
@@ -322,7 +322,7 @@ export type Protocol = {
* to the GUI when this is used, and it can be expensive to apply.
* Alternatives include using the custom attributes where possible.
*/
export type ProtocolGenerator = ({ servicesManager: any, commandsManager: any }) => {
export type ProtocolGenerator = ({ servicesManager, commandsManager }: withAppTypes) => {
protocol: Protocol;
};
+14 -12
View File
@@ -9,12 +9,18 @@ import {
UINotificationService,
UIModalService,
WorkflowStepsService,
CineService,
UserAuthenticationService,
PanelService,
UIDialogService,
UIViewportDialogService,
} from '../services';
/**
* The interface for the services object
*/
export default interface Services {
interface Services {
hangingProtocolService?: HangingProtocolService;
customizationService?: CustomizationService;
measurementService?: MeasurementService;
@@ -25,15 +31,11 @@ export default interface Services {
uiNotificationService?: UINotificationService;
stateSyncService?: StateSyncService;
workflowStepsService: WorkflowStepsService;
cineService?: unknown;
userAuthenticationService?: unknown;
cornerstoneViewportService?: unknown;
uiDialogService?: unknown;
toolGroupService?: unknown;
uiViewportDialogService?: unknown;
syncGroupService?: unknown;
cornerstoneCacheService?: unknown;
segmentationService?: unknown;
panelService?: unknown;
colorbarService?: unknown;
cineService?: CineService;
userAuthenticationService?: UserAuthenticationService;
uiDialogService?: UIDialogService;
uiViewportDialogService?: UIViewportDialogService;
panelService?: PanelService;
}
export default Services;