fix: Clicking on measurement should highlight the measurement row in the measurement panel OHIF-433 (#3111)

* fix: OHIF-433 Clicking on measurement should highlight the measurement row in the measurement panel

Added selected flag to each OHIF measurement.
Listening to CS3D ANNOTATION_SELECTION_CHANGE to keep the selected flag in sync.

* fix: OHIF-433 Clicking on measurement should highlight the measurement row in the measurement panel

Fixed broken unit tests.

* PR feedback from Alireza:
- use MEASUREMENT_UPDATED event for selection changed
- added TODO to eventually have CS3D introduce the selected flag per annotation
- added MeasurementService._publishEvent

* PR feedback: now using _broadcastEvent
This commit is contained in:
Joe Boccanfuso authored and GitHub committed 2023-01-13 13:57:18 -05:00
1 parent a997198587
commit 58ae8690a7
8 files changed
+103 -36

No files matched your search

@@ -26,6 +26,7 @@ import pubSubServiceInterface from '../_shared/pubSubServiceInterface';
* @property {number} area -
* @property {Array} points -
* @property {MeasurementSource} source -
* @property {boolean} selected -
*/
/* Measurement schema keys for object validation. */
@@ -56,6 +57,7 @@ const MEASUREMENT_SCHEMA_KEYS = [
'shortestDiameter',
'longestDiameter',
'cachedStats',
'selected',
];
const EVENTS = {
@@ -184,6 +186,20 @@ class MeasurementService {
return measurement;
}
setMeasurementSelected(measurementUID, selected) {
const measurement = this.getMeasurement(measurementUID);
if (!measurement) {
return;
}
measurement.selected = selected;
this._broadcastEvent(this.EVENTS.MEASUREMENT_UPDATED, {
source: measurement.source,
measurement,
});
}
/**
* Create a new source.
*
@@ -218,8 +234,17 @@ class MeasurementService {
version,
};
source.annotationToMeasurement = (annotationType, annotation) => {
return this.annotationToMeasurement(source, annotationType, annotation);
source.annotationToMeasurement = (
annotationType,
annotation,
isUpdate = false
) => {
return this.annotationToMeasurement(
source,
annotationType,
annotation,
isUpdate
);
};
source.remove = (measurementUID, eventDetails) => {
@@ -467,9 +492,15 @@ class MeasurementService {
* @param {MeasurementSource} source The measurement source instance
* @param {string} annotationType The source annotationType
* @param {EventDetail} sourceAnnotationDetail for the annotation event
* @param {boolean} isUpdate is this an update or an add/completed instead?
* @return {string} A measurement uid
*/
annotationToMeasurement(source, annotationType, sourceAnnotationDetail) {
annotationToMeasurement(
source,
annotationType,
sourceAnnotationDetail,
isUpdate = false
) {
if (!this._isValidSource(source)) {
throw new Error('Invalid source.');
}
@@ -524,19 +555,27 @@ class MeasurementService {
};
if (this.measurements[internalUID]) {
// TODO: Ultimately, each annotation should have a selected flag right from the soure.
// For now, it is just added in OHIF here and in setMeasurementSelected.
newMeasurement.selected = this.measurements[internalUID].selected;
this.measurements[internalUID] = newMeasurement;
this._broadcastEvent(this.EVENTS.MEASUREMENT_UPDATED, {
source,
measurement: newMeasurement,
notYetUpdatedAtSource: false,
});
if (isUpdate) {
this._broadcastEvent(this.EVENTS.MEASUREMENT_UPDATED, {
source,
measurement: newMeasurement,
notYetUpdatedAtSource: false,
});
} else {
log.info('Measurement added.', newMeasurement);
this.measurements[internalUID] = newMeasurement;
this._broadcastEvent(this.EVENTS.MEASUREMENT_ADDED, {
source,
measurement: newMeasurement,
});
}
} else {
log.info('Measurement added.', newMeasurement);
log.info('Measurement started.', newMeasurement);
this.measurements[internalUID] = newMeasurement;
this._broadcastEvent(this.EVENTS.MEASUREMENT_ADDED, {
source,
measurement: newMeasurement,
});
}
return newMeasurement.uid;
@@ -588,16 +627,10 @@ class MeasurementService {
}
this._addJumpToMeasurement(viewportIndex, measurementUID);
const eventName = this.EVENTS.JUMP_TO_MEASUREMENT;
const hasListeners = Object.keys(this.listeners).length > 0;
const hasCallbacks = Array.isArray(this.listeners[eventName]);
if (hasListeners && hasCallbacks) {
this.listeners[eventName].forEach(listener => {
listener.callback({ viewportIndex, measurement });
});
}
this._broadcastEvent(this.EVENTS.JUMP_TO_MEASUREMENT, {
viewportIndex,
measurement,
});
}
getJumpToMeasurement(viewportIndex) {
@@ -364,8 +364,9 @@ describe('MeasurementService.js', () => {
() => (addCallbackWasCalled = true)
);
/* Add new measurement */
source.annotationToMeasurement(annotationType, measurement);
/* Add new measurement - two calls needed for the start and the other for the completed*/
const uid = source.annotationToMeasurement(annotationType, measurement);
source.annotationToMeasurement(annotationType, { uid, ...measurement });
expect(addCallbackWasCalled).toBe(true);
});
@@ -392,7 +393,11 @@ describe('MeasurementService.js', () => {
const uid = source.annotationToMeasurement(annotationType, measurement);
/* Update measurement */
source.annotationToMeasurement(annotationType, { uid, ...measurement });
source.annotationToMeasurement(
annotationType,
{ uid, ...measurement },
true
);
expect(updateCallbackWasCalled).toBe(true);
});
@@ -418,8 +423,9 @@ describe('MeasurementService.js', () => {
/* Unsubscribe */
unsubscribe();
/* Create measurement */
source.annotationToMeasurement(annotationType, measurement);
/* Create measurement - two calls needed one to start and one to complete */
const uid = source.annotationToMeasurement(annotationType, measurement);
source.annotationToMeasurement(annotationType, { uid, ...measurement });
expect(updateCallbackWasCalled).toBe(false);
});