From 792aae69c0e8ce23ef6aa63cfef116ee0d454abd Mon Sep 17 00:00:00 2001 From: Simon Bear Date: Mon, 16 Nov 2020 18:01:48 +1100 Subject: [PATCH 01/22] Increment version number for next development iteration --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 516297c26..99c9346ae 100644 --- a/build.gradle +++ b/build.gradle @@ -10,7 +10,7 @@ buildscript { } } -version "3.0.0.DQ" +version "3.0.1.DQ-SNAPSHOT" group "au.org.ala.plugins.grails" apply plugin:"eclipse" From d287374e886e59faec8ecc522c231b66c988e7d4 Mon Sep 17 00:00:00 2001 From: Simon Bear Date: Fri, 27 Nov 2020 10:35:34 +1100 Subject: [PATCH 02/22] AtlasOfLivingAustralia/DataQuality#182 Add duplicate assertion type to flag an issue --- grails-app/assets/javascripts/show.js | 69 ++++++++++++++++++- .../biocache/hubs/AssertionsController.groovy | 8 ++- .../biocache/hubs/OccurrenceController.groovy | 13 ++++ grails-app/i18n/messages_en.properties | 1 + .../biocache/hubs/WebServicesService.groovy | 3 +- .../views/occurrence/_recordSidebar.gsp | 11 ++- grails-app/views/occurrence/show.gsp | 4 ++ 7 files changed, 105 insertions(+), 4 deletions(-) diff --git a/grails-app/assets/javascripts/show.js b/grails-app/assets/javascripts/show.js index f651f2c48..f4cb14ffb 100644 --- a/grails-app/assets/javascripts/show.js +++ b/grails-app/assets/javascripts/show.js @@ -26,6 +26,65 @@ $(document).ready(function() { $('.missingPropResult').toggle(); }); + $('#copyRecordIdToClipboard').on('click', function(e) { + var copyText = document.querySelector("#hidden-uuid"); + copyText.type = 'text'; + copyText.select(); + document.execCommand("copy"); + copyText.type = 'hidden'; + var $parent = $('#copyRecordIdToClipboard-parent'); + $parent.tooltip('show'); + setTimeout(function() { + $parent.tooltip('hide'); + }, 1000); + // alert("Copied"); + }); + $('#issue').on('change', function(e) { + var $this = $(this); + var val = $this.val(); + var $submit = $('#issueForm input[type=submit]'); + var $p = $('#related-record-p'); + if (val == '20020') { + $('#relatedRecordId').val(''); + $submit.prop('disabled', true); + $p.show(); + } else { + $submit.prop('disabled', false); + $p.hide(); + $('#related-record-id-not-found').hide(); + $('#related-record-id-found').hide(); + $('#related-record-id-loading').hide(); + } + }); + $('#relatedRecordId').on('change', function(e) { + var $this = $(this); + var $submit = $('#issueForm input[type=submit]'); + var val = $this.val().trim(); + if (val == OCC_REC.recordUuid) { + alert("You can't mark this record as a duplicate of itself!"); + } else if (val == '') { + $('#related-record-id-not-found').hide(); + $('#related-record-id-found').hide(); + $('#related-record-id-loading').hide(); + $submit.prop('disabled', true); + } else { + + $('#related-record-id-loading').show(); + $.get( OCC_REC.contextPath + "/occurrence/exists/" + val, function(data) { + $('#related-record-id-not-found').hide(); + $('#related-record-id-found').text(data).show(); + $('#related-record-id-loading').hide(); + $submit.prop('disabled', false); + }).error(function () { + $('#related-record-id-not-found').show(); + $('#related-record-id-found').hide(); + $('#related-record-id-loading').hide(); + $submit.prop('disabled', true); + }); + } + + }); + jQuery.i18n.properties({ name: 'messages', path: OCC_REC.contextPath + '/messages/i18n/', @@ -43,6 +102,7 @@ $(document).ready(function() { e.preventDefault(); var comment = $("#issueComment").val(); var code = $("#issue").val(); + var relatedRecordId = $('#relatedRecordId').val(); var userDisplayName = OCC_REC.userDisplayName //'${userDisplayName}'; var recordUuid = OCC_REC.recordUuid //'${ala:escapeJS(record.raw.rowKey)}'; if(code!=""){ @@ -63,6 +123,12 @@ $(document).ready(function() { if (bPreventAddingIssue) { alert("You cannot flag an issue with the same type that has already been verified."); return; + } else if (code == '20020' && !relatedRecordId) { + alert("You must provide a duplicate record id to mark this as a duplicate"); + return; + } else if (code == '20020' && relatedRecordId == recordUuid) { + alert("You can't mark a record as a duplicate of itself"); + return; } else { $.post(OCC_REC.contextPath + "/occurrences/assertions/add", @@ -72,7 +138,8 @@ $(document).ready(function() { comment: comment, userAssertionStatus: 'Open issue', userId: OCC_REC.userId, - userDisplayName: userDisplayName + userDisplayName: userDisplayName, + relatedRecordId: relatedRecordId }, function (data) { $('#assertionSubmitProgress').css({'display': 'none'}); 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 12e4dba41..8da413570 100644 --- a/grails-app/controllers/au/org/ala/biocache/hubs/AssertionsController.groovy +++ b/grails-app/controllers/au/org/ala/biocache/hubs/AssertionsController.groovy @@ -40,11 +40,17 @@ class AssertionsController { String comment = params.comment?:'' String userAssertionStatus = params.userAssertionStatus?: "" String assertionUuid = params.assertionUuid?: "" + String relatedRecordId = params.relatedRecordId ?: '' UserDetails userDetails = authService?.userDetails() // will return null if not available/not logged in if (recordUuid && code && userDetails) { + + if (code == '20020' && !relatedRecordId) { + render(status: 400, text: 'Duplicate record id not provided') + } + 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) + Map postResponse = webServicesService.addAssertion(recordUuid, code, comment, userDetails.userId, userDetails.displayName, userAssertionStatus, assertionUuid, relatedRecordId) if (postResponse.statusCode == 201) { log.info("Called REST service. Assertion should be added" ) diff --git a/grails-app/controllers/au/org/ala/biocache/hubs/OccurrenceController.groovy b/grails-app/controllers/au/org/ala/biocache/hubs/OccurrenceController.groovy index 4db6d6fd6..a0a527ed5 100644 --- a/grails-app/controllers/au/org/ala/biocache/hubs/OccurrenceController.groovy +++ b/grails-app/controllers/au/org/ala/biocache/hubs/OccurrenceController.groovy @@ -25,9 +25,12 @@ import org.grails.web.json.JSONArray import org.grails.web.json.JSONElement import org.grails.web.json.JSONObject +import javax.servlet.http.HttpServletResponse import java.text.SimpleDateFormat import static au.org.ala.biocache.hubs.TimingUtils.time +import static javax.servlet.http.HttpServletResponse.SC_NOT_FOUND +import static javax.servlet.http.HttpServletResponse.SC_NO_CONTENT /** * Controller for occurrence searches and records @@ -602,6 +605,16 @@ class OccurrenceController { render webServicesService.facetCSVDownload(requestParams), contentType: 'text/csv', fileName: 'data.csv' } + def exists(String id) { + def record = webServicesService.getRecord(id, false) + if (record.keySet()) { + log.error("{}", record) + render text: record?.processed?.classification?.vernacularName ?: record?.raw?.classification?.vernacularName ?: record?.processed?.classification?.scientificName ?: record?.raw?.classification?.scientificName + } else { + render status: SC_NOT_FOUND, text: '' + } + } + /** * JSON webservices for debugging/testing */ diff --git a/grails-app/i18n/messages_en.properties b/grails-app/i18n/messages_en.properties index 8e4b8954d..2e289ab85 100644 --- a/grails-app/i18n/messages_en.properties +++ b/grails-app/i18n/messages_en.properties @@ -133,6 +133,7 @@ show.loginorflag.div01.navigator = Click here show.loginorflag.div02.label = You are logged in as show.issueform.label01 = Issue type: show.issueform.label02 = Comment: +show.issueform.label03 = Duplicate Record ID: show.issueform.button.submit = Submit show.issueform.button.cancel = Cancel show.issueform.button.close = Close 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 0350cb27b..ccaba2c43 100644 --- a/grails-app/services/au/org/ala/biocache/hubs/WebServicesService.groovy +++ b/grails-app/services/au/org/ala/biocache/hubs/WebServicesService.groovy @@ -182,13 +182,14 @@ class WebServicesService { * @return Map postResponse */ Map addAssertion(String recordUuid, String code, String comment, String userId, String userDisplayName, - String userAssertionStatus, String assertionUuid) { + String userAssertionStatus, String assertionUuid, String relatedRecordId) { Map postBody = [ recordUuid: recordUuid, code: code, comment: comment, userAssertionStatus: userAssertionStatus, assertionUuid: assertionUuid, + relatedRecordId: relatedRecordId, userId: userId, userDisplayName: userDisplayName, apiKey: grailsApplication.config.biocache.apiKey diff --git a/grails-app/views/occurrence/_recordSidebar.gsp b/grails-app/views/occurrence/_recordSidebar.gsp index 6a3c078cf..6ef5c65ff 100644 --- a/grails-app/views/occurrence/_recordSidebar.gsp +++ b/grails-app/views/occurrence/_recordSidebar.gsp @@ -319,12 +319,21 @@

-

+

+ + + +

+

diff --git a/grails-app/views/occurrence/show.gsp b/grails-app/views/occurrence/show.gsp index e092f1365..7465e7804 100644 --- a/grails-app/views/occurrence/show.gsp +++ b/grails-app/views/occurrence/show.gsp @@ -176,6 +176,10 @@

+ + + +