From acde860fd6ce1f0e79922b4239c70ec96bff5805 Mon Sep 17 00:00:00 2001 From: "alex.huang" Date: Fri, 13 Nov 2020 17:46:29 +1100 Subject: [PATCH 1/9] initial commit --- grails-app/assets/javascripts/show.js | 43 +++++++++++++++++++ grails-app/i18n/messages_en.properties | 1 + .../views/occurrence/_recordSidebar.gsp | 5 +++ grails-app/views/occurrence/show.gsp | 3 +- 4 files changed, 51 insertions(+), 1 deletion(-) diff --git a/grails-app/assets/javascripts/show.js b/grails-app/assets/javascripts/show.js index f651f2c48..1acfeb639 100644 --- a/grails-app/assets/javascripts/show.js +++ b/grails-app/assets/javascripts/show.js @@ -48,6 +48,25 @@ $(document).ready(function() { if(code!=""){ $('#assertionSubmitProgress').css({'display':'block'}); + // only update when user changed preference + if (allMyAnnotations) { + var orig_state = $('#notifyChangeCheckbox').prop('data-orig_state') + var new_state = $('#notifyChangeCheckbox').prop('checked') + + // to add alerts + if (new_state) { + var addAlerts = OCC_REC.alertsURL + "notification/addMyAlert/" + for (var i = 0; i < allMyAnnotations.length; i++) { + $.post(addAlerts + allMyAnnotations[i].id) + } + } else { // to remove alerts + var deleteAlerts = OCC_REC.alertsURL + "notification/deleteMyAlert/" + for (var i = 0; i < allMyAnnotations.length; i++) { + $.post(deleteAlerts + allMyAnnotations[i].id) + } + } + } + $.get( OCC_REC.contextPath + "/assertions/" + OCC_REC.recordUuid, function(data) { var bPreventAddingIssue = false; for (var i = 0; i < data.userAssertions.length; i++) { @@ -107,6 +126,30 @@ $(document).ready(function() { $(el).html(replaceURLWithHTMLLinks(html)); // convert it }); + var allMyAnnotations = null; + + $('#assertionButton').click(function (e) { + var getAlerts = OCC_REC.alertsURL + "ws/alerts/user/" + OCC_REC.userId; + $.getJSON(getAlerts, function (alerts) { + //console.log(alerts); + //console.log(alerts.enabledMyAnnotations); + var myAnnotationAlertOn = false; + if (alerts !== null && alerts.enabledMyAnnotations.length > 0) { + myAnnotationAlertOn = true; + } + + if (alerts !== null && alerts.allMyAnnotations.length > 0) { + allMyAnnotations = alerts.allMyAnnotations; + } + + if (allMyAnnotations === null) { + $("#notifyChange").hide(); + } else { + $("#notifyChangeCheckbox").prop('checked', myAnnotationAlertOn); + $("#notifyChangeCheckbox").prop('data-origstate', myAnnotationAlertOn); + } + }) + }) // bind to form "close" button TODO $("input#close").on("click", function(e) { diff --git a/grails-app/i18n/messages_en.properties b/grails-app/i18n/messages_en.properties index 8e4b8954d..0ef978f70 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.notifyme = Notify me when records I have annotated are updated show.issueform.button.submit = Submit show.issueform.button.cancel = Cancel show.issueform.button.close = Close diff --git a/grails-app/views/occurrence/_recordSidebar.gsp b/grails-app/views/occurrence/_recordSidebar.gsp index 6a3c078cf..1c6432ec1 100644 --- a/grails-app/views/occurrence/_recordSidebar.gsp +++ b/grails-app/views/occurrence/_recordSidebar.gsp @@ -329,6 +329,11 @@

+ +

+ +

+

" class="btn btn-primary" /> " class="btn btn-default" onClick="$('#loginOrFlag').modal('hide');"/> diff --git a/grails-app/views/occurrence/show.gsp b/grails-app/views/occurrence/show.gsp index e092f1365..1c176c916 100644 --- a/grails-app/views/occurrence/show.gsp +++ b/grails-app/views/occurrence/show.gsp @@ -59,7 +59,8 @@ status="s">'${sds}': '${grailsApplication.config.sensitiveDatasets[sds]}'${s < (sensitiveDatasets.size() - 1) ? ',' : ''} }, - hasGoogleKey: ${grailsApplication.config.google.apikey as Boolean} + hasGoogleKey: ${grailsApplication.config.google.apikey as Boolean}, + alertsURL: "${grailsApplication.config.alerts.baseURL}" } // Google charts From 8d1323d16676f3fa2bb9a13b228d6f374d1fc1d8 Mon Sep 17 00:00:00 2001 From: alexhuang091 Date: Thu, 26 Nov 2020 14:48:48 +1100 Subject: [PATCH 2/9] updated API calls to get/add/delete alerts --- grails-app/assets/javascripts/show.js | 42 +++++++++---------- grails-app/conf/plugin.groovy | 2 + .../hubs/BiocacheHubsUrlMappings.groovy | 3 ++ .../biocache/hubs/OccurrenceController.groovy | 13 +++++- .../biocache/hubs/WebServicesService.groovy | 20 ++++++++- grails-app/views/occurrence/show.gsp | 2 +- 6 files changed, 58 insertions(+), 24 deletions(-) diff --git a/grails-app/assets/javascripts/show.js b/grails-app/assets/javascripts/show.js index 1acfeb639..e382c84a1 100644 --- a/grails-app/assets/javascripts/show.js +++ b/grails-app/assets/javascripts/show.js @@ -43,26 +43,30 @@ $(document).ready(function() { e.preventDefault(); var comment = $("#issueComment").val(); var code = $("#issue").val(); - var userDisplayName = OCC_REC.userDisplayName //'${userDisplayName}'; - var recordUuid = OCC_REC.recordUuid //'${ala:escapeJS(record.raw.rowKey)}'; + var userDisplayName = OCC_REC.userDisplayName; //'${userDisplayName}'; + var recordUuid = OCC_REC.recordUuid; //'${ala:escapeJS(record.raw.rowKey)}'; if(code!=""){ $('#assertionSubmitProgress').css({'display':'block'}); - // only update when user changed preference if (allMyAnnotations) { - var orig_state = $('#notifyChangeCheckbox').prop('data-orig_state') - var new_state = $('#notifyChangeCheckbox').prop('checked') - - // to add alerts - if (new_state) { - var addAlerts = OCC_REC.alertsURL + "notification/addMyAlert/" - for (var i = 0; i < allMyAnnotations.length; i++) { - $.post(addAlerts + allMyAnnotations[i].id) - } - } else { // to remove alerts - var deleteAlerts = OCC_REC.alertsURL + "notification/deleteMyAlert/" - for (var i = 0; i < allMyAnnotations.length; i++) { - $.post(deleteAlerts + allMyAnnotations[i].id) + var orig_state = $('#notifyChangeCheckbox').prop('data-origstate'); + var new_state = $('#notifyChangeCheckbox').prop('checked'); + + // only update when user changed preference + if (orig_state !== new_state) { + // to add alerts + if (new_state) { + var addAlerts = OCC_REC.alertsURL + "/occurrences/addAlert?userId=" + OCC_REC.userId + "&queryId="; + for (var i = 0; i < allMyAnnotations.length; i++) { + // console.log('post to: ' + addAlerts + allMyAnnotations[i].id) + $.post(addAlerts + allMyAnnotations[i].id); + } + } else { // to remove alerts + var deleteAlerts = OCC_REC.alertsURL + "/occurrences/deleteAlert?userId=" + OCC_REC.userId + "&queryId="; + for (var i = 0; i < allMyAnnotations.length; i++) { + // console.log('post to ' + deleteAlerts + allMyAnnotations[i].id) + $.post(deleteAlerts + allMyAnnotations[i].id); + } } } } @@ -83,7 +87,6 @@ $(document).ready(function() { alert("You cannot flag an issue with the same type that has already been verified."); return; } else { - $.post(OCC_REC.contextPath + "/occurrences/assertions/add", { recordUuid: recordUuid, @@ -129,10 +132,8 @@ $(document).ready(function() { var allMyAnnotations = null; $('#assertionButton').click(function (e) { - var getAlerts = OCC_REC.alertsURL + "ws/alerts/user/" + OCC_REC.userId; + var getAlerts = OCC_REC.alertsURL + "/occurrences/userAlerts?userId=" + OCC_REC.userId; $.getJSON(getAlerts, function (alerts) { - //console.log(alerts); - //console.log(alerts.enabledMyAnnotations); var myAnnotationAlertOn = false; if (alerts !== null && alerts.enabledMyAnnotations.length > 0) { myAnnotationAlertOn = true; @@ -537,7 +538,6 @@ function updateConfirmVerificationEvents(occUuid, assertionUuid, userDisplayName } console.log("Submitting an assertion with userAssertionStatus: " + userAssertionStatus) - $.post(OCC_REC.contextPath + "/occurrences/assertions/add", { recordUuid: occUuid, code: code, diff --git a/grails-app/conf/plugin.groovy b/grails-app/conf/plugin.groovy index 28086e725..06e7e7a3f 100644 --- a/grails-app/conf/plugin.groovy +++ b/grails-app/conf/plugin.groovy @@ -63,6 +63,8 @@ biocache.indexedFieldsUrl = "${biocache.baseUrl}/index/fields" collections.baseUrl = "https://collections.ala.org.au" alerts.baseUrl = "https://alerts.ala.org.au" speciesList.baseURL = "https://lists.ala.org.au" +alerts.baseURL = 'https://alerts-test.ala.org.au' +alerts.apiKey = "64ad0d69-4f6b-4f39-8e10-22a1b7062ff7" useDownloadPlugin = "" // for images-client-plugin diff --git a/grails-app/controllers/au/org/ala/biocache/hubs/BiocacheHubsUrlMappings.groovy b/grails-app/controllers/au/org/ala/biocache/hubs/BiocacheHubsUrlMappings.groovy index 49f0f4e23..fa8f2501d 100644 --- a/grails-app/controllers/au/org/ala/biocache/hubs/BiocacheHubsUrlMappings.groovy +++ b/grails-app/controllers/au/org/ala/biocache/hubs/BiocacheHubsUrlMappings.groovy @@ -24,6 +24,9 @@ class BiocacheHubsUrlMappings { "/occurrences/next"(controller: 'occurrence', action: 'next') "/occurrences/previous"(controller: 'occurrence', action: 'previous') "/occurrences/dataQualityExcludeCounts"(controller: 'occurrence', action: 'dataQualityExcludeCounts') + "/occurrences/userAlerts"(controller: 'occurrence', action: 'getUserAlerts') + "/occurrences/addAlert"(controller: 'occurrence', action: 'addAlert') + "/occurrences/deleteAlert"(controller: 'occurrence', action: 'deleteAlert') "/occurrences/$id"(controller: 'occurrence', action: 'show') "/occurrence/$id"(controller: 'occurrence', action: 'show') "/assertions/$id"(controller: 'assertions', action: 'assertions') 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 dad789fa1..5cabc9fd7 100644 --- a/grails-app/controllers/au/org/ala/biocache/hubs/OccurrenceController.groovy +++ b/grails-app/controllers/au/org/ala/biocache/hubs/OccurrenceController.groovy @@ -17,7 +17,6 @@ package au.org.ala.biocache.hubs import au.org.ala.dataquality.model.QualityProfile import au.org.ala.web.CASRoles -import com.google.common.base.Stopwatch import com.maxmind.geoip2.record.Location import grails.converters.JSON import groovy.util.logging.Slf4j @@ -634,4 +633,16 @@ class OccurrenceController { data.count = qualityService.getExcludeCount(params.categoryLabel, profile.getCategories(), requestParams) render data as JSON } + + def getUserAlerts() { + render webServicesService.userAlerts(params.userId) as JSON + } + + def addAlert() { + render webServicesService.addAlert(params.userId, params.queryId) + } + + def deleteAlert() { + render webServicesService.deleteAlert(params.userId, params.queryId) + } } 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..2b6608210 100644 --- a/grails-app/services/au/org/ala/biocache/hubs/WebServicesService.groovy +++ b/grails-app/services/au/org/ala/biocache/hubs/WebServicesService.groovy @@ -100,6 +100,21 @@ class WebServicesService { getJsonElements(url) } + def userAlerts(String userId) { + def url = "${grailsApplication.config.alerts.baseURL}" + "/api/alerts/user/" + userId + return getJsonElements(url, "${grailsApplication.config.alerts.apiKey}") + } + + def addAlert(String userId, String queryId) { + def url = "${grailsApplication.config.alerts.baseURL}" + "/api/alerts/user/" + userId + "/subscribe/" + queryId + getJsonElements(url, "${grailsApplication.config.alerts.apiKey}") + } + + def deleteAlert(String userId, String queryId) { + def url = "${grailsApplication.config.alerts.baseURL}" + "/api/alerts/user/" + userId + "/unsubscribe/" + queryId + getJsonElements(url, "${grailsApplication.config.alerts.apiKey}") + } + def JSONObject getDuplicateRecordDetails(JSONObject record) { log.debug "getDuplicateRecordDetails -> ${record?.processed?.occurrence?.associatedOccurrences}" if (record?.processed?.occurrence?.associatedOccurrences) { @@ -398,12 +413,15 @@ class WebServicesService { * @param url * @return */ - JSONElement getJsonElements(String url) { + JSONElement getJsonElements(String url, String apiKey = null) { log.debug "(internal) getJson URL = " + url def conn = new URL(url).openConnection() try { conn.setConnectTimeout(10000) conn.setReadTimeout(50000) + if (apiKey != null) { + conn.setRequestProperty('apiKey', apiKey) + } return JSON.parse(conn.getInputStream(), "UTF-8") } catch (Exception e) { def error = "Failed to get json from web service (${url}). ${e.getClass()} ${e.getMessage()}, ${e}" diff --git a/grails-app/views/occurrence/show.gsp b/grails-app/views/occurrence/show.gsp index 1c176c916..ca6c54c20 100644 --- a/grails-app/views/occurrence/show.gsp +++ b/grails-app/views/occurrence/show.gsp @@ -60,7 +60,7 @@ }, hasGoogleKey: ${grailsApplication.config.google.apikey as Boolean}, - alertsURL: "${grailsApplication.config.alerts.baseURL}" + alertsURL: "${grailsApplication.config.grails.serverURL}" } // Google charts From 7c22ecf13d7c09b0883b4a7b5f856b31ca1d26f9 Mon Sep 17 00:00:00 2001 From: alexhuang091 Date: Thu, 26 Nov 2020 14:48:48 +1100 Subject: [PATCH 3/9] updated API calls to get/add/delete alerts --- grails-app/assets/javascripts/show.js | 42 +++++++++---------- grails-app/conf/plugin.groovy | 2 + .../hubs/BiocacheHubsUrlMappings.groovy | 3 ++ .../biocache/hubs/OccurrenceController.groovy | 13 +++++- .../biocache/hubs/WebServicesService.groovy | 20 ++++++++- grails-app/views/occurrence/show.gsp | 2 +- 6 files changed, 58 insertions(+), 24 deletions(-) diff --git a/grails-app/assets/javascripts/show.js b/grails-app/assets/javascripts/show.js index 1acfeb639..e382c84a1 100644 --- a/grails-app/assets/javascripts/show.js +++ b/grails-app/assets/javascripts/show.js @@ -43,26 +43,30 @@ $(document).ready(function() { e.preventDefault(); var comment = $("#issueComment").val(); var code = $("#issue").val(); - var userDisplayName = OCC_REC.userDisplayName //'${userDisplayName}'; - var recordUuid = OCC_REC.recordUuid //'${ala:escapeJS(record.raw.rowKey)}'; + var userDisplayName = OCC_REC.userDisplayName; //'${userDisplayName}'; + var recordUuid = OCC_REC.recordUuid; //'${ala:escapeJS(record.raw.rowKey)}'; if(code!=""){ $('#assertionSubmitProgress').css({'display':'block'}); - // only update when user changed preference if (allMyAnnotations) { - var orig_state = $('#notifyChangeCheckbox').prop('data-orig_state') - var new_state = $('#notifyChangeCheckbox').prop('checked') - - // to add alerts - if (new_state) { - var addAlerts = OCC_REC.alertsURL + "notification/addMyAlert/" - for (var i = 0; i < allMyAnnotations.length; i++) { - $.post(addAlerts + allMyAnnotations[i].id) - } - } else { // to remove alerts - var deleteAlerts = OCC_REC.alertsURL + "notification/deleteMyAlert/" - for (var i = 0; i < allMyAnnotations.length; i++) { - $.post(deleteAlerts + allMyAnnotations[i].id) + var orig_state = $('#notifyChangeCheckbox').prop('data-origstate'); + var new_state = $('#notifyChangeCheckbox').prop('checked'); + + // only update when user changed preference + if (orig_state !== new_state) { + // to add alerts + if (new_state) { + var addAlerts = OCC_REC.alertsURL + "/occurrences/addAlert?userId=" + OCC_REC.userId + "&queryId="; + for (var i = 0; i < allMyAnnotations.length; i++) { + // console.log('post to: ' + addAlerts + allMyAnnotations[i].id) + $.post(addAlerts + allMyAnnotations[i].id); + } + } else { // to remove alerts + var deleteAlerts = OCC_REC.alertsURL + "/occurrences/deleteAlert?userId=" + OCC_REC.userId + "&queryId="; + for (var i = 0; i < allMyAnnotations.length; i++) { + // console.log('post to ' + deleteAlerts + allMyAnnotations[i].id) + $.post(deleteAlerts + allMyAnnotations[i].id); + } } } } @@ -83,7 +87,6 @@ $(document).ready(function() { alert("You cannot flag an issue with the same type that has already been verified."); return; } else { - $.post(OCC_REC.contextPath + "/occurrences/assertions/add", { recordUuid: recordUuid, @@ -129,10 +132,8 @@ $(document).ready(function() { var allMyAnnotations = null; $('#assertionButton').click(function (e) { - var getAlerts = OCC_REC.alertsURL + "ws/alerts/user/" + OCC_REC.userId; + var getAlerts = OCC_REC.alertsURL + "/occurrences/userAlerts?userId=" + OCC_REC.userId; $.getJSON(getAlerts, function (alerts) { - //console.log(alerts); - //console.log(alerts.enabledMyAnnotations); var myAnnotationAlertOn = false; if (alerts !== null && alerts.enabledMyAnnotations.length > 0) { myAnnotationAlertOn = true; @@ -537,7 +538,6 @@ function updateConfirmVerificationEvents(occUuid, assertionUuid, userDisplayName } console.log("Submitting an assertion with userAssertionStatus: " + userAssertionStatus) - $.post(OCC_REC.contextPath + "/occurrences/assertions/add", { recordUuid: occUuid, code: code, diff --git a/grails-app/conf/plugin.groovy b/grails-app/conf/plugin.groovy index 28086e725..06e7e7a3f 100644 --- a/grails-app/conf/plugin.groovy +++ b/grails-app/conf/plugin.groovy @@ -63,6 +63,8 @@ biocache.indexedFieldsUrl = "${biocache.baseUrl}/index/fields" collections.baseUrl = "https://collections.ala.org.au" alerts.baseUrl = "https://alerts.ala.org.au" speciesList.baseURL = "https://lists.ala.org.au" +alerts.baseURL = 'https://alerts-test.ala.org.au' +alerts.apiKey = "64ad0d69-4f6b-4f39-8e10-22a1b7062ff7" useDownloadPlugin = "" // for images-client-plugin diff --git a/grails-app/controllers/au/org/ala/biocache/hubs/BiocacheHubsUrlMappings.groovy b/grails-app/controllers/au/org/ala/biocache/hubs/BiocacheHubsUrlMappings.groovy index 49f0f4e23..fa8f2501d 100644 --- a/grails-app/controllers/au/org/ala/biocache/hubs/BiocacheHubsUrlMappings.groovy +++ b/grails-app/controllers/au/org/ala/biocache/hubs/BiocacheHubsUrlMappings.groovy @@ -24,6 +24,9 @@ class BiocacheHubsUrlMappings { "/occurrences/next"(controller: 'occurrence', action: 'next') "/occurrences/previous"(controller: 'occurrence', action: 'previous') "/occurrences/dataQualityExcludeCounts"(controller: 'occurrence', action: 'dataQualityExcludeCounts') + "/occurrences/userAlerts"(controller: 'occurrence', action: 'getUserAlerts') + "/occurrences/addAlert"(controller: 'occurrence', action: 'addAlert') + "/occurrences/deleteAlert"(controller: 'occurrence', action: 'deleteAlert') "/occurrences/$id"(controller: 'occurrence', action: 'show') "/occurrence/$id"(controller: 'occurrence', action: 'show') "/assertions/$id"(controller: 'assertions', action: 'assertions') 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 dad789fa1..3ce3493f3 100644 --- a/grails-app/controllers/au/org/ala/biocache/hubs/OccurrenceController.groovy +++ b/grails-app/controllers/au/org/ala/biocache/hubs/OccurrenceController.groovy @@ -17,7 +17,6 @@ package au.org.ala.biocache.hubs import au.org.ala.dataquality.model.QualityProfile import au.org.ala.web.CASRoles -import com.google.common.base.Stopwatch import com.maxmind.geoip2.record.Location import grails.converters.JSON import groovy.util.logging.Slf4j @@ -634,4 +633,16 @@ class OccurrenceController { data.count = qualityService.getExcludeCount(params.categoryLabel, profile.getCategories(), requestParams) render data as JSON } + + def getUserAlerts() { + render webServicesService.userAlerts(params.userId) as JSON + } + + def addAlert() { + render webServicesService.addAlert(params.userId, params.queryId) as JSON + } + + def deleteAlert() { + render webServicesService.deleteAlert(params.userId, params.queryId) as JSON + } } 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..2b6608210 100644 --- a/grails-app/services/au/org/ala/biocache/hubs/WebServicesService.groovy +++ b/grails-app/services/au/org/ala/biocache/hubs/WebServicesService.groovy @@ -100,6 +100,21 @@ class WebServicesService { getJsonElements(url) } + def userAlerts(String userId) { + def url = "${grailsApplication.config.alerts.baseURL}" + "/api/alerts/user/" + userId + return getJsonElements(url, "${grailsApplication.config.alerts.apiKey}") + } + + def addAlert(String userId, String queryId) { + def url = "${grailsApplication.config.alerts.baseURL}" + "/api/alerts/user/" + userId + "/subscribe/" + queryId + getJsonElements(url, "${grailsApplication.config.alerts.apiKey}") + } + + def deleteAlert(String userId, String queryId) { + def url = "${grailsApplication.config.alerts.baseURL}" + "/api/alerts/user/" + userId + "/unsubscribe/" + queryId + getJsonElements(url, "${grailsApplication.config.alerts.apiKey}") + } + def JSONObject getDuplicateRecordDetails(JSONObject record) { log.debug "getDuplicateRecordDetails -> ${record?.processed?.occurrence?.associatedOccurrences}" if (record?.processed?.occurrence?.associatedOccurrences) { @@ -398,12 +413,15 @@ class WebServicesService { * @param url * @return */ - JSONElement getJsonElements(String url) { + JSONElement getJsonElements(String url, String apiKey = null) { log.debug "(internal) getJson URL = " + url def conn = new URL(url).openConnection() try { conn.setConnectTimeout(10000) conn.setReadTimeout(50000) + if (apiKey != null) { + conn.setRequestProperty('apiKey', apiKey) + } return JSON.parse(conn.getInputStream(), "UTF-8") } catch (Exception e) { def error = "Failed to get json from web service (${url}). ${e.getClass()} ${e.getMessage()}, ${e}" diff --git a/grails-app/views/occurrence/show.gsp b/grails-app/views/occurrence/show.gsp index 1c176c916..ca6c54c20 100644 --- a/grails-app/views/occurrence/show.gsp +++ b/grails-app/views/occurrence/show.gsp @@ -60,7 +60,7 @@ }, hasGoogleKey: ${grailsApplication.config.google.apikey as Boolean}, - alertsURL: "${grailsApplication.config.alerts.baseURL}" + alertsURL: "${grailsApplication.config.grails.serverURL}" } // Google charts From 5d66f2cc40ab456e538534ac380d2c34b0d8efd1 Mon Sep 17 00:00:00 2001 From: alexhuang091 Date: Thu, 26 Nov 2020 18:01:13 +1100 Subject: [PATCH 4/9] use logged in user id when get/add/delete alerts --- grails-app/assets/javascripts/show.js | 6 +++--- .../au/org/ala/biocache/hubs/OccurrenceController.groovy | 9 ++++++--- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/grails-app/assets/javascripts/show.js b/grails-app/assets/javascripts/show.js index e382c84a1..7e8479766 100644 --- a/grails-app/assets/javascripts/show.js +++ b/grails-app/assets/javascripts/show.js @@ -56,13 +56,13 @@ $(document).ready(function() { if (orig_state !== new_state) { // to add alerts if (new_state) { - var addAlerts = OCC_REC.alertsURL + "/occurrences/addAlert?userId=" + OCC_REC.userId + "&queryId="; + var addAlerts = OCC_REC.alertsURL + "/occurrences/addAlert?queryId="; for (var i = 0; i < allMyAnnotations.length; i++) { // console.log('post to: ' + addAlerts + allMyAnnotations[i].id) $.post(addAlerts + allMyAnnotations[i].id); } } else { // to remove alerts - var deleteAlerts = OCC_REC.alertsURL + "/occurrences/deleteAlert?userId=" + OCC_REC.userId + "&queryId="; + var deleteAlerts = OCC_REC.alertsURL + "/occurrences/deleteAlert?queryId="; for (var i = 0; i < allMyAnnotations.length; i++) { // console.log('post to ' + deleteAlerts + allMyAnnotations[i].id) $.post(deleteAlerts + allMyAnnotations[i].id); @@ -132,7 +132,7 @@ $(document).ready(function() { var allMyAnnotations = null; $('#assertionButton').click(function (e) { - var getAlerts = OCC_REC.alertsURL + "/occurrences/userAlerts?userId=" + OCC_REC.userId; + var getAlerts = OCC_REC.alertsURL + "/occurrences/userAlerts"; $.getJSON(getAlerts, function (alerts) { var myAnnotationAlertOn = false; if (alerts !== null && alerts.enabledMyAnnotations.length > 0) { 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 3ce3493f3..2477f312f 100644 --- a/grails-app/controllers/au/org/ala/biocache/hubs/OccurrenceController.groovy +++ b/grails-app/controllers/au/org/ala/biocache/hubs/OccurrenceController.groovy @@ -635,14 +635,17 @@ class OccurrenceController { } def getUserAlerts() { - render webServicesService.userAlerts(params.userId) as JSON + String userId = authService?.getUserId() + render ((userId == null) ? [error: 'userId must be supplied to get alerts'] : webServicesService.userAlerts(userId)) as JSON } def addAlert() { - render webServicesService.addAlert(params.userId, params.queryId) as JSON + String userId = authService?.getUserId() + render ((userId == null) ? [error: 'userId must be supplied to add alert'] : webServicesService.addAlert(userId, params.queryId)) as JSON } def deleteAlert() { - render webServicesService.deleteAlert(params.userId, params.queryId) as JSON + String userId = authService?.getUserId() + render ((userId == null) ? [error: 'userId must be supplied to delete alert'] : webServicesService.deleteAlert(userId, params.queryId)) as JSON } } From b3f10d7d52a5525dfe126bc24e9f9a411103f234 Mon Sep 17 00:00:00 2001 From: alexhuang091 Date: Fri, 27 Nov 2020 09:19:09 +1100 Subject: [PATCH 5/9] removed useless config --- grails-app/conf/plugin.groovy | 2 -- 1 file changed, 2 deletions(-) diff --git a/grails-app/conf/plugin.groovy b/grails-app/conf/plugin.groovy index 06e7e7a3f..28086e725 100644 --- a/grails-app/conf/plugin.groovy +++ b/grails-app/conf/plugin.groovy @@ -63,8 +63,6 @@ biocache.indexedFieldsUrl = "${biocache.baseUrl}/index/fields" collections.baseUrl = "https://collections.ala.org.au" alerts.baseUrl = "https://alerts.ala.org.au" speciesList.baseURL = "https://lists.ala.org.au" -alerts.baseURL = 'https://alerts-test.ala.org.au' -alerts.apiKey = "64ad0d69-4f6b-4f39-8e10-22a1b7062ff7" useDownloadPlugin = "" // for images-client-plugin From 4bbd71d31e51cc5f0d86c4fc3adc32015a8d0526 Mon Sep 17 00:00:00 2001 From: alexhuang091 Date: Sun, 29 Nov 2020 16:58:50 +1100 Subject: [PATCH 6/9] update subscribe/un-subscribe my annotations --- grails-app/assets/javascripts/show.js | 50 ++++++++++--------- .../hubs/BiocacheHubsUrlMappings.groovy | 2 +- .../biocache/hubs/OccurrenceController.groovy | 4 +- .../biocache/hubs/WebServicesService.groovy | 2 +- grails-app/views/occurrence/show.gsp | 3 +- 5 files changed, 33 insertions(+), 28 deletions(-) diff --git a/grails-app/assets/javascripts/show.js b/grails-app/assets/javascripts/show.js index 7e8479766..8abb3ad13 100644 --- a/grails-app/assets/javascripts/show.js +++ b/grails-app/assets/javascripts/show.js @@ -45,10 +45,10 @@ $(document).ready(function() { var code = $("#issue").val(); var userDisplayName = OCC_REC.userDisplayName; //'${userDisplayName}'; var recordUuid = OCC_REC.recordUuid; //'${ala:escapeJS(record.raw.rowKey)}'; - if(code!=""){ + if (code != "") { $('#assertionSubmitProgress').css({'display':'block'}); - if (allMyAnnotations) { + if (myAnnotationQueryId) { var orig_state = $('#notifyChangeCheckbox').prop('data-origstate'); var new_state = $('#notifyChangeCheckbox').prop('checked'); @@ -56,17 +56,9 @@ $(document).ready(function() { if (orig_state !== new_state) { // to add alerts if (new_state) { - var addAlerts = OCC_REC.alertsURL + "/occurrences/addAlert?queryId="; - for (var i = 0; i < allMyAnnotations.length; i++) { - // console.log('post to: ' + addAlerts + allMyAnnotations[i].id) - $.post(addAlerts + allMyAnnotations[i].id); - } + $.post(OCC_REC.alertsURL + "/occurrences/addAlert?queryId=" + myAnnotationQueryId); } else { // to remove alerts - var deleteAlerts = OCC_REC.alertsURL + "/occurrences/deleteAlert?queryId="; - for (var i = 0; i < allMyAnnotations.length; i++) { - // console.log('post to ' + deleteAlerts + allMyAnnotations[i].id) - $.post(deleteAlerts + allMyAnnotations[i].id); - } + $.post(OCC_REC.alertsURL + "/occurrences/deleteAlert?queryId=" + myAnnotationQueryId); } } } @@ -129,25 +121,37 @@ $(document).ready(function() { $(el).html(replaceURLWithHTMLLinks(html)); // convert it }); - var allMyAnnotations = null; + var myAnnotationQueryId = null $('#assertionButton').click(function (e) { - var getAlerts = OCC_REC.alertsURL + "/occurrences/userAlerts"; - $.getJSON(getAlerts, function (alerts) { - var myAnnotationAlertOn = false; - if (alerts !== null && alerts.enabledMyAnnotations.length > 0) { - myAnnotationAlertOn = true; + var getAlerts = OCC_REC.alertsURL + "/occurrences/alerts"; + var myAnnotationEnabled = false + + $.getJSON(getAlerts, function (data) { + if (data.enabledQueries) { + for (var i = 0; i < data.enabledQueries.length; i++) { + if (data.enabledQueries[i].name.indexOf(OCC_REC.alertName) !== -1) { + myAnnotationEnabled = true; + myAnnotationQueryId = data.enabledQueries[i].id + } + } } - if (alerts !== null && alerts.allMyAnnotations.length > 0) { - allMyAnnotations = alerts.allMyAnnotations; + if (data.disabledQueries) { + for (var i = 0; i < data.disabledQueries.length; i++) { + if (data.disabledQueries[i].name.indexOf(OCC_REC.alertName) !== -1) { + myAnnotationEnabled = false; + myAnnotationQueryId = data.disabledQueries[i].id + } + } } - if (allMyAnnotations === null) { + // if can't find 'my annotation' hide the check box + if (myAnnotationQueryId === null) { $("#notifyChange").hide(); } else { - $("#notifyChangeCheckbox").prop('checked', myAnnotationAlertOn); - $("#notifyChangeCheckbox").prop('data-origstate', myAnnotationAlertOn); + $("#notifyChangeCheckbox").prop('checked', myAnnotationEnabled); + $("#notifyChangeCheckbox").prop('data-origstate', myAnnotationEnabled); } }) }) diff --git a/grails-app/controllers/au/org/ala/biocache/hubs/BiocacheHubsUrlMappings.groovy b/grails-app/controllers/au/org/ala/biocache/hubs/BiocacheHubsUrlMappings.groovy index fa8f2501d..14d0728a9 100644 --- a/grails-app/controllers/au/org/ala/biocache/hubs/BiocacheHubsUrlMappings.groovy +++ b/grails-app/controllers/au/org/ala/biocache/hubs/BiocacheHubsUrlMappings.groovy @@ -24,7 +24,7 @@ class BiocacheHubsUrlMappings { "/occurrences/next"(controller: 'occurrence', action: 'next') "/occurrences/previous"(controller: 'occurrence', action: 'previous') "/occurrences/dataQualityExcludeCounts"(controller: 'occurrence', action: 'dataQualityExcludeCounts') - "/occurrences/userAlerts"(controller: 'occurrence', action: 'getUserAlerts') + "/occurrences/alerts"(controller: 'occurrence', action: 'getAlerts') "/occurrences/addAlert"(controller: 'occurrence', action: 'addAlert') "/occurrences/deleteAlert"(controller: 'occurrence', action: 'deleteAlert') "/occurrences/$id"(controller: 'occurrence', action: 'show') 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 2477f312f..45c22f9fb 100644 --- a/grails-app/controllers/au/org/ala/biocache/hubs/OccurrenceController.groovy +++ b/grails-app/controllers/au/org/ala/biocache/hubs/OccurrenceController.groovy @@ -634,9 +634,9 @@ class OccurrenceController { render data as JSON } - def getUserAlerts() { + def getAlerts() { String userId = authService?.getUserId() - render ((userId == null) ? [error: 'userId must be supplied to get alerts'] : webServicesService.userAlerts(userId)) as JSON + render ((userId == null) ? [error: 'userId must be supplied to get alerts'] : webServicesService.getAlerts(userId)) as JSON } def addAlert() { 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 2b6608210..47f65b425 100644 --- a/grails-app/services/au/org/ala/biocache/hubs/WebServicesService.groovy +++ b/grails-app/services/au/org/ala/biocache/hubs/WebServicesService.groovy @@ -100,7 +100,7 @@ class WebServicesService { getJsonElements(url) } - def userAlerts(String userId) { + def getAlerts(String userId) { def url = "${grailsApplication.config.alerts.baseURL}" + "/api/alerts/user/" + userId return getJsonElements(url, "${grailsApplication.config.alerts.apiKey}") } diff --git a/grails-app/views/occurrence/show.gsp b/grails-app/views/occurrence/show.gsp index ca6c54c20..b66c87585 100644 --- a/grails-app/views/occurrence/show.gsp +++ b/grails-app/views/occurrence/show.gsp @@ -60,7 +60,8 @@ }, hasGoogleKey: ${grailsApplication.config.google.apikey as Boolean}, - alertsURL: "${grailsApplication.config.grails.serverURL}" + alertsURL: "${grailsApplication.config.grails.serverURL}", + alertName: "${grailsApplication.config.myannotation.name}" } // Google charts From 6dc61c27bb7f4d5624b58e22b11f5f777e23ec59 Mon Sep 17 00:00:00 2001 From: alexhuang091 Date: Sun, 29 Nov 2020 17:40:57 +1100 Subject: [PATCH 7/9] parameterise the alert name we want to subscribe for my annotation --- grails-app/conf/plugin.groovy | 1 + 1 file changed, 1 insertion(+) diff --git a/grails-app/conf/plugin.groovy b/grails-app/conf/plugin.groovy index 28086e725..499919855 100644 --- a/grails-app/conf/plugin.groovy +++ b/grails-app/conf/plugin.groovy @@ -140,6 +140,7 @@ alwaysshow.imagetab = false facets.defaultSelected = "data_resource_uid,taxon_name,year,multimedia" +myannotation.name="My Annotations" mapdownloads { baseLayers { default_layer { From 50956432f08fef1cd234abeed5c9fe4c134510f8 Mon Sep 17 00:00:00 2001 From: alexhuang091 Date: Mon, 14 Dec 2020 09:26:00 +1100 Subject: [PATCH 8/9] code style per code review --- grails-app/assets/javascripts/show.js | 40 +++++++++---------- .../hubs/BiocacheHubsUrlMappings.groovy | 6 +-- .../biocache/hubs/OccurrenceController.groovy | 21 ++++++++-- .../biocache/hubs/WebServicesService.groovy | 14 ++++--- grails-app/views/occurrence/show.gsp | 1 - 5 files changed, 49 insertions(+), 33 deletions(-) diff --git a/grails-app/assets/javascripts/show.js b/grails-app/assets/javascripts/show.js index 27afc893b..e23dd1895 100644 --- a/grails-app/assets/javascripts/show.js +++ b/grails-app/assets/javascripts/show.js @@ -127,21 +127,6 @@ $(document).ready(function() { if(code!=""){ $('#assertionSubmitProgress').css({'display':'block'}); - if (myAnnotationQueryId) { - var orig_state = $('#notifyChangeCheckbox').prop('data-origstate'); - var new_state = $('#notifyChangeCheckbox').prop('checked'); - - // only update when user changed preference - if (orig_state !== new_state) { - // to add alerts - if (new_state) { - $.post(OCC_REC.alertsURL + "/occurrences/addAlert?queryId=" + myAnnotationQueryId); - } else { // to remove alerts - $.post(OCC_REC.alertsURL + "/occurrences/deleteAlert?queryId=" + myAnnotationQueryId); - } - } - } - $.get( OCC_REC.contextPath + "/assertions/" + OCC_REC.recordUuid, function(data) { var bPreventAddingIssue = false; for (var i = 0; i < data.userAssertions.length; i++) { @@ -179,6 +164,18 @@ $(document).ready(function() { relatedRecordReason: relatedRecordReason, }, function (data) { + // when add assertion succeeds, we update alert settings + if (myAnnotationQueryId) { + var orig_state = $('#notifyChangeCheckbox').prop('data-origstate'); + var new_state = $('#notifyChangeCheckbox').prop('checked'); + + // only update when user changed preference + if (orig_state !== new_state) { + var actionpath = new_state ? ("/occurrences/addAlert?queryId=" + myAnnotationQueryId) : ("/occurrences/deleteAlert?queryId=" + myAnnotationQueryId) + $.post(OCC_REC.contextPath + actionpath) + } + } + $('#assertionSubmitProgress').css({'display': 'none'}); $("#submitSuccess").html("Thanks for flagging the problem!"); $("#issueFormSubmit").hide(); @@ -214,10 +211,12 @@ $(document).ready(function() { var myAnnotationQueryId = null $('#assertionButton').click(function (e) { - var getAlerts = OCC_REC.alertsURL + "/occurrences/alerts"; - var myAnnotationEnabled = false + var getAlerts = OCC_REC.contextPath + "/occurrences/alerts"; + // hide check box until we get user alerts settings + $("#notifyChange").hide(); $.getJSON(getAlerts, function (data) { + var myAnnotationEnabled = false if (data.enabledQueries) { for (var i = 0; i < data.enabledQueries.length; i++) { if (data.enabledQueries[i].name.indexOf(OCC_REC.alertName) !== -1) { @@ -236,10 +235,9 @@ $(document).ready(function() { } } - // if can't find 'my annotation' hide the check box - if (myAnnotationQueryId === null) { - $("#notifyChange").hide(); - } else { + // if find 'my annotation' show the check box + if (myAnnotationQueryId !== null) { + $("#notifyChange").show(); $("#notifyChangeCheckbox").prop('checked', myAnnotationEnabled); $("#notifyChangeCheckbox").prop('data-origstate', myAnnotationEnabled); } diff --git a/grails-app/controllers/au/org/ala/biocache/hubs/BiocacheHubsUrlMappings.groovy b/grails-app/controllers/au/org/ala/biocache/hubs/BiocacheHubsUrlMappings.groovy index 14d0728a9..2e9b8b646 100644 --- a/grails-app/controllers/au/org/ala/biocache/hubs/BiocacheHubsUrlMappings.groovy +++ b/grails-app/controllers/au/org/ala/biocache/hubs/BiocacheHubsUrlMappings.groovy @@ -24,9 +24,9 @@ class BiocacheHubsUrlMappings { "/occurrences/next"(controller: 'occurrence', action: 'next') "/occurrences/previous"(controller: 'occurrence', action: 'previous') "/occurrences/dataQualityExcludeCounts"(controller: 'occurrence', action: 'dataQualityExcludeCounts') - "/occurrences/alerts"(controller: 'occurrence', action: 'getAlerts') - "/occurrences/addAlert"(controller: 'occurrence', action: 'addAlert') - "/occurrences/deleteAlert"(controller: 'occurrence', action: 'deleteAlert') + "/occurrences/alerts"(controller: 'occurrence', action: [GET: 'getAlerts']) + "/occurrences/addAlert"(controller: 'occurrence', action: [POST: 'addAlert']) + "/occurrences/deleteAlert"(controller: 'occurrence', action: [POST: 'deleteAlert']) "/occurrences/$id"(controller: 'occurrence', action: 'show') "/occurrence/$id"(controller: 'occurrence', action: 'show') "/assertions/$id"(controller: 'assertions', action: 'assertions') 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 4c2557e24..b31c993f6 100644 --- a/grails-app/controllers/au/org/ala/biocache/hubs/OccurrenceController.groovy +++ b/grails-app/controllers/au/org/ala/biocache/hubs/OccurrenceController.groovy @@ -641,16 +641,31 @@ class OccurrenceController { def getAlerts() { String userId = authService?.getUserId() - render ((userId == null) ? [error: 'userId must be supplied to get alerts'] : webServicesService.getAlerts(userId)) as JSON + if (userId == null) { + response.status = 404 + render ([error: 'userId must be supplied to get alerts'] as JSON) + } else { + render webServicesService.getAlerts(userId) as JSON + } } def addAlert() { String userId = authService?.getUserId() - render ((userId == null) ? [error: 'userId must be supplied to add alert'] : webServicesService.addAlert(userId, params.queryId)) as JSON + if (userId == null) { + response.status = 404 + render ([error: 'userId must be supplied to add alert'] as JSON) + } else { + render webServicesService.addAlert(userId, params.queryId) as JSON + } } def deleteAlert() { String userId = authService?.getUserId() - render ((userId == null) ? [error: 'userId must be supplied to delete alert'] : webServicesService.deleteAlert(userId, params.queryId)) as JSON + if (userId == null) { + response.status = 404 + render ([error: 'userId must be supplied to delete alert'] as JSON) + } else { + render webServicesService.deleteAlert(userId, params.queryId) as JSON + } } } 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 40236794b..7034056c9 100644 --- a/grails-app/services/au/org/ala/biocache/hubs/WebServicesService.groovy +++ b/grails-app/services/au/org/ala/biocache/hubs/WebServicesService.groovy @@ -106,13 +106,13 @@ class WebServicesService { } def addAlert(String userId, String queryId) { - def url = "${grailsApplication.config.alerts.baseURL}" + "/api/alerts/user/" + userId + "/subscribe/" + queryId - getJsonElements(url, "${grailsApplication.config.alerts.apiKey}") + String url = "${grailsApplication.config.alerts.baseURL}" + "/api/alerts/user/" + userId + "/subscribe/" + queryId + postFormData(url, [:], grailsApplication.config.alerts.apiKey as String) } def deleteAlert(String userId, String queryId) { - def url = "${grailsApplication.config.alerts.baseURL}" + "/api/alerts/user/" + userId + "/unsubscribe/" + queryId - getJsonElements(url, "${grailsApplication.config.alerts.apiKey}") + String url = "${grailsApplication.config.alerts.baseURL}" + "/api/alerts/user/" + userId + "/unsubscribe/" + queryId + postFormData(url, [:], grailsApplication.config.alerts.apiKey as String) } def JSONObject getDuplicateRecordDetails(JSONObject record) { @@ -463,13 +463,17 @@ class WebServicesService { * @param postParams * @return postResponse (Map with keys: statusCode (int) and statusMsg (String) */ - def Map postFormData(String uri, Map postParams) { + def Map postFormData(String uri, Map postParams, String apiKey = null) { HTTPBuilder http = new HTTPBuilder(uri) log.debug "POST (form encoded) to ${http.uri}" Map postResponse = [:] http.request( Method.POST ) { + if (apiKey != null) { + headers.'apiKey' = apiKey + } + send ContentType.URLENC, postParams response.success = { resp -> diff --git a/grails-app/views/occurrence/show.gsp b/grails-app/views/occurrence/show.gsp index f4bb7844f..e85deb52f 100644 --- a/grails-app/views/occurrence/show.gsp +++ b/grails-app/views/occurrence/show.gsp @@ -60,7 +60,6 @@ }, hasGoogleKey: ${grailsApplication.config.google.apikey as Boolean}, - alertsURL: "${grailsApplication.config.grails.serverURL}", alertName: "${grailsApplication.config.myannotation.name}" } From 5d0c8711222c7f4332674576f3a6b228e4080fd3 Mon Sep 17 00:00:00 2001 From: alexhuang091 Date: Tue, 15 Dec 2020 10:24:48 +1100 Subject: [PATCH 9/9] init myannotations before every call --- grails-app/assets/javascripts/show.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/grails-app/assets/javascripts/show.js b/grails-app/assets/javascripts/show.js index e23dd1895..03597f2ce 100644 --- a/grails-app/assets/javascripts/show.js +++ b/grails-app/assets/javascripts/show.js @@ -216,6 +216,8 @@ $(document).ready(function() { $("#notifyChange").hide(); $.getJSON(getAlerts, function (data) { + // init status + myAnnotationQueryId = null var myAnnotationEnabled = false if (data.enabledQueries) { for (var i = 0; i < data.enabledQueries.length; i++) {