feat(segmentation): segment statistics, labelmap interpolation and segment bidirectional (#4865)
This commit is contained in:
1 parent
694f3e9611
commit
ec79b5523e
73 files changed
+3603
-1563
No files matched your search
@@ -1,47 +1,132 @@
|
||||
import React from 'react';
|
||||
import { useSegmentationTableContext } from './SegmentationTableContext';
|
||||
import { PanelSection } from '../PanelSection';
|
||||
import { SegmentationHeader } from './SegmentationHeader';
|
||||
import { SegmentationTable } from './SegmentationTable';
|
||||
import {
|
||||
useSegmentationTableContext,
|
||||
SegmentationExpandedProvider,
|
||||
useSegmentationExpanded,
|
||||
} from './contexts';
|
||||
import { Button } from '../Button';
|
||||
import { Icons } from '../Icons/Icons';
|
||||
import { DropdownMenu, DropdownMenuTrigger } from '../DropdownMenu';
|
||||
import { Tooltip, TooltipTrigger, TooltipContent } from '../Tooltip/Tooltip';
|
||||
|
||||
export const SegmentationExpanded: React.FC<{ children?: React.ReactNode }> = ({ children }) => {
|
||||
const { data } = useSegmentationTableContext('SegmentationExpanded');
|
||||
|
||||
// Separate the Header component from other children
|
||||
const headerComponent = React.Children.toArray(children).find(
|
||||
child => React.isValidElement(child) && child.type === SegmentationTable.Header
|
||||
);
|
||||
const otherChildren = React.Children.toArray(children).filter(
|
||||
child => !(React.isValidElement(child) && child.type === SegmentationTable.Header)
|
||||
);
|
||||
// The Header container component
|
||||
const SegmentationExpandedHeader = ({ children }: { children: React.ReactNode }) => {
|
||||
const { segmentation, isActive } = useSegmentationExpanded('SegmentationExpandedHeader');
|
||||
const { onSegmentationClick } = useSegmentationTableContext('SegmentationExpandedHeader');
|
||||
|
||||
return (
|
||||
<>
|
||||
{data.map(segmentationInfo => (
|
||||
<PanelSection key={segmentationInfo.segmentation.segmentationId}>
|
||||
<PanelSection.Header className="border-input border-t-2 bg-transparent pl-1">
|
||||
{headerComponent ? (
|
||||
React.cloneElement(headerComponent as React.ReactElement, {
|
||||
segmentation: segmentationInfo.segmentation,
|
||||
representation: segmentationInfo.representation,
|
||||
})
|
||||
) : (
|
||||
<SegmentationHeader segmentation={segmentationInfo.segmentation} />
|
||||
)}
|
||||
</PanelSection.Header>
|
||||
<PanelSection.Content>
|
||||
<div className="segmentation-expanded-section">
|
||||
{React.Children.map(otherChildren, child =>
|
||||
React.isValidElement(child)
|
||||
? React.cloneElement(child, {
|
||||
segmentation: segmentationInfo.segmentation,
|
||||
})
|
||||
: child
|
||||
)}
|
||||
</div>
|
||||
</PanelSection.Content>
|
||||
</PanelSection>
|
||||
))}
|
||||
</>
|
||||
<PanelSection.Header
|
||||
className={`border-input border-t-2 bg-transparent pl-1 ${isActive ? 'border-primary' : ''} py-0`}
|
||||
onClick={e => {
|
||||
e.stopPropagation();
|
||||
onSegmentationClick(segmentation.segmentationId);
|
||||
}}
|
||||
>
|
||||
<div className="text-foreground flex h-8 w-full items-center">{children}</div>
|
||||
</PanelSection.Header>
|
||||
);
|
||||
};
|
||||
|
||||
// Dropdown menu component - specifically for dropdown menu content
|
||||
const SegmentationExpandedDropdownMenu = ({ children }: { children: React.ReactNode }) => {
|
||||
return (
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
className="ml-1"
|
||||
onClick={e => e.stopPropagation()}
|
||||
>
|
||||
<Icons.More />
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
{children}
|
||||
</DropdownMenu>
|
||||
);
|
||||
};
|
||||
|
||||
// Label component - for displaying the segmentation label
|
||||
const SegmentationExpandedLabel = () => {
|
||||
const { segmentation } = useSegmentationExpanded('SegmentationExpandedLabel');
|
||||
|
||||
return <div className="pl-1.5">{segmentation.label}</div>;
|
||||
};
|
||||
|
||||
// Info component - for the info tooltip
|
||||
const SegmentationExpandedInfo = () => {
|
||||
const { segmentation } = useSegmentationExpanded('SegmentationExpandedInfo');
|
||||
|
||||
return (
|
||||
<div className="ml-auto mr-1">
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
>
|
||||
<Icons.Info className="h-6 w-6" />
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>
|
||||
<p>{segmentation.cachedStats?.info}</p>
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
// Content component
|
||||
const SegmentationExpandedContent = ({ children }: { children: React.ReactNode }) => {
|
||||
return (
|
||||
<PanelSection.Content className="py-0">
|
||||
<div className="segmentation-expanded-section">{children}</div>
|
||||
</PanelSection.Content>
|
||||
);
|
||||
};
|
||||
|
||||
// Main compound component
|
||||
const SegmentationExpandedRoot = ({ children }) => {
|
||||
const { data, activeSegmentationId, onSegmentationClick, mode } =
|
||||
useSegmentationTableContext('SegmentationExpanded');
|
||||
|
||||
// Check if we should render based on mode
|
||||
if (mode !== 'expanded' || !data || data.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="space-y-0">
|
||||
{data.map(segmentationInfo => {
|
||||
const isActive = segmentationInfo.segmentation.segmentationId === activeSegmentationId;
|
||||
|
||||
return (
|
||||
<PanelSection
|
||||
key={segmentationInfo.segmentation.segmentationId}
|
||||
className="mb-0"
|
||||
>
|
||||
<SegmentationExpandedProvider
|
||||
segmentation={segmentationInfo.segmentation}
|
||||
representation={segmentationInfo.representation}
|
||||
isActive={isActive}
|
||||
onSegmentationClick={onSegmentationClick}
|
||||
>
|
||||
{children}
|
||||
</SegmentationExpandedProvider>
|
||||
</PanelSection>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const SegmentationExpanded = Object.assign(SegmentationExpandedRoot, {
|
||||
Header: SegmentationExpandedHeader,
|
||||
DropdownMenu: SegmentationExpandedDropdownMenu,
|
||||
Label: SegmentationExpandedLabel,
|
||||
Info: SegmentationExpandedInfo,
|
||||
Content: SegmentationExpandedContent,
|
||||
});
|
||||
|
||||
export { SegmentationExpanded };
|
||||
Reference in new issue
Block a user