From 6ea1434562b5dd384f4d08769ccf5f51e5500bb6 Mon Sep 17 00:00:00 2001 From: robyngit Date: Mon, 4 Nov 2024 11:40:17 -0500 Subject: [PATCH] Show canonical dataset validation on value change (in Editor) Issue #2542 --- .../metadata/eml/EMLAnnotations.js | 26 ++++++++ src/js/models/metadata/eml211/EML211.js | 60 +++++++++++-------- src/js/views/metadata/EML211View.js | 24 ++++++++ 3 files changed, 86 insertions(+), 24 deletions(-) diff --git a/src/js/collections/metadata/eml/EMLAnnotations.js b/src/js/collections/metadata/eml/EMLAnnotations.js index 4568703d6..7aa92950e 100644 --- a/src/js/collections/metadata/eml/EMLAnnotations.js +++ b/src/js/collections/metadata/eml/EMLAnnotations.js @@ -251,6 +251,32 @@ define(["underscore", "backbone", "models/metadata/eml211/EMLAnnotation"], ( if (!filteredErrors.length) return null; + // Put canonicalDataset annotation errors in their own category + // so they can be displayed in the special canonicalDataset field. + const canonicalErrors = []; + const errorsToRemove = []; + // Check for a canonicalDataset annotation error + flatErrors.forEach((annotationError, i) => { + if (annotationError.isCanonicalDataset) { + canonicalErrors.push(annotationError); + errorsToRemove.push(i); + } + }); + + // Remove canonicalDataset errors from the annotation errors + // backwards so we don't mess up the indexes. + errorsToRemove.reverse().forEach((i) => { + flatErrors.splice(i, 1); + }); + + if (canonicalErrors.length) { + // The two canonicalDataset errors are the same, so just show one. + flatErrors.push({ + attr: "canonicalDataset", + message: canonicalErrors[0].message, + }); + } + return flatErrors; }, }, diff --git a/src/js/models/metadata/eml211/EML211.js b/src/js/models/metadata/eml211/EML211.js index c23c8df44..87aeb3bd5 100644 --- a/src/js/models/metadata/eml211/EML211.js +++ b/src/js/models/metadata/eml211/EML211.js @@ -168,6 +168,10 @@ define([ ); }, + /** + * Update the canonoical dataset URI in the annotations collection to + * match the canonicalDataset value on this model. + */ updateCanonicalDataset() { let uri = this.get("canonicalDataset"); uri = uri?.length ? uri[0] : null; @@ -1708,33 +1712,41 @@ define([ // Validate the EMLAnnotation models const annotations = this.get("annotations"); const annotationErrors = annotations.validate(); - if (annotationErrors) { - // Put canonicalDataset annotation errors in their own category - // so they can be displayed in the special canonicalDataset field. - const canonicalErrors = []; - const errorsToRemove = []; - // Check for a canonicalDataset annotation error - annotationErrors.forEach((annotationError, i) => { - if (annotationError.isCanonicalDataset) { - canonicalErrors.push(annotationError); - errorsToRemove.push(i); - } - }); - // Remove canonicalDataset errors from the annotation errors - // backwards so we don't mess up the indexes. - errorsToRemove.reverse().forEach((i) => { - annotationErrors.splice(i, 1); - }); - - if (canonicalErrors.length) { - // The two canonicalDataset errors are the same, so just show one. - errors.canonicalDataset = canonicalErrors[0].message; - } - } + // if (annotationErrors) { + // // Put canonicalDataset annotation errors in their own category + // // so they can be displayed in the special canonicalDataset field. + // const canonicalErrors = []; + // const errorsToRemove = []; + // // Check for a canonicalDataset annotation error + // annotationErrors.forEach((annotationError, i) => { + // if (annotationError.isCanonicalDataset) { + // canonicalErrors.push(annotationError); + // errorsToRemove.push(i); + // } + // }); + // // Remove canonicalDataset errors from the annotation errors + // // backwards so we don't mess up the indexes. + // errorsToRemove.reverse().forEach((i) => { + // annotationErrors.splice(i, 1); + // }); + + // if (canonicalErrors.length) { + // // The two canonicalDataset errors are the same, so just show one. + // errors.canonicalDataset = canonicalErrors[0].message; + // } + // } // Add the rest of the annotation errors if there are any // non-canonical left if (annotationErrors.length) { - errors.annotations = annotationErrors; + errors.annotations = annotationErrors.filter( + (e) => e.attr !== "canonicalDataset", + ); + const canonicalError = annotationErrors.find( + (e) => e.attr === "canonicalDataset", + ); + if (canonicalError) { + errors.canonicalDataset = canonicalError.message; + } } //Check the required fields for this MetacatUI configuration diff --git a/src/js/views/metadata/EML211View.js b/src/js/views/metadata/EML211View.js index 0a08961ac..b84784225 100644 --- a/src/js/views/metadata/EML211View.js +++ b/src/js/views/metadata/EML211View.js @@ -309,6 +309,30 @@ define([ ); $(overviewEl).find(".canonical-id").append(canonicalIdEl); + // Show canonical dataset error message on change + this.stopListening(this.model, "change:canonicalDataset"); + this.listenTo(this.model, "change:canonicalDataset", () => { + const annotations = this.model.get("annotations"); + const annoErrors = annotations.validate(); + const canonicalError = annoErrors?.filter( + (e) => e.attr === "canonicalDataset", + ); + + if (canonicalError) { + const container = canonicalIdEl.parent(); + const input = canonicalIdEl.find("input"); + const notification = container.find(".notification"); + notification.addClass("error").text(canonicalError[0].message); + input.addClass("error"); + + // When the user starts typing, remove the error message + input.one("keyup", () => { + notification.removeClass("error").text(""); + input.removeClass("error"); + }); + } + }); + //Usage //Find the model value that matches a radio button and check it // Note the replace() call removing newlines and replacing them with a single space