diff --git a/src/api/annotation/AnnotationAPI.js b/src/api/annotation/AnnotationAPI.js index bb46a805e0..f13a26de58 100644 --- a/src/api/annotation/AnnotationAPI.js +++ b/src/api/annotation/AnnotationAPI.js @@ -76,6 +76,9 @@ const ANNOTATION_LAST_CREATED = 'annotationLastCreated'; * @constructor */ export default class AnnotationAPI extends EventEmitter { + /** @type {Map boolean >>} */ + #targetComparatorMap; + /** * @param {OpenMCT} openmct */ @@ -84,6 +87,7 @@ export default class AnnotationAPI extends EventEmitter { this.openmct = openmct; this.availableTags = {}; this.namespaceToSaveAnnotations = ''; + this.#targetComparatorMap = new Map(); this.ANNOTATION_TYPES = ANNOTATION_TYPES; this.ANNOTATION_TYPE = ANNOTATION_TYPE; @@ -385,7 +389,8 @@ export default class AnnotationAPI extends EventEmitter { const combinedResults = []; results.forEach((currentAnnotation) => { const existingAnnotation = combinedResults.find((annotationToFind) => { - return _.isEqual(currentAnnotation.targets, annotationToFind.targets); + const { annotationType, targets } = currentAnnotation; + return this.areAnnotationTargetsEqual(annotationType, targets, annotationToFind.targets); }); if (!existingAnnotation) { combinedResults.push(currentAnnotation); @@ -461,4 +466,35 @@ export default class AnnotationAPI extends EventEmitter { return breakApartSeparateTargets; } + + /** + * Adds a comparator function for a given annotation type. + * The comparator functions will be used to determine if two annotations + * have the same target. + * @param {ANNOTATION_TYPES} annotationType + * @param {(t1, t2) => boolean} comparator + */ + addTargetComparator(annotationType, comparator) { + const comparatorList = this.#targetComparatorMap.get(annotationType) ?? []; + comparatorList.push(comparator); + this.#targetComparatorMap.set(annotationType, comparatorList); + } + + /** + * Compare two sets of targets to see if they are equal. First checks if + * any targets comparators evaluate to true, then falls back to a deep + * equality check. + * @param {ANNOTATION_TYPES} annotationType + * @param {*} targets + * @param {*} otherTargets + * @returns true if the targets are equal, false otherwise + */ + areAnnotationTargetsEqual(annotationType, targets, otherTargets) { + const targetComparatorList = this.#targetComparatorMap.get(annotationType); + return ( + (targetComparatorList?.length && + targetComparatorList.some((targetComparator) => targetComparator(targets, otherTargets))) || + _.isEqual(targets, otherTargets) + ); + } } diff --git a/src/plugins/inspectorViews/annotations/AnnotationsInspectorView.vue b/src/plugins/inspectorViews/annotations/AnnotationsInspectorView.vue index 109c1752fc..5e990943fc 100644 --- a/src/plugins/inspectorViews/annotations/AnnotationsInspectorView.vue +++ b/src/plugins/inspectorViews/annotations/AnnotationsInspectorView.vue @@ -41,7 +41,6 @@