fix(segmentation): Display "No description S:{series number} {modality}" for segmentations with no label. (#5874)

* Bump CS3D dependency to get the fallbackLabel field additions.
This commit is contained in:
Joe Boccanfuso authored and GitHub committed 2026-03-12 18:39:14 -04:00
1 parent 15f14e34e4
commit 7b5d0ce40e
23 files changed
+349 -228

No files matched your search

+1 -1
View File
@@ -54,7 +54,7 @@
"@cornerstonejs/codec-libjpeg-turbo-8bit": "1.2.2",
"@cornerstonejs/codec-openjpeg": "1.3.0",
"@cornerstonejs/codec-openjph": "2.4.7",
"@cornerstonejs/dicom-image-loader": "4.18.2",
"@cornerstonejs/dicom-image-loader": "4.19.0",
"@emotion/serialize": "1.3.3",
"@ohif/core": "3.13.0-beta.37",
"@ohif/extension-cornerstone": "3.13.0-beta.37",
+2 -2
View File
@@ -37,8 +37,8 @@
"@cornerstonejs/codec-libjpeg-turbo-8bit": "1.2.2",
"@cornerstonejs/codec-openjpeg": "1.3.0",
"@cornerstonejs/codec-openjph": "2.4.7",
"@cornerstonejs/core": "4.18.2",
"@cornerstonejs/dicom-image-loader": "4.18.2",
"@cornerstonejs/core": "4.19.0",
"@cornerstonejs/dicom-image-loader": "4.19.0",
"@ohif/ui": "3.13.0-beta.37",
"cornerstone-math": "0.1.9",
"dicom-parser": "1.8.21"
@@ -64,5 +64,6 @@
"Not available on the current viewport": "Not available on the current viewport",
"Add segment to enable this tool": "Add segment to enable this tool",
"Segment Bidirectional": "Segment Bidirectional",
"Draw a segment before using bidirectional measurement": "Draw a segment before using bidirectional measurement"
"Draw a segment before using bidirectional measurement": "Draw a segment before using bidirectional measurement",
"No description": "No description"
}
@@ -64,5 +64,6 @@
"Not available on the current viewport": "Test Not available on the current viewport",
"Add segment to enable this tool": "Test Add segment to enable this tool",
"Segment Bidirectional": "Test Segment Bidirectional",
"Draw a segment before using bidirectional measurement": "Test Draw a segment before using bidirectional measurement"
"Draw a segment before using bidirectional measurement": "Test Draw a segment before using bidirectional measurement",
"No description": "Test No description"
}
@@ -5,6 +5,7 @@ import {
SegmentationExpandedProvider,
useSegmentationExpanded,
} from './contexts';
import { SegmentationLabel } from './SegmentationLabel';
import { useTranslation } from 'react-i18next';
import {
Button,
@@ -56,7 +57,7 @@ const SegmentationCollapsedDropdownMenu = ({ children }: { children: React.React
// Selector component - for the segmentation selection dropdown
const SegmentationCollapsedSelector = () => {
const { t } = useTranslation('SegmentationPanel.HeaderCollapsed');
const { t } = useTranslation('SegmentationPanel');
const { data, onSegmentationClick, segmentationRepresentationTypes } =
useSegmentationTableContext('SegmentationCollapsedSelector');
const { segmentation } = useSegmentationExpanded('SegmentationCollapsedSelector');
@@ -74,16 +75,28 @@ const SegmentationCollapsedSelector = () => {
)
.map(seg => ({
id: seg.segmentation.segmentationId,
label: seg.segmentation.label,
segmentation: seg.segmentation,
}));
const dataCyTypeSuffix = segmentationRepresentationTypes
? `-${segmentationRepresentationTypes[0]}`
: '';
return (
<Select
onValueChange={value => onSegmentationClick(value)}
value={segmentation?.segmentationId}
>
<SelectTrigger className="w-full overflow-hidden">
<SelectValue placeholder={t('Select a segmentation')} />
<SelectTrigger
className="w-full overflow-hidden"
data-cy={`segmentation-select${dataCyTypeSuffix}`}
>
<SelectValue
placeholder={t('Select a segmentation')}
data-cy={`segmentation-select-value${dataCyTypeSuffix}`}
>
<SegmentationLabel segmentation={segmentation} />
</SelectValue>
</SelectTrigger>
<SelectContent>
{segmentations.map(seg => (
@@ -91,7 +104,7 @@ const SegmentationCollapsedSelector = () => {
key={seg.id}
value={seg.id}
>
{seg.label}
<SegmentationLabel segmentation={seg.segmentation} />
</SelectItem>
))}
</SelectContent>
@@ -11,6 +11,7 @@ import { DropdownMenu, DropdownMenuTrigger } from '../DropdownMenu';
import { Tooltip, TooltipTrigger, TooltipContent } from '../Tooltip/Tooltip';
import { ScrollArea } from '../../components';
import { useDynamicMaxHeight } from '../../hooks/useDynamicMaxHeight';
import { SegmentationLabel } from './SegmentationLabel';
// The Header container component
const SegmentationExpandedHeader = ({ children }: { children: React.ReactNode }) => {
@@ -53,7 +54,11 @@ const SegmentationExpandedDropdownMenu = ({ children }: { children: React.ReactN
const SegmentationExpandedLabel = () => {
const { segmentation } = useSegmentationExpanded('SegmentationExpandedLabel');
return <div className="pl-1.5">{segmentation.label}</div>;
return (
<div className="pl-1.5">
<SegmentationLabel segmentation={segmentation} />
</div>
);
};
// Info component - for the info tooltip
@@ -0,0 +1,27 @@
import React from 'react';
import { useTranslation } from 'react-i18next';
import { Segmentation } from './contexts/SegmentationTableContext';
/**
* Displays the segmentation label. When the label is blank, shows a translated
* "No description" with the series/modality suffix styled in a lighter, muted font.
*/
export const SegmentationLabel = ({ segmentation }: { segmentation: Segmentation }) => {
const { t } = useTranslation('SegmentationPanel');
if (!segmentation) {
return null;
}
if (segmentation.label) {
return <>{segmentation.label}</>;
}
const suffix = segmentation.fallbackLabel;
return (
<>
<span>{t('No description')}</span>
{suffix && <span className="text-muted-foreground text-xxs">&nbsp;&nbsp;{suffix}</span>}
</>
);
};
@@ -17,6 +17,7 @@ export interface Segmentation {
segmentationId: string;
label: string;
cachedStats: SegmentStats;
fallbackLabel?: string;
segments: Record<number, Segment>;
}