diff --git a/extensions/cornerstone-dicom-rt/src/getSopClassHandlerModule.js b/extensions/cornerstone-dicom-rt/src/getSopClassHandlerModule.ts similarity index 91% rename from extensions/cornerstone-dicom-rt/src/getSopClassHandlerModule.js rename to extensions/cornerstone-dicom-rt/src/getSopClassHandlerModule.ts index a7a232f19..6f65a1bf5 100644 --- a/extensions/cornerstone-dicom-rt/src/getSopClassHandlerModule.js +++ b/extensions/cornerstone-dicom-rt/src/getSopClassHandlerModule.ts @@ -5,9 +5,13 @@ import loadRTStruct from './loadRTStruct'; const sopClassUids = ['1.2.840.10008.5.1.4.1.1.481.3']; -let loadPromises = {}; +const loadPromises = {}; -function _getDisplaySetsFromSeries(instances, servicesManager, extensionManager) { +function _getDisplaySetsFromSeries( + instances, + servicesManager: AppTypes.ServicesManager, + extensionManager +) { const instance = instances[0]; const { @@ -69,8 +73,8 @@ function _getDisplaySetsFromSeries(instances, servicesManager, extensionManager) displaySet.referencedSeriesInstanceUID = referencedSeries.SeriesInstanceUID; displaySet.getReferenceDisplaySet = () => { - const { DisplaySetService } = servicesManager.services; - const referencedDisplaySets = DisplaySetService.getDisplaySetsForSeries( + const { displaySetService } = servicesManager.services; + const referencedDisplaySets = displaySetService.getDisplaySetsForSeries( displaySet.referencedSeriesInstanceUID ); @@ -90,7 +94,7 @@ function _getDisplaySetsFromSeries(instances, servicesManager, extensionManager) return [displaySet]; } -function _load(rtDisplaySet, servicesManager, extensionManager, headers) { +function _load(rtDisplaySet, servicesManager: AppTypes.ServicesManager, extensionManager, headers) { const { SOPInstanceUID } = rtDisplaySet; const { segmentationService } = servicesManager.services; if ( @@ -168,7 +172,10 @@ function _deriveReferencedSeriesSequenceFromFrameOfReferenceSequence( return ReferencedSeriesSequence; } -function _segmentationExistsInCache(rtDisplaySet, segmentationService) { +function _segmentationExistsInCache( + rtDisplaySet, + segmentationService: AppTypes.SegmentationService +) { // Todo: fix this return false; // This should be abstracted with the CornerstoneCacheService diff --git a/extensions/cornerstone-dicom-rt/src/utils/promptHydrateRT.ts b/extensions/cornerstone-dicom-rt/src/utils/promptHydrateRT.ts index 5a095c116..3894c12bd 100644 --- a/extensions/cornerstone-dicom-rt/src/utils/promptHydrateRT.ts +++ b/extensions/cornerstone-dicom-rt/src/utils/promptHydrateRT.ts @@ -13,7 +13,7 @@ function promptHydrateRT({ toolGroupId = 'default', preHydrateCallbacks, hydrateRTDisplaySet, -}) { +}: withAppTypes) { const { uiViewportDialogService } = servicesManager.services; const extensionManager = servicesManager._extensionManager; const appConfig = extensionManager._appConfig; @@ -41,7 +41,7 @@ function promptHydrateRT({ }); } -function _askHydrate(uiViewportDialogService, viewportId) { +function _askHydrate(uiViewportDialogService: AppTypes.UIViewportDialogService, viewportId) { return new Promise(function (resolve, reject) { const message = 'Do you want to open this Segmentation?'; const actions = [ @@ -62,6 +62,7 @@ function _askHydrate(uiViewportDialogService, viewportId) { }; uiViewportDialogService.show({ + id: 'promptHydrateRT', viewportId, type: 'info', message, diff --git a/extensions/cornerstone-dicom-rt/src/viewports/OHIFCornerstoneRTViewport.tsx b/extensions/cornerstone-dicom-rt/src/viewports/OHIFCornerstoneRTViewport.tsx index 1b2b42b22..b8e6aa1a5 100644 --- a/extensions/cornerstone-dicom-rt/src/viewports/OHIFCornerstoneRTViewport.tsx +++ b/extensions/cornerstone-dicom-rt/src/viewports/OHIFCornerstoneRTViewport.tsx @@ -8,7 +8,7 @@ import createRTToolGroupAndAddTools from '../utils/initRTToolGroup'; const RT_TOOLGROUP_BASE_NAME = 'RTToolGroup'; -function OHIFCornerstoneRTViewport(props) { +function OHIFCornerstoneRTViewport(props: withAppTypes) { const { children, displaySets, diff --git a/extensions/cornerstone-dicom-seg/src/commandsModule.ts b/extensions/cornerstone-dicom-seg/src/commandsModule.ts index e43065f6c..e49530e92 100644 --- a/extensions/cornerstone-dicom-seg/src/commandsModule.ts +++ b/extensions/cornerstone-dicom-seg/src/commandsModule.ts @@ -1,6 +1,6 @@ import dcmjs from 'dcmjs'; import { createReportDialogPrompt } from '@ohif/extension-default'; -import { ServicesManager, Types } from '@ohif/core'; +import { Types } from '@ohif/core'; import { cache, metaData } from '@cornerstonejs/core'; import { segmentation as cornerstoneToolsSegmentation, @@ -48,7 +48,7 @@ const commandsModule = ({ displaySetService, viewportGridService, toolGroupService, - } = (servicesManager as ServicesManager).services; + } = servicesManager.services; const actions = { /** diff --git a/extensions/cornerstone-dicom-seg/src/getPanelModule.tsx b/extensions/cornerstone-dicom-seg/src/getPanelModule.tsx index a86144d4f..42c13fff3 100644 --- a/extensions/cornerstone-dicom-seg/src/getPanelModule.tsx +++ b/extensions/cornerstone-dicom-seg/src/getPanelModule.tsx @@ -10,7 +10,7 @@ const getPanelModule = ({ extensionManager, configuration, title, -}) => { +}: withAppTypes) => { const { customizationService } = servicesManager.services; const wrappedPanelSegmentation = configuration => { diff --git a/extensions/cornerstone-dicom-seg/src/getSopClassHandlerModule.js b/extensions/cornerstone-dicom-seg/src/getSopClassHandlerModule.ts similarity index 93% rename from extensions/cornerstone-dicom-seg/src/getSopClassHandlerModule.js rename to extensions/cornerstone-dicom-seg/src/getSopClassHandlerModule.ts index d150201e0..96952db30 100644 --- a/extensions/cornerstone-dicom-seg/src/getSopClassHandlerModule.js +++ b/extensions/cornerstone-dicom-seg/src/getSopClassHandlerModule.ts @@ -8,9 +8,13 @@ import { dicomlabToRGB } from './utils/dicomlabToRGB'; const sopClassUids = ['1.2.840.10008.5.1.4.1.1.66.4']; -let loadPromises = {}; +const loadPromises = {}; -function _getDisplaySetsFromSeries(instances, servicesManager, extensionManager) { +function _getDisplaySetsFromSeries( + instances, + servicesManager: AppTypes.ServicesManager, + extensionManager +) { const instance = instances[0]; const { @@ -95,7 +99,12 @@ function _getDisplaySetsFromSeries(instances, servicesManager, extensionManager) return [displaySet]; } -function _load(segDisplaySet, servicesManager, extensionManager, headers) { +function _load( + segDisplaySet, + servicesManager: AppTypes.ServicesManager, + extensionManager, + headers +) { const { SOPInstanceUID } = segDisplaySet; const { segmentationService } = servicesManager.services; @@ -137,7 +146,12 @@ function _load(segDisplaySet, servicesManager, extensionManager, headers) { return loadPromises[SOPInstanceUID]; } -async function _loadSegments({ extensionManager, servicesManager, segDisplaySet, headers }) { +async function _loadSegments({ + extensionManager, + servicesManager, + segDisplaySet, + headers, +}: withAppTypes) { const utilityModule = extensionManager.getModuleEntry( '@ohif/extension-cornerstone.utilityModule.common' ); @@ -212,7 +226,7 @@ async function _loadSegments({ extensionManager, servicesManager, segDisplaySet, Object.assign(segDisplaySet, results); } -function _segmentationExists(segDisplaySet, segmentationService) { +function _segmentationExists(segDisplaySet, segmentationService: AppTypes.SegmentationService) { // This should be abstracted with the CornerstoneCacheService return segmentationService.getSegmentation(segDisplaySet.displaySetInstanceUID); } diff --git a/extensions/cornerstone-dicom-seg/src/getToolbarModule.ts b/extensions/cornerstone-dicom-seg/src/getToolbarModule.ts index 4234cf71c..e991d778c 100644 --- a/extensions/cornerstone-dicom-seg/src/getToolbarModule.ts +++ b/extensions/cornerstone-dicom-seg/src/getToolbarModule.ts @@ -1,4 +1,4 @@ -export function getToolbarModule({ servicesManager }) { +export function getToolbarModule({ servicesManager }: withAppTypes) { const { segmentationService, toolbarService, toolGroupService } = servicesManager.services; return [ { diff --git a/extensions/cornerstone-dicom-seg/src/panels/PanelSegmentation.tsx b/extensions/cornerstone-dicom-seg/src/panels/PanelSegmentation.tsx index 9dd15e8f2..afe861947 100644 --- a/extensions/cornerstone-dicom-seg/src/panels/PanelSegmentation.tsx +++ b/extensions/cornerstone-dicom-seg/src/panels/PanelSegmentation.tsx @@ -17,7 +17,7 @@ export default function PanelSegmentation({ commandsManager, extensionManager, configuration, -}) { +}: withAppTypes) { const { segmentationService, viewportGridService, diff --git a/extensions/cornerstone-dicom-seg/src/utils/hydrationUtils.ts b/extensions/cornerstone-dicom-seg/src/utils/hydrationUtils.ts index 8726d9dc4..9e292ba98 100644 --- a/extensions/cornerstone-dicom-seg/src/utils/hydrationUtils.ts +++ b/extensions/cornerstone-dicom-seg/src/utils/hydrationUtils.ts @@ -22,7 +22,7 @@ async function updateViewportsForSegmentationRendering({ }: { viewportId: string; loadFn: () => Promise; - servicesManager: any; + servicesManager: AppTypes.ServicesManager; referencedDisplaySetInstanceUID?: string; }) { const { cornerstoneViewportService, segmentationService, viewportGridService } = @@ -134,7 +134,7 @@ function getUpdatedViewportsForSegmentation({ viewportId, servicesManager, referencedDisplaySetInstanceUID, -}) { +}: withAppTypes) { const { hangingProtocolService, displaySetService, segmentationService, viewportGridService } = servicesManager.services; diff --git a/extensions/cornerstone-dicom-seg/src/utils/promptHydrateSEG.ts b/extensions/cornerstone-dicom-seg/src/utils/promptHydrateSEG.ts index 9bd7ef66d..ef5f738d9 100644 --- a/extensions/cornerstone-dicom-seg/src/utils/promptHydrateSEG.ts +++ b/extensions/cornerstone-dicom-seg/src/utils/promptHydrateSEG.ts @@ -12,7 +12,7 @@ function promptHydrateSEG({ viewportId, preHydrateCallbacks, hydrateSEGDisplaySet, -}) { +}: withAppTypes) { const { uiViewportDialogService } = servicesManager.services; const extensionManager = servicesManager._extensionManager; const appConfig = extensionManager._appConfig; diff --git a/extensions/cornerstone-dicom-seg/src/viewports/OHIFCornerstoneSEGViewport.tsx b/extensions/cornerstone-dicom-seg/src/viewports/OHIFCornerstoneSEGViewport.tsx index b4e0f4528..da2cc18a7 100644 --- a/extensions/cornerstone-dicom-seg/src/viewports/OHIFCornerstoneSEGViewport.tsx +++ b/extensions/cornerstone-dicom-seg/src/viewports/OHIFCornerstoneSEGViewport.tsx @@ -8,7 +8,7 @@ import _getStatusComponent from './_getStatusComponent'; const SEG_TOOLGROUP_BASE_NAME = 'SEGToolGroup'; -function OHIFCornerstoneSEGViewport(props) { +function OHIFCornerstoneSEGViewport(props: withAppTypes) { const { children, displaySets, diff --git a/extensions/cornerstone-dicom-sr/src/commandsModule.js b/extensions/cornerstone-dicom-sr/src/commandsModule.ts similarity index 97% rename from extensions/cornerstone-dicom-sr/src/commandsModule.js rename to extensions/cornerstone-dicom-sr/src/commandsModule.ts index 2f355bc09..e4cfb53b4 100644 --- a/extensions/cornerstone-dicom-sr/src/commandsModule.js +++ b/extensions/cornerstone-dicom-sr/src/commandsModule.ts @@ -40,7 +40,7 @@ const _generateReport = (measurementData, additionalFindingTypes, options = {}) return dataset; }; -const commandsModule = props => { +const commandsModule = (props: withAppTypes) => { const { servicesManager } = props; const { customizationService } = servicesManager.services; const actions = { @@ -57,7 +57,7 @@ const commandsModule = props => { const reportBlob = dcmjs.data.datasetToBlob(srDataset); //Create a URL for the binary. - var objectUrl = URL.createObjectURL(reportBlob); + const objectUrl = URL.createObjectURL(reportBlob); window.location.assign(objectUrl); }, diff --git a/extensions/cornerstone-dicom-sr/src/getSopClassHandlerModule.ts b/extensions/cornerstone-dicom-sr/src/getSopClassHandlerModule.ts index be946bcfb..73789049f 100644 --- a/extensions/cornerstone-dicom-sr/src/getSopClassHandlerModule.ts +++ b/extensions/cornerstone-dicom-sr/src/getSopClassHandlerModule.ts @@ -85,7 +85,11 @@ function addInstances(instances: InstanceMetadata[], displaySetService: DisplayS * @param servicesManager is the services that can be used for creating * @returns The list of display sets created for the given instances object */ -function _getDisplaySetsFromSeries(instances, servicesManager, extensionManager) { +function _getDisplaySetsFromSeries( + instances, + servicesManager: AppTypes.ServicesManager, + extensionManager +) { // If the series has no instances, stop here if (!instances || !instances.length) { throw new Error('No instances were provided'); @@ -150,7 +154,7 @@ function _getDisplaySetsFromSeries(instances, servicesManager, extensionManager) return [displaySet]; } -async function _load(displaySet, servicesManager, extensionManager) { +async function _load(displaySet, servicesManager: AppTypes.ServicesManager, extensionManager) { const { displaySetService, measurementService } = servicesManager.services; const dataSources = extensionManager.getDataSources(); const dataSource = dataSources[0]; @@ -223,7 +227,7 @@ function _checkIfCanAddMeasurementsToDisplaySet( srDisplaySet, newDisplaySet, dataSource, - servicesManager + servicesManager: AppTypes.ServicesManager ) { const { customizationService } = servicesManager.services; let unloadedMeasurements = srDisplaySet.measurements.filter( diff --git a/extensions/cornerstone-dicom-sr/src/utils/hydrateStructuredReport.js b/extensions/cornerstone-dicom-sr/src/utils/hydrateStructuredReport.ts similarity index 99% rename from extensions/cornerstone-dicom-sr/src/utils/hydrateStructuredReport.js rename to extensions/cornerstone-dicom-sr/src/utils/hydrateStructuredReport.ts index 7dc9e657a..c254d1758 100644 --- a/extensions/cornerstone-dicom-sr/src/utils/hydrateStructuredReport.js +++ b/extensions/cornerstone-dicom-sr/src/utils/hydrateStructuredReport.ts @@ -43,7 +43,7 @@ const convertSites = (codingValues, sites) => { * */ export default function hydrateStructuredReport( - { servicesManager, extensionManager, appConfig }, + { servicesManager, extensionManager, appConfig }: withAppTypes, displaySetInstanceUID ) { const annotationManager = CsAnnotation.state.getAnnotationManager(); diff --git a/extensions/cornerstone-dicom-sr/src/viewports/OHIFCornerstoneSRViewport.tsx b/extensions/cornerstone-dicom-sr/src/viewports/OHIFCornerstoneSRViewport.tsx index 6158df331..b59853c7e 100644 --- a/extensions/cornerstone-dicom-sr/src/viewports/OHIFCornerstoneSRViewport.tsx +++ b/extensions/cornerstone-dicom-sr/src/viewports/OHIFCornerstoneSRViewport.tsx @@ -1,7 +1,7 @@ import PropTypes from 'prop-types'; import React, { useCallback, useContext, useEffect, useState } from 'react'; import { useTranslation } from 'react-i18next'; -import { ServicesManager, ExtensionManager } from '@ohif/core'; +import { ExtensionManager } from '@ohif/core'; import { setTrackingUniqueIdentifiersForElement } from '../tools/modules/dicomSRModule'; @@ -14,7 +14,7 @@ const MEASUREMENT_TRACKING_EXTENSION_ID = '@ohif/extension-measurement-tracking' const SR_TOOLGROUP_BASE_NAME = 'SRToolGroup'; -function OHIFCornerstoneSRViewport(props) { +function OHIFCornerstoneSRViewport(props: withAppTypes) { const { children, dataSource, displaySets, viewportOptions, servicesManager, extensionManager } = props; @@ -369,7 +369,7 @@ OHIFCornerstoneSRViewport.propTypes = { viewportLabel: PropTypes.string, customProps: PropTypes.object, viewportOptions: PropTypes.object, - servicesManager: PropTypes.instanceOf(ServicesManager).isRequired, + servicesManager: PropTypes.object.isRequired, extensionManager: PropTypes.instanceOf(ExtensionManager).isRequired, }; diff --git a/extensions/cornerstone-dynamic-volume/src/actions/updateSegmentationsChartDisplaySet.ts b/extensions/cornerstone-dynamic-volume/src/actions/updateSegmentationsChartDisplaySet.ts index 810d98488..1f013d986 100644 --- a/extensions/cornerstone-dynamic-volume/src/actions/updateSegmentationsChartDisplaySet.ts +++ b/extensions/cornerstone-dynamic-volume/src/actions/updateSegmentationsChartDisplaySet.ts @@ -265,7 +265,7 @@ function _getInstanceFromSegmentations(segmentations, displaySetService) { return { seriesMetadata, instance }; } -function updateSegmentationsChartDisplaySet({ servicesManager }): void { +function updateSegmentationsChartDisplaySet({ servicesManager }: withAppTypes): void { const { segmentationService, displaySetService } = servicesManager.services; const segmentations = segmentationService.getSegmentations(); const { seriesMetadata, instance } = diff --git a/extensions/cornerstone-dynamic-volume/src/commandsModule.ts b/extensions/cornerstone-dynamic-volume/src/commandsModule.ts index a6cdf6cda..7828dd3f6 100644 --- a/extensions/cornerstone-dynamic-volume/src/commandsModule.ts +++ b/extensions/cornerstone-dynamic-volume/src/commandsModule.ts @@ -4,7 +4,7 @@ import { cache } from '@cornerstonejs/core'; const LABELMAP = Enums.SegmentationRepresentations.Labelmap; -const commandsModule = ({ commandsManager, servicesManager }) => { +const commandsModule = ({ commandsManager, servicesManager }: withAppTypes) => { const services = servicesManager.services; const { displaySetService, viewportGridService, segmentationService } = services; diff --git a/extensions/cornerstone-dynamic-volume/src/panels/DynamicExport.tsx b/extensions/cornerstone-dynamic-volume/src/panels/DynamicExport.tsx index 020278c4b..4a3eb7928 100644 --- a/extensions/cornerstone-dynamic-volume/src/panels/DynamicExport.tsx +++ b/extensions/cornerstone-dynamic-volume/src/panels/DynamicExport.tsx @@ -2,7 +2,7 @@ import React, { useState, useEffect } from 'react'; import { ActionButtons } from '@ohif/ui'; import { useTranslation } from 'react-i18next'; -function DynamicExport({ commandsManager, servicesManager, extensionManager }) { +function DynamicExport({ commandsManager, servicesManager, extensionManager }: withAppTypes) { const { segmentationService } = servicesManager.services; const { t } = useTranslation('dynamicExport'); diff --git a/extensions/cornerstone-dynamic-volume/src/panels/PanelGenerateImage.tsx b/extensions/cornerstone-dynamic-volume/src/panels/PanelGenerateImage.tsx index 9f8d821fd..163b55eba 100644 --- a/extensions/cornerstone-dynamic-volume/src/panels/PanelGenerateImage.tsx +++ b/extensions/cornerstone-dynamic-volume/src/panels/PanelGenerateImage.tsx @@ -8,7 +8,7 @@ import DynamicVolumeControls from './DynamicVolumeControls'; const SOPClassHandlerId = '@ohif/extension-default.sopClassHandlerModule.stack'; -export default function PanelGenerateImage({ servicesManager, commandsManager }) { +export default function PanelGenerateImage({ servicesManager, commandsManager }: withAppTypes) { const { cornerstoneViewportService, viewportGridService, displaySetService } = servicesManager.services; diff --git a/extensions/cornerstone/src/Viewport/OHIFCornerstoneViewport.tsx b/extensions/cornerstone/src/Viewport/OHIFCornerstoneViewport.tsx index b74bfde6a..e5ad2c3ef 100644 --- a/extensions/cornerstone/src/Viewport/OHIFCornerstoneViewport.tsx +++ b/extensions/cornerstone/src/Viewport/OHIFCornerstoneViewport.tsx @@ -18,7 +18,6 @@ import { setEnabledElement } from '../state'; import './OHIFCornerstoneViewport.css'; import CornerstoneOverlays from './Overlays/CornerstoneOverlays'; import getSOPInstanceAttributes from '../utils/measurementServiceMappings/utils/getSOPInstanceAttributes'; -import CornerstoneServices from '../types/CornerstoneServices'; import CinePlayer from '../components/CinePlayer'; import { Types } from '@ohif/core'; @@ -100,7 +99,7 @@ function areEqual(prevProps, nextProps) { // Todo: This should be done with expose of internal API similar to react-vtkjs-viewport // Then we don't need to worry about the re-renders if the props change. -const OHIFCornerstoneViewport = React.memo(props => { +const OHIFCornerstoneViewport = React.memo((props: withAppTypes) => { const { displaySets, dataSource, @@ -108,11 +107,13 @@ const OHIFCornerstoneViewport = React.memo(props => { displaySetOptions, servicesManager, onElementEnabled, + // eslint-disable-next-line react/prop-types onElementDisabled, isJumpToMeasurementDisabled, // Note: you SHOULD NOT use the initialImageIdOrIndex for manipulation // of the imageData in the OHIFCornerstoneViewport. This prop is used // to set the initial state of the viewport's first image to render + // eslint-disable-next-line react/prop-types initialImageIndex, // if the viewport is part of a hanging protocol layout // we should not really rely on the old synchronizers and @@ -120,6 +121,7 @@ const OHIFCornerstoneViewport = React.memo(props => { // is not part of the hanging protocol layout. HPs should // define their own synchronizers. Since the synchronizers are // viewportId dependent and + // eslint-disable-next-line react/prop-types isHangingProtocolLayout, } = props; @@ -152,7 +154,7 @@ const OHIFCornerstoneViewport = React.memo(props => { viewportGridService, stateSyncService, viewportActionCornersService, - } = servicesManager.services as CornerstoneServices; + } = servicesManager.services; const [viewportDialogState] = useViewportDialog(); // useCallback for scroll bar height calculation diff --git a/extensions/cornerstone/src/Viewport/Overlays/CornerstoneOverlays.tsx b/extensions/cornerstone/src/Viewport/Overlays/CornerstoneOverlays.tsx index 69f7b10fa..43ec800c4 100644 --- a/extensions/cornerstone/src/Viewport/Overlays/CornerstoneOverlays.tsx +++ b/extensions/cornerstone/src/Viewport/Overlays/CornerstoneOverlays.tsx @@ -5,7 +5,7 @@ import CustomizableViewportOverlay from './CustomizableViewportOverlay'; import ViewportOrientationMarkers from './ViewportOrientationMarkers'; import ViewportImageSliceLoadingIndicator from './ViewportImageSliceLoadingIndicator'; -function CornerstoneOverlays(props) { +function CornerstoneOverlays(props: withAppTypes) { const { viewportId, element, scrollbarHeight, servicesManager } = props; const { cornerstoneViewportService } = servicesManager.services; const [imageSliceData, setImageSliceData] = useState({ diff --git a/extensions/cornerstone/src/Viewport/Overlays/CustomizableViewportOverlay.tsx b/extensions/cornerstone/src/Viewport/Overlays/CustomizableViewportOverlay.tsx index eb8e834c2..9cfd4544f 100644 --- a/extensions/cornerstone/src/Viewport/Overlays/CustomizableViewportOverlay.tsx +++ b/extensions/cornerstone/src/Viewport/Overlays/CustomizableViewportOverlay.tsx @@ -4,7 +4,6 @@ import PropTypes from 'prop-types'; import { metaData, Enums, utilities } from '@cornerstonejs/core'; import { ImageSliceData } from '@cornerstonejs/core/dist/esm/types'; import { ViewportOverlay } from '@ohif/ui'; -import { ServicesManager } from '@ohif/core'; import { InstanceMetadata } from '@ohif/core/src/types'; import { formatPN, formatDICOMDate, formatDICOMTime, formatNumberPrecision } from './utils'; import { StackViewportData, VolumeViewportData } from '../../types/CornerstoneCacheService'; @@ -19,7 +18,7 @@ interface OverlayItemProps { element: HTMLElement; viewportData: ViewportData; imageSliceData: ImageSliceData; - servicesManager: ServicesManager; + servicesManager: AppTypes.ServicesManager; viewportId: string; instance: InstanceMetadata; customization: any; @@ -59,7 +58,7 @@ function CustomizableViewportOverlay({ viewportData: ViewportData; imageSliceData: ImageSliceData; viewportId: string; - servicesManager: ServicesManager; + servicesManager: AppTypes.ServicesManager; }) { const { cornerstoneViewportService, customizationService, toolGroupService } = servicesManager.services; diff --git a/extensions/cornerstone/src/Viewport/Overlays/ViewportImageScrollbar.tsx b/extensions/cornerstone/src/Viewport/Overlays/ViewportImageScrollbar.tsx index eb7fe2af3..88ab4e4ae 100644 --- a/extensions/cornerstone/src/Viewport/Overlays/ViewportImageScrollbar.tsx +++ b/extensions/cornerstone/src/Viewport/Overlays/ViewportImageScrollbar.tsx @@ -3,7 +3,6 @@ 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,8 +12,8 @@ function CornerstoneImageScrollbar({ setImageSliceData, scrollbarHeight, servicesManager, -}) { - const { cineService, cornerstoneViewportService } = (servicesManager as ServicesManger).services; +}: withAppTypes) { + const { cineService, cornerstoneViewportService } = servicesManager.services; const onImageScrollbarChange = (imageIndex, viewportId) => { const viewport = cornerstoneViewportService.getCornerstoneViewport(viewportId); diff --git a/extensions/cornerstone/src/Viewport/Overlays/ViewportOrientationMarkers.tsx b/extensions/cornerstone/src/Viewport/Overlays/ViewportOrientationMarkers.tsx index 45b85b705..eb1dd8200 100644 --- a/extensions/cornerstone/src/Viewport/Overlays/ViewportOrientationMarkers.tsx +++ b/extensions/cornerstone/src/Viewport/Overlays/ViewportOrientationMarkers.tsx @@ -22,7 +22,7 @@ function ViewportOrientationMarkers({ viewportId, servicesManager, orientationMarkers = ['top', 'left'], -}) { +}: withAppTypes) { // Rotation is in degrees const [rotation, setRotation] = useState(0); const [flipHorizontal, setFlipHorizontal] = useState(false); diff --git a/extensions/cornerstone/src/commandsModule.ts b/extensions/cornerstone/src/commandsModule.ts index ecabf31fb..69f51168a 100644 --- a/extensions/cornerstone/src/commandsModule.ts +++ b/extensions/cornerstone/src/commandsModule.ts @@ -20,7 +20,6 @@ import { callLabelAutocompleteDialog, showLabelAnnotationPopup } from './utils/c import toggleImageSliceSync from './utils/imageSliceSync/toggleImageSliceSync'; import { getFirstAnnotationSelected } from './utils/measurementServiceMappings/utils/selection'; import getActiveViewportEnabledElement from './utils/getActiveViewportEnabledElement'; -import { CornerstoneServices } from './types'; import toggleVOISliceSync from './utils/toggleVOISliceSync'; const toggleSyncFunctions = { @@ -44,7 +43,7 @@ function commandsModule({ colorbarService, hangingProtocolService, syncGroupService, - } = servicesManager.services as CornerstoneServices; + } = servicesManager.services; const { measurementServiceSource } = this; diff --git a/extensions/cornerstone/src/components/ActiveViewportWindowLevel/ActiveViewportWindowLevel.tsx b/extensions/cornerstone/src/components/ActiveViewportWindowLevel/ActiveViewportWindowLevel.tsx index 4a301679f..295d6bd60 100644 --- a/extensions/cornerstone/src/components/ActiveViewportWindowLevel/ActiveViewportWindowLevel.tsx +++ b/extensions/cornerstone/src/components/ActiveViewportWindowLevel/ActiveViewportWindowLevel.tsx @@ -1,14 +1,9 @@ import React, { ReactElement } from 'react'; import PropTypes from 'prop-types'; -import { ServicesManager } from '@ohif/core'; import { useViewportGrid } from '@ohif/ui'; import ViewportWindowLevel from '../ViewportWindowLevel/ViewportWindowLevel'; -const ActiveViewportWindowLevel = ({ - servicesManager, -}: { - servicesManager: ServicesManager; -}): ReactElement => { +const ActiveViewportWindowLevel = ({ servicesManager }: withAppTypes): ReactElement => { const [viewportGrid] = useViewportGrid(); const { activeViewportId } = viewportGrid; @@ -25,7 +20,7 @@ const ActiveViewportWindowLevel = ({ }; ActiveViewportWindowLevel.propTypes = { - servicesManager: PropTypes.instanceOf(ServicesManager), + servicesManager: PropTypes.object.isRequired, }; export default ActiveViewportWindowLevel; diff --git a/extensions/cornerstone/src/components/CinePlayer/CinePlayer.tsx b/extensions/cornerstone/src/components/CinePlayer/CinePlayer.tsx index 1ab5a47e3..af78066ab 100644 --- a/extensions/cornerstone/src/components/CinePlayer/CinePlayer.tsx +++ b/extensions/cornerstone/src/components/CinePlayer/CinePlayer.tsx @@ -4,7 +4,14 @@ import { Enums, eventTarget, cache } from '@cornerstonejs/core'; import { Enums as StreamingEnums } from '@cornerstonejs/streaming-image-volume-loader'; import { useAppConfig } from '@state'; -function WrappedCinePlayer({ enabledVPElement, viewportId, servicesManager }) { +function WrappedCinePlayer({ + enabledVPElement, + viewportId, + servicesManager, +}: withAppTypes<{ + enabledVPElement: HTMLElement; + viewportId: string; +}>) { const { customizationService, displaySetService, viewportGridService } = servicesManager.services; const [{ isCineEnabled, cines }, cineService] = useCine(); const [newStackFrameRate, setNewStackFrameRate] = useState(24); diff --git a/extensions/cornerstone/src/components/ViewportWindowLevel/ViewportWindowLevel.tsx b/extensions/cornerstone/src/components/ViewportWindowLevel/ViewportWindowLevel.tsx index d4e193dd9..522022965 100644 --- a/extensions/cornerstone/src/components/ViewportWindowLevel/ViewportWindowLevel.tsx +++ b/extensions/cornerstone/src/components/ViewportWindowLevel/ViewportWindowLevel.tsx @@ -1,7 +1,6 @@ import React, { useEffect, useCallback, useState, ReactElement } from 'react'; import PropTypes from 'prop-types'; import debounce from 'lodash.debounce'; -import { ServicesManager } from '@ohif/core'; import { PanelSection, WindowLevel } from '@ohif/ui'; import vtkColorMaps from '@kitware/vtk.js/Rendering/Core/ColorTransferFunction/ColorMaps'; import { Enums, eventTarget, cache as cs3DCache, utilities as csUtils } from '@cornerstonejs/core'; @@ -12,10 +11,9 @@ const { Events } = Enums; const ViewportWindowLevel = ({ servicesManager, viewportId, -}: { - servicesManager: ServicesManager; +}: withAppTypes<{ viewportId: string; -}): ReactElement => { +}>): ReactElement => { const { cornerstoneViewportService } = servicesManager.services; const [windowLevels, setWindowLevels] = useState([]); const [cachedHistograms, setCachedHistograms] = useState({}); @@ -380,7 +378,7 @@ const ViewportWindowLevel = ({ }; ViewportWindowLevel.propTypes = { - servicesManager: PropTypes.instanceOf(ServicesManager), + servicesManager: PropTypes.object.isRequired, viewportId: PropTypes.string.isRequired, }; diff --git a/extensions/cornerstone/src/components/WindowLevelActionMenu/Colorbar.tsx b/extensions/cornerstone/src/components/WindowLevelActionMenu/Colorbar.tsx index 91493b072..298c2ae84 100644 --- a/extensions/cornerstone/src/components/WindowLevelActionMenu/Colorbar.tsx +++ b/extensions/cornerstone/src/components/WindowLevelActionMenu/Colorbar.tsx @@ -8,10 +8,10 @@ export function setViewportColorbar( viewportId, displaySets, commandsManager, - serviceManager, + servicesManager: AppTypes.ServicesManager, colorbarOptions ) { - const { cornerstoneViewportService } = serviceManager.services; + const { cornerstoneViewportService } = servicesManager.services; const viewport = cornerstoneViewportService.getCornerstoneViewport(viewportId); const viewportInfo = cornerstoneViewportService.getViewportInfo(viewportId); @@ -59,10 +59,10 @@ export function Colorbar({ viewportId, displaySets, commandsManager, - serviceManager, + servicesManager, colorbarProperties, -}: ColorbarProps): ReactElement { - const { colorbarService } = serviceManager.services; +}: withAppTypes): ReactElement { + const { colorbarService } = servicesManager.services; const { width: colorbarWidth, colorbarTickPosition, @@ -73,7 +73,7 @@ export function Colorbar({ const [showColorbar, setShowColorbar] = useState(colorbarService.hasColorbar(viewportId)); const onSetColorbar = useCallback(() => { - setViewportColorbar(viewportId, displaySets, commandsManager, serviceManager, { + setViewportColorbar(viewportId, displaySets, commandsManager, servicesManager, { viewportId, colormaps, ticks: { diff --git a/extensions/cornerstone/src/components/WindowLevelActionMenu/Colormap.tsx b/extensions/cornerstone/src/components/WindowLevelActionMenu/Colormap.tsx index a37eae3a9..51764c956 100644 --- a/extensions/cornerstone/src/components/WindowLevelActionMenu/Colormap.tsx +++ b/extensions/cornerstone/src/components/WindowLevelActionMenu/Colormap.tsx @@ -8,9 +8,9 @@ export function Colormap({ viewportId, displaySets, commandsManager, - serviceManager, + servicesManager, }: ColormapProps): ReactElement { - const { cornerstoneViewportService } = serviceManager.services; + const { cornerstoneViewportService } = servicesManager.services; const [activeDisplaySet, setActiveDisplaySet] = useState(displaySets[0]); diff --git a/extensions/cornerstone/src/components/WindowLevelActionMenu/VolumeLighting.tsx b/extensions/cornerstone/src/components/WindowLevelActionMenu/VolumeLighting.tsx index 7cd7d4f85..6aa6f5610 100644 --- a/extensions/cornerstone/src/components/WindowLevelActionMenu/VolumeLighting.tsx +++ b/extensions/cornerstone/src/components/WindowLevelActionMenu/VolumeLighting.tsx @@ -2,11 +2,11 @@ import React, { ReactElement, useState, useEffect, useCallback } from 'react'; import { VolumeLightingProps } from '../../types/ViewportPresets'; export function VolumeLighting({ - serviceManager, + servicesManager, commandsManager, viewportId, }: VolumeLightingProps): ReactElement { - const { cornerstoneViewportService } = serviceManager.services; + const { cornerstoneViewportService } = servicesManager.services; const [ambient, setAmbient] = useState(null); const [diffuse, setDiffuse] = useState(null); const [specular, setSpecular] = useState(null); diff --git a/extensions/cornerstone/src/components/WindowLevelActionMenu/VolumeRenderingOptions.tsx b/extensions/cornerstone/src/components/WindowLevelActionMenu/VolumeRenderingOptions.tsx index 1e0901ad3..c62515cc8 100644 --- a/extensions/cornerstone/src/components/WindowLevelActionMenu/VolumeRenderingOptions.tsx +++ b/extensions/cornerstone/src/components/WindowLevelActionMenu/VolumeRenderingOptions.tsx @@ -9,21 +9,21 @@ export function VolumeRenderingOptions({ viewportId, commandsManager, volumeRenderingQualityRange, - serviceManager, + servicesManager, }: VolumeRenderingOptionsProps): ReactElement { return (
LIGHTING
@@ -32,14 +32,14 @@ export function VolumeRenderingOptions({
); diff --git a/extensions/cornerstone/src/components/WindowLevelActionMenu/VolumeRenderingPresets.tsx b/extensions/cornerstone/src/components/WindowLevelActionMenu/VolumeRenderingPresets.tsx index bbf2c5705..031e5bdc4 100644 --- a/extensions/cornerstone/src/components/WindowLevelActionMenu/VolumeRenderingPresets.tsx +++ b/extensions/cornerstone/src/components/WindowLevelActionMenu/VolumeRenderingPresets.tsx @@ -5,11 +5,11 @@ import { VolumeRenderingPresetsContent } from './VolumeRenderingPresetsContent'; export function VolumeRenderingPresets({ viewportId, - serviceManager, + servicesManager, commandsManager, volumeRenderingPresets, }: VolumeRenderingPresetsProps): ReactElement { - const { uiModalService } = serviceManager.services; + const { uiModalService } = servicesManager.services; const onClickPresets = () => { uiModalService.show({ diff --git a/extensions/cornerstone/src/components/WindowLevelActionMenu/VolumeRenderingQuality.tsx b/extensions/cornerstone/src/components/WindowLevelActionMenu/VolumeRenderingQuality.tsx index 7a6fce9a6..01864812e 100644 --- a/extensions/cornerstone/src/components/WindowLevelActionMenu/VolumeRenderingQuality.tsx +++ b/extensions/cornerstone/src/components/WindowLevelActionMenu/VolumeRenderingQuality.tsx @@ -4,10 +4,10 @@ import { VolumeRenderingQualityProps } from '../../types/ViewportPresets'; export function VolumeRenderingQuality({ volumeRenderingQualityRange, commandsManager, - serviceManager, + servicesManager, viewportId, }: VolumeRenderingQualityProps): ReactElement { - const { cornerstoneViewportService } = serviceManager.services; + const { cornerstoneViewportService } = servicesManager.services; const { min, max, step } = volumeRenderingQualityRange; const [quality, setQuality] = useState(null); diff --git a/extensions/cornerstone/src/components/WindowLevelActionMenu/VolumeShade.tsx b/extensions/cornerstone/src/components/WindowLevelActionMenu/VolumeShade.tsx index 319158dab..4ef52c0b2 100644 --- a/extensions/cornerstone/src/components/WindowLevelActionMenu/VolumeShade.tsx +++ b/extensions/cornerstone/src/components/WindowLevelActionMenu/VolumeShade.tsx @@ -5,9 +5,9 @@ import { VolumeShadeProps } from '../../types/ViewportPresets'; export function VolumeShade({ commandsManager, viewportId, - serviceManager, + servicesManager, }: VolumeShadeProps): ReactElement { - const { cornerstoneViewportService } = serviceManager.services; + const { cornerstoneViewportService } = servicesManager.services; const [shade, setShade] = useState(true); const [key, setKey] = useState(0); diff --git a/extensions/cornerstone/src/components/WindowLevelActionMenu/VolumeShift.tsx b/extensions/cornerstone/src/components/WindowLevelActionMenu/VolumeShift.tsx index 274f71599..353126901 100644 --- a/extensions/cornerstone/src/components/WindowLevelActionMenu/VolumeShift.tsx +++ b/extensions/cornerstone/src/components/WindowLevelActionMenu/VolumeShift.tsx @@ -4,9 +4,9 @@ import { VolumeShiftProps } from '../../types/ViewportPresets'; export function VolumeShift({ viewportId, commandsManager, - serviceManager, + servicesManager, }: VolumeShiftProps): ReactElement { - const { cornerstoneViewportService } = serviceManager.services; + const { cornerstoneViewportService } = servicesManager.services; const [minShift, setMinShift] = useState(null); const [maxShift, setMaxShift] = useState(null); const [shift, setShift] = useState( diff --git a/extensions/cornerstone/src/components/WindowLevelActionMenu/WindowLevelActionMenu.tsx b/extensions/cornerstone/src/components/WindowLevelActionMenu/WindowLevelActionMenu.tsx index c6f20158f..55b4d53b9 100644 --- a/extensions/cornerstone/src/components/WindowLevelActionMenu/WindowLevelActionMenu.tsx +++ b/extensions/cornerstone/src/components/WindowLevelActionMenu/WindowLevelActionMenu.tsx @@ -2,7 +2,6 @@ import React, { ReactElement, useCallback, useEffect, useState } from 'react'; import { useTranslation } from 'react-i18next'; import classNames from 'classnames'; import { AllInOneMenu, useViewportGrid } from '@ohif/ui'; -import { CommandsManager, ServicesManager } from '@ohif/core'; import { Colormap } from './Colormap'; import { Colorbar } from './Colorbar'; import { setViewportColorbar } from './Colorbar'; @@ -22,8 +21,6 @@ export type WindowLevelActionMenuProps = { presets: Array>>; verticalDirection: AllInOneMenu.VerticalDirection; horizontalDirection: AllInOneMenu.HorizontalDirection; - commandsManager: CommandsManager; - serviceManager: ServicesManager; colorbarProperties: ColorbarProperties; displaySets: Array; volumeRenderingPresets: Array; @@ -37,12 +34,12 @@ export function WindowLevelActionMenu({ verticalDirection, horizontalDirection, commandsManager, - serviceManager, + servicesManager, colorbarProperties, displaySets, volumeRenderingPresets, volumeRenderingQualityRange, -}: WindowLevelActionMenuProps): ReactElement { +}: withAppTypes): ReactElement { const { colormaps, colorbarContainerPosition, @@ -50,7 +47,7 @@ export function WindowLevelActionMenu({ colorbarTickPosition, width: colorbarWidth, } = colorbarProperties; - const { colorbarService, cornerstoneViewportService } = serviceManager.services; + const { colorbarService, cornerstoneViewportService } = servicesManager.services; const viewportInfo = cornerstoneViewportService.getViewportInfo(viewportId); const viewport = cornerstoneViewportService.getCornerstoneViewport(viewportId); const backgroundColor = viewportInfo.getViewportOptions().background; @@ -68,7 +65,7 @@ export function WindowLevelActionMenu({ const [is3DVolume, setIs3DVolume] = useState(false); const onSetColorbar = useCallback(() => { - setViewportColorbar(viewportId, displaySets, commandsManager, serviceManager, { + setViewportColorbar(viewportId, displaySets, commandsManager, servicesManager, { colormaps, ticks: { position: colorbarTickPosition, @@ -138,7 +135,7 @@ export function WindowLevelActionMenu({ viewportId={viewportId} displaySets={displaySets.filter(ds => !nonImageModalities.includes(ds.Modality))} commandsManager={commandsManager} - serviceManager={serviceManager} + servicesManager={servicesManager} colorbarProperties={colorbarProperties} /> )} @@ -154,7 +151,7 @@ export function WindowLevelActionMenu({ viewportId={viewportId} displaySets={displaySets.filter(ds => !nonImageModalities.includes(ds.Modality))} commandsManager={commandsManager} - serviceManager={serviceManager} + servicesManager={servicesManager} /> )} @@ -175,7 +172,7 @@ export function WindowLevelActionMenu({ {volumeRenderingPresets && is3DVolume && ( )} diff --git a/extensions/cornerstone/src/components/WindowLevelActionMenu/getWindowLevelActionMenu.tsx b/extensions/cornerstone/src/components/WindowLevelActionMenu/getWindowLevelActionMenu.tsx index b07fa7899..c18176a58 100644 --- a/extensions/cornerstone/src/components/WindowLevelActionMenu/getWindowLevelActionMenu.tsx +++ b/extensions/cornerstone/src/components/WindowLevelActionMenu/getWindowLevelActionMenu.tsx @@ -9,7 +9,7 @@ export function getWindowLevelActionMenu({ commandsManager, verticalDirection, horizontalDirection, -}): ReactNode { +}: withAppTypes): ReactNode { const { customizationService } = servicesManager.services; const { presets } = customizationService.get('cornerstone.windowLevelPresets'); @@ -32,7 +32,7 @@ export function getWindowLevelActionMenu({ verticalDirection={verticalDirection} horizontalDirection={horizontalDirection} commandsManager={commandsManager} - serviceManager={servicesManager} + servicesManager={servicesManager} colorbarProperties={colorbarProperties} displaySets={displaySets} volumeRenderingPresets={volumeRenderingPresets} diff --git a/extensions/cornerstone/src/getToolbarModule.tsx b/extensions/cornerstone/src/getToolbarModule.tsx index 61a6428ed..da2e57f47 100644 --- a/extensions/cornerstone/src/getToolbarModule.tsx +++ b/extensions/cornerstone/src/getToolbarModule.tsx @@ -6,7 +6,7 @@ const getToggledClassName = (isToggled: boolean) => { : '!text-common-bright hover:!bg-primary-dark hover:text-primary-light'; }; -export default function getToolbarModule({ commandsManager, servicesManager }) { +export default function getToolbarModule({ commandsManager, servicesManager }: withAppTypes) { const { toolGroupService, toolbarService, diff --git a/extensions/cornerstone/src/index.tsx b/extensions/cornerstone/src/index.tsx index d2b8cf24b..748d57942 100644 --- a/extensions/cornerstone/src/index.tsx +++ b/extensions/cornerstone/src/index.tsx @@ -8,7 +8,7 @@ import { } from '@cornerstonejs/core'; import * as csStreamingImageVolumeLoader from '@cornerstonejs/streaming-image-volume-loader'; import { Enums as cs3DToolsEnums } from '@cornerstonejs/tools'; -import { ServicesManager, Types } from '@ohif/core'; +import { Types } from '@ohif/core'; import init from './init'; import getCustomizationModule from './getCustomizationModule'; @@ -61,7 +61,7 @@ const cornerstoneExtension: Types.Extensions.Extension = { */ id, - onModeEnter: ({ servicesManager }): void => { + onModeEnter: ({ servicesManager }: withAppTypes): void => { const { cornerstoneViewportService, toolbarService, segmentationService } = servicesManager.services; toolbarService.registerEventForToolbarUpdate(cornerstoneViewportService, [ @@ -79,7 +79,7 @@ const cornerstoneExtension: Types.Extensions.Extension = { ]); }, - onModeExit: ({ servicesManager }): void => { + onModeExit: ({ servicesManager }: withAppTypes): void => { const { cineService } = servicesManager.services; // Empty out the image load and retrieval pools to prevent memory leaks // on the mode exits @@ -132,7 +132,7 @@ const cornerstoneExtension: Types.Extensions.Extension = { // const onNewImageHandler = jumpData => { // commandsManager.runCommand('jumpToImage', jumpData); // }; - const { toolbarService } = (servicesManager as ServicesManager).services; + const { toolbarService } = servicesManager.services; return ( ({ viewportId })); } -function initCineService(servicesManager) { +function initCineService(servicesManager: AppTypes.ServicesManager) { const { cineService } = servicesManager.services; const getSyncedViewports = viewportId => { diff --git a/extensions/cornerstone/src/initMeasurementService.js b/extensions/cornerstone/src/initMeasurementService.ts similarity index 99% rename from extensions/cornerstone/src/initMeasurementService.js rename to extensions/cornerstone/src/initMeasurementService.ts index 79d94f78f..b2682953b 100644 --- a/extensions/cornerstone/src/initMeasurementService.js +++ b/extensions/cornerstone/src/initMeasurementService.ts @@ -178,7 +178,7 @@ const initMeasurementService = ( return csTools3DVer1MeasurementSource; }; -const connectToolsToMeasurementService = servicesManager => { +const connectToolsToMeasurementService = (servicesManager: AppTypes.ServicesManager) => { const { measurementService, displaySetService, diff --git a/extensions/cornerstone/src/services/CornerstoneCacheService/CornerstoneCacheService.ts b/extensions/cornerstone/src/services/CornerstoneCacheService/CornerstoneCacheService.ts index 74f5d7ac3..b02cc43f1 100644 --- a/extensions/cornerstone/src/services/CornerstoneCacheService/CornerstoneCacheService.ts +++ b/extensions/cornerstone/src/services/CornerstoneCacheService/CornerstoneCacheService.ts @@ -1,4 +1,4 @@ -import { ServicesManager, Types } from '@ohif/core'; +import { Types } from '@ohif/core'; import { cache as cs3DCache, Enums, volumeLoader, utilities as utils } from '@cornerstonejs/core'; import getCornerstoneViewportType from '../../utils/getCornerstoneViewportType'; @@ -17,9 +17,9 @@ class CornerstoneCacheService { stackImageIds: Map = new Map(); volumeImageIds: Map = new Map(); - readonly servicesManager: ServicesManager; + readonly servicesManager: AppTypes.ServicesManager; - constructor(servicesManager: ServicesManager) { + constructor(servicesManager: AppTypes.ServicesManager) { this.servicesManager = servicesManager; } diff --git a/extensions/cornerstone/src/services/SegmentationService/SegmentationService.ts b/extensions/cornerstone/src/services/SegmentationService/SegmentationService.ts index 87b2590ee..bc2c2a838 100644 --- a/extensions/cornerstone/src/services/SegmentationService/SegmentationService.ts +++ b/extensions/cornerstone/src/services/SegmentationService/SegmentationService.ts @@ -1,4 +1,4 @@ -import { Types as OhifTypes, ServicesManager, PubSubService } from '@ohif/core'; +import { Types as OhifTypes, PubSubService } from '@ohif/core'; import { cache, Enums as csEnums, @@ -60,7 +60,7 @@ class SegmentationService extends PubSubService { }; segmentations: Record; - readonly servicesManager: ServicesManager; + readonly servicesManager: AppTypes.ServicesManager; highlightIntervalId = null; readonly EVENTS = EVENTS; diff --git a/extensions/cornerstone/src/services/SyncGroupService/SyncGroupService.ts b/extensions/cornerstone/src/services/SyncGroupService/SyncGroupService.ts index b9c9be682..55ba5e6ce 100644 --- a/extensions/cornerstone/src/services/SyncGroupService/SyncGroupService.ts +++ b/extensions/cornerstone/src/services/SyncGroupService/SyncGroupService.ts @@ -1,7 +1,7 @@ import { synchronizers, SynchronizerManager, Synchronizer } from '@cornerstonejs/tools'; import { getRenderingEngines, utilities } from '@cornerstonejs/core'; -import { pubSubServiceInterface, Types, ServicesManager } from '@ohif/core'; +import { pubSubServiceInterface, Types } from '@ohif/core'; const EVENTS = { TOOL_GROUP_CREATED: 'event::cornerstone::syncgroupservice:toolgroupcreated', @@ -40,7 +40,7 @@ export default class SyncGroupService { }, }; - servicesManager: ServicesManager; + servicesManager: AppTypes.ServicesManager; listeners: { [key: string]: (...args: any[]) => void } = {}; EVENTS: { [key: string]: string }; synchronizerCreators: Record = { @@ -55,8 +55,8 @@ export default class SyncGroupService { synchronizersByType: { [key: string]: Synchronizer[] } = {}; - constructor(serviceManager: ServicesManager) { - this.servicesManager = serviceManager; + constructor(servicesManager: AppTypes.ServicesManager) { + this.servicesManager = servicesManager; this.listeners = {}; this.EVENTS = EVENTS; // diff --git a/extensions/cornerstone/src/services/ToolGroupService/ToolGroupService.ts b/extensions/cornerstone/src/services/ToolGroupService/ToolGroupService.ts index a6926ad2c..298f28612 100644 --- a/extensions/cornerstone/src/services/ToolGroupService/ToolGroupService.ts +++ b/extensions/cornerstone/src/services/ToolGroupService/ToolGroupService.ts @@ -32,7 +32,10 @@ export default class ToolGroupService { }, }; - serviceManager: any; + servicesManager: AppTypes.ServicesManager; + cornerstoneViewportService: any; + viewportGridService: any; + uiNotificationService: any; private toolGroupIds: Set = new Set(); /** * Service-specific @@ -40,9 +43,9 @@ export default class ToolGroupService { listeners: { [key: string]: Function[] }; EVENTS: { [key: string]: string }; - constructor(serviceManager) { + constructor(servicesManager: AppTypes.ServicesManager) { const { cornerstoneViewportService, viewportGridService, uiNotificationService } = - serviceManager.services; + servicesManager.services; this.cornerstoneViewportService = cornerstoneViewportService; this.viewportGridService = viewportGridService; this.uiNotificationService = uiNotificationService; diff --git a/extensions/cornerstone/src/services/ViewportService/CornerstoneViewportService.ts b/extensions/cornerstone/src/services/ViewportService/CornerstoneViewportService.ts index 9fd4f3ce5..b59b11d90 100644 --- a/extensions/cornerstone/src/services/ViewportService/CornerstoneViewportService.ts +++ b/extensions/cornerstone/src/services/ViewportService/CornerstoneViewportService.ts @@ -1,4 +1,4 @@ -import { PubSubService, ServicesManager } from '@ohif/core'; +import { PubSubService } from '@ohif/core'; import * as OhifTypes from '@ohif/core/types'; import { RenderingEngine, @@ -52,14 +52,14 @@ class CornerstoneViewportService extends PubSubService implements IViewportServi enableResizeDetector: true; resizeRefreshRateMs: 200; resizeRefreshMode: 'debounce'; - servicesManager = null; + servicesManager: AppTypes.ServicesManager = null; resizeQueue = []; viewportResizeTimer = null; gridResizeDelay = 50; gridResizeTimeOut = null; - constructor(servicesManager: ServicesManager) { + constructor(servicesManager: AppTypes.ServicesManager) { super(EVENTS); this.renderingEngine = null; this.viewportGridResizeObserver = null; diff --git a/extensions/cornerstone/src/services/ViewportService/IViewportService.ts b/extensions/cornerstone/src/services/ViewportService/IViewportService.ts index b16fa989f..46d4acd5b 100644 --- a/extensions/cornerstone/src/services/ViewportService/IViewportService.ts +++ b/extensions/cornerstone/src/services/ViewportService/IViewportService.ts @@ -8,7 +8,7 @@ import { Presentations } from '../../types/Presentation'; * updating the viewport. */ export interface IViewportService { - servicesManager: unknown; + servicesManager: AppTypes.ServicesManager; hangingProtocolService: unknown; renderingEngine: unknown; viewportGridResizeObserver: unknown; diff --git a/extensions/cornerstone/src/tools/CalibrationLineTool.ts b/extensions/cornerstone/src/tools/CalibrationLineTool.ts index c9e008fc6..6c77fbe79 100644 --- a/extensions/cornerstone/src/tools/CalibrationLineTool.ts +++ b/extensions/cornerstone/src/tools/CalibrationLineTool.ts @@ -1,4 +1,3 @@ -import { metaData } from '@cornerstonejs/core'; import { LengthTool, utilities } from '@cornerstonejs/tools'; import callInputDialog from '../utils/callInputDialog'; import getActiveViewportEnabledElement from '../utils/getActiveViewportEnabledElement'; @@ -49,7 +48,10 @@ function calculateLength3(pos1, pos2) { export default CalibrationLineTool; -export function onCompletedCalibrationLine(servicesManager, csToolsEvent) { +export function onCompletedCalibrationLine( + servicesManager: AppTypes.ServicesManager, + csToolsEvent +) { const { uiDialogService, viewportGridService } = servicesManager.services; // calculate length (mm) with the current Pixel Spacing diff --git a/extensions/cornerstone/src/types/AppTypes.ts b/extensions/cornerstone/src/types/AppTypes.ts new file mode 100644 index 000000000..45c523079 --- /dev/null +++ b/extensions/cornerstone/src/types/AppTypes.ts @@ -0,0 +1,29 @@ +/* eslint-disable @typescript-eslint/no-namespace */ +import CornerstoneCacheServiceType from '../services/CornerstoneCacheService'; +import CornerstoneViewportServiceType from '../services/ViewportService/CornerstoneViewportService'; +import SegmentationServiceType from '../services/SegmentationService'; +import SyncGroupServiceType from '../services/SyncGroupService'; +import ToolGroupServiceType from '../services/ToolGroupService'; +import ViewportActionCornersServiceType from '../services/ViewportActionCornersService/ViewportActionCornersService'; +import ColorbarServiceType from '../services/ColorbarService'; + +declare global { + namespace AppTypes { + export type CornerstoneCacheService = CornerstoneCacheServiceType; + export type CornerstoneViewportService = CornerstoneViewportServiceType; + export type SegmentationService = SegmentationServiceType; + export type SyncGroupService = SyncGroupServiceType; + export type ToolGroupService = ToolGroupServiceType; + export type ViewportActionCornersService = ViewportActionCornersServiceType; + export type ColorbarService = ColorbarServiceType; + export interface Services { + cornerstoneViewportService?: CornerstoneViewportServiceType; + toolGroupService?: ToolGroupServiceType; + syncGroupService?: SyncGroupServiceType; + segmentationService?: SegmentationServiceType; + cornerstoneCacheService?: CornerstoneCacheServiceType; + viewportActionCornersService?: ViewportActionCornersServiceType; + colorbarService?: ColorbarServiceType; + } + } +} diff --git a/extensions/cornerstone/src/types/Colorbar.ts b/extensions/cornerstone/src/types/Colorbar.ts index 79beb199f..9eea7553c 100644 --- a/extensions/cornerstone/src/types/Colorbar.ts +++ b/extensions/cornerstone/src/types/Colorbar.ts @@ -1,5 +1,4 @@ import { ColorMapPreset } from './Colormap'; -import { CommandsManager, ServicesManager } from '@ohif/core'; export type ColorbarOptions = { position: string; @@ -11,8 +10,6 @@ export type ColorbarOptions = { export type ColorbarProps = { viewportId: string; - commandsManager: CommandsManager; - serviceManager: ServicesManager; displaySets: Array; colorbarProperties: ColorbarProperties; }; diff --git a/extensions/cornerstone/src/types/Colormap.ts b/extensions/cornerstone/src/types/Colormap.ts index d0cf1b22a..6e3032243 100644 --- a/extensions/cornerstone/src/types/Colormap.ts +++ b/extensions/cornerstone/src/types/Colormap.ts @@ -1,4 +1,4 @@ -import { CommandsManager, ServicesManager } from '@ohif/core'; +import { CommandsManager } from '@ohif/core'; export type ColorMapPreset = { ColorSpace; @@ -10,7 +10,7 @@ export type ColorMapPreset = { export type ColormapProps = { viewportId: string; commandsManager: CommandsManager; - serviceManager: ServicesManager; + servicesManager: AppTypes.ServicesManager; colormaps: Array; displaySets: Array; }; diff --git a/extensions/cornerstone/src/types/CornerstoneServices.ts b/extensions/cornerstone/src/types/CornerstoneServices.ts index a55b4ab47..b11dc97ee 100644 --- a/extensions/cornerstone/src/types/CornerstoneServices.ts +++ b/extensions/cornerstone/src/types/CornerstoneServices.ts @@ -5,6 +5,7 @@ import SegmentationService from '../services/SegmentationService'; import CornerstoneCacheService from '../services/CornerstoneCacheService'; import CornerstoneViewportService from '../services/ViewportService/CornerstoneViewportService'; import ViewportActionCornersService from '../services/ViewportActionCornersService/ViewportActionCornersService'; +import ColorbarService from '../services/ColorbarService'; interface CornerstoneServices extends Types.Services { cornerstoneViewportService: CornerstoneViewportService; @@ -13,6 +14,7 @@ interface CornerstoneServices extends Types.Services { segmentationService: SegmentationService; cornerstoneCacheService: CornerstoneCacheService; viewportActionCornersService: ViewportActionCornersService; + colorbarService: ColorbarService; } export default CornerstoneServices; diff --git a/extensions/cornerstone/src/types/ViewportPresets.ts b/extensions/cornerstone/src/types/ViewportPresets.ts index 070a6bbde..e954c2292 100644 --- a/extensions/cornerstone/src/types/ViewportPresets.ts +++ b/extensions/cornerstone/src/types/ViewportPresets.ts @@ -1,4 +1,4 @@ -import { ServicesManager, CommandsManager } from '@ohif/core'; +import { CommandsManager } from '@ohif/core'; export type ViewportPreset = { name: string; @@ -15,7 +15,7 @@ export type ViewportPreset = { export type VolumeRenderingPresetsProps = { viewportId: string; - serviceManager: ServicesManager; + servicesManager: AppTypes.ServicesManager; commandsManager: CommandsManager; volumeRenderingPresets: ViewportPreset[]; }; @@ -30,7 +30,7 @@ export type VolumeRenderingPresetsContentProps = { export type VolumeRenderingOptionsProps = { viewportId: string; commandsManager: CommandsManager; - serviceManager: ServicesManager; + servicesManager: AppTypes.ServicesManager; volumeRenderingQualityRange: VolumeRenderingQualityRange; }; @@ -43,24 +43,24 @@ export type VolumeRenderingQualityRange = { export type VolumeRenderingQualityProps = { viewportId: string; commandsManager: CommandsManager; - serviceManager: ServicesManager; + servicesManager: AppTypes.ServicesManager; volumeRenderingQualityRange: VolumeRenderingQualityRange; }; export type VolumeShiftProps = { viewportId: string; commandsManager: CommandsManager; - serviceManager: ServicesManager; + servicesManager: AppTypes.ServicesManager; }; export type VolumeShadeProps = { viewportId: string; commandsManager: CommandsManager; - serviceManager: ServicesManager; + servicesManager: AppTypes.ServicesManager; }; export type VolumeLightingProps = { viewportId: string; commandsManager: CommandsManager; - serviceManager: ServicesManager; + servicesManager: AppTypes.ServicesManager; }; diff --git a/extensions/cornerstone/src/utils/imageSliceSync/toggleImageSliceSync.ts b/extensions/cornerstone/src/utils/imageSliceSync/toggleImageSliceSync.ts index 1a8e8cd78..1ba3931ff 100644 --- a/extensions/cornerstone/src/utils/imageSliceSync/toggleImageSliceSync.ts +++ b/extensions/cornerstone/src/utils/imageSliceSync/toggleImageSliceSync.ts @@ -1,10 +1,12 @@ +import { DisplaySetService, ViewportGridService } from '@ohif/core'; + const IMAGE_SLICE_SYNC_NAME = 'IMAGE_SLICE_SYNC'; export default function toggleImageSliceSync({ servicesManager, viewports: providedViewports, syncId, -}) { +}: withAppTypes) { const { syncGroupService, viewportGridService, displaySetService, cornerstoneViewportService } = servicesManager.services; @@ -46,7 +48,7 @@ export default function toggleImageSliceSync({ }); } -function disableSync(syncName, servicesManager) { +function disableSync(syncName, servicesManager: AppTypes.ServicesManager) { const { syncGroupService, viewportGridService, displaySetService, cornerstoneViewportService } = servicesManager.services; const viewports = getReconstructableStackViewports(viewportGridService, displaySetService); @@ -68,7 +70,10 @@ function disableSync(syncName, servicesManager) { * Gets the consistent spacing stack viewport types, which are the ones which * can be navigated using the stack image sync right now. */ -function getReconstructableStackViewports(viewportGridService, displaySetService) { +function getReconstructableStackViewports( + viewportGridService: ViewportGridService, + displaySetService: DisplaySetService +) { let { viewports } = viewportGridService.getState(); viewports = [...viewports.values()]; diff --git a/extensions/cornerstone/src/utils/toggleVOISliceSync.ts b/extensions/cornerstone/src/utils/toggleVOISliceSync.ts index 0677cff37..57e23d116 100644 --- a/extensions/cornerstone/src/utils/toggleVOISliceSync.ts +++ b/extensions/cornerstone/src/utils/toggleVOISliceSync.ts @@ -1,3 +1,5 @@ +import { DisplaySetService, ViewportGridService } from '@ohif/core'; + const VOI_SYNC_NAME = 'VOI_SYNC'; const getSyncId = modality => `${VOI_SYNC_NAME}_${modality}`; @@ -6,7 +8,7 @@ export default function toggleVOISliceSync({ servicesManager, viewports: providedViewports, syncId, -}) { +}: withAppTypes) { const { syncGroupService, viewportGridService, displaySetService, cornerstoneViewportService } = servicesManager.services; @@ -52,7 +54,7 @@ export default function toggleVOISliceSync({ } } -function disableSync(modalityViewports, syncId, servicesManager) { +function disableSync(modalityViewports, syncId, servicesManager: AppTypes.ServicesManager) { const { syncGroupService, cornerstoneViewportService } = servicesManager.services; const viewports = modalityViewports; @@ -70,7 +72,10 @@ function disableSync(modalityViewports, syncId, servicesManager) { }); } -function groupViewportsByModality(viewportGridService, displaySetService) { +function groupViewportsByModality( + viewportGridService: ViewportGridService, + displaySetService: DisplaySetService +) { let { viewports } = viewportGridService.getState(); viewports = [...viewports.values()]; diff --git a/extensions/default/src/Actions/createReportAsync.tsx b/extensions/default/src/Actions/createReportAsync.tsx index 6248421e4..360894437 100644 --- a/extensions/default/src/Actions/createReportAsync.tsx +++ b/extensions/default/src/Actions/createReportAsync.tsx @@ -5,7 +5,11 @@ import { DicomMetadataStore } from '@ohif/core'; * * @param {*} servicesManager */ -async function createReportAsync({ servicesManager, getReport, reportType = 'measurement' }) { +async function createReportAsync({ + servicesManager, + getReport, + reportType = 'measurement', +}: withAppTypes) { const { displaySetService, uiNotificationService, uiDialogService } = servicesManager.services; const loadingDialogId = uiDialogService.create({ showOverlay: true, diff --git a/extensions/default/src/Components/DataSourceConfigurationComponent.tsx b/extensions/default/src/Components/DataSourceConfigurationComponent.tsx index 97896a92c..dd61dc551 100644 --- a/extensions/default/src/Components/DataSourceConfigurationComponent.tsx +++ b/extensions/default/src/Components/DataSourceConfigurationComponent.tsx @@ -1,18 +1,13 @@ import React, { ReactElement, useCallback, useEffect, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { Icon, useModal } from '@ohif/ui'; -import { ExtensionManager, ServicesManager, Types } from '@ohif/core'; +import { Types } from '@ohif/core'; import DataSourceConfigurationModalComponent from './DataSourceConfigurationModalComponent'; -type DataSourceConfigurationComponentProps = { - servicesManager: ServicesManager; - extensionManager: ExtensionManager; -}; - function DataSourceConfigurationComponent({ servicesManager, extensionManager, -}: DataSourceConfigurationComponentProps): ReactElement { +}: withAppTypes): ReactElement { const { t } = useTranslation('DataSourceConfiguration'); const { show, hide } = useModal(); diff --git a/extensions/default/src/Components/SidePanelWithServices.tsx b/extensions/default/src/Components/SidePanelWithServices.tsx index 5ca05df4e..48fb98652 100644 --- a/extensions/default/src/Components/SidePanelWithServices.tsx +++ b/extensions/default/src/Components/SidePanelWithServices.tsx @@ -1,9 +1,9 @@ import React, { useEffect, useState, useCallback } from 'react'; import { SidePanel } from '@ohif/ui'; -import { PanelService, ServicesManager, Types } from '@ohif/core'; +import { Types } from '@ohif/core'; export type SidePanelWithServicesProps = { - servicesManager: ServicesManager; + servicesManager: AppTypes.ServicesManager; side: 'left' | 'right'; className: string; activeTabIndex: number; @@ -19,7 +19,7 @@ const SidePanelWithServices = ({ expandedWidth, ...props }: SidePanelWithServicesProps) => { - const panelService: PanelService = servicesManager?.services?.panelService; + const panelService = servicesManager?.services?.panelService; // Tracks whether this SidePanel has been opened at least once since this SidePanel was inserted into the DOM. // Thus going to the Study List page and back to the viewer resets this flag for a SidePanel. diff --git a/extensions/default/src/CustomizableContextMenu/ContextMenuController.tsx b/extensions/default/src/CustomizableContextMenu/ContextMenuController.tsx index 2e0a73819..2e7af439c 100644 --- a/extensions/default/src/CustomizableContextMenu/ContextMenuController.tsx +++ b/extensions/default/src/CustomizableContextMenu/ContextMenuController.tsx @@ -1,6 +1,6 @@ import * as ContextMenuItemsBuilder from './ContextMenuItemsBuilder'; import ContextMenu from '../../../../platform/ui/src/components/ContextMenu/ContextMenu'; -import { CommandsManager, ServicesManager, Types } from '@ohif/core'; +import { CommandsManager } from '@ohif/core'; import { annotation as CsAnnotation } from '@cornerstonejs/tools'; import { Menu, MenuItem, Point, ContextMenuProps } from './types'; @@ -17,11 +17,11 @@ import { Menu, MenuItem, Point, ContextMenuProps } from './types'; */ export default class ContextMenuController { commandsManager: CommandsManager; - services: Types.Services; + services: AppTypes.Services; menuItems: Menu[] | MenuItem[]; - constructor(servicesManager: ServicesManager, commandsManager: CommandsManager) { - this.services = servicesManager.services as Obj; + constructor(servicesManager: AppTypes.ServicesManager, commandsManager: CommandsManager) { + this.services = servicesManager.services; this.commandsManager = commandsManager; } diff --git a/extensions/default/src/DataSourceConfigurationAPI/GoogleCloudDataSourceConfigurationAPI.ts b/extensions/default/src/DataSourceConfigurationAPI/GoogleCloudDataSourceConfigurationAPI.ts index 4e02cafae..1be638df4 100644 --- a/extensions/default/src/DataSourceConfigurationAPI/GoogleCloudDataSourceConfigurationAPI.ts +++ b/extensions/default/src/DataSourceConfigurationAPI/GoogleCloudDataSourceConfigurationAPI.ts @@ -42,7 +42,7 @@ class GoogleCloudDataSourceConfigurationAPI implements Types.BaseDataSourceConfi private _fetchOptions: { method: string; headers: unknown }; private _dataSourceName: string; - constructor(dataSourceName, servicesManager, extensionManager) { + constructor(dataSourceName, servicesManager: AppTypes.ServicesManager, extensionManager) { this._dataSourceName = dataSourceName; this._extensionManager = extensionManager; const userAuthenticationService = servicesManager.services.userAuthenticationService; diff --git a/extensions/default/src/DicomWebDataSource/index.js b/extensions/default/src/DicomWebDataSource/index.js index 23c5329c4..cbb8c2028 100644 --- a/extensions/default/src/DicomWebDataSource/index.js +++ b/extensions/default/src/DicomWebDataSource/index.js @@ -8,13 +8,13 @@ import { processResults, processSeriesResults, } from './qido.js'; -import dcm4cheeReject from './dcm4cheeReject'; +import dcm4cheeReject from './dcm4cheeReject.js'; -import getImageId from './utils/getImageId'; +import getImageId from './utils/getImageId.js'; import dcmjs from 'dcmjs'; import { retrieveStudyMetadata, deleteStudyMetadataPromise } from './retrieveStudyMetadata.js'; import StaticWadoClient from './utils/StaticWadoClient'; -import getDirectURL from '../utils/getDirectURL'; +import getDirectURL from '../utils/getDirectURL.js'; import { fixBulkDataURI } from './utils/fixBulkDataURI'; const { DicomMetaDictionary, DicomDict } = dcmjs.data; @@ -89,9 +89,9 @@ function createDicomWebApi(dicomWebConfig, servicesManager) { }; generateWadoHeader = () => { - let authorizationHeader = getAuthrorizationHeader(); + const authorizationHeader = getAuthrorizationHeader(); //Generate accept header depending on config params - let formattedAcceptHeader = utils.generateAcceptHeader( + const formattedAcceptHeader = utils.generateAcceptHeader( dicomWebConfig.acceptHeader, dicomWebConfig.requestTransferSyntaxUID, dicomWebConfig.omitQuotationForMultipartRequest diff --git a/extensions/default/src/DicomWebProxyDataSource/index.js b/extensions/default/src/DicomWebProxyDataSource/index.ts similarity index 97% rename from extensions/default/src/DicomWebProxyDataSource/index.js rename to extensions/default/src/DicomWebProxyDataSource/index.ts index 99007de3e..8dad9cfb4 100644 --- a/extensions/default/src/DicomWebProxyDataSource/index.js +++ b/extensions/default/src/DicomWebProxyDataSource/index.ts @@ -9,7 +9,7 @@ import { createDicomWebApi } from '../DicomWebDataSource/index'; * dicomWeb configuration array * */ -function createDicomWebProxyApi(dicomWebProxyConfig, servicesManager) { +function createDicomWebProxyApi(dicomWebProxyConfig, servicesManager: AppTypes.ServicesManager) { const { name } = dicomWebProxyConfig; let dicomWebDelegate = undefined; @@ -21,7 +21,7 @@ function createDicomWebProxyApi(dicomWebProxyConfig, servicesManager) { throw new Error(`No url for '${name}'`); } else { const response = await fetch(url); - let data = await response.json(); + const data = await response.json(); if (!data.servers?.dicomWeb?.[0]) { throw new Error('Invalid configuration returned by url'); } diff --git a/extensions/default/src/MergeDataSource/index.ts b/extensions/default/src/MergeDataSource/index.ts index 42e49c694..607427b5c 100644 --- a/extensions/default/src/MergeDataSource/index.ts +++ b/extensions/default/src/MergeDataSource/index.ts @@ -167,7 +167,7 @@ export const callByRetrieveAETitle = ({ function createMergeDataSourceApi( mergeConfig: MergeConfig, - servicesManager: unknown, + servicesManager: AppTypes.ServicesManager, extensionManager ) { const { seriesMerge } = mergeConfig; diff --git a/extensions/default/src/Panels/PanelMeasurementTable.tsx b/extensions/default/src/Panels/PanelMeasurementTable.tsx index 7cb491660..3c49a48db 100644 --- a/extensions/default/src/Panels/PanelMeasurementTable.tsx +++ b/extensions/default/src/Panels/PanelMeasurementTable.tsx @@ -1,7 +1,7 @@ import React, { useEffect, useState } from 'react'; import PropTypes from 'prop-types'; import { useTranslation } from 'react-i18next'; -import { utils, ServicesManager } from '@ohif/core'; +import { utils } from '@ohif/core'; import { MeasurementTable, Dialog, @@ -24,14 +24,13 @@ export default function PanelMeasurementTable({ servicesManager, commandsManager, extensionManager, -}): React.FunctionComponent { +}: withAppTypes): React.FunctionComponent { const { t } = useTranslation('MeasurementTable'); const [viewportGrid, viewportGridService] = useViewportGrid(); const { activeViewportId, viewports } = viewportGrid; - const { measurementService, uiDialogService, uiNotificationService, displaySetService } = ( - servicesManager as ServicesManager - ).services; + const { measurementService, uiDialogService, uiNotificationService, displaySetService } = + servicesManager.services; const [displayMeasurements, setDisplayMeasurements] = useState([]); useEffect(() => { @@ -245,7 +244,7 @@ export default function PanelMeasurementTable({ } PanelMeasurementTable.propTypes = { - servicesManager: PropTypes.instanceOf(ServicesManager).isRequired, + servicesManager: PropTypes.object.isRequired, }; function _getMappedMeasurements(measurementService) { diff --git a/extensions/default/src/Panels/PanelStudyBrowser.tsx b/extensions/default/src/Panels/PanelStudyBrowser.tsx index e1e6c30c0..af2d232fb 100644 --- a/extensions/default/src/Panels/PanelStudyBrowser.tsx +++ b/extensions/default/src/Panels/PanelStudyBrowser.tsx @@ -16,7 +16,7 @@ function PanelStudyBrowser({ getStudiesForPatientByMRN, requestDisplaySetCreationForStudy, dataSource, -}) { +}: withAppTypes) { const { hangingProtocolService, displaySetService, uiNotificationService } = servicesManager.services; const navigate = useNavigate(); diff --git a/extensions/default/src/Toolbar/LegacyLayoutSelector.tsx b/extensions/default/src/Toolbar/LegacyLayoutSelector.tsx index 341f6686e..9847d94e0 100644 --- a/extensions/default/src/Toolbar/LegacyLayoutSelector.tsx +++ b/extensions/default/src/Toolbar/LegacyLayoutSelector.tsx @@ -1,9 +1,8 @@ import React, { useEffect, useState, useCallback } from 'react'; import PropTypes from 'prop-types'; import { LayoutSelector as OHIFLayoutSelector, ToolbarButton } from '@ohif/ui'; -import { ServicesManager } from '@ohif/core'; -function LegacyLayoutSelectorWithServices({ servicesManager, ...props }) { +function LegacyLayoutSelectorWithServices({ servicesManager, ...props }: withAppTypes) { const { toolbarService } = servicesManager.services; const onSelection = useCallback( @@ -76,7 +75,7 @@ LayoutSelector.propTypes = { rows: PropTypes.number, columns: PropTypes.number, onLayoutChange: PropTypes.func, - servicesManager: PropTypes.instanceOf(ServicesManager), + servicesManager: PropTypes.object.isRequired, }; LayoutSelector.defaultProps = { diff --git a/extensions/default/src/Toolbar/ToolbarLayoutSelector.tsx b/extensions/default/src/Toolbar/ToolbarLayoutSelector.tsx index 0f4b2e0c8..771b7d6b9 100644 --- a/extensions/default/src/Toolbar/ToolbarLayoutSelector.tsx +++ b/extensions/default/src/Toolbar/ToolbarLayoutSelector.tsx @@ -1,7 +1,6 @@ import React, { useEffect, useState, useCallback } from 'react'; import PropTypes from 'prop-types'; import { LayoutSelector as OHIFLayoutSelector, ToolbarButton, LayoutPreset } from '@ohif/ui'; -import { ServicesManager } from '@ohif/core'; const defaultCommonPresets = [ { @@ -45,7 +44,7 @@ const _areSelectorsValid = (hp, displaySets, hangingProtocolService) => { ); }; -const generateAdvancedPresets = ({ servicesManager }) => { +const generateAdvancedPresets = ({ servicesManager }: withAppTypes) => { const { hangingProtocolService, viewportGridService, displaySetService } = servicesManager.services; @@ -84,7 +83,11 @@ const generateAdvancedPresets = ({ servicesManager }) => { .filter(preset => preset !== null); }; -function ToolbarLayoutSelectorWithServices({ commandsManager, servicesManager, ...props }) { +function ToolbarLayoutSelectorWithServices({ + commandsManager, + servicesManager, + ...props +}: withAppTypes) { const [isDisabled, setIsDisabled] = useState(false); const handleMouseEnter = () => { @@ -129,7 +132,7 @@ function LayoutSelector({ servicesManager, tooltipDisabled, ...rest -}) { +}: withAppTypes) { const [isOpen, setIsOpen] = useState(false); const { customizationService } = servicesManager.services; @@ -225,7 +228,7 @@ LayoutSelector.propTypes = { rows: PropTypes.number, columns: PropTypes.number, onLayoutChange: PropTypes.func, - servicesManager: PropTypes.instanceOf(ServicesManager), + servicesManager: PropTypes.object.isRequired, }; LayoutSelector.defaultProps = { diff --git a/extensions/default/src/Toolbar/ToolbarSplitButtonWithServices.tsx b/extensions/default/src/Toolbar/ToolbarSplitButtonWithServices.tsx index 5dfee4ad5..3bbc14b6e 100644 --- a/extensions/default/src/Toolbar/ToolbarSplitButtonWithServices.tsx +++ b/extensions/default/src/Toolbar/ToolbarSplitButtonWithServices.tsx @@ -10,7 +10,7 @@ function ToolbarSplitButtonWithServices({ renderer, onInteraction, servicesManager, -}) { +}: withAppTypes) { const { toolbarService } = servicesManager?.services; /* Bubbles up individual item clicks */ diff --git a/extensions/default/src/ViewerLayout/ViewerHeader.tsx b/extensions/default/src/ViewerLayout/ViewerHeader.tsx index 6dd130dd9..851db7f14 100644 --- a/extensions/default/src/ViewerLayout/ViewerHeader.tsx +++ b/extensions/default/src/ViewerLayout/ViewerHeader.tsx @@ -10,7 +10,12 @@ import { Toolbar } from '../Toolbar/Toolbar'; const { availableLanguages, defaultLanguage, currentLanguage } = i18n; -function ViewerHeader({ hotkeysManager, extensionManager, servicesManager, appConfig }) { +function ViewerHeader({ + hotkeysManager, + extensionManager, + servicesManager, + appConfig, +}: withAppTypes) { const navigate = useNavigate(); const location = useLocation(); diff --git a/extensions/default/src/ViewerLayout/index.tsx b/extensions/default/src/ViewerLayout/index.tsx index b47cca83b..d39d6e181 100644 --- a/extensions/default/src/ViewerLayout/index.tsx +++ b/extensions/default/src/ViewerLayout/index.tsx @@ -2,7 +2,7 @@ import React, { useEffect, useState, useCallback } from 'react'; import PropTypes from 'prop-types'; import { ErrorBoundary, LoadingIndicatorProgress, InvestigationalUseDialog } from '@ohif/ui'; -import { ServicesManager, HangingProtocolService, CommandsManager } from '@ohif/core'; +import { HangingProtocolService, CommandsManager } from '@ohif/core'; import { useAppConfig } from '@state'; import ViewerHeader from './ViewerHeader'; import SidePanelWithServices from '../Components/SidePanelWithServices'; @@ -18,7 +18,7 @@ function ViewerLayout({ ViewportGridComp, leftPanelClosed = false, rightPanelClosed = false, -}): React.FunctionComponent { +}: withAppTypes): React.FunctionComponent { const [appConfig] = useAppConfig(); const { panelService, hangingProtocolService } = servicesManager.services; @@ -167,7 +167,7 @@ ViewerLayout.propTypes = { getModuleEntry: PropTypes.func.isRequired, }).isRequired, commandsManager: PropTypes.instanceOf(CommandsManager), - servicesManager: PropTypes.instanceOf(ServicesManager), + servicesManager: PropTypes.object.isRequired, // From modes leftPanels: PropTypes.array, rightPanels: PropTypes.array, diff --git a/extensions/default/src/commandsModule.ts b/extensions/default/src/commandsModule.ts index 76507b203..7ed6886e3 100644 --- a/extensions/default/src/commandsModule.ts +++ b/extensions/default/src/commandsModule.ts @@ -1,4 +1,4 @@ -import { ServicesManager, utils, Types } from '@ohif/core'; +import { utils, Types } from '@ohif/core'; import { ContextMenuController, defaultContextMenu } from './CustomizableContextMenu'; import DicomTagBrowser from './DicomTagBrowser/DicomTagBrowser'; @@ -12,7 +12,6 @@ import { NavigateHistory } from './types/commandModuleTypes'; import { history } from '@ohif/app'; const { subscribeToNextViewportGridChange } = utils; - export type HangingProtocolParams = { protocolId?: string; stageIndex?: number; @@ -38,7 +37,7 @@ const commandsModule = ({ viewportGridService, displaySetService, stateSyncService, - } = (servicesManager as ServicesManager).services; + } = servicesManager.services; // Define a context menu controller for use with any context menus const contextMenuController = new ContextMenuController(servicesManager, commandsManager); diff --git a/extensions/default/src/components/ProgressDropdownWithService/ProgressDropdownWithService.tsx b/extensions/default/src/components/ProgressDropdownWithService/ProgressDropdownWithService.tsx index e3ed34f3f..8ecbf6caa 100644 --- a/extensions/default/src/components/ProgressDropdownWithService/ProgressDropdownWithService.tsx +++ b/extensions/default/src/components/ProgressDropdownWithService/ProgressDropdownWithService.tsx @@ -1,5 +1,4 @@ import React, { useEffect, useState, useCallback, ReactElement } from 'react'; -import { ServicesManager } from '@ohif/core'; import { ProgressDropdown } from '@ohif/ui'; const workflowStepsToDropdownOptions = (steps = []) => @@ -11,11 +10,7 @@ const workflowStepsToDropdownOptions = (steps = []) => completed: false, })); -function ProgressDropdownWithService({ - servicesManager, -}: { - servicesManager: ServicesManager; -}): ReactElement { +function ProgressDropdownWithService({ servicesManager }: withAppTypes): ReactElement { const { workflowStepsService } = servicesManager.services; const [activeStepId, setActiveStepId] = useState(workflowStepsService.activeWorkflowStep?.id); diff --git a/extensions/default/src/getDataSourcesModule.js b/extensions/default/src/getDataSourcesModule.js index 8c918e0c6..cc4aee56f 100644 --- a/extensions/default/src/getDataSourcesModule.js +++ b/extensions/default/src/getDataSourcesModule.js @@ -5,7 +5,7 @@ import { createDicomWebApi } from './DicomWebDataSource/index.js'; import { createDicomJSONApi } from './DicomJSONDataSource/index.js'; import { createDicomLocalApi } from './DicomLocalDataSource/index.js'; -import { createDicomWebProxyApi } from './DicomWebProxyDataSource/index.js'; +import { createDicomWebProxyApi } from './DicomWebProxyDataSource/index'; import { createMergeDataSourceApi } from './MergeDataSource/index'; /** diff --git a/extensions/default/src/getToolbarModule.tsx b/extensions/default/src/getToolbarModule.tsx index 762aea9f0..f40ad01f9 100644 --- a/extensions/default/src/getToolbarModule.tsx +++ b/extensions/default/src/getToolbarModule.tsx @@ -13,7 +13,7 @@ const getClassName = isToggled => { }; }; -export default function getToolbarModule({ commandsManager, servicesManager }) { +export default function getToolbarModule({ commandsManager, servicesManager }: withAppTypes) { const { cineService } = servicesManager.services; return [ { diff --git a/extensions/default/src/getViewportModule.tsx b/extensions/default/src/getViewportModule.tsx index 7ac8adb64..c3ca1efbb 100644 --- a/extensions/default/src/getViewportModule.tsx +++ b/extensions/default/src/getViewportModule.tsx @@ -1,4 +1,4 @@ -import { ServicesManager, CommandsManager, ExtensionManager } from '@ohif/core'; +import { CommandsManager, ExtensionManager } from '@ohif/core'; import LineChartViewport from './Components/LineChartViewport/index'; const getViewportModule = ({ @@ -6,7 +6,7 @@ const getViewportModule = ({ commandsManager, extensionManager, }: { - servicesManager: ServicesManager; + servicesManager: AppTypes.ServicesManager; commandsManager: CommandsManager; extensionManager: ExtensionManager; }) => { diff --git a/extensions/default/src/init.ts b/extensions/default/src/init.ts index 4821e15ad..e1c77c911 100644 --- a/extensions/default/src/init.ts +++ b/extensions/default/src/init.ts @@ -10,7 +10,11 @@ const metadataProvider = classes.MetadataProvider; * @param {Object} servicesManager * @param {Object} configuration */ -export default function init({ servicesManager, configuration = {}, commandsManager }): void { +export default function init({ + servicesManager, + configuration = {}, + commandsManager, +}: withAppTypes): void { const { stateSyncService, toolbarService, cineService, viewportGridService } = servicesManager.services; diff --git a/extensions/dicom-microscopy/src/components/MicroscopyPanel/MicroscopyPanel.tsx b/extensions/dicom-microscopy/src/components/MicroscopyPanel/MicroscopyPanel.tsx index 3da3b5d4b..c0c983a4c 100644 --- a/extensions/dicom-microscopy/src/components/MicroscopyPanel/MicroscopyPanel.tsx +++ b/extensions/dicom-microscopy/src/components/MicroscopyPanel/MicroscopyPanel.tsx @@ -1,6 +1,6 @@ import React, { useState, useEffect } from 'react'; import PropTypes from 'prop-types'; -import { ServicesManager, ExtensionManager, CommandsManager, DicomMetadataStore } from '@ohif/core'; +import { ExtensionManager, CommandsManager, DicomMetadataStore } from '@ohif/core'; import { MeasurementTable } from '@ohif/ui'; import { withTranslation, WithTranslation } from 'react-i18next'; import { EVENTS as MicroscopyEvents } from '../../services/MicroscopyService'; @@ -53,7 +53,7 @@ interface IMicroscopyPanelProps extends WithTranslation { onRejectComplete?: PropTypes.func; // callback when rejected annotations // - servicesManager: ServicesManager; + servicesManager: AppTypes.ServicesManager; extensionManager: ExtensionManager; commandsManager: CommandsManager; } diff --git a/extensions/dicom-microscopy/src/getCommandsModule.ts b/extensions/dicom-microscopy/src/getCommandsModule.ts index 02d7ee8b8..28750f917 100644 --- a/extensions/dicom-microscopy/src/getCommandsModule.ts +++ b/extensions/dicom-microscopy/src/getCommandsModule.ts @@ -1,4 +1,4 @@ -import { ServicesManager, CommandsManager, ExtensionManager } from '@ohif/core'; +import { CommandsManager, ExtensionManager } from '@ohif/core'; import styles from './utils/styles'; import callInputDialog from './utils/callInputDialog'; @@ -7,7 +7,7 @@ export default function getCommandsModule({ commandsManager, extensionManager, }: { - servicesManager: ServicesManager; + servicesManager: AppTypes.ServicesManager; commandsManager: CommandsManager; extensionManager: ExtensionManager; }) { diff --git a/extensions/dicom-microscopy/src/getPanelModule.tsx b/extensions/dicom-microscopy/src/getPanelModule.tsx index 58e4f2f09..e47c4c7dd 100644 --- a/extensions/dicom-microscopy/src/getPanelModule.tsx +++ b/extensions/dicom-microscopy/src/getPanelModule.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { ServicesManager, CommandsManager, ExtensionManager } from '@ohif/core'; +import { CommandsManager, ExtensionManager } from '@ohif/core'; import { useViewportGrid } from '@ohif/ui'; import MicroscopyPanel from './components/MicroscopyPanel/MicroscopyPanel'; @@ -13,7 +13,7 @@ export default function getPanelModule({ extensionManager, servicesManager, }: { - servicesManager: ServicesManager; + servicesManager: AppTypes.ServicesManager; commandsManager: CommandsManager; extensionManager: ExtensionManager; }) { diff --git a/extensions/dicom-microscopy/src/services/MicroscopyService.ts b/extensions/dicom-microscopy/src/services/MicroscopyService.ts index 0f6005f5d..4068ad910 100644 --- a/extensions/dicom-microscopy/src/services/MicroscopyService.ts +++ b/extensions/dicom-microscopy/src/services/MicroscopyService.ts @@ -18,17 +18,17 @@ const EVENTS = { * ROI annotations relevant to the application */ export default class MicroscopyService extends PubSubService { - public static REGISTRATION = serviceManager => { + public static REGISTRATION = servicesManager => { return { name: 'microscopyService', altName: 'MicroscopyService', create: ({ configuration = {} }) => { - return new MicroscopyService(serviceManager); + return new MicroscopyService(servicesManager); }, }; }; - serviceManager: any; + servicesManager: any; managedViewers = new Set(); roiUids = new Set(); @@ -36,9 +36,9 @@ export default class MicroscopyService extends PubSubService { selectedAnnotation = null; pendingFocus = false; - constructor(serviceManager) { + constructor(servicesManager) { super(EVENTS); - this.serviceManager = serviceManager; + this.servicesManager = servicesManager; this._onRoiAdded = this._onRoiAdded.bind(this); this._onRoiModified = this._onRoiModified.bind(this); this._onRoiRemoved = this._onRoiRemoved.bind(this); diff --git a/extensions/dicom-microscopy/src/types/AppTypes.ts b/extensions/dicom-microscopy/src/types/AppTypes.ts new file mode 100644 index 000000000..87fe89760 --- /dev/null +++ b/extensions/dicom-microscopy/src/types/AppTypes.ts @@ -0,0 +1,11 @@ +/* eslint-disable @typescript-eslint/no-namespace */ +import MicroscopyServiceType from '../services/MicroscopyService'; + +declare global { + namespace AppTypes { + export type MicroscopyService = MicroscopyServiceType; + export interface Services { + microscopyService?: MicroscopyServiceType; + } + } +} diff --git a/extensions/dicom-microscopy/src/utils/dicomWebClient.ts b/extensions/dicom-microscopy/src/utils/dicomWebClient.ts index dc906b120..42455fe0c 100644 --- a/extensions/dicom-microscopy/src/utils/dicomWebClient.ts +++ b/extensions/dicom-microscopy/src/utils/dicomWebClient.ts @@ -9,7 +9,7 @@ import { StaticWadoClient } from '@ohif/extension-default'; * @param param0 * @returns */ -export default function getDicomWebClient({ extensionManager, servicesManager }) { +export default function getDicomWebClient({ extensionManager, servicesManager }: withAppTypes) { const dataSourceConfig = window.config.dataSources.find( ds => ds.sourceName === extensionManager.activeDataSource ); diff --git a/extensions/dicom-microscopy/tsconfig.json b/extensions/dicom-microscopy/tsconfig.json deleted file mode 100644 index e8977ec34..000000000 --- a/extensions/dicom-microscopy/tsconfig.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "compilerOptions": { - "outDir": "./dist/", - "noImplicitAny": true, - "module": "es6", - "target": "es5", - "jsx": "react", - "allowJs": true, - "moduleResolution": "node" - } -} diff --git a/extensions/measurement-tracking/src/contexts/TrackedMeasurementsContext/TrackedMeasurementsContext.tsx b/extensions/measurement-tracking/src/contexts/TrackedMeasurementsContext/TrackedMeasurementsContext.tsx index 74657e85d..ef74b98c0 100644 --- a/extensions/measurement-tracking/src/contexts/TrackedMeasurementsContext/TrackedMeasurementsContext.tsx +++ b/extensions/measurement-tracking/src/contexts/TrackedMeasurementsContext/TrackedMeasurementsContext.tsx @@ -24,7 +24,7 @@ const SR_SOPCLASSHANDLERID = '@ohif/extension-cornerstone-dicom-sr.sopClassHandl * @param {*} param0 */ function TrackedMeasurementsContextProvider( - { servicesManager, commandsManager, extensionManager }, // Bound by consumer + { servicesManager, commandsManager, extensionManager }: withAppTypes, // Bound by consumer { children } // Component props ) { const [appConfig] = useAppConfig(); diff --git a/extensions/measurement-tracking/src/contexts/TrackedMeasurementsContext/hydrateStructuredReport.tsx b/extensions/measurement-tracking/src/contexts/TrackedMeasurementsContext/hydrateStructuredReport.tsx index 480b33310..caf57c2e8 100644 --- a/extensions/measurement-tracking/src/contexts/TrackedMeasurementsContext/hydrateStructuredReport.tsx +++ b/extensions/measurement-tracking/src/contexts/TrackedMeasurementsContext/hydrateStructuredReport.tsx @@ -1,6 +1,10 @@ import { hydrateStructuredReport as baseHydrateStructuredReport } from '@ohif/extension-cornerstone-dicom-sr'; -function hydrateStructuredReport({ servicesManager, extensionManager, appConfig }, ctx, evt) { +function hydrateStructuredReport( + { servicesManager, extensionManager, appConfig }: withAppTypes, + ctx, + evt +) { const { displaySetService } = servicesManager.services; const { viewportId, displaySetInstanceUID } = evt; const srDisplaySet = displaySetService.getDisplaySetByUID(displaySetInstanceUID); diff --git a/extensions/measurement-tracking/src/contexts/TrackedMeasurementsContext/promptTrackNewStudy.js b/extensions/measurement-tracking/src/contexts/TrackedMeasurementsContext/promptTrackNewStudy.ts similarity index 85% rename from extensions/measurement-tracking/src/contexts/TrackedMeasurementsContext/promptTrackNewStudy.js rename to extensions/measurement-tracking/src/contexts/TrackedMeasurementsContext/promptTrackNewStudy.ts index 48762f72e..1ce586999 100644 --- a/extensions/measurement-tracking/src/contexts/TrackedMeasurementsContext/promptTrackNewStudy.js +++ b/extensions/measurement-tracking/src/contexts/TrackedMeasurementsContext/promptTrackNewStudy.ts @@ -9,21 +9,18 @@ const RESPONSE = { NO_NOT_FOR_SERIES: 4, }; -function promptTrackNewStudy({ servicesManager, extensionManager }, ctx, evt) { - const { UIViewportDialogService } = servicesManager.services; - const appConfig = extensionManager._appConfig; +function promptTrackNewStudy({ servicesManager, extensionManager }: withAppTypes, ctx, evt) { + const { uiViewportDialogService } = servicesManager.services; // When the state change happens after a promise, the state machine sends the retult in evt.data; // In case of direct transition to the state, the state machine sends the data in evt; const { viewportId, StudyInstanceUID, SeriesInstanceUID } = evt.data || evt; return new Promise(async function (resolve, reject) { - let promptResult = appConfig?.disableConfirmationPrompts - ? RESPONSE.SET_STUDY_AND_SERIES - : await _askTrackMeasurements(UIViewportDialogService, viewportId); + let promptResult = await _askTrackMeasurements(uiViewportDialogService, viewportId); if (promptResult === RESPONSE.SET_STUDY_AND_SERIES) { promptResult = ctx.isDirty - ? await _askSaveDiscardOrCancel(UIViewportDialogService, viewportId) + ? await _askSaveDiscardOrCancel(uiViewportDialogService, viewportId) : RESPONSE.SET_STUDY_AND_SERIES; } @@ -37,7 +34,10 @@ function promptTrackNewStudy({ servicesManager, extensionManager }, ctx, evt) { }); } -function _askTrackMeasurements(UIViewportDialogService, viewportId) { +function _askTrackMeasurements( + UIViewportDialogService: AppTypes.UIViewportDialogService, + viewportId +) { return new Promise(function (resolve, reject) { const message = i18n.t('MeasurementTable:Track measurements for this series?'); const actions = [ @@ -78,7 +78,10 @@ function _askTrackMeasurements(UIViewportDialogService, viewportId) { }); } -function _askSaveDiscardOrCancel(UIViewportDialogService, viewportId) { +function _askSaveDiscardOrCancel( + UIViewportDialogService: AppTypes.UIViewportDialogService, + viewportId +) { return new Promise(function (resolve, reject) { const message = 'Measurements cannot span across multiple studies. Do you want to save your tracked measurements?'; diff --git a/extensions/measurement-tracking/src/panels/PanelMeasurementTableTracking/index.tsx b/extensions/measurement-tracking/src/panels/PanelMeasurementTableTracking/index.tsx index 6d7fbf31d..ee7b65405 100644 --- a/extensions/measurement-tracking/src/panels/PanelMeasurementTableTracking/index.tsx +++ b/extensions/measurement-tracking/src/panels/PanelMeasurementTableTracking/index.tsx @@ -18,7 +18,7 @@ const DISPLAY_STUDY_SUMMARY_INITIAL_VALUE = { description: '', // 'CHEST/ABD/PELVIS W CONTRAST', }; -function PanelMeasurementTableTracking({ servicesManager, extensionManager }) { +function PanelMeasurementTableTracking({ servicesManager, extensionManager }: withAppTypes) { const [viewportGrid] = useViewportGrid(); const { t } = useTranslation('MeasurementTable'); const [measurementChangeTimestamp, setMeasurementsUpdated] = useState(Date.now().toString()); diff --git a/extensions/measurement-tracking/src/panels/PanelStudyBrowserTracking/PanelStudyBrowserTracking.tsx b/extensions/measurement-tracking/src/panels/PanelStudyBrowserTracking/PanelStudyBrowserTracking.tsx index 05cce40ec..d6f6e0844 100644 --- a/extensions/measurement-tracking/src/panels/PanelStudyBrowserTracking/PanelStudyBrowserTracking.tsx +++ b/extensions/measurement-tracking/src/panels/PanelStudyBrowserTracking/PanelStudyBrowserTracking.tsx @@ -18,7 +18,7 @@ function PanelStudyBrowserTracking({ getStudiesForPatientByMRN, requestDisplaySetCreationForStudy, dataSource, -}) { +}: withAppTypes) { const { displaySetService, uiDialogService, diff --git a/extensions/measurement-tracking/src/panels/PanelStudyBrowserTracking/index.tsx b/extensions/measurement-tracking/src/panels/PanelStudyBrowserTracking/index.tsx index cffd41bb0..b276579db 100644 --- a/extensions/measurement-tracking/src/panels/PanelStudyBrowserTracking/index.tsx +++ b/extensions/measurement-tracking/src/panels/PanelStudyBrowserTracking/index.tsx @@ -21,7 +21,11 @@ function _getStudyForPatientUtility(extensionManager) { * @param {object} commandsManager * @param {object} extensionManager */ -function WrappedPanelStudyBrowserTracking({ commandsManager, extensionManager, servicesManager }) { +function WrappedPanelStudyBrowserTracking({ + commandsManager, + extensionManager, + servicesManager, +}: withAppTypes) { const dataSource = extensionManager.getActiveDataSource()[0]; const getStudiesForPatientByMRN = _getStudyForPatientUtility(extensionManager); diff --git a/extensions/measurement-tracking/src/viewports/TrackedCornerstoneViewport.tsx b/extensions/measurement-tracking/src/viewports/TrackedCornerstoneViewport.tsx index 94ca843bb..a805630ec 100644 --- a/extensions/measurement-tracking/src/viewports/TrackedCornerstoneViewport.tsx +++ b/extensions/measurement-tracking/src/viewports/TrackedCornerstoneViewport.tsx @@ -8,7 +8,7 @@ import { useTrackedMeasurements } from './../getContextModule'; import { BaseVolumeViewport, Enums } from '@cornerstonejs/core'; import { useTranslation } from 'react-i18next'; -function TrackedCornerstoneViewport(props) { +function TrackedCornerstoneViewport(props: withAppTypes) { const { displaySets, viewportId, servicesManager, extensionManager } = props; const { @@ -251,7 +251,7 @@ TrackedCornerstoneViewport.defaultProps = { function _getNextMeasurementUID( direction, - servicesManager, + servicesManager: AppTypes.ServicesManager, trackedMeasurementId, trackedMeasurements ) { diff --git a/extensions/tmtv/src/Panels/PanelPetSUV.tsx b/extensions/tmtv/src/Panels/PanelPetSUV.tsx index eccd76afb..087fe310d 100644 --- a/extensions/tmtv/src/Panels/PanelPetSUV.tsx +++ b/extensions/tmtv/src/Panels/PanelPetSUV.tsx @@ -1,7 +1,7 @@ import React, { useEffect, useState } from 'react'; import PropTypes from 'prop-types'; import { PanelSection, Input, Button } from '@ohif/ui'; -import { DicomMetadataStore, ServicesManager } from '@ohif/core'; +import { DicomMetadataStore } from '@ohif/core'; import { useTranslation } from 'react-i18next'; const DEFAULT_MEATADATA = { @@ -22,11 +22,10 @@ const DEFAULT_MEATADATA = { * @param param0 * @returns */ -export default function PanelPetSUV({ servicesManager, commandsManager }) { +export default function PanelPetSUV({ servicesManager, commandsManager }: withAppTypes) { const { t } = useTranslation('PanelSUV'); - const { displaySetService, toolGroupService, toolbarService, hangingProtocolService } = ( - servicesManager as ServicesManager - ).services; + const { displaySetService, toolGroupService, toolbarService, hangingProtocolService } = + servicesManager.services; const [metadata, setMetadata] = useState(DEFAULT_MEATADATA); const [ptDisplaySet, setPtDisplaySet] = useState(null); diff --git a/extensions/tmtv/src/Panels/PanelROIThresholdSegmentation/PanelROIThresholdExport.tsx b/extensions/tmtv/src/Panels/PanelROIThresholdSegmentation/PanelROIThresholdExport.tsx index a16eaa812..1e429c1f8 100644 --- a/extensions/tmtv/src/Panels/PanelROIThresholdSegmentation/PanelROIThresholdExport.tsx +++ b/extensions/tmtv/src/Panels/PanelROIThresholdSegmentation/PanelROIThresholdExport.tsx @@ -6,7 +6,10 @@ import { eventTarget } from '@cornerstonejs/core'; import { Enums } from '@cornerstonejs/tools'; import { handleROIThresholding } from '../../utils/handleROIThresholding'; -export default function PanelRoiThresholdSegmentation({ servicesManager, commandsManager }) { +export default function PanelRoiThresholdSegmentation({ + servicesManager, + commandsManager, +}: withAppTypes) { const { segmentationService, uiNotificationService } = servicesManager.services; const { t } = useTranslation('PanelSUVExport'); diff --git a/extensions/tmtv/src/Panels/PanelROIThresholdSegmentation/segmentationEditHandler.tsx b/extensions/tmtv/src/Panels/PanelROIThresholdSegmentation/segmentationEditHandler.tsx index c17e0a511..1ec15652e 100644 --- a/extensions/tmtv/src/Panels/PanelROIThresholdSegmentation/segmentationEditHandler.tsx +++ b/extensions/tmtv/src/Panels/PanelROIThresholdSegmentation/segmentationEditHandler.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { Input, Dialog, ButtonEnums } from '@ohif/ui'; -function segmentationItemEditHandler({ id, servicesManager }) { +function segmentationItemEditHandler({ id, servicesManager }: withAppTypes) { const { segmentationService, uiDialogService } = servicesManager.services; const segmentation = segmentationService.getSegmentation(id); diff --git a/extensions/tmtv/src/Panels/RectangleROIOptions.tsx b/extensions/tmtv/src/Panels/RectangleROIOptions.tsx index 5a227b652..85d13821a 100644 --- a/extensions/tmtv/src/Panels/RectangleROIOptions.tsx +++ b/extensions/tmtv/src/Panels/RectangleROIOptions.tsx @@ -40,7 +40,7 @@ function reducer(state, action) { } } -function RectangleROIOptions({ servicesManager, commandsManager }) { +function RectangleROIOptions({ servicesManager, commandsManager }: withAppTypes) { const { segmentationService } = servicesManager.services; const [selectedSegmentationId, setSelectedSegmentationId] = useState(null); diff --git a/extensions/tmtv/src/commandsModule.js b/extensions/tmtv/src/commandsModule.ts similarity index 99% rename from extensions/tmtv/src/commandsModule.js rename to extensions/tmtv/src/commandsModule.ts index d948f46a9..75b264074 100644 --- a/extensions/tmtv/src/commandsModule.js +++ b/extensions/tmtv/src/commandsModule.ts @@ -35,7 +35,7 @@ const workerFn = () => { }); }; -const commandsModule = ({ servicesManager, commandsManager, extensionManager }) => { +const commandsModule = ({ servicesManager, commandsManager, extensionManager }: withAppTypes) => { const { viewportGridService, uiNotificationService, @@ -354,7 +354,7 @@ const commandsModule = ({ servicesManager, commandsManager, extensionManager }) let segmentationMax = -Infinity; let segmentationMin = Infinity; - let segmentationValues = []; + const segmentationValues = []; let voxelCount = 0; for (let i = 0; i < scalarData.length; i++) { @@ -551,7 +551,7 @@ const commandsModule = ({ servicesManager, commandsManager, extensionManager }) segmentations = segmentationService.getSegmentations(); } - let report = {}; + const report = {}; for (const segmentation of segmentations) { const { id, label, cachedStats: data } = segmentation; @@ -633,7 +633,7 @@ const commandsModule = ({ servicesManager, commandsManager, extensionManager }) const fusionViewportIds = toolGroup.getViewportIds(); - let viewports = []; + const viewports = []; fusionViewportIds.forEach(viewportId => { commandsManager.runCommand('setViewportColormap', { viewportId, diff --git a/modes/basic-dev-mode/.webpack/webpack.dev.js b/modes/basic-dev-mode/.webpack/webpack.dev.js index 4bf848b6c..1b8e34cfd 100644 --- a/modes/basic-dev-mode/.webpack/webpack.dev.js +++ b/modes/basic-dev-mode/.webpack/webpack.dev.js @@ -4,7 +4,7 @@ const SRC_DIR = path.join(__dirname, '../src'); const DIST_DIR = path.join(__dirname, '../dist'); const ENTRY = { - app: `${SRC_DIR}/index.js`, + app: `${SRC_DIR}/index.ts`, }; module.exports = (env, argv) => { diff --git a/modes/basic-dev-mode/.webpack/webpack.prod.js b/modes/basic-dev-mode/.webpack/webpack.prod.js index 26c62c7d4..a835b9a23 100644 --- a/modes/basic-dev-mode/.webpack/webpack.prod.js +++ b/modes/basic-dev-mode/.webpack/webpack.prod.js @@ -9,7 +9,7 @@ const SRC_DIR = path.join(__dirname, '../src'); const DIST_DIR = path.join(__dirname, '../dist'); const ENTRY = { - app: `${SRC_DIR}/index.js`, + app: `${SRC_DIR}/index.ts`, }; module.exports = (env, argv) => { diff --git a/modes/basic-dev-mode/package.json b/modes/basic-dev-mode/package.json index e1918b93f..efa2cd8ae 100644 --- a/modes/basic-dev-mode/package.json +++ b/modes/basic-dev-mode/package.json @@ -6,7 +6,7 @@ "license": "MIT", "repository": "OHIF/Viewers", "main": "dist/ohif-mode-basic-dev-mode.umd.js", - "module": "src/index.js", + "module": "src/index.ts", "engines": { "node": ">=10", "npm": ">=6", diff --git a/modes/basic-dev-mode/src/index.js b/modes/basic-dev-mode/src/index.ts similarity index 97% rename from modes/basic-dev-mode/src/index.js rename to modes/basic-dev-mode/src/index.ts index 4bc20e843..649dd81cd 100644 --- a/modes/basic-dev-mode/src/index.js +++ b/modes/basic-dev-mode/src/index.ts @@ -50,7 +50,7 @@ function modeFactory({ modeConfiguration }) { /** * Lifecycle hooks */ - onModeEnter: ({ servicesManager, extensionManager }) => { + onModeEnter: ({ servicesManager, extensionManager }: withAppTypes) => { const { toolbarService, toolGroupService } = servicesManager.services; const utilityModule = extensionManager.getModuleEntry( '@ohif/extension-cornerstone.utilityModule.tools' @@ -101,7 +101,7 @@ function modeFactory({ modeConfiguration }) { 'MoreTools', ]); }, - onModeExit: ({ servicesManager }) => { + onModeExit: ({ servicesManager }: withAppTypes) => { const { toolGroupService, measurementService, diff --git a/modes/basic-test-mode/src/index.ts b/modes/basic-test-mode/src/index.ts index 52dc5ebc1..7cb9eda04 100644 --- a/modes/basic-test-mode/src/index.ts +++ b/modes/basic-test-mode/src/index.ts @@ -64,7 +64,7 @@ function modeFactory() { /** * Lifecycle hooks */ - onModeEnter: ({ servicesManager, extensionManager, commandsManager }) => { + onModeEnter: ({ servicesManager, extensionManager, commandsManager }: withAppTypes) => { const { measurementService, toolbarService, toolGroupService, customizationService } = servicesManager.services; @@ -91,7 +91,7 @@ function modeFactory() { 'MoreTools', ]); }, - onModeExit: ({ servicesManager }) => { + onModeExit: ({ servicesManager }: withAppTypes) => { const { toolGroupService, syncGroupService, diff --git a/modes/longitudinal/.webpack/webpack.dev.js b/modes/longitudinal/.webpack/webpack.dev.js index 4bf848b6c..1b8e34cfd 100644 --- a/modes/longitudinal/.webpack/webpack.dev.js +++ b/modes/longitudinal/.webpack/webpack.dev.js @@ -4,7 +4,7 @@ const SRC_DIR = path.join(__dirname, '../src'); const DIST_DIR = path.join(__dirname, '../dist'); const ENTRY = { - app: `${SRC_DIR}/index.js`, + app: `${SRC_DIR}/index.ts`, }; module.exports = (env, argv) => { diff --git a/modes/longitudinal/.webpack/webpack.prod.js b/modes/longitudinal/.webpack/webpack.prod.js index 6b84361f2..b60b8908a 100644 --- a/modes/longitudinal/.webpack/webpack.prod.js +++ b/modes/longitudinal/.webpack/webpack.prod.js @@ -10,7 +10,7 @@ const ROOT_DIR = path.join(__dirname, './../'); const SRC_DIR = path.join(__dirname, '../src'); const DIST_DIR = path.join(__dirname, '../dist'); const ENTRY = { - app: `${SRC_DIR}/index.js`, + app: `${SRC_DIR}/index.ts`, }; module.exports = (env, argv) => { diff --git a/modes/longitudinal/package.json b/modes/longitudinal/package.json index 62f9c4823..e5030a5c9 100644 --- a/modes/longitudinal/package.json +++ b/modes/longitudinal/package.json @@ -6,7 +6,7 @@ "license": "MIT", "repository": "OHIF/Viewers", "main": "dist/ohif-mode-longitudinal.js", - "module": "src/index.js", + "module": "src/index.ts", "engines": { "node": ">=14", "npm": ">=6", diff --git a/modes/longitudinal/src/index.js b/modes/longitudinal/src/index.ts similarity index 98% rename from modes/longitudinal/src/index.js rename to modes/longitudinal/src/index.ts index bfa6792ca..ac05c4e84 100644 --- a/modes/longitudinal/src/index.js +++ b/modes/longitudinal/src/index.ts @@ -70,7 +70,7 @@ function modeFactory({ modeConfiguration }) { /** * Lifecycle hooks */ - onModeEnter: function ({ servicesManager, extensionManager, commandsManager }) { + onModeEnter: function ({ servicesManager, extensionManager, commandsManager }: withAppTypes) { const { measurementService, toolbarService, toolGroupService, customizationService } = servicesManager.services; @@ -135,7 +135,7 @@ function modeFactory({ modeConfiguration }) { // ]), // ]; }, - onModeExit: ({ servicesManager }) => { + onModeExit: ({ servicesManager }: withAppTypes) => { const { toolGroupService, syncGroupService, diff --git a/modes/microscopy/src/index.tsx b/modes/microscopy/src/index.tsx index 42bf3f536..f2c34097a 100644 --- a/modes/microscopy/src/index.tsx +++ b/modes/microscopy/src/index.tsx @@ -47,14 +47,14 @@ function modeFactory({ modeConfiguration }) { /** * Lifecycle hooks */ - onModeEnter: ({ servicesManager, extensionManager, commandsManager }) => { + onModeEnter: ({ servicesManager, extensionManager, commandsManager }: withAppTypes) => { const { toolbarService } = servicesManager.services; toolbarService.addButtons(toolbarButtons); toolbarService.createButtonSection('primary', ['MeasurementTools', 'dragPan', 'TagBrowser']); }, - onModeExit: ({ servicesManager }) => { + onModeExit: ({ servicesManager }: withAppTypes) => { const { toolbarService, uiDialogService, uiModalService } = servicesManager.services; uiDialogService.dismissAll(); diff --git a/modes/preclinical-4d/src/index.tsx b/modes/preclinical-4d/src/index.tsx index 213a5f618..6a14b5db2 100644 --- a/modes/preclinical-4d/src/index.tsx +++ b/modes/preclinical-4d/src/index.tsx @@ -37,7 +37,7 @@ function modeFactory({ modeConfiguration }) { id, routeName: 'dynamic-volume', displayName: '4D PT/CT', - onModeEnter: function ({ servicesManager, extensionManager, commandsManager }) { + onModeEnter: function ({ servicesManager, extensionManager, commandsManager }: withAppTypes) { const { measurementService, toolbarService, @@ -86,12 +86,12 @@ function modeFactory({ modeConfiguration }) { } ); }, - onSetupRouteComplete: ({ servicesManager }) => { + onSetupRouteComplete: ({ servicesManager }: withAppTypes) => { // This needs to run after hanging protocol matching process because // it may change the protocol/stage based on workflow stage settings initWorkflowSteps({ servicesManager }); }, - onModeExit: ({ servicesManager }) => { + onModeExit: ({ servicesManager }: withAppTypes) => { const { toolGroupService, syncGroupService, diff --git a/modes/preclinical-4d/src/initWorkflowSteps.ts b/modes/preclinical-4d/src/initWorkflowSteps.ts index 8b36fe48d..47b423a63 100644 --- a/modes/preclinical-4d/src/initWorkflowSteps.ts +++ b/modes/preclinical-4d/src/initWorkflowSteps.ts @@ -1,6 +1,6 @@ import getWorkflowSettings from './getWorkflowSettings'; -export default function initWorkflowSteps({ servicesManager }): void { +export default function initWorkflowSteps({ servicesManager }: withAppTypes): void { const { workflowStepsService } = servicesManager.services; const workflowSettings = getWorkflowSettings({ servicesManager }); diff --git a/modes/segmentation/src/index.tsx b/modes/segmentation/src/index.tsx index 85a55a830..30961fe1f 100644 --- a/modes/segmentation/src/index.tsx +++ b/modes/segmentation/src/index.tsx @@ -53,7 +53,7 @@ function modeFactory({ modeConfiguration }) { * Runs when the Mode Route is mounted to the DOM. Usually used to initialize * Services and other resources. */ - onModeEnter: ({ servicesManager, extensionManager, commandsManager }) => { + onModeEnter: ({ servicesManager, extensionManager, commandsManager }: withAppTypes) => { const { measurementService, toolbarService, toolGroupService } = servicesManager.services; measurementService.clearMeasurements(); @@ -76,7 +76,7 @@ function modeFactory({ modeConfiguration }) { ]); toolbarService.createButtonSection('segmentationToolbox', ['BrushTools', 'Shapes']); }, - onModeExit: ({ servicesManager }) => { + onModeExit: ({ servicesManager }: withAppTypes) => { const { toolGroupService, syncGroupService, diff --git a/modes/tmtv/.webpack/webpack.dev.js b/modes/tmtv/.webpack/webpack.dev.js index 4bf848b6c..1b8e34cfd 100644 --- a/modes/tmtv/.webpack/webpack.dev.js +++ b/modes/tmtv/.webpack/webpack.dev.js @@ -4,7 +4,7 @@ const SRC_DIR = path.join(__dirname, '../src'); const DIST_DIR = path.join(__dirname, '../dist'); const ENTRY = { - app: `${SRC_DIR}/index.js`, + app: `${SRC_DIR}/index.ts`, }; module.exports = (env, argv) => { diff --git a/modes/tmtv/.webpack/webpack.prod.js b/modes/tmtv/.webpack/webpack.prod.js index 018db058d..f2edb43fa 100644 --- a/modes/tmtv/.webpack/webpack.prod.js +++ b/modes/tmtv/.webpack/webpack.prod.js @@ -11,7 +11,7 @@ const SRC_DIR = path.join(__dirname, '../src'); const DIST_DIR = path.join(__dirname, '../dist'); const ENTRY = { - app: `${SRC_DIR}/index.js`, + app: `${SRC_DIR}/index.ts`, }; module.exports = (env, argv) => { diff --git a/modes/tmtv/package.json b/modes/tmtv/package.json index 293a3db1f..6ff21f883 100644 --- a/modes/tmtv/package.json +++ b/modes/tmtv/package.json @@ -6,7 +6,7 @@ "license": "MIT", "repository": "OHIF/Viewers", "main": "dist/ohif-mode-tmtv.umd.js", - "module": "src/index.js", + "module": "src/index.ts", "engines": { "node": ">=14", "npm": ">=6", diff --git a/modes/tmtv/src/index.js b/modes/tmtv/src/index.ts similarity index 98% rename from modes/tmtv/src/index.js rename to modes/tmtv/src/index.ts index 03c73baff..2b3753897 100644 --- a/modes/tmtv/src/index.js +++ b/modes/tmtv/src/index.ts @@ -35,7 +35,7 @@ const extensionDependencies = { '@ohif/extension-tmtv': '^3.0.0', }; -let unsubscriptions = []; +const unsubscriptions = []; function modeFactory({ modeConfiguration }) { return { // TODO: We're using this as a route segment @@ -46,7 +46,7 @@ function modeFactory({ modeConfiguration }) { /** * Lifecycle hooks */ - onModeEnter: ({ servicesManager, extensionManager, commandsManager }) => { + onModeEnter: ({ servicesManager, extensionManager, commandsManager }: withAppTypes) => { const { toolbarService, toolGroupService, @@ -146,7 +146,7 @@ function modeFactory({ modeConfiguration }) { } ); }, - onModeExit: ({ servicesManager }) => { + onModeExit: ({ servicesManager }: withAppTypes) => { const { toolGroupService, syncGroupService, diff --git a/platform/app/src/App.tsx b/platform/app/src/App.tsx index 35a9c094b..0d06d22ee 100644 --- a/platform/app/src/App.tsx +++ b/platform/app/src/App.tsx @@ -6,7 +6,6 @@ import { I18nextProvider } from 'react-i18next'; import { BrowserRouter } from 'react-router-dom'; import Compose from './routes/Mode/Compose'; import { - ServicesManager, ExtensionManager, CommandsManager, HotkeysManager, @@ -33,7 +32,7 @@ import OpenIdConnectRoutes from './utils/OpenIdConnectRoutes'; let commandsManager: CommandsManager, extensionManager: ExtensionManager, - servicesManager: ServicesManager, + servicesManager: AppTypes.ServicesManager, serviceProvidersManager: ServiceProvidersManager, hotkeysManager: HotkeysManager; diff --git a/platform/app/src/components/ViewportGrid.tsx b/platform/app/src/components/ViewportGrid.tsx index 45a74910a..427887b9c 100644 --- a/platform/app/src/components/ViewportGrid.tsx +++ b/platform/app/src/components/ViewportGrid.tsx @@ -1,13 +1,13 @@ import React, { useEffect, useCallback, useRef, useState } from 'react'; import ReactResizeDetector from 'react-resize-detector'; import PropTypes from 'prop-types'; -import { ServicesManager, Types, MeasurementService } from '@ohif/core'; +import { Types, MeasurementService } from '@ohif/core'; import { ViewportGrid, ViewportPane, useViewportGrid } from '@ohif/ui'; import EmptyViewport from './EmptyViewport'; import classNames from 'classnames'; import { useAppConfig } from '@state'; -function ViewerViewportGrid(props) { +function ViewerViewportGrid(props: withAppTypes) { const { servicesManager, viewportComponents, dataSource } = props; const [viewportGrid, viewportGridService] = useViewportGrid(); const [appConfig] = useAppConfig(); @@ -18,9 +18,8 @@ function ViewerViewportGrid(props) { const layoutHash = useRef(null); // TODO -> Need some way of selecting which displaySets hit the viewports. - const { displaySetService, measurementService, hangingProtocolService, uiNotificationService } = ( - servicesManager as ServicesManager - ).services; + const { displaySetService, measurementService, hangingProtocolService, uiNotificationService } = + servicesManager.services; const generateLayoutHash = () => `${numCols}-${numRows}`; @@ -387,7 +386,7 @@ function ViewerViewportGrid(props) { ViewerViewportGrid.propTypes = { viewportComponents: PropTypes.array.isRequired, - servicesManager: PropTypes.instanceOf(ServicesManager), + servicesManager: PropTypes.instanceOf(Object).isRequired, }; ViewerViewportGrid.defaultProps = { diff --git a/platform/app/src/routes/Mode/Mode.tsx b/platform/app/src/routes/Mode/Mode.tsx index 791927455..0e78c74be 100644 --- a/platform/app/src/routes/Mode/Mode.tsx +++ b/platform/app/src/routes/Mode/Mode.tsx @@ -1,7 +1,7 @@ import React, { useEffect, useState, useRef } from 'react'; import { useParams, useLocation, useNavigate } from 'react-router'; import PropTypes from 'prop-types'; -import { ServicesManager, utils } from '@ohif/core'; +import { utils } from '@ohif/core'; import { DragAndDropProvider, ImageViewerProvider } from '@ohif/ui'; import { useSearchParams } from '@hooks'; import { useAppConfig } from '@state'; @@ -21,7 +21,7 @@ export default function ModeRoute({ servicesManager, commandsManager, hotkeysManager, -}) { +}: withAppTypes) { const [appConfig] = useAppConfig(); // Parse route params/querystring @@ -60,9 +60,8 @@ export default function ModeRoute({ locationRef.current = location; } - const { displaySetService, panelService, hangingProtocolService, userAuthenticationService } = ( - servicesManager as ServicesManager - ).services; + const { displaySetService, panelService, hangingProtocolService, userAuthenticationService } = + servicesManager.services; const { extensions, sopClassHandlers, hotkeys: hotkeyObj, hangingProtocol } = mode; diff --git a/platform/app/src/routes/Mode/defaultRouteInit.ts b/platform/app/src/routes/Mode/defaultRouteInit.ts index 863cb1946..4a29201d1 100644 --- a/platform/app/src/routes/Mode/defaultRouteInit.ts +++ b/platform/app/src/routes/Mode/defaultRouteInit.ts @@ -16,7 +16,7 @@ const { sortingCriteria, getSplitParam } = utils; * @returns array of subscriptions to cancel */ export async function defaultRouteInit( - { servicesManager, studyInstanceUIDs, dataSource, filters, appConfig }, + { servicesManager, studyInstanceUIDs, dataSource, filters, appConfig }: withAppTypes, hangingProtocolId ) { const { displaySetService, hangingProtocolService, uiNotificationService, customizationService } = diff --git a/platform/app/src/routes/WorkList/WorkList.tsx b/platform/app/src/routes/WorkList/WorkList.tsx index 171ed7994..de4738a7e 100644 --- a/platform/app/src/routes/WorkList/WorkList.tsx +++ b/platform/app/src/routes/WorkList/WorkList.tsx @@ -1,6 +1,6 @@ import React, { useState, useEffect, useMemo } from 'react'; import classnames from 'classnames'; -import PropTypes from 'prop-types'; +import PropTypes, { object } from 'prop-types'; import { Link, useNavigate } from 'react-router-dom'; import moment from 'moment'; import qs from 'query-string'; @@ -10,7 +10,7 @@ import { useTranslation } from 'react-i18next'; import filtersMeta from './filtersMeta.js'; import { useAppConfig } from '@state'; import { useDebounce, useSearchParams } from '@hooks'; -import { utils, hotkeys, ServicesManager } from '@ohif/core'; +import { utils, hotkeys } from '@ohif/core'; import { Icon, @@ -56,7 +56,7 @@ function WorkList({ dataPath, onRefresh, servicesManager, -}) { +}: withAppTypes) { const { hotkeyDefinitions, hotkeyDefaults } = hotkeysManager; const { show, hide } = useModal(); const { t } = useTranslation(); @@ -585,7 +585,7 @@ WorkList.propTypes = { getConfig: PropTypes.func, }).isRequired, isLoadingData: PropTypes.bool.isRequired, - servicesManager: PropTypes.instanceOf(ServicesManager), + servicesManager: PropTypes.object.isRequired, }; const defaultFilterValues = { diff --git a/platform/app/src/routes/buildModeRoutes.tsx b/platform/app/src/routes/buildModeRoutes.tsx index be46177b6..cda7b6b80 100644 --- a/platform/app/src/routes/buildModeRoutes.tsx +++ b/platform/app/src/routes/buildModeRoutes.tsx @@ -28,7 +28,7 @@ export default function buildModeRoutes({ servicesManager, commandsManager, hotkeysManager, -}) { +}: withAppTypes) { const routes = []; const dataSourceNames = []; diff --git a/platform/app/src/routes/index.tsx b/platform/app/src/routes/index.tsx index a202d9b3d..7226b55d5 100644 --- a/platform/app/src/routes/index.tsx +++ b/platform/app/src/routes/index.tsx @@ -88,7 +88,7 @@ const createRoutes = ({ hotkeysManager, routerBasename, showStudyList, -}) => { +}: withAppTypes) => { const routes = buildModeRoutes({ modes, diff --git a/platform/cli/templates/mode/src/index.tsx b/platform/cli/templates/mode/src/index.tsx index b607e921a..5ef254dc9 100644 --- a/platform/cli/templates/mode/src/index.tsx +++ b/platform/cli/templates/mode/src/index.tsx @@ -40,7 +40,7 @@ function modeFactory({ modeConfiguration }) { * Runs when the Mode Route is mounted to the DOM. Usually used to initialize * Services and other resources. */ - onModeEnter: ({ servicesManager, extensionManager, commandsManager }) => { + onModeEnter: ({ servicesManager, extensionManager, commandsManager }: withAppTypes) => { const { measurementService, toolbarService, toolGroupService } = servicesManager.services; measurementService.clearMeasurements(); @@ -60,7 +60,7 @@ function modeFactory({ modeConfiguration }) { 'MoreTools', ]); }, - onModeExit: ({ servicesManager }) => { + onModeExit: ({ servicesManager }: withAppTypes) => { const { toolGroupService, syncGroupService, diff --git a/platform/core/src/classes/HotkeysManager.ts b/platform/core/src/classes/HotkeysManager.ts index 8a01446b6..b7ca44308 100644 --- a/platform/core/src/classes/HotkeysManager.ts +++ b/platform/core/src/classes/HotkeysManager.ts @@ -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; diff --git a/platform/core/src/extensions/ExtensionManager.ts b/platform/core/src/extensions/ExtensionManager.ts index d7997c9fc..e8f7fcadf 100644 --- a/platform/core/src/extensions/ExtensionManager.ts +++ b/platform/core/src/extensions/ExtensionManager.ts @@ -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; */ 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; diff --git a/platform/core/src/hooks/useToolbar.tsx b/platform/core/src/hooks/useToolbar.tsx index 31eeb1d62..2dbd94fc8 100644 --- a/platform/core/src/hooks/useToolbar.tsx +++ b/platform/core/src/hooks/useToolbar.tsx @@ -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; diff --git a/platform/core/src/services/HangingProtocolService/HangingProtocolService.ts b/platform/core/src/services/HangingProtocolService/HangingProtocolService.ts index 8f3821e96..d71626062 100644 --- a/platform/core/src/services/HangingProtocolService/HangingProtocolService.ts +++ b/platform/core/src/services/HangingProtocolService/HangingProtocolService.ts @@ -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; diff --git a/platform/core/src/services/ServicesManager.ts b/platform/core/src/services/ServicesManager.ts index fb96db0f9..759a965f4 100644 --- a/platform/core/src/services/ServicesManager.ts +++ b/platform/core/src/services/ServicesManager.ts @@ -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; diff --git a/platform/core/src/services/ToolBarService/ToolbarService.ts b/platform/core/src/services/ToolBarService/ToolbarService.ts index a31421f2b..7d80f843a 100644 --- a/platform/core/src/services/ToolBarService/ToolbarService.ts +++ b/platform/core/src/services/ToolBarService/ToolbarService.ts @@ -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 = {}; _serviceSubscriptions = []; constructor( commandsManager: CommandsManager, extensionManager: ExtensionManager, - servicesManager: ServicesManager + servicesManager: AppTypes.ServicesManager ) { super(EVENTS); this._commandsManager = commandsManager; diff --git a/platform/core/src/services/UIDialogService/UIDialogService.ts b/platform/core/src/services/UIDialogService/UIDialogService.ts new file mode 100644 index 000000000..079a1943a --- /dev/null +++ b/platform/core/src/services/UIDialogService/UIDialogService.ts @@ -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; diff --git a/platform/core/src/services/UIDialogService/index.js b/platform/core/src/services/UIDialogService/index.js deleted file mode 100644 index dfa38c63c..000000000 --- a/platform/core/src/services/UIDialogService/index.js +++ /dev/null @@ -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; - }, - }, -}; diff --git a/platform/core/src/services/UIDialogService/index.ts b/platform/core/src/services/UIDialogService/index.ts new file mode 100644 index 000000000..3d787a5b0 --- /dev/null +++ b/platform/core/src/services/UIDialogService/index.ts @@ -0,0 +1,3 @@ +import UIDialogService from './UIDialogService'; + +export default UIDialogService; diff --git a/platform/core/src/services/UIViewportDialogService/UIViewportDialogService.ts b/platform/core/src/services/UIViewportDialogService/UIViewportDialogService.ts new file mode 100644 index 000000000..37b64188f --- /dev/null +++ b/platform/core/src/services/UIViewportDialogService/UIViewportDialogService.ts @@ -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; diff --git a/platform/core/src/services/UIViewportDialogService/index.js b/platform/core/src/services/UIViewportDialogService/index.js deleted file mode 100644 index 20e962a58..000000000 --- a/platform/core/src/services/UIViewportDialogService/index.js +++ /dev/null @@ -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; - }, - }, -}; diff --git a/platform/core/src/services/UIViewportDialogService/index.ts b/platform/core/src/services/UIViewportDialogService/index.ts new file mode 100644 index 000000000..a968569ec --- /dev/null +++ b/platform/core/src/services/UIViewportDialogService/index.ts @@ -0,0 +1,3 @@ +import UIViewportDialogService from './UIViewportDialogService'; + +export default UIViewportDialogService; diff --git a/platform/core/src/services/UserAuthenticationService/UserAuthenticationService.js b/platform/core/src/services/UserAuthenticationService/UserAuthenticationService.js deleted file mode 100644 index 5c1ec921b..000000000 --- a/platform/core/src/services/UserAuthenticationService/UserAuthenticationService.js +++ /dev/null @@ -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; - }, - }, -}; diff --git a/platform/core/src/services/UserAuthenticationService/UserAuthenticationService.ts b/platform/core/src/services/UserAuthenticationService/UserAuthenticationService.ts new file mode 100644 index 000000000..6ae3c8e92 --- /dev/null +++ b/platform/core/src/services/UserAuthenticationService/UserAuthenticationService.ts @@ -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; diff --git a/platform/core/src/services/UserAuthenticationService/index.js b/platform/core/src/services/UserAuthenticationService/index.ts similarity index 100% rename from platform/core/src/services/UserAuthenticationService/index.js rename to platform/core/src/services/UserAuthenticationService/index.ts diff --git a/platform/core/src/services/WorkflowStepsService/WorkflowStepsService.ts b/platform/core/src/services/WorkflowStepsService/WorkflowStepsService.ts index 8a5d33782..5165e55a1 100644 --- a/platform/core/src/services/WorkflowStepsService/WorkflowStepsService.ts +++ b/platform/core/src/services/WorkflowStepsService/WorkflowStepsService.ts @@ -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 = []; diff --git a/platform/core/src/types/AppConfig.ts b/platform/core/src/types/AppConfig.ts index 3c75694cb..d63c4146b 100644 --- a/platform/core/src/types/AppConfig.ts +++ b/platform/core/src/types/AppConfig.ts @@ -4,4 +4,18 @@ export interface AppConfig { extensions?: string[]; defaultDataSourceName?: string; hotkeys?: Record | 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; + }; } diff --git a/platform/core/src/types/AppTypes.ts b/platform/core/src/types/AppTypes.ts new file mode 100644 index 000000000..0354d7afd --- /dev/null +++ b/platform/core/src/types/AppTypes.ts @@ -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 & + AppTypes.Services & + AppTypes.Managers & { + [key: string]: any; + }; +} diff --git a/platform/core/src/types/HangingProtocol.ts b/platform/core/src/types/HangingProtocol.ts index 5fabe5417..e8d669545 100644 --- a/platform/core/src/types/HangingProtocol.ts +++ b/platform/core/src/types/HangingProtocol.ts @@ -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; }; diff --git a/platform/core/src/types/Services.ts b/platform/core/src/types/Services.ts index 9cedd0ad3..119a2da87 100644 --- a/platform/core/src/types/Services.ts +++ b/platform/core/src/types/Services.ts @@ -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; diff --git a/platform/docs/docs/development/types.md b/platform/docs/docs/development/types.md new file mode 100644 index 000000000..a6af5df12 --- /dev/null +++ b/platform/docs/docs/development/types.md @@ -0,0 +1,85 @@ +--- +sidebar_position: 10 +sidebar_label: Global Types +--- + +# Extending App Types and Services in Your Application + +This documentation provides an overview and examples on how to use and extend `withAppTypes`, integrate custom properties, and add services in the global namespace of the application. This helps in enhancing the application's modularity and extensibility. + +## Overview of `withAppTypes` + +The `withAppTypes` function is a TypeScript utility that extends the base properties of components or modules with the application's core service and manager types. It allows for a more flexible and type-safe way to pass around core functionality and custom properties. + +### Using `withAppTypes` + +`withAppTypes` can be enhanced using generics to include custom properties. This is particularly useful for passing additional data or configurations specific to your component or service. + +### Extending with Custom Properties + +You can extend `withAppTypes` to include custom properties by defining an interface for the props you need. For example: + +```typescript +interface ColorbarProps { + viewportId: string; + displaySets: Array; + colorbarProperties: ColorbarProperties; +} + +export function Colorbar({ + viewportId, + displaySets, + commandsManager, // injected type + servicesManager, // injected type + colorbarProperties, +}: withAppTypes): ReactElement { + // Component logic here +} +``` + +In this example, `ColorbarProps` is a custom interface that extends the application types through `withAppTypes`. + +## Typing the custom extensions's new services + +Extensions can define additional services that integrate seamlessly into the application's global service architecture, and will be available on the ServicesManager for use across the application. + +### Adding the extension's services Types + +Declare your service in the global namespace and use it across your application as demonstrated below: + +`extensions/my-extension/src/types/whatever.ts` + +```typescript +declare global { + namespace AppTypes { + // only add if you need direct access to the service ex. AppTypes.MicroscopyService + export type MicroscopyService = MicroscopyServiceType; + // add to the global Services interface, and to withAppTypes + export interface Services { + microscopyService?: MicroscopyServiceType; + } + } +} +``` + +Doing the above adds the `microscopyService` to the global Services interface, which ServicesManager uses by default `public services: AppTypes.Services = {};` to type services, and is also used by withAppTypes to inject services into components. +You will also get access to the seperate services via `AppTypes.YourServiceName` in your application. + + +```typescript +export function CustomComponent({ + servicesManager, +}: withAppTypes): ReactElement { + const { microscopyService } = servicesManager.services; + microscopyService.someMethod(); // auto completation available + +} +``` + +```typescript +export function CustomComponent2( + microscopyService: AppTypes.MicroscopyService, +): ReactElement { + microscopyService.someMethod(); // auto completation available +} +``` diff --git a/platform/docs/docs/platform/extensions/lifecycle.md b/platform/docs/docs/platform/extensions/lifecycle.md index ccb1392ee..27868888c 100644 --- a/platform/docs/docs/platform/extensions/lifecycle.md +++ b/platform/docs/docs/platform/extensions/lifecycle.md @@ -36,11 +36,11 @@ for `OHIF-v3`. // new service inside new extension import MyNewService from './MyNewService'; -export default function MyNewServiceWithServices(serviceManager) { +export default function MyNewServiceWithServices(servicesManager) { return { name: 'MyNewService', create: ({ configuration = {} }) => { - return new MyNewService(serviceManager); + return new MyNewService(servicesManager); }, }; } diff --git a/platform/docs/docs/platform/managers/service.md b/platform/docs/docs/platform/managers/service.md index 63c6248a5..d9269e46c 100644 --- a/platform/docs/docs/platform/managers/service.md +++ b/platform/docs/docs/platform/managers/service.md @@ -146,12 +146,12 @@ and the logic for your service shall be // Canonical name of upper camel case BackEndService for the class import BackEndService from './BackEndService'; -export default function WrappedBackEndService(serviceManager) { +export default function WrappedBackEndService(servicesManager) { return { // Note the canonical name of lower camel case backEndService name: 'backEndService', create: ({ configuration = {} }) => { - return new BackEndService(serviceManager); + return new BackEndService(servicesManager); }, }; } @@ -161,8 +161,8 @@ with implementation of ```ts export default class BackEndService { - constructor(serviceManager) { - this.serviceManager = serviceManager; + constructor(servicesManager) { + this.servicesManager = servicesManager; } putAnnotations() { diff --git a/platform/docs/docs/platform/services/data/index.md b/platform/docs/docs/platform/services/data/index.md index 6b92fdde1..d9a9c7465 100644 --- a/platform/docs/docs/platform/services/data/index.md +++ b/platform/docs/docs/platform/services/data/index.md @@ -28,7 +28,7 @@ We maintain the following non-ui Services: ![services-data](../../../assets/img/services-data.png) > We have explained services and how to create a custom service in the -> [`ServiceManager`](../../managers/service.md) section of the docs +> [`ServicesManager`](../../managers/service.md) section of the docs To recap: The simplest service return a new object that has a `name` property, and `Create` method which instantiate the service class. The "Factory Function" @@ -39,11 +39,11 @@ different for UI Services). // extensions/customExtension/src/services/backEndService/index.js import backEndService from './backEndService'; -export default function WrappedBackEndService(serviceManager) { +export default function WrappedBackEndService(servicesManager) { return { name: 'myService', create: ({ configuration = {} }) => { - return new backEndService(serviceManager); + return new backEndService(servicesManager); }, }; } diff --git a/platform/ui/src/components/Header/Header.tsx b/platform/ui/src/components/Header/Header.tsx index c75dfa923..94fbb3fda 100644 --- a/platform/ui/src/components/Header/Header.tsx +++ b/platform/ui/src/components/Header/Header.tsx @@ -23,7 +23,7 @@ function Header({ Secondary, appConfig, ...props -}): ReactNode { +}: withAppTypes): ReactNode { const { t } = useTranslation('Header'); // TODO: this should be passed in as a prop instead and the react-router-dom diff --git a/platform/ui/src/components/HeaderPatientInfo/HeaderPatientInfo.tsx b/platform/ui/src/components/HeaderPatientInfo/HeaderPatientInfo.tsx index e2940f31d..7e7de4d23 100644 --- a/platform/ui/src/components/HeaderPatientInfo/HeaderPatientInfo.tsx +++ b/platform/ui/src/components/HeaderPatientInfo/HeaderPatientInfo.tsx @@ -13,7 +13,7 @@ const formatWithEllipsis = (str, maxLength) => { return str; }; -function usePatientInfo(servicesManager) { +function usePatientInfo(servicesManager: AppTypes.ServicesManager) { const { displaySetService } = servicesManager.services; const [patientInfo, setPatientInfo] = useState({ @@ -70,7 +70,7 @@ function usePatientInfo(servicesManager) { return { patientInfo, isMixedPatients }; } -function HeaderPatientInfo({ servicesManager, appConfig }) { +function HeaderPatientInfo({ servicesManager, appConfig }: withAppTypes) { const initialExpandedState = appConfig.showPatientInfo === PatientInfoVisibility.VISIBLE || appConfig.showPatientInfo === PatientInfoVisibility.VISIBLE_READONLY; diff --git a/platform/ui/src/components/LegacySidePanel/LegacySidePanel.tsx b/platform/ui/src/components/LegacySidePanel/LegacySidePanel.tsx index ceb9c491f..402d0bf14 100644 --- a/platform/ui/src/components/LegacySidePanel/LegacySidePanel.tsx +++ b/platform/ui/src/components/LegacySidePanel/LegacySidePanel.tsx @@ -5,7 +5,7 @@ import { useTranslation } from 'react-i18next'; import SwiperCore, { A11y, Controller, Navigation, Pagination, Scrollbar } from 'swiper'; import { Swiper, SwiperSlide } from 'swiper/react'; -import { PanelService, ServicesManager, Types } from '@ohif/core'; +import { Types } from '@ohif/core'; import LegacyButton from '../LegacyButton'; import Icon from '../Icon'; @@ -71,8 +71,8 @@ const LegacySidePanel = ({ className, activeTabIndex: activeTabIndexProp, tabs, -}) => { - const panelService: PanelService = servicesManager?.services?.panelService; +}: withAppTypes) => { + const panelService = servicesManager?.services?.panelService; const { t } = useTranslation('LegacySidePanel'); @@ -288,7 +288,7 @@ LegacySidePanel.defaultProps = { }; LegacySidePanel.propTypes = { - servicesManager: PropTypes.instanceOf(ServicesManager), + servicesManager: PropTypes.object.isRequired, side: PropTypes.oneOf(['left', 'right']).isRequired, className: PropTypes.string, activeTabIndex: PropTypes.number, diff --git a/platform/ui/src/components/MeasurementTable/MeasurementTable.tsx b/platform/ui/src/components/MeasurementTable/MeasurementTable.tsx index 86fbdae28..210bcde5a 100644 --- a/platform/ui/src/components/MeasurementTable/MeasurementTable.tsx +++ b/platform/ui/src/components/MeasurementTable/MeasurementTable.tsx @@ -1,12 +1,17 @@ import React from 'react'; -import { ServicesManager } from '@ohif/core'; import PropTypes from 'prop-types'; import { useTranslation } from 'react-i18next'; import MeasurementItem from './MeasurementItem'; -const MeasurementTable = ({ data, title, onClick, onEdit, onDelete, servicesManager }) => { - servicesManager = servicesManager as ServicesManager; +const MeasurementTable = ({ + data, + title, + onClick, + onEdit, + onDelete, + servicesManager, +}: withAppTypes) => { const { customizationService, measurementService } = servicesManager.services; const { t } = useTranslation('MeasurementTable'); const amount = data.length; diff --git a/platform/ui/src/components/StudyBrowser/StudyBrowser.tsx b/platform/ui/src/components/StudyBrowser/StudyBrowser.tsx index c212de7ff..89175ccbb 100644 --- a/platform/ui/src/components/StudyBrowser/StudyBrowser.tsx +++ b/platform/ui/src/components/StudyBrowser/StudyBrowser.tsx @@ -30,7 +30,7 @@ const StudyBrowser = ({ onClickUntrack, activeDisplaySetInstanceUIDs, servicesManager, -}) => { +}: withAppTypes) => { const { t } = useTranslation('StudyBrowser'); const { customizationService } = servicesManager?.services || {}; diff --git a/platform/ui/src/components/Toolbox/Toolbox.tsx b/platform/ui/src/components/Toolbox/Toolbox.tsx index e27deed38..a8030e201 100644 --- a/platform/ui/src/components/Toolbox/Toolbox.tsx +++ b/platform/ui/src/components/Toolbox/Toolbox.tsx @@ -13,7 +13,13 @@ import { useToolbox } from '../../contextProviders'; * role in enhancing the app with a toolbox by providing a way to integrate * and display various tools and their corresponding options */ -function Toolbox({ servicesManager, buttonSectionId, commandsManager, title, ...props }) { +function Toolbox({ + servicesManager, + buttonSectionId, + commandsManager, + title, + ...props +}: withAppTypes) { const { state: toolboxState, api } = useToolbox(buttonSectionId); const { onInteraction, toolbarButtons } = useToolbar({ servicesManager, diff --git a/platform/ui/src/components/Toolbox/ToolboxUI.tsx b/platform/ui/src/components/Toolbox/ToolboxUI.tsx index 5755de911..184cac654 100644 --- a/platform/ui/src/components/Toolbox/ToolboxUI.tsx +++ b/platform/ui/src/components/Toolbox/ToolboxUI.tsx @@ -15,7 +15,7 @@ function usePrevious(value) { /** * Just refactoring from the toolbox component to make it more readable */ -function ToolboxUI(props) { +function ToolboxUI(props: withAppTypes) { const { toolbarButtons, handleToolSelect,