From f6a1d6345129a4543fec68fb2a88974b4de7d1a0 Mon Sep 17 00:00:00 2001 From: temi Date: Fri, 10 Jan 2025 16:12:56 +1100 Subject: [PATCH 1/7] - stops sending request for image when species guid is special --- grails-app/assets/javascripts/speciesModel.js | 48 ++++++++++--------- 1 file changed, 26 insertions(+), 22 deletions(-) diff --git a/grails-app/assets/javascripts/speciesModel.js b/grails-app/assets/javascripts/speciesModel.js index c34ca66..dd6ad02 100644 --- a/grails-app/assets/javascripts/speciesModel.js +++ b/grails-app/assets/javascripts/speciesModel.js @@ -222,7 +222,7 @@ var speciesSearchEngines = function() { * Allows species information to be searched for and displayed. */ var SpeciesViewModel = function(data, options, context) { - + var SPECIAL_GUIDS = ['A_GUID']; var self = this; ecodata.forms.DataModelItem.apply(self, [options.metadata || {}, context, options]); @@ -352,29 +352,33 @@ var SpeciesViewModel = function(data, options, context) { } if (self.guid() && !options.printable) { + if (SPECIAL_GUIDS.indexOf(self.guid()) === -1) { + var profileInfo = "No profile available"; + self.transients.speciesInformation(profileInfo); + } + else { + var profileUrl = options.bieUrl + '/species/' + encodeURIComponent(self.guid()); + $.ajax({ + url: options.speciesProfileUrl + '?id=' + encodeURIComponent(self.guid()), + dataType: 'json', + success: function (data) { + var profileInfo = ''; + var imageUrl = data.thumbnail || (data.taxonConcept && data.taxonConcept.smallImageUrl); - var profileUrl = options.bieUrl + '/species/' + encodeURIComponent(self.guid()); - $.ajax({ - url: options.speciesProfileUrl+'?id=' + encodeURIComponent(self.guid()), - dataType: 'json', - success: function (data) { - var profileInfo = ''; - var imageUrl = data.thumbnail || (data.taxonConcept && data.taxonConcept.smallImageUrl); - - if (imageUrl) { - profileInfo += ""; - } - else { - profileInfo += "No profile image available"; + if (imageUrl) { + profileInfo += ""; + } else { + profileInfo += "No profile image available"; + } + profileInfo += ""; + profileInfo += kvpInfo; + self.transients.speciesInformation(profileInfo); + }, + error: function (request, status, error) { + console.log(error); } - profileInfo += ""; - profileInfo += kvpInfo; - self.transients.speciesInformation(profileInfo); - }, - error: function(request, status, error) { - console.log(error); - } - }); + }); + } } else { From 88ff0e660076b8c045a9b0679c4efb1687a276b5 Mon Sep 17 00:00:00 2001 From: temi Date: Fri, 10 Jan 2025 16:52:20 +1100 Subject: [PATCH 2/7] - trigger build --- build.gradle | 1 - 1 file changed, 1 deletion(-) diff --git a/build.gradle b/build.gradle index 4398da6..9bbff5d 100644 --- a/build.gradle +++ b/build.gradle @@ -17,7 +17,6 @@ plugins { id 'jacoco' } - version "7.2-SNAPSHOT" group "org.grails.plugins" From b6223a4e4c4185fc4562d2f3f4c694a4f2d62161 Mon Sep 17 00:00:00 2001 From: temi Date: Fri, 10 Jan 2025 17:06:18 +1100 Subject: [PATCH 3/7] fixed bug --- grails-app/assets/javascripts/speciesModel.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/grails-app/assets/javascripts/speciesModel.js b/grails-app/assets/javascripts/speciesModel.js index dd6ad02..a5dc307 100644 --- a/grails-app/assets/javascripts/speciesModel.js +++ b/grails-app/assets/javascripts/speciesModel.js @@ -352,7 +352,7 @@ var SpeciesViewModel = function(data, options, context) { } if (self.guid() && !options.printable) { - if (SPECIAL_GUIDS.indexOf(self.guid()) === -1) { + if (SPECIAL_GUIDS.indexOf(self.guid()) >= 0) { var profileInfo = "No profile available"; self.transients.speciesInformation(profileInfo); } From 4e1f6d3e140c845b39a3e8018fc9193ed94c9b1a Mon Sep 17 00:00:00 2001 From: temi Date: Mon, 20 Jan 2025 17:29:51 +1100 Subject: [PATCH 4/7] AtlasOfLivingAustralia/ecodata-client-plugin#269 code change to fetch species image only if user trigger popover icon --- .../assets/javascripts/knockout-utils.js | 79 ++++++++++++++----- grails-app/assets/javascripts/speciesModel.js | 12 +-- grails-app/views/output/_speciesTemplate.gsp | 2 +- .../forms/EditModelWidgetRenderer.groovy | 2 +- 4 files changed, 67 insertions(+), 28 deletions(-) diff --git a/grails-app/assets/javascripts/knockout-utils.js b/grails-app/assets/javascripts/knockout-utils.js index d4f9397..e101942 100644 --- a/grails-app/assets/javascripts/knockout-utils.js +++ b/grails-app/assets/javascripts/knockout-utils.js @@ -13,53 +13,90 @@ */ ko.bindingHandlers.popover = { - init: function (element, valueAccessor) { + init: function(element, valueAccessor) { ko.bindingHandlers.popover.initPopover(element, valueAccessor); }, - update: function (element, valueAccessor) { + update: function(element, valueAccessor) { + var $element = $(element), + instance = $element.data('bs.popover'), + popOptions = ko.bindingHandlers.popover.getOptions(valueAccessor), + combinedOptions = popOptions.combinedOptions, + options = popOptions.options; + + if (!instance) { + ko.bindingHandlers.popover.initPopover(element, valueAccessor); + instance = $element.data('bs.popover'); + } + + if (!instance) + return; + + // if view model has changed, update the popover + instance.config.title = combinedOptions.title || ""; + instance.config.content = combinedOptions.content; - var $element = $(element); - $element.popover('dispose'); - var options = ko.bindingHandlers.popover.initPopover(element, valueAccessor); if (options.autoShow) { if ($element.data('firstPopover') === false) { - $element.popover('show'); - $('body').on('click', function (e) { - + instance.show(); + $('body').on('click', function(e) { if (e.target != element && $element.find(e.target).length == 0) { - $element.popover('dispose'); + instance.hide(); } }); } + $element.data('firstPopover', false); } + // refresh popover content + if(ko.bindingHandlers.popover.isPopoverShown(element)) { + instance.show(); + } }, defaultOptions: { placement: "right", animation: true, html: true, - trigger: "hover", - delay: { - show: 250 - } + trigger: "hover" }, - initPopover: function (element, valueAccessor) { + initPopover: function(element, valueAccessor) { + var popOptions = ko.bindingHandlers.popover.getOptions(valueAccessor), + options = popOptions.options, + combinedOptions = popOptions.combinedOptions; + $(element).popover(combinedOptions); + ko.utils.domNodeDisposal.addDisposeCallback(element, function() { + $(element).popover("dispose"); + }); + + return options; + }, + /** + * constructs the options object from valueAccessor + * @param valueAccessor + * @returns {{combinedOptions: any, options: any}} + */ + getOptions: function(valueAccessor) { var options = ko.utils.unwrapObservable(valueAccessor()); + if (typeof(options.content) === "undefined") { + options.content = "" + } var combinedOptions = ko.utils.extend({}, ko.bindingHandlers.popover.defaultOptions); var content = ko.utils.unwrapObservable(options.content); ko.utils.extend(combinedOptions, options); combinedOptions.description = content; - - $(element).popover(combinedOptions); - - ko.utils.domNodeDisposal.addDisposeCallback(element, function () { - $(element).popover("dispose"); - }); - return options; + return {combinedOptions: combinedOptions, options: options}; + }, + /** + * id of the popover is stored in the element's aria-describedby attribute + * @param element + * @returns {boolean} + */ + isPopoverShown: function isPopoverShown(element) { + const popoverId = $(element).attr("aria-describedby"); + return $("#" + popoverId).length > 0; } }; diff --git a/grails-app/assets/javascripts/speciesModel.js b/grails-app/assets/javascripts/speciesModel.js index a5dc307..463556d 100644 --- a/grails-app/assets/javascripts/speciesModel.js +++ b/grails-app/assets/javascripts/speciesModel.js @@ -232,6 +232,7 @@ var SpeciesViewModel = function(data, options, context) { var output = options.output || ""; var dataFieldName = options.dataFieldName || ""; var surveyName = options.surveyName || ""; + var kvpInfo = ""; self.guid = ko.observable(); self.name = ko.observable(); @@ -252,7 +253,7 @@ var SpeciesViewModel = function(data, options, context) { self.transients.source = ko.observable(options.speciesSearchUrl + '&output=' + output+ '&dataFieldName=' + dataFieldName + '&surveyName=' + surveyName); self.transients.bieUrl = ko.observable(); - self.transients.speciesInformation = ko.observable(); + self.transients.speciesInformation = ko.observable(''); self.transients.speciesTitle = ko.observable(); self.transients.matched = ko.computed(function() { return self.guid() && self.guid() != "A_GUID" && self.listId != "unmatched"; @@ -328,7 +329,6 @@ var SpeciesViewModel = function(data, options, context) { self.transients.textFieldValue(self.name()); // Species Translation - var kvpInfo = ""; var languages = ["Waramungu", "Warlpiri name"]; var listsId = 'dr8016'; if(self.listId() == listsId || output == 'CLC 2Ha Track Plot') { @@ -350,7 +350,9 @@ var SpeciesViewModel = function(data, options, context) { } }); } + }; + self.fetchSpeciesImage = function() { if (self.guid() && !options.printable) { if (SPECIAL_GUIDS.indexOf(self.guid()) >= 0) { var profileInfo = "No profile available"; @@ -360,6 +362,7 @@ var SpeciesViewModel = function(data, options, context) { var profileUrl = options.bieUrl + '/species/' + encodeURIComponent(self.guid()); $.ajax({ url: options.speciesProfileUrl + '?id=' + encodeURIComponent(self.guid()), + cache: true, dataType: 'json', success: function (data) { var profileInfo = ''; @@ -375,17 +378,16 @@ var SpeciesViewModel = function(data, options, context) { self.transients.speciesInformation(profileInfo); }, error: function (request, status, error) { + self.transients.speciesInformation(""); console.log(error); } }); } - } else { self.transients.speciesInformation("No profile information is available."); } - - }; + } self.focusLost = function(event) { self.transients.editing(false); diff --git a/grails-app/views/output/_speciesTemplate.gsp b/grails-app/views/output/_speciesTemplate.gsp index 15f8c54..a9ff40c 100644 --- a/grails-app/views/output/_speciesTemplate.gsp +++ b/grails-app/views/output/_speciesTemplate.gsp @@ -11,7 +11,7 @@
- +
diff --git a/src/main/groovy/au/org/ala/ecodata/forms/EditModelWidgetRenderer.groovy b/src/main/groovy/au/org/ala/ecodata/forms/EditModelWidgetRenderer.groovy index c332d91..966af41 100644 --- a/src/main/groovy/au/org/ala/ecodata/forms/EditModelWidgetRenderer.groovy +++ b/src/main/groovy/au/org/ala/ecodata/forms/EditModelWidgetRenderer.groovy @@ -372,7 +372,7 @@ public class EditModelWidgetRenderer implements ModelWidgetRenderer {
- +
""" } From c5b8ada47d4862ef837dcd423038ce97e9ee3cf0 Mon Sep 17 00:00:00 2001 From: temi Date: Tue, 21 Jan 2025 14:54:21 +1100 Subject: [PATCH 5/7] - fixed a bug in functional test - default empty value for content --- grails-app/assets/javascripts/knockout-utils.js | 2 +- .../output/_imageDataTypeViewModelWithMetadataTemplate.gsp | 2 +- .../groovy/au/org/ala/ecodata/forms/ImageTypeSpec.groovy | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/grails-app/assets/javascripts/knockout-utils.js b/grails-app/assets/javascripts/knockout-utils.js index e101942..77310f3 100644 --- a/grails-app/assets/javascripts/knockout-utils.js +++ b/grails-app/assets/javascripts/knockout-utils.js @@ -33,7 +33,7 @@ // if view model has changed, update the popover instance.config.title = combinedOptions.title || ""; - instance.config.content = combinedOptions.content; + instance.config.content = combinedOptions.content || ""; if (options.autoShow) { if ($element.data('firstPopover') === false) { diff --git a/grails-app/views/output/_imageDataTypeViewModelWithMetadataTemplate.gsp b/grails-app/views/output/_imageDataTypeViewModelWithMetadataTemplate.gsp index 4a07df4..095e9d8 100644 --- a/grails-app/views/output/_imageDataTypeViewModelWithMetadataTemplate.gsp +++ b/grails-app/views/output/_imageDataTypeViewModelWithMetadataTemplate.gsp @@ -5,7 +5,7 @@
  • -