From 2701381f2d47e2e4e69966a1486b7268f59e3cda Mon Sep 17 00:00:00 2001 From: Adam Collins Date: Tue, 25 Feb 2025 10:03:19 +1000 Subject: [PATCH] #619 add edit button for annotation comments --- grails-app/assets/javascripts/show.js | 94 ++++++++++++++++--- .../biocache/hubs/AssertionsController.groovy | 3 +- grails-app/i18n/messages_en.properties | 3 + .../biocache/hubs/WebServicesService.groovy | 5 +- .../views/occurrence/_recordSidebar.gsp | 2 + grails-app/views/occurrence/show.gsp | 18 +++- 6 files changed, 107 insertions(+), 18 deletions(-) diff --git a/grails-app/assets/javascripts/show.js b/grails-app/assets/javascripts/show.js index bea8bacd..e3f9dd79 100644 --- a/grails-app/assets/javascripts/show.js +++ b/grails-app/assets/javascripts/show.js @@ -196,6 +196,7 @@ function init() { var relatedRecordReason = $('#relatedRecordReason').val(); var userDisplayName = OCC_REC.userDisplayName //'${userDisplayName}'; var recordUuid = OCC_REC.recordUuid //'${ala:escapeJS(record.raw.rowKey)}'; + var assertionId = $('#assertionId').val(); if(code!=""){ $('#assertionSubmitProgress').css({'display':'block'}); @@ -234,6 +235,7 @@ function init() { userDisplayName: userDisplayName, relatedRecordId: relatedRecordId, relatedRecordReason: relatedRecordReason, + updateId: assertionId }, function (data) { // when add assertion succeeds, we update alert settings (only when myannotation is enabled) @@ -472,6 +474,26 @@ function init() { } }); + $('#loginOrFlag').on('show.bs.modal', function (event) { + var editMode = $('#editMode').val(); + if (editMode === 'true') { + // alter form for edit mode + $('#loginOrFlag').find('#loginOrFlagLabel').text(jQuery.i18n.prop('show.loginorflag.title.edit')); + $('#loginOrFlag').find('#issue').prop('disabled', true); + + // the assertionId, issue code and comment are set elsewhere + } else { + // reset form to default state for creating a new issue, probably not required as the page does a reload + $('#loginOrFlag').find('#loginOrFlagLabel').text(jQuery.i18n.prop('show.loginorflag.title')); + $('#loginOrFlag').find('#issue').prop('disabled', false); + + var code = $('#loginOrFlag').find('#issue').children().first().val(); + $('#loginOrFlag').find('#issue').val(code); + $('#loginOrFlag').find('#issueComment').val(""); + $('#loginOrFlag').find('#assertionId').val(""); + } + }); + } /** @@ -552,6 +574,8 @@ function refreshUserAnnotations(){ if (userAssertion.code != 50000) { $clone.prop('id', "userAnnotation_" + userAssertion.uuid); $clone.find('.issue').text(jQuery.i18n.prop(userAssertion.name)).attr('i18nkey', userAssertion.name); + $clone.find('.issueCode').text(userAssertion.code); + $clone.find('.issueComment').text(userAssertion.comment); $clone.find('.user').text(userAssertion.userDisplayName); if (userAssertion.hasOwnProperty('comment')) { $clone.find('.comment').text('Comment: ' + userAssertion.comment); @@ -613,7 +637,7 @@ function refreshUserAnnotations(){ $clone.find('.userEntity').text(', ' + userAssertion.userEntityName); } - //if the current user is the author of the annotation, they can delete + //if the current user is the author of the annotation, they can delete and edit if(OCC_REC.userId == userAssertion.userId){ $clone.find('.deleteAnnotation').css({display:'block'}); $clone.find('.deleteAnnotation').attr('id', userAssertion.uuid); @@ -674,7 +698,7 @@ function refreshUserAnnotations(){ } } - updateDeleteEvents(enableDelete, disableDelete); + updateEditDeleteEvents(enableDelete, disableDelete); }); } @@ -687,6 +711,28 @@ function updateDeleteVerificationEvents(relatedAssertionId) { deleteAssertion(OCC_REC.recordUuid, this.parentElement.parentElement.id.split('_').pop()); } }); + + $('#userAnnotation_' + relatedAssertionId + ' .editVerificationButton').off("click"); + $('#userAnnotation_' + relatedAssertionId + ' .editVerificationButton').on("click", function (e) { + e.preventDefault(); + + var element = $(this.parentElement.parentElement); + + // reset the form on open + var assertionId = this.parentElement.parentElement.id.split('_').pop(); + var code = element.find('.qaStatus').attr('i18nkey').split('.').pop(); + var comment = element.find('.comment').text(); + $("#verifyComment").val(comment); + $("#userAssertionStatusSelection").val(code); + $(".verifyAsk").show(); + $(".verifyDone").hide(); + $("#verifySpinner").hide(); + updateConfirmVerificationEvents(OCC_REC.recordUuid, relatedAssertionId, OCC_REC.userDisplayName, assertionId); + + $("#userAssertionStatusSelection").attr('disabled', 'disabled') + + $('#verifyRecordModal').modal('show'); + }); } function deleteAssertionPrompt(event) { @@ -698,23 +744,47 @@ function deleteAssertionPrompt(event) { } } -function updateDeleteEvents(enableDelete, disableDelete){ +function updateEditDeleteEvents(enableDelete, disableDelete){ for(var i = 0; i < enableDelete.length; i++){ - $('#userAnnotation_' + enableDelete[i] + ' .deleteAnnotation').off("click"); - $('#userAnnotation_' + enableDelete[i] + ' .deleteAnnotation').click({rec_uuid: OCC_REC.recordUuid, qa_uuid: enableDelete[i]}, deleteAssertionPrompt); + $('#userAnnotation_' + enableDelete[i] + ' .deleteAnnotationButton').off("click"); + $('#userAnnotation_' + enableDelete[i] + ' .deleteAnnotationButton').click({rec_uuid: OCC_REC.recordUuid, qa_uuid: enableDelete[i]}, deleteAssertionPrompt); + + $('#userAnnotation_' + enableDelete[i] + ' .editAnnotationButton').off("click"); + $('#userAnnotation_' + enableDelete[i] + ' .editAnnotationButton').attr('annotationId', enableDelete[i]); + $('#userAnnotation_' + enableDelete[i] + ' .editAnnotationButton').on("click", function(e){ + e.preventDefault(); + + // update loginOrFlag modal state + var annotationId = $(this).attr('annotationId'); + var code = $('#userAnnotation_' +annotationId + ' .issueCode').text(); + var comment = $('#userAnnotation_' + annotationId + ' .issueComment').text(); + $('#loginOrFlag').find('#issue').val(code); + $('#loginOrFlag').find('#editMode').val('true'); + $('#loginOrFlag').find('#assertionId').val(annotationId); + $('#loginOrFlag').find('#issueComment').val(comment); + + $('#loginOrFlag').modal('show'); + }); + updateVerificationEvents(enableDelete[i]); } for(var i = 0; i < disableDelete.length; i++){ + $('#userAnnotation_' + disableDelete[i] + ' .editAnnotationButton').attr('disabled', 'disabled'); + $('#userAnnotation_' + disableDelete[i] + ' .editAnnotationButton').attr('title', 'Unable to edit, as this assertion has a verification'); + $('#userAnnotation_' + disableDelete[i] + ' .editAnnotationButton').off("click"); + $('#userAnnotation_' + disableDelete[i] + ' .editAnnotationButton').on("click", function (e) { + e.preventDefault(); + }); + $('#userAnnotation_' + disableDelete[i] + ' .deleteAnnotationButton').attr('disabled', 'disabled'); $('#userAnnotation_' + disableDelete[i] + ' .deleteAnnotationButton').attr('title', 'Unable to delete, as this assertion has a verification'); - - - $('#userAnnotation_' + disableDelete[i] + ' .deleteAnnotation').off("click"); - $('#userAnnotation_' + disableDelete[i] + ' .deleteAnnotation').on("click", function (e) { + $('#userAnnotation_' + disableDelete[i] + ' .deleteAnnotationButton').off("click"); + $('#userAnnotation_' + disableDelete[i] + ' .deleteAnnotationButton').on("click", function (e) { e.preventDefault(); }); + updateVerificationEvents(disableDelete[i]); } @@ -735,7 +805,8 @@ function updateVerificationEvents(assertionId) { }); } -function updateConfirmVerificationEvents(occUuid, assertionUuid, userDisplayName){ +// provide assertionId when editing a verification, do not provide when creating a verification +function updateConfirmVerificationEvents(occUuid, assertionUuid, userDisplayName, updateId){ $('.closeVerify').on("click", function(e){ e.preventDefault(); @@ -765,7 +836,8 @@ function updateConfirmVerificationEvents(occUuid, assertionUuid, userDisplayName userAssertionStatus: userAssertionStatus, assertionUuid: assertionUuid, userId: OCC_REC.userId, - userDisplayName: userDisplayName}, + userDisplayName: userDisplayName, + updateId: updateId }, function(data) { // service simply returns status or OK or FORBIDDEN, so assume it worked... $(".verifyAsk").fadeOut(); diff --git a/grails-app/controllers/au/org/ala/biocache/hubs/AssertionsController.groovy b/grails-app/controllers/au/org/ala/biocache/hubs/AssertionsController.groovy index 8bae8855..9a8abc93 100644 --- a/grails-app/controllers/au/org/ala/biocache/hubs/AssertionsController.groovy +++ b/grails-app/controllers/au/org/ala/biocache/hubs/AssertionsController.groovy @@ -53,6 +53,7 @@ class AssertionsController { String assertionUuid = params.assertionUuid ?: "" String relatedRecordId = params.relatedRecordId ?: '' String relatedRecordReason = params.relatedRecordReason ?: '' + String updateId = params.updateId ?: '' UserDetails userDetails = authService?.userDetails() // will return null if not available/not logged in if (recordUuid && code && userDetails) { @@ -66,7 +67,7 @@ class AssertionsController { } log.info("Adding assertion to UUID: ${recordUuid}, code: ${code}, comment: ${comment}, userAssertionStatus: ${userAssertionStatus}, userId: ${userDetails.userId}, userEmail: ${userDetails.email}") - Map postResponse = webServicesService.addAssertion(recordUuid, code, comment, userDetails.userId, userDetails.displayName, userAssertionStatus, assertionUuid, relatedRecordId, relatedRecordReason) + Map postResponse = webServicesService.addAssertion(recordUuid, code, comment, userDetails.userId, userDetails.displayName, userAssertionStatus, assertionUuid, relatedRecordId, relatedRecordReason, updateId) if (postResponse.statusCode == 201) { log.info("Called REST service. Assertion should be added") diff --git a/grails-app/i18n/messages_en.properties b/grails-app/i18n/messages_en.properties index 8294d702..779b1950 100644 --- a/grails-app/i18n/messages_en.properties +++ b/grails-app/i18n/messages_en.properties @@ -147,6 +147,7 @@ show.sidebar01.volunteer.navigator = DigiVol show.button.viewdraftbutton.span = See draft in DigiVol show.button.assertionbutton.span = Flag an issue show.loginorflag.title = Flag an issue +show.loginorflag.title.edit = Edit an issue show.loginorflag.div01.label = Login please: show.loginorflag.div01.navigator = Click here show.loginorflag.div02.label = You are logged in as @@ -227,6 +228,8 @@ show.userannotationtemplate.p01.navigator = View more with this annotation show.userannotationtemplate.p02.navigator = Delete this annotation show.userannotationtemplate.p03.navigator = Verify this annotation show.userannotationtemplate.p04.navigator = Delete this verification +show.userannotationtemplate.p05.navigator = Edit +show.userannotationtemplate.p06.navigator = Edit show.userannotationtemplate.relatedrecord.userduplicate.a = View duplicated record show.userannotationtemplate.relatedrecord.default.a = View related record show.headingbar02.title = Record Not Found diff --git a/grails-app/services/au/org/ala/biocache/hubs/WebServicesService.groovy b/grails-app/services/au/org/ala/biocache/hubs/WebServicesService.groovy index ea25597f..6d82ce7a 100644 --- a/grails-app/services/au/org/ala/biocache/hubs/WebServicesService.groovy +++ b/grails-app/services/au/org/ala/biocache/hubs/WebServicesService.groovy @@ -216,7 +216,7 @@ class WebServicesService { */ Map addAssertion(String recordUuid, String code, String comment, String userId, String userDisplayName, String userAssertionStatus, String assertionUuid, String relatedRecordId, - String relatedRecordReason) { + String relatedRecordReason, String updateId) { Map postBody = [ recordUuid : recordUuid, code : code, @@ -226,7 +226,8 @@ class WebServicesService { relatedRecordId : relatedRecordId, relatedRecordReason: relatedRecordReason, userId : userId, - userDisplayName : userDisplayName + userDisplayName : userDisplayName, + updateId : updateId ] postFormData(grailsApplication.config.getProperty('biocache.baseUrl') + "/occurrences/assertions/add", postBody, true, true) diff --git a/grails-app/views/occurrence/_recordSidebar.gsp b/grails-app/views/occurrence/_recordSidebar.gsp index f097a613..153b1e60 100644 --- a/grails-app/views/occurrence/_recordSidebar.gsp +++ b/grails-app/views/occurrence/_recordSidebar.gsp @@ -279,6 +279,8 @@
${userDisplayName} (${alatag.loggedInUserEmail()}).
+ +