Add support for "additional findings" section (#1867)
This commit is contained in:
parent
b7760dc291
commit
e2c72d48fe
@ -31,8 +31,16 @@ function PanelMeasurementTableTracking({ servicesManager, extensionManager }) {
|
|||||||
measurementChangeTimestamp,
|
measurementChangeTimestamp,
|
||||||
200
|
200
|
||||||
);
|
);
|
||||||
const { MeasurementService, UINotificationService, UIDialogService, DisplaySetService } = servicesManager.services;
|
const {
|
||||||
const [trackedMeasurements, sendTrackedMeasurementsEvent] = useTrackedMeasurements();
|
MeasurementService,
|
||||||
|
UINotificationService,
|
||||||
|
UIDialogService,
|
||||||
|
DisplaySetService,
|
||||||
|
} = servicesManager.services;
|
||||||
|
const [
|
||||||
|
trackedMeasurements,
|
||||||
|
sendTrackedMeasurementsEvent,
|
||||||
|
] = useTrackedMeasurements();
|
||||||
const { trackedStudy, trackedSeries } = trackedMeasurements.context;
|
const { trackedStudy, trackedSeries } = trackedMeasurements.context;
|
||||||
const [displayStudySummary, setDisplayStudySummary] = useState(
|
const [displayStudySummary, setDisplayStudySummary] = useState(
|
||||||
DISPLAY_STUDY_SUMMARY_INITIAL_VALUE
|
DISPLAY_STUDY_SUMMARY_INITIAL_VALUE
|
||||||
@ -90,7 +98,12 @@ function PanelMeasurementTableTracking({ servicesManager, extensionManager }) {
|
|||||||
// ~~ DisplayStudySummary
|
// ~~ DisplayStudySummary
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
updateDisplayStudySummary();
|
updateDisplayStudySummary();
|
||||||
}, [displayStudySummary.key, trackedMeasurements, trackedStudy]);
|
}, [
|
||||||
|
displayStudySummary.key,
|
||||||
|
trackedMeasurements,
|
||||||
|
trackedStudy,
|
||||||
|
updateDisplayStudySummary,
|
||||||
|
]);
|
||||||
|
|
||||||
// TODO: Better way to consolidated, debounce, check on change?
|
// TODO: Better way to consolidated, debounce, check on change?
|
||||||
// Are we exposing the right API for measurementService?
|
// Are we exposing the right API for measurementService?
|
||||||
@ -152,17 +165,23 @@ function PanelMeasurementTableTracking({ servicesManager, extensionManager }) {
|
|||||||
const measurement = MeasurementService.getMeasurement(id);
|
const measurement = MeasurementService.getMeasurement(id);
|
||||||
const { referenceSeriesUID, SOPInstanceUID } = measurement;
|
const { referenceSeriesUID, SOPInstanceUID } = measurement;
|
||||||
|
|
||||||
const displaySets = DisplaySetService.getDisplaySetsForSeries(referenceSeriesUID);
|
const displaySets = DisplaySetService.getDisplaySetsForSeries(
|
||||||
|
referenceSeriesUID
|
||||||
|
);
|
||||||
const displaySet = displaySets.find(ds => {
|
const displaySet = displaySets.find(ds => {
|
||||||
return ds.images && ds.images.some(i => i.SOPInstanceUID === SOPInstanceUID)
|
return (
|
||||||
|
ds.images && ds.images.some(i => i.SOPInstanceUID === SOPInstanceUID)
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
const imageIndex = displaySet.images.map(i => i.SOPInstanceUID).indexOf(SOPInstanceUID);
|
const imageIndex = displaySet.images
|
||||||
|
.map(i => i.SOPInstanceUID)
|
||||||
|
.indexOf(SOPInstanceUID);
|
||||||
|
|
||||||
viewportGridService.setDisplaysetForViewport({
|
viewportGridService.setDisplaysetForViewport({
|
||||||
viewportIndex: viewportGrid.activeViewportIndex,
|
viewportIndex: viewportGrid.activeViewportIndex,
|
||||||
displaySetInstanceUID: displaySet.displaySetInstanceUID,
|
displaySetInstanceUID: displaySet.displaySetInstanceUID,
|
||||||
imageIndex
|
imageIndex,
|
||||||
});
|
});
|
||||||
|
|
||||||
onMeasurementItemClickHandler({ id, isActive });
|
onMeasurementItemClickHandler({ id, isActive });
|
||||||
@ -177,12 +196,12 @@ function PanelMeasurementTableTracking({ servicesManager, extensionManager }) {
|
|||||||
case 'save': {
|
case 'save': {
|
||||||
MeasurementService.update(id, {
|
MeasurementService.update(id, {
|
||||||
...measurement,
|
...measurement,
|
||||||
...value
|
...value,
|
||||||
});
|
});
|
||||||
UINotificationService.show({
|
UINotificationService.show({
|
||||||
title: 'Measurements',
|
title: 'Measurements',
|
||||||
message: 'Label updated successfully',
|
message: 'Label updated successfully',
|
||||||
type: 'success'
|
type: 'success',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -199,7 +218,7 @@ function PanelMeasurementTableTracking({ servicesManager, extensionManager }) {
|
|||||||
noCloseButton: true,
|
noCloseButton: true,
|
||||||
value: { label: measurement.label || '' },
|
value: { label: measurement.label || '' },
|
||||||
body: ({ value, setValue }) => {
|
body: ({ value, setValue }) => {
|
||||||
const onChangeHandler = (event) => {
|
const onChangeHandler = event => {
|
||||||
event.persist();
|
event.persist();
|
||||||
setValue(value => ({ ...value, label: event.target.value }));
|
setValue(value => ({ ...value, label: event.target.value }));
|
||||||
};
|
};
|
||||||
@ -227,8 +246,8 @@ function PanelMeasurementTableTracking({ servicesManager, extensionManager }) {
|
|||||||
{ id: 'cancel', text: 'Cancel', type: 'secondary' },
|
{ id: 'cancel', text: 'Cancel', type: 'secondary' },
|
||||||
{ id: 'save', text: 'Save', type: 'primary' },
|
{ id: 'save', text: 'Save', type: 'primary' },
|
||||||
],
|
],
|
||||||
onSubmit: onSubmitHandler
|
onSubmit: onSubmitHandler,
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -236,12 +255,20 @@ function PanelMeasurementTableTracking({ servicesManager, extensionManager }) {
|
|||||||
if (!isActive) {
|
if (!isActive) {
|
||||||
const measurements = [...displayMeasurements];
|
const measurements = [...displayMeasurements];
|
||||||
const measurement = measurements.find(m => m.id === id);
|
const measurement = measurements.find(m => m.id === id);
|
||||||
measurements.forEach(m => m.isActive = m.id !== id ? false : true);
|
|
||||||
|
measurements.forEach(m => (m.isActive = m.id !== id ? false : true));
|
||||||
measurement.isActive = true;
|
measurement.isActive = true;
|
||||||
setDisplayMeasurements(measurements);
|
setDisplayMeasurements(measurements);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const displayMeasurementsWithoutFindings = displayMeasurements.filter(
|
||||||
|
dm => dm.measurementType !== MeasurementService.VALUE_TYPES.POINT
|
||||||
|
);
|
||||||
|
const additionalFindings = displayMeasurements.filter(
|
||||||
|
dm => dm.measurementType === MeasurementService.VALUE_TYPES.POINT
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="overflow-x-hidden overflow-y-auto invisible-scrollbar">
|
<div className="overflow-x-hidden overflow-y-auto invisible-scrollbar">
|
||||||
@ -254,11 +281,20 @@ function PanelMeasurementTableTracking({ servicesManager, extensionManager }) {
|
|||||||
)}
|
)}
|
||||||
<MeasurementTable
|
<MeasurementTable
|
||||||
title="Measurements"
|
title="Measurements"
|
||||||
amount={displayMeasurements.length}
|
amount={displayMeasurementsWithoutFindings.length}
|
||||||
data={displayMeasurements}
|
data={displayMeasurementsWithoutFindings}
|
||||||
onClick={jumpToImage}
|
onClick={jumpToImage}
|
||||||
onEdit={onMeasurementItemEditHandler}
|
onEdit={onMeasurementItemEditHandler}
|
||||||
/>
|
/>
|
||||||
|
{additionalFindings.length !== 0 && (
|
||||||
|
<MeasurementTable
|
||||||
|
title="Additional Findings"
|
||||||
|
amount={additionalFindings.length}
|
||||||
|
data={additionalFindings}
|
||||||
|
onClick={jumpToImage}
|
||||||
|
onEdit={onMeasurementItemEditHandler}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="flex justify-center p-4">
|
<div className="flex justify-center p-4">
|
||||||
<ActionButtons
|
<ActionButtons
|
||||||
@ -298,19 +334,19 @@ function _mapMeasurementToDisplay(measurement, index, types) {
|
|||||||
SOPInstanceUID
|
SOPInstanceUID
|
||||||
);
|
);
|
||||||
const { PixelSpacing, SeriesNumber, InstanceNumber } = instance;
|
const { PixelSpacing, SeriesNumber, InstanceNumber } = instance;
|
||||||
|
const displayText = _getDisplayText(
|
||||||
return {
|
|
||||||
id: measurement.id,
|
|
||||||
label: measurement.label || '(empty)',
|
|
||||||
displayText:
|
|
||||||
_getDisplayText(
|
|
||||||
measurement,
|
measurement,
|
||||||
PixelSpacing,
|
PixelSpacing,
|
||||||
SeriesNumber,
|
SeriesNumber,
|
||||||
InstanceNumber,
|
InstanceNumber,
|
||||||
types
|
types
|
||||||
) || [],
|
);
|
||||||
// TODO: handle one layer down
|
|
||||||
|
return {
|
||||||
|
id: measurement.id,
|
||||||
|
label: measurement.label || '(empty)',
|
||||||
|
measurementType: measurement.type,
|
||||||
|
displayText: displayText || [],
|
||||||
isActive: false, // activeMeasurementItem === i + 1,
|
isActive: false, // activeMeasurementItem === i + 1,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -365,8 +401,8 @@ function _getDisplayText(
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
case types.POINT: {
|
case types.POINT: {
|
||||||
const { text } = measurement;
|
const { text } = measurement; // Will display in "short description"
|
||||||
return [`${text} (S:${seriesNumber}, I:${instanceNumber})`];
|
return [`(S:${seriesNumber}, I:${instanceNumber})`];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user