feat(segmentation): Enhance dropdown menu functionality in SegmentationTable (#4553)
This commit is contained in:
1 parent
144ec791a2
commit
397fd85653
6 files changed
+153
-167
No files matched your search
@@ -26,10 +26,7 @@ export const SegmentationExpanded: React.FC<{ children?: React.ReactNode }> = ({
|
||||
representation: segmentationInfo.representation,
|
||||
})
|
||||
) : (
|
||||
<SegmentationHeader
|
||||
segmentation={segmentationInfo.segmentation}
|
||||
representation={segmentationInfo.representation}
|
||||
/>
|
||||
<SegmentationHeader segmentation={segmentationInfo.segmentation} />
|
||||
)}
|
||||
</PanelSection.Header>
|
||||
<PanelSection.Content>
|
||||
@@ -38,7 +35,6 @@ export const SegmentationExpanded: React.FC<{ children?: React.ReactNode }> = ({
|
||||
React.isValidElement(child)
|
||||
? React.cloneElement(child, {
|
||||
segmentation: segmentationInfo.segmentation,
|
||||
representation: segmentationInfo.representation,
|
||||
})
|
||||
: child
|
||||
)}
|
||||
|
||||
@@ -1,39 +1,31 @@
|
||||
import React from 'react';
|
||||
import { Button } from '../Button';
|
||||
import { Icons } from '../Icons/Icons';
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuTrigger,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuSeparator,
|
||||
DropdownMenuSub,
|
||||
DropdownMenuSubTrigger,
|
||||
DropdownMenuSubContent,
|
||||
DropdownMenuPortal,
|
||||
} from '../DropdownMenu';
|
||||
import { DropdownMenu, DropdownMenuTrigger } from '../DropdownMenu';
|
||||
import { Tooltip, TooltipTrigger, TooltipContent } from '../Tooltip/Tooltip';
|
||||
import { useSegmentationTableContext } from './SegmentationTableContext';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
export const SegmentationHeader: React.FC<{
|
||||
children?: React.ReactNode;
|
||||
segmentation?: any;
|
||||
}> = ({ segmentation }) => {
|
||||
}> = ({ children, segmentation }) => {
|
||||
const { t } = useTranslation('SegmentationTable');
|
||||
const {
|
||||
onSegmentAdd,
|
||||
onSegmentationRemoveFromViewport,
|
||||
onSegmentationEdit,
|
||||
onSegmentationDelete,
|
||||
onSegmentationDownload,
|
||||
onSegmentationDownloadRTSS,
|
||||
storeSegmentation,
|
||||
} = useSegmentationTableContext('SegmentationHeader');
|
||||
const { ...contextProps } = useSegmentationTableContext('SegmentationHeader');
|
||||
|
||||
if (!segmentation) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const childrenWithProps = React.Children.map(children, child =>
|
||||
React.isValidElement(child)
|
||||
? React.cloneElement(child, {
|
||||
t,
|
||||
...contextProps,
|
||||
})
|
||||
: child
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="text-foreground flex h-8 w-full items-center justify-between">
|
||||
<div className="flex items-center space-x-1">
|
||||
@@ -48,79 +40,7 @@ export const SegmentationHeader: React.FC<{
|
||||
<Icons.More />
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align="start">
|
||||
<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>
|
||||
{childrenWithProps}
|
||||
</DropdownMenu>
|
||||
<div className="pl-1.5">{segmentation.label}</div>
|
||||
</div>
|
||||
|
||||
@@ -4,17 +4,9 @@ import {
|
||||
Button,
|
||||
DropdownMenu,
|
||||
DropdownMenuTrigger,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuSeparator,
|
||||
DropdownMenuSub,
|
||||
DropdownMenuPortal,
|
||||
DropdownMenuSubContent,
|
||||
DropdownMenuSubTrigger,
|
||||
Tooltip,
|
||||
TooltipTrigger,
|
||||
TooltipContent,
|
||||
DropdownMenuLabel,
|
||||
} from '../../components';
|
||||
|
||||
import { useTranslation } from 'react-i18next';
|
||||
@@ -26,20 +18,8 @@ export const SegmentationSelectorHeader: React.FC<{ children?: React.ReactNode }
|
||||
}) => {
|
||||
const { t } = useTranslation('SegmentationTable.HeaderCollapsed');
|
||||
|
||||
const {
|
||||
data,
|
||||
activeSegmentationId,
|
||||
mode,
|
||||
onSegmentationClick,
|
||||
onSegmentationAdd,
|
||||
onSegmentationRemoveFromViewport,
|
||||
onSegmentationEdit,
|
||||
onSegmentationDelete,
|
||||
onSegmentationDownload,
|
||||
onSegmentationDownloadRTSS,
|
||||
storeSegmentation,
|
||||
exportOptions,
|
||||
} = useSegmentationTableContext('SegmentationTable.HeaderCollapsed');
|
||||
const { data, activeSegmentationId, mode, onSegmentationClick, exportOptions, ...contextProps } =
|
||||
useSegmentationTableContext('SegmentationTable.HeaderCollapsed');
|
||||
|
||||
if (mode !== 'collapsed' || !data?.length) {
|
||||
return null;
|
||||
@@ -65,6 +45,17 @@ export const SegmentationSelectorHeader: React.FC<{ children?: React.ReactNode }
|
||||
({ segmentationId }) => segmentationId === activeSegmentation.id
|
||||
)?.isExportable;
|
||||
|
||||
const childrenWithProps = React.Children.map(children, child =>
|
||||
React.isValidElement(child)
|
||||
? React.cloneElement(child, {
|
||||
activeSegmentation,
|
||||
allowExport,
|
||||
t,
|
||||
...contextProps,
|
||||
})
|
||||
: child
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="bg-primary-dark flex h-10 w-full items-center space-x-1 rounded-t px-1.5">
|
||||
<DropdownMenu>
|
||||
@@ -76,49 +67,7 @@ export const SegmentationSelectorHeader: React.FC<{ children?: React.ReactNode }
|
||||
<Icons.More className="h-6 w-6" />
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
<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>
|
||||
{childrenWithProps}
|
||||
</DropdownMenu>
|
||||
<Select
|
||||
onValueChange={value => onSegmentationClick(value)}
|
||||
|
||||
Reference in new issue
Block a user