From ebfde6eebea03aa178f669841962c7344056ee5d Mon Sep 17 00:00:00 2001 From: Ibrahim <93064150+IbrahimCSAE@users.noreply.github.com> Date: Mon, 18 Mar 2024 20:27:12 -0400 Subject: [PATCH] feat(worklist): New worklist buttons and tooltips (#3989) --- modes/basic-dev-mode/src/index.js | 16 ++++-- modes/basic-test-mode/src/index.ts | 12 ++++- modes/longitudinal/src/index.js | 12 ++++- modes/microscopy/src/index.tsx | 10 ++-- modes/segmentation/src/index.tsx | 11 +++-- modes/tmtv/src/index.js | 9 +++- platform/app/public/config/default.js | 1 + platform/app/src/routes/WorkList/WorkList.tsx | 49 +++++++++++++++---- platform/cli/templates/mode/src/index.tsx | 4 ++ platform/ui/src/assets/icons/launch-arrow.svg | 6 +-- platform/ui/src/assets/icons/launch-info.svg | 9 ++-- platform/ui/src/components/Button/Button.tsx | 15 ++++-- .../StudyListTable/StudyListTableRow.tsx | 2 +- 13 files changed, 120 insertions(+), 36 deletions(-) diff --git a/modes/basic-dev-mode/src/index.js b/modes/basic-dev-mode/src/index.js index 01513492fea..bcedc4aca8f 100644 --- a/modes/basic-dev-mode/src/index.js +++ b/modes/basic-dev-mode/src/index.js @@ -133,8 +133,15 @@ function modeFactory({ modeConfiguration }) { ]); }, onModeExit: ({ servicesManager }) => { - const { toolGroupService, measurementService, toolbarService } = servicesManager.services; - + const { + toolGroupService, + measurementService, + toolbarService, + uiDialogService, + uiModalService, + } = servicesManager.services; + uiDialogService.dismissAll(); + uiModalService.hide(); toolGroupService.destroy(); }, validationTags: { @@ -145,7 +152,10 @@ function modeFactory({ modeConfiguration }) { const modalities_list = modalities.split('\\'); // Slide Microscopy modality not supported by basic mode yet - return !modalities_list.includes('SM'); + return { + valid: !modalities_list.includes('SM'), + description: 'The mode does not support the following modalities: SM', + }; }, routes: [ { diff --git a/modes/basic-test-mode/src/index.ts b/modes/basic-test-mode/src/index.ts index 1c434217936..a6e9d0827ad 100644 --- a/modes/basic-test-mode/src/index.ts +++ b/modes/basic-test-mode/src/index.ts @@ -143,8 +143,12 @@ function modeFactory() { syncGroupService, segmentationService, cornerstoneViewportService, + uiDialogService, + uiModalService, } = servicesManager.services; + uiDialogService.dismissAll(); + uiModalService.hide(); toolGroupService.destroy(); syncGroupService.destroy(); segmentationService.destroy(); @@ -159,8 +163,12 @@ function modeFactory() { const modalities_list = modalities.split('\\'); // Exclude non-image modalities - return !!modalities_list.filter(modality => NON_IMAGE_MODALITIES.indexOf(modality) === -1) - .length; + return { + valid: !!modalities_list.filter(modality => NON_IMAGE_MODALITIES.indexOf(modality) === -1) + .length, + description: + 'The mode does not support studies that ONLY include the following modalities: SM, ECG, SR, SEG', + }; }, routes: [ { diff --git a/modes/longitudinal/src/index.js b/modes/longitudinal/src/index.js index 0d9be56af58..571d6a5f69e 100644 --- a/modes/longitudinal/src/index.js +++ b/modes/longitudinal/src/index.js @@ -179,11 +179,15 @@ function modeFactory({ modeConfiguration }) { toolbarService, segmentationService, cornerstoneViewportService, + uiDialogService, + uiModalService, } = servicesManager.services; _activatePanelTriggersSubscriptions.forEach(sub => sub.unsubscribe()); _activatePanelTriggersSubscriptions = []; + uiDialogService.dismissAll(); + uiModalService.hide(); toolGroupService.destroy(); syncGroupService.destroy(); segmentationService.destroy(); @@ -198,8 +202,12 @@ function modeFactory({ modeConfiguration }) { const modalities_list = modalities.split('\\'); // Exclude non-image modalities - return !!modalities_list.filter(modality => NON_IMAGE_MODALITIES.indexOf(modality) === -1) - .length; + return { + valid: !!modalities_list.filter(modality => NON_IMAGE_MODALITIES.indexOf(modality) === -1) + .length, + description: + 'The mode does not support studies that ONLY include the following modalities: SM, ECG, SR, SEG, RTSTRUCT', + }; }, routes: [ { diff --git a/modes/microscopy/src/index.tsx b/modes/microscopy/src/index.tsx index 7165b7cc39c..557ec00d03b 100644 --- a/modes/microscopy/src/index.tsx +++ b/modes/microscopy/src/index.tsx @@ -56,8 +56,10 @@ function modeFactory({ modeConfiguration }) { }, onModeExit: ({ servicesManager }) => { - const { toolbarService } = servicesManager.services; + const { toolbarService, uiDialogService, uiModalService } = servicesManager.services; + uiDialogService.dismissAll(); + uiModalService.hide(); toolbarService.reset(); }, @@ -69,8 +71,10 @@ function modeFactory({ modeConfiguration }) { isValidMode: ({ modalities }) => { const modalities_list = modalities.split('\\'); - // Slide Microscopy and ECG modality not supported by basic mode yet - return modalities_list.includes('SM'); + return { + valid: modalities_list.includes('SM'), + description: 'Microscopy mode only supports the SM modality', + }; }, routes: [ diff --git a/modes/segmentation/src/index.tsx b/modes/segmentation/src/index.tsx index 8b24196f161..57b46c60357 100644 --- a/modes/segmentation/src/index.tsx +++ b/modes/segmentation/src/index.tsx @@ -106,8 +106,12 @@ function modeFactory({ modeConfiguration }) { toolbarService, segmentationService, cornerstoneViewportService, + uiDialogService, + uiModalService, } = servicesManager.services; + uiDialogService.dismissAll(); + uiModalService.hide(); toolGroupService.destroy(); syncGroupService.destroy(); segmentationService.destroy(); @@ -127,11 +131,10 @@ function modeFactory({ modeConfiguration }) { // Don't show the mode if the selected studies have only one modality // that is not supported by the mode const modalitiesArray = modalities.split('\\'); - if (modalitiesArray.length === 1) { - return !['SM', 'US', 'MG', 'OT', 'DOC', 'CR'].includes(modalitiesArray[0]); + return { + valid: modalitiesArray.length === 1 ? !['SM', 'US', 'MG', 'OT', 'DOC', 'CR'].includes(modalitiesArray[0]) : true, + description: 'The mode does not support studies that ONLY include the following modalities: SM, US, MG, OT, DOC, CR', } - - return true; }, /** * Mode Routes are used to define the mode's behavior. A list of Mode Route diff --git a/modes/tmtv/src/index.js b/modes/tmtv/src/index.js index dd57be35e06..b21a375828c 100644 --- a/modes/tmtv/src/index.js +++ b/modes/tmtv/src/index.js @@ -165,9 +165,13 @@ function modeFactory({ modeConfiguration }) { syncGroupService, segmentationService, cornerstoneViewportService, + uiDialogService, + uiModalService, } = servicesManager.services; unsubscriptions.forEach(unsubscribe => unsubscribe()); + uiDialogService.dismissAll(); + uiModalService.hide(); toolGroupService.destroy(); syncGroupService.destroy(); segmentationService.destroy(); @@ -193,7 +197,10 @@ function modeFactory({ modeConfiguration }) { study.studyInstanceUid !== '1.3.6.1.4.1.12842.1.1.14.3.20220915.105557.468.2963630849'; // there should be both CT and PT modalities and the modality should not be SM - return isValid; + return { + valid: isValid, + description: 'The mode requires both PT and CT series in the study', + }; }, routes: [ { diff --git a/platform/app/public/config/default.js b/platform/app/public/config/default.js index 00013529ea8..88f7b872e12 100644 --- a/platform/app/public/config/default.js +++ b/platform/app/public/config/default.js @@ -12,6 +12,7 @@ window.config = { showCPUFallbackMessage: true, showLoadingIndicator: true, strictZSpacingForVolumeViewport: true, + groupEnabledModesFirst: true, maxNumRequests: { interaction: 100, thumbnail: 75, diff --git a/platform/app/src/routes/WorkList/WorkList.tsx b/platform/app/src/routes/WorkList/WorkList.tsx index ae518a29611..50cfccf2961 100644 --- a/platform/app/src/routes/WorkList/WorkList.tsx +++ b/platform/app/src/routes/WorkList/WorkList.tsx @@ -27,6 +27,8 @@ import { UserPreferences, LoadingIndicatorProgress, useSessionStorage, + Button, + ButtonEnums, } from '@ohif/ui'; import i18n from '@ohif/i18n'; @@ -254,11 +256,13 @@ function WorkList({ const studyDate = date && moment(date, ['YYYYMMDD', 'YYYY.MM.DD'], true).isValid() && - moment(date, ['YYYYMMDD', 'YYYY.MM.DD']).format(t('Common:localDateFormat','MMM-DD-YYYY')); + moment(date, ['YYYYMMDD', 'YYYY.MM.DD']).format(t('Common:localDateFormat', 'MMM-DD-YYYY')); const studyTime = time && moment(time, ['HH', 'HHmm', 'HHmmss', 'HHmmss.SSS']).isValid() && - moment(time, ['HH', 'HHmm', 'HHmmss', 'HHmmss.SSS']).format(t('Common:localTimeFormat', 'hh:mm A')); + moment(time, ['HH', 'HHmm', 'HHmmss', 'HHmmss.SSS']).format( + t('Common:localTimeFormat', 'hh:mm A') + ); return { dataCY: `studyRow-${studyInstanceUid}`, @@ -346,10 +350,24 @@ function WorkList({ } >