feat(segmentation): Enhance dropdown menu functionality in SegmentationTable (#4553)
This commit is contained in:
parent
144ec791a2
commit
397fd85653
@ -1,5 +1,16 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { SegmentationTable } from '@ohif/ui-next';
|
import {
|
||||||
|
DropdownMenuLabel,
|
||||||
|
DropdownMenuContent,
|
||||||
|
DropdownMenuItem,
|
||||||
|
DropdownMenuPortal,
|
||||||
|
DropdownMenuSeparator,
|
||||||
|
DropdownMenuSub,
|
||||||
|
DropdownMenuSubContent,
|
||||||
|
Icons,
|
||||||
|
SegmentationTable,
|
||||||
|
DropdownMenuSubTrigger,
|
||||||
|
} from '@ohif/ui-next';
|
||||||
import { useActiveViewportSegmentationRepresentations } from '../hooks/useActiveViewportSegmentationRepresentations';
|
import { useActiveViewportSegmentationRepresentations } from '../hooks/useActiveViewportSegmentationRepresentations';
|
||||||
import { metaData } from '@cornerstonejs/core';
|
import { metaData } from '@cornerstonejs/core';
|
||||||
|
|
||||||
@ -147,6 +158,66 @@ export default function PanelSegmentation({
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const CustomDropdownMenuContent = customizationService.getCustomComponent(
|
||||||
|
'PanelSegmentation.CustomDropdownMenuContent',
|
||||||
|
({
|
||||||
|
activeSegmentation,
|
||||||
|
onSegmentationAdd,
|
||||||
|
onSegmentationRemoveFromViewport,
|
||||||
|
onSegmentationEdit,
|
||||||
|
onSegmentationDelete,
|
||||||
|
allowExport,
|
||||||
|
storeSegmentation,
|
||||||
|
onSegmentationDownload,
|
||||||
|
onSegmentationDownloadRTSS,
|
||||||
|
t,
|
||||||
|
}) => (
|
||||||
|
<DropdownMenuContent align="start">
|
||||||
|
<DropdownMenuItem onClick={() => onSegmentationAdd(activeSegmentation.id)}>
|
||||||
|
<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(activeSegmentation.id)}>
|
||||||
|
<Icons.Series className="text-foreground" />
|
||||||
|
<span className="pl-2">{t('Remove from Viewport')}</span>
|
||||||
|
</DropdownMenuItem>
|
||||||
|
<DropdownMenuItem onClick={() => onSegmentationEdit(activeSegmentation.id)}>
|
||||||
|
<Icons.Rename className="text-foreground" />
|
||||||
|
<span className="pl-2">{t('Rename')}</span>
|
||||||
|
</DropdownMenuItem>
|
||||||
|
<DropdownMenuSub>
|
||||||
|
<DropdownMenuSubTrigger
|
||||||
|
disabled={!allowExport}
|
||||||
|
className="pl-1"
|
||||||
|
>
|
||||||
|
<Icons.Export className="text-foreground" />
|
||||||
|
<span className="pl-2">{t('Export & Download')}</span>
|
||||||
|
</DropdownMenuSubTrigger>
|
||||||
|
<DropdownMenuPortal>
|
||||||
|
<DropdownMenuSubContent>
|
||||||
|
<DropdownMenuItem onClick={() => storeSegmentation(activeSegmentation.id)}>
|
||||||
|
{t('Export DICOM SEG')}
|
||||||
|
</DropdownMenuItem>
|
||||||
|
<DropdownMenuItem onClick={() => onSegmentationDownload(activeSegmentation.id)}>
|
||||||
|
{t('Download DICOM SEG')}
|
||||||
|
</DropdownMenuItem>
|
||||||
|
<DropdownMenuItem onClick={() => onSegmentationDownloadRTSS(activeSegmentation.id)}>
|
||||||
|
{t('Download DICOM RTSTRUCT')}
|
||||||
|
</DropdownMenuItem>
|
||||||
|
</DropdownMenuSubContent>
|
||||||
|
</DropdownMenuPortal>
|
||||||
|
</DropdownMenuSub>
|
||||||
|
<DropdownMenuSeparator />
|
||||||
|
<DropdownMenuItem onClick={() => onSegmentationDelete(activeSegmentation.id)}>
|
||||||
|
<Icons.Delete className="text-red-600" />
|
||||||
|
<span className="pl-2 text-red-600">{t('Delete')}</span>
|
||||||
|
</DropdownMenuItem>
|
||||||
|
</DropdownMenuContent>
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
const exportOptions = segmentationsWithRepresentations.map(({ segmentation }) => {
|
const exportOptions = segmentationsWithRepresentations.map(({ segmentation }) => {
|
||||||
const { representationData, segmentationId } = segmentation;
|
const { representationData, segmentationId } = segmentation;
|
||||||
const { Labelmap } = representationData;
|
const { Labelmap } = representationData;
|
||||||
@ -219,13 +290,17 @@ export default function PanelSegmentation({
|
|||||||
|
|
||||||
{SegmentationTableMode === 'collapsed' ? (
|
{SegmentationTableMode === 'collapsed' ? (
|
||||||
<SegmentationTable.Collapsed>
|
<SegmentationTable.Collapsed>
|
||||||
<SegmentationTable.SelectorHeader />
|
<SegmentationTable.SelectorHeader>
|
||||||
|
<CustomDropdownMenuContent />
|
||||||
|
</SegmentationTable.SelectorHeader>
|
||||||
<SegmentationTable.AddSegmentRow />
|
<SegmentationTable.AddSegmentRow />
|
||||||
<SegmentationTable.Segments />
|
<SegmentationTable.Segments />
|
||||||
</SegmentationTable.Collapsed>
|
</SegmentationTable.Collapsed>
|
||||||
) : (
|
) : (
|
||||||
<SegmentationTable.Expanded>
|
<SegmentationTable.Expanded>
|
||||||
<SegmentationTable.Header />
|
<SegmentationTable.Header>
|
||||||
|
<CustomDropdownMenuContent />
|
||||||
|
</SegmentationTable.Header>
|
||||||
{/* <SegmentationTable.AddSegmentRow /> */}
|
{/* <SegmentationTable.AddSegmentRow /> */}
|
||||||
<SegmentationTable.Segments />
|
<SegmentationTable.Segments />
|
||||||
</SegmentationTable.Expanded>
|
</SegmentationTable.Expanded>
|
||||||
|
|||||||
@ -124,6 +124,14 @@ const commandsModule = ({
|
|||||||
* @param options.stageId - the stageId to apply
|
* @param options.stageId - the stageId to apply
|
||||||
* @param options.stageIndex - the index of the stage to go to.
|
* @param options.stageIndex - the index of the stage to go to.
|
||||||
* @param options.reset - flag to indicate if the HP should be reset to its original and not restored to a previous state
|
* @param options.reset - flag to indicate if the HP should be reset to its original and not restored to a previous state
|
||||||
|
*
|
||||||
|
* commandsManager.run('setHangingProtocol', {
|
||||||
|
* activeStudyUID: '1.2.3',
|
||||||
|
* protocolId: 'myProtocol',
|
||||||
|
* stageId: 'myStage',
|
||||||
|
* stageIndex: 0,
|
||||||
|
* reset: false,
|
||||||
|
* });
|
||||||
*/
|
*/
|
||||||
setHangingProtocol: ({
|
setHangingProtocol: ({
|
||||||
activeStudyUID = '',
|
activeStudyUID = '',
|
||||||
|
|||||||
@ -1,3 +1,16 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import {
|
||||||
|
DropdownMenuContent,
|
||||||
|
DropdownMenuItem,
|
||||||
|
DropdownMenuSeparator,
|
||||||
|
DropdownMenuSub,
|
||||||
|
DropdownMenuSubContent,
|
||||||
|
DropdownMenuSubTrigger,
|
||||||
|
DropdownMenuPortal,
|
||||||
|
DropdownMenuLabel,
|
||||||
|
Icons,
|
||||||
|
} from '@ohif/ui-next';
|
||||||
|
|
||||||
export const performCustomizations = customizationService => {
|
export const performCustomizations = customizationService => {
|
||||||
// Set the custom SegmentationTable
|
// Set the custom SegmentationTable
|
||||||
customizationService.addModeCustomizations([
|
customizationService.addModeCustomizations([
|
||||||
@ -22,5 +35,30 @@ export const performCustomizations = customizationService => {
|
|||||||
// { value: 'Toe', label: 'Toe' },
|
// { value: 'Toe', label: 'Toe' },
|
||||||
// ],
|
// ],
|
||||||
// },
|
// },
|
||||||
|
/**
|
||||||
|
* Custom Dropdown Menu Item
|
||||||
|
*/
|
||||||
|
// {
|
||||||
|
// id: 'PanelSegmentation.CustomDropdownMenuContent',
|
||||||
|
// content: ({
|
||||||
|
// activeSegmentation,
|
||||||
|
// onSegmentationAdd,
|
||||||
|
// onSegmentationRemoveFromViewport,
|
||||||
|
// onSegmentationEdit,
|
||||||
|
// onSegmentationDelete,
|
||||||
|
// allowExport,
|
||||||
|
// storeSegmentation,
|
||||||
|
// onSegmentationDownload,
|
||||||
|
// onSegmentationDownloadRTSS,
|
||||||
|
// t,
|
||||||
|
// }) => (
|
||||||
|
// <DropdownMenuContent align="start">
|
||||||
|
// <DropdownMenuItem onClick={() => onSegmentationDelete(activeSegmentation.id)}>
|
||||||
|
// <Icons.Delete className="text-red-600" />
|
||||||
|
// <span className="pl-2 text-red-600">{t('My Custom Dropdown Menu Item')}</span>
|
||||||
|
// </DropdownMenuItem>
|
||||||
|
// </DropdownMenuContent>
|
||||||
|
// ),
|
||||||
|
// },
|
||||||
]);
|
]);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -26,10 +26,7 @@ export const SegmentationExpanded: React.FC<{ children?: React.ReactNode }> = ({
|
|||||||
representation: segmentationInfo.representation,
|
representation: segmentationInfo.representation,
|
||||||
})
|
})
|
||||||
) : (
|
) : (
|
||||||
<SegmentationHeader
|
<SegmentationHeader segmentation={segmentationInfo.segmentation} />
|
||||||
segmentation={segmentationInfo.segmentation}
|
|
||||||
representation={segmentationInfo.representation}
|
|
||||||
/>
|
|
||||||
)}
|
)}
|
||||||
</PanelSection.Header>
|
</PanelSection.Header>
|
||||||
<PanelSection.Content>
|
<PanelSection.Content>
|
||||||
@ -38,7 +35,6 @@ export const SegmentationExpanded: React.FC<{ children?: React.ReactNode }> = ({
|
|||||||
React.isValidElement(child)
|
React.isValidElement(child)
|
||||||
? React.cloneElement(child, {
|
? React.cloneElement(child, {
|
||||||
segmentation: segmentationInfo.segmentation,
|
segmentation: segmentationInfo.segmentation,
|
||||||
representation: segmentationInfo.representation,
|
|
||||||
})
|
})
|
||||||
: child
|
: child
|
||||||
)}
|
)}
|
||||||
|
|||||||
@ -1,39 +1,31 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Button } from '../Button';
|
import { Button } from '../Button';
|
||||||
import { Icons } from '../Icons/Icons';
|
import { Icons } from '../Icons/Icons';
|
||||||
import {
|
import { DropdownMenu, DropdownMenuTrigger } from '../DropdownMenu';
|
||||||
DropdownMenu,
|
|
||||||
DropdownMenuTrigger,
|
|
||||||
DropdownMenuContent,
|
|
||||||
DropdownMenuItem,
|
|
||||||
DropdownMenuSeparator,
|
|
||||||
DropdownMenuSub,
|
|
||||||
DropdownMenuSubTrigger,
|
|
||||||
DropdownMenuSubContent,
|
|
||||||
DropdownMenuPortal,
|
|
||||||
} from '../DropdownMenu';
|
|
||||||
import { Tooltip, TooltipTrigger, TooltipContent } from '../Tooltip/Tooltip';
|
import { Tooltip, TooltipTrigger, TooltipContent } from '../Tooltip/Tooltip';
|
||||||
import { useSegmentationTableContext } from './SegmentationTableContext';
|
import { useSegmentationTableContext } from './SegmentationTableContext';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
export const SegmentationHeader: React.FC<{
|
export const SegmentationHeader: React.FC<{
|
||||||
|
children?: React.ReactNode;
|
||||||
segmentation?: any;
|
segmentation?: any;
|
||||||
}> = ({ segmentation }) => {
|
}> = ({ children, segmentation }) => {
|
||||||
const { t } = useTranslation('SegmentationTable');
|
const { t } = useTranslation('SegmentationTable');
|
||||||
const {
|
const { ...contextProps } = useSegmentationTableContext('SegmentationHeader');
|
||||||
onSegmentAdd,
|
|
||||||
onSegmentationRemoveFromViewport,
|
|
||||||
onSegmentationEdit,
|
|
||||||
onSegmentationDelete,
|
|
||||||
onSegmentationDownload,
|
|
||||||
onSegmentationDownloadRTSS,
|
|
||||||
storeSegmentation,
|
|
||||||
} = useSegmentationTableContext('SegmentationHeader');
|
|
||||||
|
|
||||||
if (!segmentation) {
|
if (!segmentation) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const childrenWithProps = React.Children.map(children, child =>
|
||||||
|
React.isValidElement(child)
|
||||||
|
? React.cloneElement(child, {
|
||||||
|
t,
|
||||||
|
...contextProps,
|
||||||
|
})
|
||||||
|
: child
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="text-foreground flex h-8 w-full items-center justify-between">
|
<div className="text-foreground flex h-8 w-full items-center justify-between">
|
||||||
<div className="flex items-center space-x-1">
|
<div className="flex items-center space-x-1">
|
||||||
@ -48,79 +40,7 @@ export const SegmentationHeader: React.FC<{
|
|||||||
<Icons.More />
|
<Icons.More />
|
||||||
</Button>
|
</Button>
|
||||||
</DropdownMenuTrigger>
|
</DropdownMenuTrigger>
|
||||||
<DropdownMenuContent align="start">
|
{childrenWithProps}
|
||||||
<DropdownMenuItem
|
|
||||||
onClick={e => {
|
|
||||||
e.stopPropagation();
|
|
||||||
onSegmentAdd(segmentation.segmentationId);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Icons.Add className="text-foreground" />
|
|
||||||
<span className="pl-2">{t('Add Segment')}</span>
|
|
||||||
</DropdownMenuItem>
|
|
||||||
<DropdownMenuSeparator />
|
|
||||||
<DropdownMenuItem
|
|
||||||
onClick={e => {
|
|
||||||
e.stopPropagation();
|
|
||||||
onSegmentationRemoveFromViewport(segmentation.segmentationId);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Icons.Series className="text-foreground" />
|
|
||||||
<span className="pl-2">{t('Remove from Viewport')}</span>
|
|
||||||
</DropdownMenuItem>
|
|
||||||
<DropdownMenuItem
|
|
||||||
onClick={e => {
|
|
||||||
e.stopPropagation();
|
|
||||||
onSegmentationEdit(segmentation.segmentationId);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Icons.Rename className="text-foreground" />
|
|
||||||
<span className="pl-2">{t('Rename')}</span>
|
|
||||||
</DropdownMenuItem>
|
|
||||||
<DropdownMenuItem onClick={e => e.stopPropagation()}>
|
|
||||||
<Icons.Hide className="text-foreground" />
|
|
||||||
<span className="pl-2">{t('Hide or Show all Segments')}</span>
|
|
||||||
</DropdownMenuItem>
|
|
||||||
<DropdownMenuSub>
|
|
||||||
<DropdownMenuSubTrigger onClick={e => e.stopPropagation()}>
|
|
||||||
<Icons.Export className="text-foreground" />
|
|
||||||
<span className="pl-2">{t('Export & Download')}</span>
|
|
||||||
</DropdownMenuSubTrigger>
|
|
||||||
<DropdownMenuPortal>
|
|
||||||
<DropdownMenuSubContent>
|
|
||||||
<DropdownMenuItem
|
|
||||||
onClick={e => {
|
|
||||||
e.stopPropagation();
|
|
||||||
storeSegmentation(segmentation.segmentationId);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{t('Export DICOM SEG')}
|
|
||||||
</DropdownMenuItem>
|
|
||||||
<DropdownMenuItem
|
|
||||||
onClick={e => {
|
|
||||||
e.stopPropagation();
|
|
||||||
onSegmentationDownload(segmentation.segmentationId);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{t('Download DICOM SEG')}
|
|
||||||
</DropdownMenuItem>
|
|
||||||
<DropdownMenuItem
|
|
||||||
onClick={e => {
|
|
||||||
e.stopPropagation();
|
|
||||||
onSegmentationDownloadRTSS(segmentation.segmentationId);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{t('Download DICOM RTSTRUCT')}
|
|
||||||
</DropdownMenuItem>
|
|
||||||
</DropdownMenuSubContent>
|
|
||||||
</DropdownMenuPortal>
|
|
||||||
</DropdownMenuSub>
|
|
||||||
<DropdownMenuSeparator />
|
|
||||||
<DropdownMenuItem onClick={() => onSegmentationDelete(segmentation.segmentationId)}>
|
|
||||||
<Icons.Delete className="text-red-600" />
|
|
||||||
<span className="pl-2 text-red-600">{t('Delete')}</span>
|
|
||||||
</DropdownMenuItem>
|
|
||||||
</DropdownMenuContent>
|
|
||||||
</DropdownMenu>
|
</DropdownMenu>
|
||||||
<div className="pl-1.5">{segmentation.label}</div>
|
<div className="pl-1.5">{segmentation.label}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -4,17 +4,9 @@ import {
|
|||||||
Button,
|
Button,
|
||||||
DropdownMenu,
|
DropdownMenu,
|
||||||
DropdownMenuTrigger,
|
DropdownMenuTrigger,
|
||||||
DropdownMenuItem,
|
|
||||||
DropdownMenuContent,
|
|
||||||
DropdownMenuSeparator,
|
|
||||||
DropdownMenuSub,
|
|
||||||
DropdownMenuPortal,
|
|
||||||
DropdownMenuSubContent,
|
|
||||||
DropdownMenuSubTrigger,
|
|
||||||
Tooltip,
|
Tooltip,
|
||||||
TooltipTrigger,
|
TooltipTrigger,
|
||||||
TooltipContent,
|
TooltipContent,
|
||||||
DropdownMenuLabel,
|
|
||||||
} from '../../components';
|
} from '../../components';
|
||||||
|
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
@ -26,20 +18,8 @@ export const SegmentationSelectorHeader: React.FC<{ children?: React.ReactNode }
|
|||||||
}) => {
|
}) => {
|
||||||
const { t } = useTranslation('SegmentationTable.HeaderCollapsed');
|
const { t } = useTranslation('SegmentationTable.HeaderCollapsed');
|
||||||
|
|
||||||
const {
|
const { data, activeSegmentationId, mode, onSegmentationClick, exportOptions, ...contextProps } =
|
||||||
data,
|
useSegmentationTableContext('SegmentationTable.HeaderCollapsed');
|
||||||
activeSegmentationId,
|
|
||||||
mode,
|
|
||||||
onSegmentationClick,
|
|
||||||
onSegmentationAdd,
|
|
||||||
onSegmentationRemoveFromViewport,
|
|
||||||
onSegmentationEdit,
|
|
||||||
onSegmentationDelete,
|
|
||||||
onSegmentationDownload,
|
|
||||||
onSegmentationDownloadRTSS,
|
|
||||||
storeSegmentation,
|
|
||||||
exportOptions,
|
|
||||||
} = useSegmentationTableContext('SegmentationTable.HeaderCollapsed');
|
|
||||||
|
|
||||||
if (mode !== 'collapsed' || !data?.length) {
|
if (mode !== 'collapsed' || !data?.length) {
|
||||||
return null;
|
return null;
|
||||||
@ -65,6 +45,17 @@ export const SegmentationSelectorHeader: React.FC<{ children?: React.ReactNode }
|
|||||||
({ segmentationId }) => segmentationId === activeSegmentation.id
|
({ segmentationId }) => segmentationId === activeSegmentation.id
|
||||||
)?.isExportable;
|
)?.isExportable;
|
||||||
|
|
||||||
|
const childrenWithProps = React.Children.map(children, child =>
|
||||||
|
React.isValidElement(child)
|
||||||
|
? React.cloneElement(child, {
|
||||||
|
activeSegmentation,
|
||||||
|
allowExport,
|
||||||
|
t,
|
||||||
|
...contextProps,
|
||||||
|
})
|
||||||
|
: child
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="bg-primary-dark flex h-10 w-full items-center space-x-1 rounded-t px-1.5">
|
<div className="bg-primary-dark flex h-10 w-full items-center space-x-1 rounded-t px-1.5">
|
||||||
<DropdownMenu>
|
<DropdownMenu>
|
||||||
@ -76,49 +67,7 @@ export const SegmentationSelectorHeader: React.FC<{ children?: React.ReactNode }
|
|||||||
<Icons.More className="h-6 w-6" />
|
<Icons.More className="h-6 w-6" />
|
||||||
</Button>
|
</Button>
|
||||||
</DropdownMenuTrigger>
|
</DropdownMenuTrigger>
|
||||||
<DropdownMenuContent align="start">
|
{childrenWithProps}
|
||||||
<DropdownMenuItem onClick={() => onSegmentationAdd(activeSegmentation.id)}>
|
|
||||||
<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(activeSegmentation.id)}>
|
|
||||||
<Icons.Series className="text-foreground" />
|
|
||||||
<span className="pl-2">{t('Remove from Viewport')}</span>
|
|
||||||
</DropdownMenuItem>
|
|
||||||
<DropdownMenuItem onClick={() => onSegmentationEdit(activeSegmentation.id)}>
|
|
||||||
<Icons.Rename className="text-foreground" />
|
|
||||||
<span className="pl-2">{t('Rename')}</span>
|
|
||||||
</DropdownMenuItem>
|
|
||||||
<DropdownMenuSub>
|
|
||||||
<DropdownMenuSubTrigger
|
|
||||||
disabled={!allowExport}
|
|
||||||
className="pl-1"
|
|
||||||
>
|
|
||||||
<Icons.Export className="text-foreground" />
|
|
||||||
<span className="pl-2">{t('Export & Download')}</span>
|
|
||||||
</DropdownMenuSubTrigger>
|
|
||||||
<DropdownMenuPortal>
|
|
||||||
<DropdownMenuSubContent>
|
|
||||||
<DropdownMenuItem onClick={() => storeSegmentation(activeSegmentation.id)}>
|
|
||||||
{t('Export DICOM SEG')}
|
|
||||||
</DropdownMenuItem>
|
|
||||||
<DropdownMenuItem onClick={() => onSegmentationDownload(activeSegmentation.id)}>
|
|
||||||
{t('Download DICOM SEG')}
|
|
||||||
</DropdownMenuItem>
|
|
||||||
<DropdownMenuItem onClick={() => onSegmentationDownloadRTSS(activeSegmentation.id)}>
|
|
||||||
{t('Download DICOM RTSTRUCT')}
|
|
||||||
</DropdownMenuItem>
|
|
||||||
</DropdownMenuSubContent>
|
|
||||||
</DropdownMenuPortal>
|
|
||||||
</DropdownMenuSub>
|
|
||||||
<DropdownMenuSeparator />
|
|
||||||
<DropdownMenuItem onClick={() => onSegmentationDelete(activeSegmentation.id)}>
|
|
||||||
<Icons.Delete className="text-red-600" />
|
|
||||||
<span className="pl-2 text-red-600">{t('Delete')}</span>
|
|
||||||
</DropdownMenuItem>
|
|
||||||
</DropdownMenuContent>
|
|
||||||
</DropdownMenu>
|
</DropdownMenu>
|
||||||
<Select
|
<Select
|
||||||
onValueChange={value => onSegmentationClick(value)}
|
onValueChange={value => onSegmentationClick(value)}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user