Files
ohif-viewer/extensions/cornerstone/src/customizations/CustomDropdownMenuContent.tsx
T
Joe Boccanfuso 82e6a18735 fix(segmentation): List surface representations in the segmentation table for 3D views. (#5700)
This was done by using an array of representation types instead of a single type for a panel.
The first element of the array is the primary type of the panel, and the rest are secondary types
that can also be displayed in the panel.

PR feedback:
- added test to check number of segments in side panel for 3D only view
- fixed jumping to segment in 3D only view
- fixed exception when adding contour segment in 3D only view
2026-01-13 15:57:44 -05:00

117 lines
3.9 KiB
TypeScript

import React from 'react';
import {
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuLabel,
DropdownMenuSeparator,
Icons,
useSegmentationTableContext,
useSegmentationExpanded,
} from '@ohif/ui-next';
import { useTranslation } from 'react-i18next';
import { useSystem } from '@ohif/core/src';
import { ExportSegmentationSubMenuItem } from '../components/ExportSegmentationSubMenuItem';
/**
* Custom dropdown menu component for segmentation panel that uses context for data
*/
export const CustomDropdownMenuContent = () => {
const { commandsManager } = useSystem();
const { t } = useTranslation('SegmentationPanel');
const {
onSegmentationAdd,
onSegmentationRemoveFromViewport,
onSegmentationEdit,
onSegmentationDelete,
exportOptions,
activeSegmentation,
activeSegmentationId,
segmentationRepresentationTypes,
disableEditing,
} = useSegmentationTableContext('CustomDropdownMenu');
// Try to get segmentation data from expanded context first, fall back to table context
let segmentation;
let segmentationId;
let allowExport = false;
try {
// Try to get from expanded context
const context = useSegmentationExpanded();
segmentation = context.segmentation;
segmentationId = segmentation.segmentationId;
} catch (e) {
// If not in expanded context, fallback to active segmentation from table context
segmentation = activeSegmentation;
segmentationId = activeSegmentationId;
}
if (!segmentation || !segmentationId) {
return null;
}
// Determine if export is allowed for this segmentation
if (exportOptions) {
const exportOption = exportOptions.find(opt => opt.segmentationId === segmentationId);
allowExport = exportOption?.isExportable || false;
}
const actions = {
storeSegmentation: async (segmentationId, modality = 'SEG') => {
commandsManager.run({
commandName: 'storeSegmentation',
commandOptions: { segmentationId, modality },
context: 'CORNERSTONE',
});
},
onSegmentationDownloadRTSS: segmentationId => {
commandsManager.run('downloadRTSS', { segmentationId });
},
onSegmentationDownload: segmentationId => {
commandsManager.run('downloadSegmentation', { segmentationId });
},
downloadCSVSegmentationReport: segmentationId => {
commandsManager.run('downloadCSVSegmentationReport', { segmentationId });
},
};
return (
<DropdownMenuContent align="start">
{!disableEditing && (
<DropdownMenuItem
onClick={() =>
onSegmentationAdd({
segmentationId,
segmentationRepresentationType: segmentationRepresentationTypes?.[0],
})
}
>
<Icons.Add className="text-foreground" />
<span className="pl-2">{t('Create New Segmentation')}</span>
</DropdownMenuItem>
)}
<DropdownMenuSeparator />
<DropdownMenuLabel>{t('Manage Current Segmentation')}</DropdownMenuLabel>
<DropdownMenuItem onClick={() => onSegmentationRemoveFromViewport(segmentationId)}>
<Icons.Series className="text-foreground" />
<span className="pl-2">{t('Remove from Viewport')}</span>
</DropdownMenuItem>
<DropdownMenuItem onClick={() => onSegmentationEdit(segmentationId)}>
<Icons.Rename className="text-foreground" />
<span className="pl-2">{t('Rename')}</span>
</DropdownMenuItem>
<ExportSegmentationSubMenuItem
segmentationId={segmentationId}
segmentationRepresentationType={segmentationRepresentationTypes?.[0]}
allowExport={allowExport}
actions={actions}
/>
<DropdownMenuSeparator />
<DropdownMenuItem onClick={() => onSegmentationDelete(segmentationId)}>
<Icons.Delete className="text-red-600" />
<span className="pl-2 text-red-600">{t('Delete')}</span>
</DropdownMenuItem>
</DropdownMenuContent>
);
};