Merge branch 'IbrahimCSAE-feat/interactive-onboarding-guides'

This commit is contained in:
Ibrahim committed 2024-10-04 12:53:33 -04:00
commit 579a592812
20 files changed
+846 -4

No files matched your search

+2
View File
@@ -98,6 +98,8 @@
"react-resize-detector": "^10.0.1",
"react-router": "^6.23.1",
"react-router-dom": "^6.8.1",
"react-shepherd": "^6.1.1",
"shepherd.js": "^13.0.3",
"url-loader": "^4.1.1"
},
"devDependencies": {
+208
View File
@@ -291,4 +291,212 @@ window.config = {
keys: ['9'],
},
],
tours: [
{
id: 'basicViewerTour',
route: '/viewer',
steps: [
{
id: 'scroll',
title: 'Scrolling Through Images',
text: 'You can scroll through the images using the mouse wheel or scrollbar.',
attachTo: {
element: '.viewport-element',
on: 'top',
},
advanceOn: {
selector: '.cornerstone-viewport-element',
event: 'CORNERSTONE_TOOLS_MOUSE_WHEEL',
},
beforeShowPromise: () => waitForElement('.viewport-element'),
},
{
id: 'zoom',
title: 'Zooming In and Out',
text: 'You can zoom the images using the right click.',
attachTo: {
element: '.viewport-element',
on: 'left',
},
advanceOn: {
selector: '.cornerstone-viewport-element',
event: 'CORNERSTONE_TOOLS_MOUSE_UP',
},
beforeShowPromise: () => waitForElement('.viewport-element'),
},
{
id: 'pan',
title: 'Panning the Image',
text: 'You can pan the images using the middle click.',
attachTo: {
element: '.viewport-element',
on: 'top',
},
advanceOn: {
selector: '.cornerstone-viewport-element',
event: 'CORNERSTONE_TOOLS_MOUSE_UP',
},
beforeShowPromise: () => waitForElement('.viewport-element'),
},
{
id: 'windowing',
title: 'Adjusting Window Level',
text: 'You can modify the window level using the left click.',
attachTo: {
element: '.viewport-element',
on: 'left',
},
advanceOn: {
selector: '.cornerstone-viewport-element',
event: 'CORNERSTONE_TOOLS_MOUSE_UP',
},
beforeShowPromise: () => waitForElement('.viewport-element'),
},
{
id: 'length',
title: 'Using the Measurement Tools',
text: 'You can measure the length of a region using the Length tool.',
attachTo: {
element: '[data-cy="MeasurementTools-split-button-primary"]',
on: 'bottom',
},
advanceOn: {
selector: '[data-cy="MeasurementTools-split-button-primary"]',
event: 'click',
},
beforeShowPromise: () =>
waitForElement('[data-cy="MeasurementTools-split-button-primary]'),
},
{
id: 'drawAnnotation',
title: 'Drawing Length Annotations',
text: 'Use the length tool on the viewport to measure the length of a region.',
attachTo: {
element: '.viewport-element',
on: 'right',
},
advanceOn: {
selector: 'body',
event: 'event::measurement_added',
},
beforeShowPromise: () => waitForElement('.viewport-element'),
},
{
id: 'trackMeasurement',
title: 'Tracking Measurements in the Panel',
text: 'Click yes to track the measurements in the measurement panel.',
attachTo: {
element: '[data-cy="prompt-begin-tracking-yes-btn"]',
on: 'bottom',
},
advanceOn: {
selector: '[data-cy="prompt-begin-tracking-yes-btn"]',
event: 'click',
},
beforeShowPromise: () => waitForElement('[data-cy="prompt-begin-tracking-yes-btn"]'),
},
{
id: 'openMeasurementPanel',
title: 'Opening the Measurements Panel',
text: 'Click the measurements button to open the measurements panel.',
attachTo: {
element: '#trackedMeasurements-btn',
on: 'left-start',
},
advanceOn: {
selector: '#trackedMeasurements-btn',
event: 'click',
},
beforeShowPromise: () => waitForElement('#trackedMeasurements-btn'),
},
{
id: 'scrollAwayFromMeasurement',
title: 'Scrolling Away from a Measurement',
text: 'Scroll the images using the mouse wheel away from the measurement.',
attachTo: {
element: '.viewport-element',
on: 'left',
},
advanceOn: {
selector: '.cornerstone-viewport-element',
event: 'CORNERSTONE_TOOLS_MOUSE_WHEEL',
},
beforeShowPromise: () => waitForElement('.viewport-element'),
},
{
id: 'jumpToMeasurement',
title: 'Jumping to Measurements in the Panel',
text: 'Click the measurement in the measurement panel to jump to it.',
attachTo: {
element: '[data-cy="measurement-item"]',
on: 'left-start',
},
advanceOn: {
selector: '[data-cy="measurement-item"]',
event: 'click',
},
beforeShowPromise: () => waitForElement('[data-cy="measurement-item"]'),
},
{
id: 'changeLayout',
title: 'Changing Layout',
text: 'You can change the layout of the viewer using the layout button.',
attachTo: {
element: '[data-cy="Layout"]',
on: 'bottom',
},
advanceOn: {
selector: '[data-cy="Layout"]',
event: 'click',
},
beforeShowPromise: () => waitForElement('[data-cy="Layout"]'),
},
{
id: 'selectLayout',
title: 'Selecting the MPR Layout',
text: 'Select the MPR layout to view the images in MPR mode.',
attachTo: {
element: '[data-cy="MPR"]',
on: 'left-start',
},
advanceOn: {
selector: '[data-cy="MPR"]',
event: 'click',
},
beforeShowPromise: () => waitForElement('[data-cy="MPR"]'),
},
],
tourOptions: {
useModalOverlay: true,
defaultStepOptions: {
buttons: [
{
text: 'Skip all',
action() {
this.complete();
},
secondary: true,
},
],
},
},
},
],
};
function waitForElement(selector, maxAttempts = 20, interval = 25) {
return new Promise(resolve => {
let attempts = 0;
const checkForElement = setInterval(() => {
const element = document.querySelector(selector);
if (element || attempts >= maxAttempts) {
clearInterval(checkForElement);
resolve();
}
attempts++;
}, interval);
});
}
+208
View File
@@ -247,4 +247,212 @@ window.config = {
keys: ['9'],
},
],
tours: [
{
id: 'basicViewerTour',
route: '/viewer',
steps: [
{
id: 'scroll',
title: 'Scrolling Through Images',
text: 'You can scroll through the images using the mouse wheel or scrollbar.',
attachTo: {
element: '.viewport-element',
on: 'top',
},
advanceOn: {
selector: '.cornerstone-viewport-element',
event: 'CORNERSTONE_TOOLS_MOUSE_WHEEL',
},
beforeShowPromise: () => waitForElement('.viewport-element'),
},
{
id: 'zoom',
title: 'Zooming In and Out',
text: 'You can zoom the images using the right click.',
attachTo: {
element: '.viewport-element',
on: 'left',
},
advanceOn: {
selector: '.cornerstone-viewport-element',
event: 'CORNERSTONE_TOOLS_MOUSE_UP',
},
beforeShowPromise: () => waitForElement('.viewport-element'),
},
{
id: 'pan',
title: 'Panning the Image',
text: 'You can pan the images using the middle click.',
attachTo: {
element: '.viewport-element',
on: 'top',
},
advanceOn: {
selector: '.cornerstone-viewport-element',
event: 'CORNERSTONE_TOOLS_MOUSE_UP',
},
beforeShowPromise: () => waitForElement('.viewport-element'),
},
{
id: 'windowing',
title: 'Adjusting Window Level',
text: 'You can modify the window level using the left click.',
attachTo: {
element: '.viewport-element',
on: 'left',
},
advanceOn: {
selector: '.cornerstone-viewport-element',
event: 'CORNERSTONE_TOOLS_MOUSE_UP',
},
beforeShowPromise: () => waitForElement('.viewport-element'),
},
{
id: 'length',
title: 'Using the Measurement Tools',
text: 'You can measure the length of a region using the Length tool.',
attachTo: {
element: '[data-cy="MeasurementTools-split-button-primary"]',
on: 'bottom',
},
advanceOn: {
selector: '[data-cy="MeasurementTools-split-button-primary"]',
event: 'click',
},
beforeShowPromise: () =>
waitForElement('[data-cy="MeasurementTools-split-button-primary]'),
},
{
id: 'drawAnnotation',
title: 'Drawing Length Annotations',
text: 'Use the length tool on the viewport to measure the length of a region.',
attachTo: {
element: '.viewport-element',
on: 'right',
},
advanceOn: {
selector: 'body',
event: 'event::measurement_added',
},
beforeShowPromise: () => waitForElement('.viewport-element'),
},
{
id: 'trackMeasurement',
title: 'Tracking Measurements in the Panel',
text: 'Click yes to track the measurements in the measurement panel.',
attachTo: {
element: '[data-cy="prompt-begin-tracking-yes-btn"]',
on: 'bottom',
},
advanceOn: {
selector: '[data-cy="prompt-begin-tracking-yes-btn"]',
event: 'click',
},
beforeShowPromise: () => waitForElement('[data-cy="prompt-begin-tracking-yes-btn"]'),
},
{
id: 'openMeasurementPanel',
title: 'Opening the Measurements Panel',
text: 'Click the measurements button to open the measurements panel.',
attachTo: {
element: '#trackedMeasurements-btn',
on: 'left-start',
},
advanceOn: {
selector: '#trackedMeasurements-btn',
event: 'click',
},
beforeShowPromise: () => waitForElement('#trackedMeasurements-btn'),
},
{
id: 'scrollAwayFromMeasurement',
title: 'Scrolling Away from a Measurement',
text: 'Scroll the images using the mouse wheel away from the measurement.',
attachTo: {
element: '.viewport-element',
on: 'left',
},
advanceOn: {
selector: '.cornerstone-viewport-element',
event: 'CORNERSTONE_TOOLS_MOUSE_WHEEL',
},
beforeShowPromise: () => waitForElement('.viewport-element'),
},
{
id: 'jumpToMeasurement',
title: 'Jumping to Measurements in the Panel',
text: 'Click the measurement in the measurement panel to jump to it.',
attachTo: {
element: '[data-cy="measurement-item"]',
on: 'left-start',
},
advanceOn: {
selector: '[data-cy="measurement-item"]',
event: 'click',
},
beforeShowPromise: () => waitForElement('[data-cy="measurement-item"]'),
},
{
id: 'changeLayout',
title: 'Changing Layout',
text: 'You can change the layout of the viewer using the layout button.',
attachTo: {
element: '[data-cy="Layout"]',
on: 'bottom',
},
advanceOn: {
selector: '[data-cy="Layout"]',
event: 'click',
},
beforeShowPromise: () => waitForElement('[data-cy="Layout"]'),
},
{
id: 'selectLayout',
title: 'Selecting the MPR Layout',
text: 'Select the MPR layout to view the images in MPR mode.',
attachTo: {
element: '[data-cy="MPR"]',
on: 'left-start',
},
advanceOn: {
selector: '[data-cy="MPR"]',
event: 'click',
},
beforeShowPromise: () => waitForElement('[data-cy="MPR"]'),
},
],
tourOptions: {
useModalOverlay: true,
defaultStepOptions: {
buttons: [
{
text: 'Skip all',
action() {
this.complete();
},
secondary: true,
},
],
},
},
},
],
};
function waitForElement(selector, maxAttempts = 20, interval = 25) {
return new Promise(resolve => {
let attempts = 0;
const checkForElement = setInterval(() => {
const element = document.querySelector(selector);
if (element || attempts >= maxAttempts) {
clearInterval(checkForElement);
resolve();
}
attempts++;
}, interval);
});
}
+2
View File
@@ -31,6 +31,7 @@ import { AppConfigProvider } from '@state';
import createRoutes from './routes';
import appInit from './appInit.js';
import OpenIdConnectRoutes from './utils/OpenIdConnectRoutes';
import { ShepherdJourneyProvider } from 'react-shepherd';
let commandsManager: CommandsManager,
extensionManager: ExtensionManager,
@@ -115,6 +116,7 @@ function App({
[SnackbarProvider, { service: uiNotificationService }],
[DialogProvider, { service: uiDialogService }],
[ModalProvider, { service: uiModalService, modal: Modal }],
[ShepherdJourneyProvider],
];
// Loop through and register each of the service providers registered with the ServiceProvidersManager.
@@ -34,6 +34,7 @@ import {
import { Types } from '@ohif/ui';
import i18n from '@ohif/i18n';
import { Onboarding } from '@ohif/ui-next';
const PatientInfoVisibility = Types.PatientInfoVisibility;
@@ -411,7 +412,7 @@ function WorkList({
disabled={!isValidMode}
startIconTooltip={
!isValidMode ? (
<div className="font-inter flex w-[206px] whitespace-normal text-left text-xs font-normal text-white ">
<div className="font-inter flex w-[206px] whitespace-normal text-left text-xs font-normal text-white">
{invalidModeDescription}
</div>
) : null
@@ -534,6 +535,7 @@ function WorkList({
WhiteLabeling={appConfig.whiteLabeling}
showPatientInfo={PatientInfoVisibility.DISABLED}
/>
<Onboarding />
<InvestigationalUseDialog dialogConfiguration={appConfig?.investigationalUseDialog} />
<div className="ohif-scrollbar ohif-scrollbar-stable-gutter flex grow flex-col overflow-y-auto sm:px-5">
<StudyListFilter