From d582a951f9e69eaf2ce66d5f1296af29e2da5b31 Mon Sep 17 00:00:00 2001 From: Adithyan Dinesh Date: Thu, 18 Apr 2024 16:44:45 +0530 Subject: [PATCH 1/2] Support for object versioning of segmentations. --- .../src/getSopClassHandlerModule.js | 2 +- .../src/panels/PanelSegmentation.tsx | 113 ++++++++++++++++++ .../ObjectVersionList/ObjectVersionList.tsx | 77 ++++++++++++ .../src/components/ObjectVersionList/index.ts | 2 + .../SegmentationDropDownRow.tsx | 21 +++- .../SegmentationGroup.tsx | 6 + .../SegmentationGroupTable.tsx | 7 ++ platform/ui/src/components/index.js | 2 + 8 files changed, 227 insertions(+), 3 deletions(-) create mode 100644 platform/ui/src/components/ObjectVersionList/ObjectVersionList.tsx create mode 100644 platform/ui/src/components/ObjectVersionList/index.ts diff --git a/extensions/cornerstone-dicom-seg/src/getSopClassHandlerModule.js b/extensions/cornerstone-dicom-seg/src/getSopClassHandlerModule.js index a0043fefcda..3eddd4371d5 100644 --- a/extensions/cornerstone-dicom-seg/src/getSopClassHandlerModule.js +++ b/extensions/cornerstone-dicom-seg/src/getSopClassHandlerModule.js @@ -121,7 +121,7 @@ function _load(segDisplaySet, servicesManager, extensionManager, headers) { }); } - const suppressEvents = true; + const suppressEvents = false; segmentationService .createSegmentationForSEGDisplaySet(segDisplaySet, null, suppressEvents) .then(() => { diff --git a/extensions/cornerstone-dicom-seg/src/panels/PanelSegmentation.tsx b/extensions/cornerstone-dicom-seg/src/panels/PanelSegmentation.tsx index 141bb8f5935..54483c38530 100644 --- a/extensions/cornerstone-dicom-seg/src/panels/PanelSegmentation.tsx +++ b/extensions/cornerstone-dicom-seg/src/panels/PanelSegmentation.tsx @@ -35,6 +35,15 @@ export default function PanelSegmentation({ userAuthenticationService, CropDisplayAreaService, } = servicesManager.services; + const utilityModule = extensionManager.getModuleEntry( + '@gradienthealth/ohif-gradienthealth-extension.utilityModule.version' + ); + const { + getObjectVersions, + confirmSEGVersionRestore, + restoreObjectVersion, + parseUrlToBucketAndFileName, + } = utilityModule.exports; const { t } = useTranslation('PanelSegmentation'); @@ -44,6 +53,7 @@ export default function PanelSegmentation({ ); const [segmentations, setSegmentations] = useState(() => segmentationService.getSegmentations()); + const [versionsMap, setVersionsMap] = useState(new Map()); const [savedStatusStates, dispatch] = useReducer(savedStatusReducer, {}); useEffect(() => { @@ -69,6 +79,20 @@ export default function PanelSegmentation({ }; }, []); + useEffect(() => { + updateVersions(segmentations); + const { unsubscribe } = segmentationService.subscribe( + segmentationService.EVENTS.SEGMENTATION_ADDED, + ({ segmentation: newSegmentation }) => { + updateVersions([newSegmentation]); + } + ); + + return () => { + unsubscribe(); + }; + }, []); + useEffect(() => { let changedSegmentations: any[] = [], timerId; @@ -125,6 +149,7 @@ export default function PanelSegmentation({ const savedSegmentations = Object.keys(payload).filter( id => payload[id] === SAVED_STATUS_ICON.SAVED ); + updateVersions(changedSegmentations); changedSegmentations = changedSegmentations.filter( cs => !savedSegmentations.includes(cs.id) ); @@ -346,6 +371,7 @@ export default function PanelSegmentation({ }); dispatch({ payload: { [segmentationId]: SAVED_STATUS_ICON.SAVED } }); + updateVersions([segmentations.find(segmentation => segmentation.id === segmentationId)]); } catch (error) { console.warn(error.message); dispatch({ payload: { [segmentationId]: SAVED_STATUS_ICON.ERROR } }); @@ -372,6 +398,91 @@ export default function PanelSegmentation({ }); }; + const onVersionClick = (segmentationId, version) => { + setSegmentationActive(segmentationId); + + const headers = userAuthenticationService.getAuthorizationHeader(); + const displaySet = displaySetService.getDisplaySetByUID(segmentationId); + const referencedDisplaySetInstanceUID = displaySet.referencedDisplaySetInstanceUID; + const referencedDisplaySet = displaySetService.getDisplaySetByUID( + referencedDisplaySetInstanceUID + ); + const { activeViewportId } = viewportGridService.getState(); + + const url = new URL(displaySet.instances[0].url); + url.searchParams.set('generation', version.generation); + const newUrl = url.toString(); + const { bucket, fileName } = parseUrlToBucketAndFileName(newUrl); + + displaySet.instances[0].url = displaySet.instance.url = newUrl; + displaySet.instance.imageId = newUrl; + displaySet.instance.getImageId = () => newUrl; + + displaySet.isLoaded = false; + + segmentationService.remove(segmentationId); + + displaySet + .load({ headers: headers }) + .then(() => { + const toolGroupIds = getToolGroupIds(segmentationId); + const promises = toolGroupIds.map(toolGroupId => + segmentationService.addSegmentationRepresentationToToolGroup( + toolGroupId, + segmentationId, + true + ) + ); + return Promise.all(promises); + }) + .then(async () => { + referencedDisplaySet.needsRerendering = true; + viewportGridService.setDisplaySetsForViewport({ + viewportId: activeViewportId, + displaySetInstanceUIDs: [referencedDisplaySetInstanceUID], + }); + + return confirmSEGVersionRestore(activeViewportId, servicesManager); + }) + .then(status => { + if (status) { + restoreObjectVersion(bucket, fileName, version.generation, headers).then(() => + updateVersions([segmentations.find(segmentation => segmentation.id === segmentationId)]) + ); + } + }) + .catch(error => console.warn(error)); + }; + + const updateVersions = updatedSegmentations => { + const headers = userAuthenticationService.getAuthorizationHeader(); + const newVersionsMap = new Map(); + + const promises = updatedSegmentations.map(async segmentation => { + const displaySet = displaySetService.getDisplaySetByUID(segmentation.id); + if (displaySet) { + const url = new URL(displaySet.instances[0].url); + url.searchParams.delete('generation'); + const { bucket, fileName } = parseUrlToBucketAndFileName(url.toString()); + return getObjectVersions(bucket, fileName, headers).then(versions => ({ + id: segmentation.id, + versions, + })); + } + }); + + Promise.all(promises).then(results => { + results.forEach(result => { + if (result) { + newVersionsMap.set(result.id, result.versions); + } + }); + setVersionsMap( + prevState => new Map([...Array.from(prevState), ...Array.from(newVersionsMap)]) + ); + }); + }; + const params = new URLSearchParams(window.location.search); const showAddSegmentation = params.get('disableAddSegmentation') !== 'true'; @@ -381,6 +492,7 @@ export default function PanelSegmentation({ diff --git a/platform/ui/src/components/ObjectVersionList/ObjectVersionList.tsx b/platform/ui/src/components/ObjectVersionList/ObjectVersionList.tsx new file mode 100644 index 00000000000..16369378f05 --- /dev/null +++ b/platform/ui/src/components/ObjectVersionList/ObjectVersionList.tsx @@ -0,0 +1,77 @@ +import React, { useEffect, useRef } from 'react'; +import PropTypes from 'prop-types'; +import moment from 'moment'; + +export default function ObjectVersionsList({ show, versions, onVersionSelect, onClose }) { + const element = useRef(null); + + const handleClick = e => { + if (element.current && !element.current.contains(e.target)) { + onClose(); + } + }; + + useEffect(() => { + document.addEventListener('click', handleClick); + + if (!show) { + document.removeEventListener('click', handleClick); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [show]); + + const filteredVersions = versions.sort( + (a, b) => new Date(b.updated).getTime() - new Date(a.updated).getTime() + ); + + return ( + <> + {show ? ( +
+
+ {filteredVersions.length ? ( + filteredVersions.map((version, index) => ( +
{ + evt.preventDefault(); + onVersionSelect(version); + }} + > + {index === 0 + ? 'Current Version' + : moment(version.updated).format('MMMM D, h:mm A')} +
+ )) + ) : ( +
+ No noncurrent versions Found +
+ )} +
+
+ ) : null} + + ); +} + +ObjectVersionsList.propTypes = { + show: PropTypes.bool, + versions: PropTypes.arrayOf( + PropTypes.shape({ + name: PropTypes.string, + generation: PropTypes.string, + updated: PropTypes.string, + }) + ).isRequired, + onVersionSelect: PropTypes.func, + onClose: PropTypes.func, +}; diff --git a/platform/ui/src/components/ObjectVersionList/index.ts b/platform/ui/src/components/ObjectVersionList/index.ts new file mode 100644 index 00000000000..6ccb7beb432 --- /dev/null +++ b/platform/ui/src/components/ObjectVersionList/index.ts @@ -0,0 +1,2 @@ +import ObjectVersionsList from './ObjectVersionList'; +export default ObjectVersionsList; diff --git a/platform/ui/src/components/SegmentationGroupTable/SegmentationDropDownRow.tsx b/platform/ui/src/components/SegmentationGroupTable/SegmentationDropDownRow.tsx index 401a95b3505..ca81f485073 100644 --- a/platform/ui/src/components/SegmentationGroupTable/SegmentationDropDownRow.tsx +++ b/platform/ui/src/components/SegmentationGroupTable/SegmentationDropDownRow.tsx @@ -1,10 +1,11 @@ -import React from 'react'; -import { Icon, Dropdown } from '../../components'; +import React, { useState } from 'react'; +import { Icon, Dropdown, ObjectVersionsList } from '../../components'; import PropTypes from 'prop-types'; import { useTranslation } from 'react-i18next'; function SegmentationDropDownRow({ segmentation, + versions, savedStatusState, activeSegmentationId, disableEditing, @@ -18,8 +19,10 @@ function SegmentationDropDownRow({ onSegmentationDelete, onSegmentAdd, onToggleShowSegments, + onVersionClick, showSegments, }) { + const [showVersionHistory, setShowVersionHistory] = useState(false); const { t } = useTranslation('SegmentationTable'); if (!segmentation) { @@ -28,6 +31,12 @@ function SegmentationDropDownRow({ return (
+ onVersionClick(segmentation.id, version)} + onClose={() => setShowVersionHistory(false)} + />
{ e.stopPropagation(); @@ -78,6 +87,12 @@ function SegmentationDropDownRow({ ] : []), ...[ + { + title: t('Show Version History'), + onClick: () => { + setShowVersionHistory(true); + }, + }, { title: t('Download DICOM SEG'), onClick: () => { @@ -157,6 +172,7 @@ SegmentationDropDownRow.propTypes = { label: PropTypes.string.isRequired, isVisible: PropTypes.bool.isRequired, }), + versions: PropTypes.array, savedStatusState: PropTypes.string, activeSegmentationId: PropTypes.string, disableEditing: PropTypes.bool, @@ -170,6 +186,7 @@ SegmentationDropDownRow.propTypes = { onSegmentationDelete: PropTypes.func, onSegmentAdd: PropTypes.func, onToggleShowSegments: PropTypes.func, + onVersionClick: PropTypes.func, showSegments: PropTypes.bool, }; diff --git a/platform/ui/src/components/SegmentationGroupTable/SegmentationGroup.tsx b/platform/ui/src/components/SegmentationGroupTable/SegmentationGroup.tsx index cea71e8f14e..a5da874de55 100644 --- a/platform/ui/src/components/SegmentationGroupTable/SegmentationGroup.tsx +++ b/platform/ui/src/components/SegmentationGroupTable/SegmentationGroup.tsx @@ -6,6 +6,7 @@ import SegmentationGroupSegment from './SegmentationGroupSegment'; const SegmentationGroup = ({ segmentation, + versions, savedStatusState, activeSegmentationId, disableEditing, @@ -24,6 +25,7 @@ const SegmentationGroup = ({ onToggleSegmentVisibility, onToggleSegmentLock, onSegmentColorClick, + onVersionClick, showDeleteSegment, CropDisplayAreaService, }) => { @@ -37,6 +39,7 @@ const SegmentationGroup = ({
@@ -111,6 +115,7 @@ SegmentationGroup.propTypes = { }) ), }), + versions: PropTypes.array, savedStatusState: PropTypes.string, activeSegmentationId: PropTypes.string, disableEditing: PropTypes.bool, @@ -130,6 +135,7 @@ SegmentationGroup.propTypes = { onToggleSegmentVisibility: PropTypes.func.isRequired, onToggleSegmentLock: PropTypes.func.isRequired, onSegmentColorClick: PropTypes.func.isRequired, + onVersionClick: PropTypes.func, CropDisplayAreaService: PropTypes.any, }; diff --git a/platform/ui/src/components/SegmentationGroupTable/SegmentationGroupTable.tsx b/platform/ui/src/components/SegmentationGroupTable/SegmentationGroupTable.tsx index a7a22f23aeb..90d1be823f3 100644 --- a/platform/ui/src/components/SegmentationGroupTable/SegmentationGroupTable.tsx +++ b/platform/ui/src/components/SegmentationGroupTable/SegmentationGroupTable.tsx @@ -9,6 +9,7 @@ import SegmentationGroup from './SegmentationGroup'; const SegmentationGroupTable = ({ segmentations, + versionsMap, savedStatusStates, // segmentation initial config segmentationConfig, @@ -34,6 +35,8 @@ const SegmentationGroupTable = ({ onToggleSegmentVisibility, onToggleSegmentLock, onSegmentColorClick, + // object version handlers + onVersionClick, // segmentation config handlers setFillAlpha, setFillAlphaInactive, @@ -115,6 +118,7 @@ const SegmentationGroupTable = ({ key={segmentation.id} activeSegmentationId={activeSegmentationId} segmentation={segmentation} + versions={versionsMap?.get(segmentation.id)} savedStatusState={savedStatusStates[segmentation.id]} disableEditing={disableEditing} showAddSegment={showAddSegment} @@ -132,6 +136,7 @@ const SegmentationGroupTable = ({ onToggleSegmentVisibility={onToggleSegmentVisibility} onToggleSegmentLock={onToggleSegmentLock} onSegmentColorClick={onSegmentColorClick} + onVersionClick={onVersionClick} showDeleteSegment={showDeleteSegment} CropDisplayAreaService={CropDisplayAreaService} /> @@ -159,6 +164,7 @@ SegmentationGroupTable.propTypes = { ), }) ), + versionsMap: PropTypes.object, savedStatusStates: PropTypes.object, segmentationConfig: PropTypes.object.isRequired, disableEditing: PropTypes.bool, @@ -180,6 +186,7 @@ SegmentationGroupTable.propTypes = { onToggleSegmentVisibility: PropTypes.func.isRequired, onToggleSegmentLock: PropTypes.func.isRequired, onSegmentColorClick: PropTypes.func.isRequired, + onVersionClick: PropTypes.func, setFillAlpha: PropTypes.func.isRequired, setFillAlphaInactive: PropTypes.func.isRequired, setOutlineWidthActive: PropTypes.func.isRequired, diff --git a/platform/ui/src/components/index.js b/platform/ui/src/components/index.js index b51bc92cf88..d07e9aa823b 100644 --- a/platform/ui/src/components/index.js +++ b/platform/ui/src/components/index.js @@ -79,6 +79,7 @@ import PanelSection from './PanelSection'; import AdvancedToolbox from './AdvancedToolbox'; import InputDoubleRange from './InputDoubleRange'; import LegacyButtonGroup from './LegacyButtonGroup'; +import ObjectVersionsList from './ObjectVersionList'; export { AboutModal, @@ -126,6 +127,7 @@ export { Modal, NavBar, Notification, + ObjectVersionsList, ProgressLoadingBar, PanelSection, Select, From d49e0591ca10dd6a1902fc0b371ad58aa06bbddd Mon Sep 17 00:00:00 2001 From: Adithyan Dinesh Date: Fri, 19 Apr 2024 20:27:35 +0530 Subject: [PATCH 2/2] 1) Revert to live version of segmentation if version restore is canceled, another segmentation is selected or segmentation panel is unmounted. 2) Caching versions on clicking versions history. --- .../src/panels/PanelSegmentation.tsx | 78 +++++++++++++++---- .../SegmentationDropDownRow.tsx | 13 ++++ .../SegmentationGroup.tsx | 7 +- .../SegmentationGroupTable.tsx | 6 +- 4 files changed, 86 insertions(+), 18 deletions(-) diff --git a/extensions/cornerstone-dicom-seg/src/panels/PanelSegmentation.tsx b/extensions/cornerstone-dicom-seg/src/panels/PanelSegmentation.tsx index 54483c38530..f96acbf0d09 100644 --- a/extensions/cornerstone-dicom-seg/src/panels/PanelSegmentation.tsx +++ b/extensions/cornerstone-dicom-seg/src/panels/PanelSegmentation.tsx @@ -1,5 +1,5 @@ import { createReportAsync } from '@ohif/extension-default'; -import React, { useEffect, useState, useCallback, useReducer } from 'react'; +import React, { useEffect, useState, useCallback, useReducer, useRef } from 'react'; import PropTypes from 'prop-types'; import { SegmentationGroupTable, LegacyButtonGroup, LegacyButton } from '@ohif/ui'; @@ -33,7 +33,8 @@ export default function PanelSegmentation({ uiDialogService, displaySetService, userAuthenticationService, - CropDisplayAreaService, + CacheAPIService, + uiViewportDialogService, } = servicesManager.services; const utilityModule = extensionManager.getModuleEntry( '@gradienthealth/ohif-gradienthealth-extension.utilityModule.version' @@ -55,6 +56,7 @@ export default function PanelSegmentation({ const [segmentations, setSegmentations] = useState(() => segmentationService.getSegmentations()); const [versionsMap, setVersionsMap] = useState(new Map()); const [savedStatusStates, dispatch] = useReducer(savedStatusReducer, {}); + const componentWillUnMount = useRef(false); useEffect(() => { // ~~ Subscription @@ -163,6 +165,30 @@ export default function PanelSegmentation({ }; }, []); + useEffect(() => { + return () => { + componentWillUnMount.current = true; + }; + }, []); + + useEffect(() => { + const loadActiveSegLiveVersion = () => { + const activeSegmentation = segmentations?.find(segmentation => segmentation.isActive); + if (activeSegmentation) { + const liveVersion = versionsMap + .get(activeSegmentation.id) + ?.find(version => !version.timeDeleted); + liveVersion && onVersionClick(activeSegmentation.id, liveVersion); + } + }; + + return () => { + if (componentWillUnMount.current) { + loadActiveSegLiveVersion(); + } + }; + }, [segmentations, versionsMap]); + const setSegmentationActive = segmentationId => { setReferencedDisplaySet(segmentationId); @@ -178,6 +204,14 @@ export default function PanelSegmentation({ // Set referenced displaySet of the segmentation to the viewport // if it is not displayed in any of the viewports. const setReferencedDisplaySet = segmentationId => { + const activeSegmentation = segmentations.find(segmentation => segmentation.isActive); + if (activeSegmentation.id !== segmentationId) { + const liveVersion = versionsMap + .get(activeSegmentation.id) + ?.find(version => !version.timeDeleted); + liveVersion && onVersionClick(activeSegmentation.id, liveVersion); + } + const segDisplayset = displaySetService.getDisplaySetByUID(segmentationId); if (!segDisplayset) { return; @@ -399,8 +433,6 @@ export default function PanelSegmentation({ }; const onVersionClick = (segmentationId, version) => { - setSegmentationActive(segmentationId); - const headers = userAuthenticationService.getAuthorizationHeader(); const displaySet = displaySetService.getDisplaySetByUID(segmentationId); const referencedDisplaySetInstanceUID = displaySet.referencedDisplaySetInstanceUID; @@ -410,22 +442,29 @@ export default function PanelSegmentation({ const { activeViewportId } = viewportGridService.getState(); const url = new URL(displaySet.instances[0].url); + + if (url.searchParams.get('generation') === version.generation) { + return; + } + url.searchParams.set('generation', version.generation); const newUrl = url.toString(); const { bucket, fileName } = parseUrlToBucketAndFileName(newUrl); + const imageIdToFileUriMap = CacheAPIService.getImageIdToFileUriMap(); + const imageId = imageIdToFileUriMap.get(newUrl) || newUrl; displaySet.instances[0].url = displaySet.instance.url = newUrl; - displaySet.instance.imageId = newUrl; - displaySet.instance.getImageId = () => newUrl; + displaySet.instance.imageId = imageId; + displaySet.instance.getImageId = () => imageId; + const liveVersion = versionsMap.get(segmentationId).find(version => !version.timeDeleted); displaySet.isLoaded = false; - + const toolGroupIds = getToolGroupIds(segmentationId); segmentationService.remove(segmentationId); displaySet .load({ headers: headers }) .then(() => { - const toolGroupIds = getToolGroupIds(segmentationId); const promises = toolGroupIds.map(toolGroupId => segmentationService.addSegmentationRepresentationToToolGroup( toolGroupId, @@ -442,13 +481,26 @@ export default function PanelSegmentation({ displaySetInstanceUIDs: [referencedDisplaySetInstanceUID], }); + if (liveVersion.generation === version.generation) { + return; + } + return confirmSEGVersionRestore(activeViewportId, servicesManager); }) .then(status => { - if (status) { - restoreObjectVersion(bucket, fileName, version.generation, headers).then(() => - updateVersions([segmentations.find(segmentation => segmentation.id === segmentationId)]) - ); + switch (status) { + case 1: + restoreObjectVersion(bucket, fileName, version.generation, headers).then(() => + updateVersions([ + segmentations.find(segmentation => segmentation.id === segmentationId), + ]) + ); + break; + case 0: + onVersionClick(segmentationId, liveVersion); + break; + default: + uiViewportDialogService.hide(); // This case is when we are load live version. } }) .catch(error => console.warn(error)); @@ -540,7 +592,7 @@ export default function PanelSegmentation({ setFillAlphaInactive={value => _setSegmentationConfiguration(selectedSegmentationId, 'fillAlphaInactive', value) } - CropDisplayAreaService={CropDisplayAreaService} + servicesManager={servicesManager} />
diff --git a/platform/ui/src/components/SegmentationGroupTable/SegmentationDropDownRow.tsx b/platform/ui/src/components/SegmentationGroupTable/SegmentationDropDownRow.tsx index ca81f485073..65f040225ac 100644 --- a/platform/ui/src/components/SegmentationGroupTable/SegmentationDropDownRow.tsx +++ b/platform/ui/src/components/SegmentationGroupTable/SegmentationDropDownRow.tsx @@ -21,6 +21,7 @@ function SegmentationDropDownRow({ onToggleShowSegments, onVersionClick, showSegments, + CacheAPIService, }) { const [showVersionHistory, setShowVersionHistory] = useState(false); const { t } = useTranslation('SegmentationTable'); @@ -29,6 +30,15 @@ function SegmentationDropDownRow({ return null; } + const cacheVersions = () => { + const versionUrls = + versions?.map(version => { + return `dicomweb:https://storage.googleapis.com/${version.bucket}/${version.name}?generation=${version.generation}`; + }) || []; + + CacheAPIService.cacheFiles(versionUrls); + }; + return (
{ + cacheVersions(); + onSegmentationClick(segmentation.id); setShowVersionHistory(true); }, }, @@ -188,6 +200,7 @@ SegmentationDropDownRow.propTypes = { onToggleShowSegments: PropTypes.func, onVersionClick: PropTypes.func, showSegments: PropTypes.bool, + CacheAPIService: PropTypes.any, }; SegmentationDropDownRow.defaultProps = { diff --git a/platform/ui/src/components/SegmentationGroupTable/SegmentationGroup.tsx b/platform/ui/src/components/SegmentationGroupTable/SegmentationGroup.tsx index a5da874de55..faf969f27ad 100644 --- a/platform/ui/src/components/SegmentationGroupTable/SegmentationGroup.tsx +++ b/platform/ui/src/components/SegmentationGroupTable/SegmentationGroup.tsx @@ -27,8 +27,10 @@ const SegmentationGroup = ({ onSegmentColorClick, onVersionClick, showDeleteSegment, - CropDisplayAreaService, + servicesManager, }) => { + const { CacheAPIService, CropDisplayAreaService } = servicesManager.services; + const [showSegments, toggleShowSegments] = useState(true); return ( @@ -55,6 +57,7 @@ const SegmentationGroup = ({ onToggleShowSegments={toggleShowSegments} onVersionClick={onVersionClick} showSegments={showSegments} + CacheAPIService={CacheAPIService} />
{showSegments && ( @@ -136,7 +139,7 @@ SegmentationGroup.propTypes = { onToggleSegmentLock: PropTypes.func.isRequired, onSegmentColorClick: PropTypes.func.isRequired, onVersionClick: PropTypes.func, - CropDisplayAreaService: PropTypes.any, + servicesManager: PropTypes.any, }; export default SegmentationGroup; diff --git a/platform/ui/src/components/SegmentationGroupTable/SegmentationGroupTable.tsx b/platform/ui/src/components/SegmentationGroupTable/SegmentationGroupTable.tsx index 90d1be823f3..7c5529e6455 100644 --- a/platform/ui/src/components/SegmentationGroupTable/SegmentationGroupTable.tsx +++ b/platform/ui/src/components/SegmentationGroupTable/SegmentationGroupTable.tsx @@ -45,7 +45,7 @@ const SegmentationGroupTable = ({ setRenderFill, setRenderInactiveSegmentations, setRenderOutline, - CropDisplayAreaService, + servicesManager, }) => { const [isConfigOpen, setIsConfigOpen] = useState(false); const [activeSegmentationId, setActiveSegmentationId] = useState(null); @@ -138,7 +138,7 @@ const SegmentationGroupTable = ({ onSegmentColorClick={onSegmentColorClick} onVersionClick={onVersionClick} showDeleteSegment={showDeleteSegment} - CropDisplayAreaService={CropDisplayAreaService} + servicesManager={servicesManager} /> )) )} @@ -194,7 +194,7 @@ SegmentationGroupTable.propTypes = { setRenderFill: PropTypes.func.isRequired, setRenderInactiveSegmentations: PropTypes.func.isRequired, setRenderOutline: PropTypes.func.isRequired, - CropDisplayAreaService: PropTypes.any, + servicesManager: PropTypes.any, }; SegmentationGroupTable.defaultProps = {