ohif-viewer/extensions/cornerstone/src/getPanelModule.tsx
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

127 lines
3.8 KiB
TypeScript

import React from 'react';
import { useTranslation } from 'react-i18next';
import { Toolbox } from '@ohif/extension-default';
import PanelSegmentation from './panels/PanelSegmentation';
import ActiveViewportWindowLevel from './components/ActiveViewportWindowLevel';
import PanelMeasurement from './panels/PanelMeasurement';
import { SegmentationRepresentations } from '@cornerstonejs/tools/enums';
import i18n from '@ohif/i18n';
const getPanelModule = ({ commandsManager, servicesManager, extensionManager }: withAppTypes) => {
const { toolbarService } = servicesManager.services;
const toolSectionMap = {
[SegmentationRepresentations.Labelmap]: toolbarService.sections.labelMapSegmentationToolbox,
[SegmentationRepresentations.Contour]: toolbarService.sections.contourSegmentationToolbox,
};
const wrappedPanelSegmentation = props => {
return (
<PanelSegmentation
commandsManager={commandsManager}
servicesManager={servicesManager}
extensionManager={extensionManager}
configuration={{
...props?.configuration,
}}
segmentationRepresentationTypes={props?.segmentationRepresentationTypes}
/>
);
};
const wrappedPanelSegmentationNoHeader = props => {
return (
<PanelSegmentation
commandsManager={commandsManager}
servicesManager={servicesManager}
extensionManager={extensionManager}
configuration={{
...props?.configuration,
}}
segmentationRepresentationTypes={props?.segmentationRepresentationTypes}
/>
);
};
const wrappedPanelSegmentationWithTools = props => {
const { t } = useTranslation('SegmentationPanel');
const tKey = `${props.segmentationRepresentationTypes?.[0] ?? 'Segmentation'} tools`;
const tValue = t(tKey);
return (
<>
<Toolbox
buttonSectionId={toolSectionMap[props.segmentationRepresentationTypes?.[0]]}
title={tValue}
/>
<PanelSegmentation
commandsManager={commandsManager}
servicesManager={servicesManager}
extensionManager={extensionManager}
configuration={{
...props?.configuration,
}}
segmentationRepresentationTypes={props?.segmentationRepresentationTypes}
/>
</>
);
};
return [
{
name: 'activeViewportWindowLevel',
component: () => {
return <ActiveViewportWindowLevel servicesManager={servicesManager} />;
},
},
{
name: 'panelMeasurement',
iconName: 'tab-linear',
iconLabel: 'Measure',
label: 'Measurement',
component: PanelMeasurement,
},
{
name: 'panelSegmentation',
iconName: 'tab-segmentation',
iconLabel: 'Segmentation',
label: 'Segmentation',
component: wrappedPanelSegmentation,
},
{
name: 'panelSegmentationNoHeader',
iconName: 'tab-segmentation',
iconLabel: 'Segmentation',
label: 'Segmentation',
component: wrappedPanelSegmentationNoHeader,
},
{
name: 'panelSegmentationWithToolsLabelMap',
iconName: 'tab-segmentation',
iconLabel: 'Segmentation',
label: i18n.t('SegmentationPanel:Labelmap'),
component: props =>
wrappedPanelSegmentationWithTools({
...props,
segmentationRepresentationTypes: [
SegmentationRepresentations.Labelmap,
SegmentationRepresentations.Surface,
],
}),
},
{
name: 'panelSegmentationWithToolsContour',
iconName: 'tab-contours',
iconLabel: 'Segmentation',
label: i18n.t('SegmentationPanel:Contour'),
component: props =>
wrappedPanelSegmentationWithTools({
...props,
segmentationRepresentationTypes: [SegmentationRepresentations.Contour],
}),
},
];
};
export default getPanelModule;