feat: add customization to PanelStudyBrowser dbl click callback (#4871)

This commit is contained in:
Pedro Köhler 2025-03-20 13:06:26 -03:00 committed by GitHub
parent f73c485821
commit 01c3726ced
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 154 additions and 27 deletions

View File

@ -1,4 +1,4 @@
import React, { useState, useEffect } from 'react'; import React, { useState, useEffect, useCallback } from 'react';
import { useImageViewer } from '@ohif/ui'; import { useImageViewer } from '@ohif/ui';
import { useViewportGrid } from '@ohif/ui-next'; import { useViewportGrid } from '@ohif/ui-next';
import { StudyBrowser } from '@ohif/ui-next'; import { StudyBrowser } from '@ohif/ui-next';
@ -8,6 +8,7 @@ import { Separator } from '@ohif/ui-next';
import { PanelStudyBrowserHeader } from './PanelStudyBrowserHeader'; import { PanelStudyBrowserHeader } from './PanelStudyBrowserHeader';
import { defaultActionIcons } from './constants'; import { defaultActionIcons } from './constants';
import MoreDropdownMenu from '../../Components/MoreDropdownMenu'; import MoreDropdownMenu from '../../Components/MoreDropdownMenu';
import { CallbackCustomization } from 'platform/core/src/types';
const { sortStudyInstances, formatDate, createStudyBrowserTabs } = utils; const { sortStudyInstances, formatDate, createStudyBrowserTabs } = utils;
@ -22,16 +23,14 @@ function PanelStudyBrowser({
dataSource, dataSource,
}) { }) {
const { servicesManager, commandsManager } = useSystem(); const { servicesManager, commandsManager } = useSystem();
const { hangingProtocolService, displaySetService, uiNotificationService, customizationService } = const { displaySetService, customizationService } = servicesManager.services;
servicesManager.services;
const navigate = useNavigate(); const navigate = useNavigate();
// Normally you nest the components so the tree isn't so deep, and the data // Normally you nest the components so the tree isn't so deep, and the data
// doesn't have to have such an intense shape. This works well enough for now. // doesn't have to have such an intense shape. This works well enough for now.
// Tabs --> Studies --> DisplaySets --> Thumbnails // Tabs --> Studies --> DisplaySets --> Thumbnails
const { StudyInstanceUIDs } = useImageViewer(); const { StudyInstanceUIDs } = useImageViewer();
const [{ activeViewportId, viewports, isHangingProtocolLayout }, viewportGridService] = const [{ activeViewportId, viewports, isHangingProtocolLayout }] = useViewportGrid();
useViewportGrid();
const [activeTabName, setActiveTabName] = useState('all'); const [activeTabName, setActiveTabName] = useState('all');
const [expandedStudyInstanceUIDs, setExpandedStudyInstanceUIDs] = useState([ const [expandedStudyInstanceUIDs, setExpandedStudyInstanceUIDs] = useState([
...StudyInstanceUIDs, ...StudyInstanceUIDs,
@ -66,27 +65,33 @@ function PanelStudyBrowser({
setViewPresets(newViewPresets); setViewPresets(newViewPresets);
}; };
const onDoubleClickThumbnailHandler = displaySetInstanceUID => { const onDoubleClickThumbnailHandler = useCallback(
let updatedViewports = []; async displaySetInstanceUID => {
const viewportId = activeViewportId; const customHandler = customizationService.getCustomization(
try { 'studyBrowser.thumbnailDoubleClickCallback'
updatedViewports = hangingProtocolService.getViewportsRequireUpdate( ) as CallbackCustomization;
viewportId,
displaySetInstanceUID,
isHangingProtocolLayout
);
} catch (error) {
console.warn(error);
uiNotificationService.show({
title: 'Thumbnail Double Click',
message: 'The selected display sets could not be added to the viewport.',
type: 'error',
duration: 3000,
});
}
viewportGridService.setDisplaySetsForViewports(updatedViewports); const setupArgs = {
}; activeViewportId,
commandsManager,
servicesManager,
isHangingProtocolLayout,
};
const handlers = customHandler?.callbacks.map(callback => callback(setupArgs));
for (const handler of handlers) {
await handler(displaySetInstanceUID);
}
},
[
activeViewportId,
commandsManager,
servicesManager,
isHangingProtocolLayout,
customizationService,
]
);
// ~~ studyDisplayList // ~~ studyDisplayList
useEffect(() => { useEffect(() => {
@ -163,7 +168,7 @@ function PanelStudyBrowser({
thumbnailSrc = await displaySet.getThumbnailSrc(); thumbnailSrc = await displaySet.getThumbnailSrc();
} }
if (!thumbnailSrc) { if (!thumbnailSrc) {
let thumbnailSrc = await getImageSrc(imageId); const thumbnailSrc = await getImageSrc(imageId);
displaySet.thumbnailSrc = thumbnailSrc; displaySet.thumbnailSrc = thumbnailSrc;
} }
newImageSrcEntry[dSet.displaySetInstanceUID] = thumbnailSrc; newImageSrcEntry[dSet.displaySetInstanceUID] = thumbnailSrc;

View File

@ -44,4 +44,33 @@ export default {
}, },
], ],
'studyBrowser.studyMode': 'all', 'studyBrowser.studyMode': 'all',
'studyBrowser.thumbnailDoubleClickCallback': {
callbacks: [
({ activeViewportId, servicesManager, isHangingProtocolLayout }) =>
async displaySetInstanceUID => {
const { hangingProtocolService, viewportGridService, uiNotificationService } =
servicesManager.services;
let updatedViewports = [];
const viewportId = activeViewportId;
try {
updatedViewports = hangingProtocolService.getViewportsRequireUpdate(
viewportId,
displaySetInstanceUID,
isHangingProtocolLayout
);
} catch (error) {
console.warn(error);
uiNotificationService.show({
title: 'Thumbnail Double Click',
message: 'The selected display sets could not be added to the viewport.',
type: 'error',
duration: 3000,
});
}
viewportGridService.setDisplaySetsForViewports(updatedViewports);
},
],
},
}; };

View File

@ -27,13 +27,18 @@ export interface ComponentCustomization extends BaseCustomization {
content: (...props: any) => React.JSX.Element; content: (...props: any) => React.JSX.Element;
} }
export interface CallbackCustomization extends BaseCustomization {
callbacks: Array<(...props: any) => any>;
}
export type Customization = export type Customization =
| React.ComponentType | React.ComponentType
| BaseCustomization | BaseCustomization
| LabelCustomization | LabelCustomization
| CommandCustomization | CommandCustomization
| CodeCustomization | CodeCustomization
| ComponentCustomization; | ComponentCustomization
| CallbackCustomization;
export default Customization; export default Customization;

View File

@ -1476,6 +1476,94 @@ window.config = {
}, },
}, },
], ],
};
`,
},
{
id: 'studyBrowser.thumbnailDoubleClickCallback',
description:
'Defines the callback function for when the user double clicks a series on the study browser.',
default: `{
callback: ({
activeViewportId,
servicesManager,
isHangingProtocolLayout
}) =>
async displaySetInstanceUID => {
const {
hangingProtocolService,
viewportGridService,
uiNotificationService
} =
servicesManager.services;
let updatedViewports = [];
const viewportId = activeViewportId;
try {
updatedViewports = hangingProtocolService.getViewportsRequireUpdate(
viewportId,
displaySetInstanceUID,
isHangingProtocolLayout
);
} catch (error) {
console.warn(error);
uiNotificationService.show({
title: 'Thumbnail Double Click',
message: 'The selected display sets could not be added to the viewport.',
type: 'error',
duration: 3000,
});
}
viewportGridService.setDisplaySetsForViewports(updatedViewports);
},
}`,
configuration: `
window.config = {
// rest of window config
customizationService: [{
'studyBrowser.thumbnailDoubleClickCallback': {
callback: ({
activeViewportId,
commandsManager,
servicesManager,
isHangingProtocolLayout
}) =>
async displaySetInstanceUID => {
const {
hangingProtocolService,
viewportGridService,
uiNotificationService
} =
servicesManager.services;
let updatedViewports = [];
const viewportId = activeViewportId;
// Changing original function here:
if (isBlacklistedModality(displaySetInstanceUID)) {
return;
}
try {
updatedViewports = hangingProtocolService.getViewportsRequireUpdate(
viewportId,
displaySetInstanceUID,
isHangingProtocolLayout
);
} catch (error) {
console.warn(error);
uiNotificationService.show({
title: 'Thumbnail Double Click',
message: 'The selected display sets could not be added to the viewport.',
type: 'error',
duration: 3000,
});
}
viewportGridService.setDisplaySetsForViewports(updatedViewports);
};
},
}],
}; };
`, `,
}, },