Skip to content

Commit

Permalink
Merge branch 'develop' into epic/grails4/develop
Browse files Browse the repository at this point in the history
* develop: (51 commits)
  Revert "Merge branch 'develop' into epic/develop-branch-fix"
  cherry pick of commit brucehyslop@646c31f
  Translation of Map legend button and pagination next and previous button
  3.0.6-SNAPSHOT
  release 3.0.5 (#449)
  #379 Records from DigiVol don't show "Flag an issue" button
  #443 fixes for flash.message exposing apiKey
  3.0.5-SNAPSHOT
  Release/3.0.4 (#442)
  Fix jquery.i18n load errors
  Feature my annotation (#435)
  #434 fix duplicate record facet labels
  version to 3.0.4-SNAPSHOT
  release 3.0.3 (#432)
  enhanced duplicate record flag (#431)
  Feature/duplicate record (#429)
  updated version to 3.0.3-SNAPSHOT for next iteration
  Issue 245 - enhancement to batch taxon search tab (#523)
  added biosecurity user assertion
  biocache-hubs change due to backend changes (#521)
  ...

# Conflicts:
#	grails-app/controllers/au/org/ala/biocache/hubs/ProxyController.groovy
  • Loading branch information
brucehyslop committed Jan 12, 2022
2 parents e66f790 + d59e4e4 commit 60f14bd
Show file tree
Hide file tree
Showing 29 changed files with 511 additions and 301 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,15 @@
*/
jQuery(document).ready(function() {
// Autocomplete
var bieBaseUrl = BC_CONF.bieWebServiceUrl;
var bieParams = { limit: 20 };
var autoHints = BC_CONF.autocompleteHints; // expects { fq: "kingdom:Plantae" }
$.extend( bieParams, autoHints ); // merge autoHints into bieParams
var autocompleteUrl = BC_CONF.autocompleteUrl;
var params = {};
if (BC_CONF.autocompleteUseBie) {
$.extend(params, {limit: 20});
var autoHints = BC_CONF.autocompleteHints; // expects { fq: "kingdom:Plantae" }
$.extend(params, autoHints); // merge autoHints into params
} else {
$.extend(params, {pageSize: 20});
}

function getMatchingName(item) {
if (item.scientificNameMatches && item.scientificNameMatches.length) {
Expand All @@ -34,7 +39,7 @@ jQuery(document).ready(function() {
} else {
return item.name;
}
};
}

function formatAutocompleteList(list) {
var results = [];
Expand All @@ -46,17 +51,17 @@ jQuery(document).ready(function() {
}

return results;
};
}

$.ui.autocomplete({
source: function (request, response) {
bieParams.q = request.term;
params.q = request.term;
$.ajax( {
url: bieBaseUrl + '/search/auto.json',
url: autocompleteUrl,
dataType: "json",
data: bieParams,
data: params,
success: function( data ) {
response( formatAutocompleteList(data.autoCompleteList) );
response( formatAutocompleteList(BC_CONF.autocompleteUseBie ? data.autoCompleteList : data.searchResults.results) );
}
} );
}
Expand Down
25 changes: 22 additions & 3 deletions grails-app/assets/javascripts/search.js
Original file line number Diff line number Diff line change
Expand Up @@ -248,8 +248,8 @@ $(document).ready(function() {
synListSize++;
synList1 += "<input type='checkbox' name='raw_taxon_guid' id='rawTaxon_" + index + "_" + j +
"' class='rawTaxonCheckBox' value='" + el1.label + "'/>&nbsp;" +
"<a href='" + BC_CONF.contextPath + "/occurrences/search?q=raw_taxon_name:%22" + el1.label +
"%22'>" + el1.label + "</a> (" + el1.count + ")<br/>";
"<a href=\"" + BC_CONF.contextPath + "/occurrences/search?q=raw_taxon_name:%22" + encodeURIComponent(el1.label) +
"%22\">" + el1.label + "</a> (" + el1.count + ")<br/>";
});
}
});
Expand Down Expand Up @@ -645,6 +645,25 @@ $(document).ready(function() {
window.location.href = BC_CONF.serverName + "/occurrences/facets/download" + BC_CONF.facetDownloadQuery + '&facets=' + facetName;
});

$('#copy-al4r').on('click', function() {
var input = document.querySelector('#al4rcode');
navigator.clipboard.writeText(input.value)
.then(() => {
$(this).qtip({
content: jQuery.i18n.prop('list.copylinks.tooltip.copied'),
show: true,
hide: { when: { event: 'mouseout'} }
})})
.catch((error) => { alert(jQuery.i18n.prop('list.copylinks.alert.failed') + error) })
});

$('#copy-al4r').on('mouseleave', function() {
$(this).qtip({
content: jQuery.i18n.prop('list.copylinks.tooltip.copytoclipboard'),
show: { when: { event: 'mouseover'} }
})
})

// when open the user preference dlg
$('.DQPrefSettingsLink').click(function() {
var prefSettings = $('#DQPrefSettings');
Expand Down Expand Up @@ -1185,7 +1204,7 @@ $(document).ready(function() {
});

// user preference settings and download link tooltips will be above the control
$("#usersettings, a.newDownload").qtip({
$("#usersettings, a.copyLink").qtip({
style: {
classes: 'ui-tooltip-rounded ui-tooltip-shadow'
},
Expand Down
30 changes: 25 additions & 5 deletions grails-app/assets/javascripts/show.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,33 @@
//= require linkifyjs/linkify-jquery.js
//= require leaflet/leaflet.js
//= require leaflet-plugins/layer/tile/Google.js
//= require biocache-hubs.js
//= require_self
*/
/**
* JQuery on document ready callback
*/

function updatei18n() {
$('.i8nupdate').each(function() {
var key = $(this).attr('i18nkey')
if (key !== undefined) {
$(this).text(jQuery.i18n.prop(key));
}
});
}

$(document).ready(function() {
if (typeof BC_CONF != 'undefined' && BC_CONF.hasOwnProperty('contextPath')) {
jQuery.i18n.properties({
name: 'messages',
path: BC_CONF.contextPath + '/messages/i18n/',
mode: 'map',
async: true,
cache: true,
language: BC_CONF.locale, // default is to use browser specified locale
callback: updatei18n
});
}

$('#showUncheckedTests').on('click', function(e){
$('.uncheckTestResult').toggle();
Expand Down Expand Up @@ -481,7 +501,7 @@ function refreshUserAnnotations(){
// if the code == 50000, then we have verification - so don't display here
if (userAssertion.code != 50000) {
$clone.prop('id', "userAnnotation_" + userAssertion.uuid);
$clone.find('.issue').text(jQuery.i18n.prop(userAssertion.name));
$clone.find('.issue').text(jQuery.i18n.prop(userAssertion.name)).attr('i18nkey', userAssertion.name);
$clone.find('.user').text(userAssertion.userDisplayName);
if (userAssertion.hasOwnProperty('comment')) {
$clone.find('.comment').text('Comment: ' + userAssertion.comment);
Expand Down Expand Up @@ -533,8 +553,8 @@ function refreshUserAnnotations(){
}
if (userAssertion.relatedRecordReason) {
$clone.find('.related-record-reason').show();
$clone.find('.related-record-reason-span').text(jQuery.i18n.prop('related.record.reason.' + userAssertion.relatedRecordReason));
$clone.find('.related-record-reason-explanation').text(jQuery.i18n.prop('related.record.reason.explanation.' + userAssertion.relatedRecordReason)).show();
$clone.find('.related-record-reason-span').text(jQuery.i18n.prop('related.record.reason.' + userAssertion.relatedRecordReason)).attr('i18nkey', 'related.record.reason.' + userAssertion.relatedRecordReason);
$clone.find('.related-record-reason-explanation').text(jQuery.i18n.prop('related.record.reason.explanation.' + userAssertion.relatedRecordReason)).attr('i18nkey', 'related.record.reason.explanation.' + userAssertion.relatedRecordReason).show();
}
if (userAssertion.userRole != null) {
$clone.find('.userRole').text(', ' + userAssertion.userRole);
Expand Down Expand Up @@ -575,7 +595,7 @@ function refreshUserAnnotations(){
var $clone = $('#userVerificationTemplate').clone();
$clone.prop('id', "userVerificationAnnotation_" + sortedVerifiedAssertion[i].uuid);
var qaStatusMessage = jQuery.i18n.prop("user_assertions." + sortedVerifiedAssertion[i].qaStatus);
$clone.find('.qaStatus').text(qaStatusMessage);
$clone.find('.qaStatus').text(qaStatusMessage).attr('i18nkey', "user_assertions." + sortedVerifiedAssertion[i].qaStatus);
$clone.find('.comment').text(sortedVerifiedAssertion[i].comment);
$clone.find('.userDisplayName').text(sortedVerifiedAssertion[i].userDisplayName);
$clone.find('.created').text((moment(sortedVerifiedAssertion[i].created, "YYYY-MM-DDTHH:mm:ssZ").format('YYYY-MM-DD HH:mm:ss')));
Expand Down
77 changes: 77 additions & 0 deletions grails-app/assets/stylesheets/search.css
Original file line number Diff line number Diff line change
Expand Up @@ -1097,3 +1097,80 @@ a.leaflet-control-zoom-fullscreen + a.leaflet-control-zoom-fullscreen {
font-style: normal;
font-weight: bold;
}

#dq-collapse-caret {
color: black;
}

#DQProfileDetails .filter-description {
word-break: break-word;
}

#DQProfileDetails .filter-value {
word-break: keep-all;
}

#DQProfileDetails .filter-value span{
white-space: nowrap;
}

#DQManageFilters .expand {
vertical-align: middle;
margin: 0;
padding: 0;
text-decoration: none;
font-size: 14px
}

#DQManageFilters .expanded {
vertical-align: middle;
margin: 0;
font-style: italic;
}

.valign-middle {
vertical-align: middle;
}

.DQPrefSettingsLink {
float: right;
}

.DQPrefSettingsLink span {
color: black;
}

#excluded, #filter-value {
margin-bottom: 0
}

#view-excluded, #expandfilters {
text-decoration: none;
padding: 0;
}

#DQDetailsTable {
margin-top: 20px;
}

#fqdetail-heading-description {
font-style: italic;
}

#download-button-area {
padding-right: 5px;
}

a.copyLink {
border-color: black;
color: black
}

#copy-al4r {
border-color: black;
}

#content .tooltip-inner {
word-break: break-word;
white-space: normal;
}
2 changes: 1 addition & 1 deletion grails-app/conf/plugin.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ test.var = "test"
// used to link temporary data resources back to an originating sandbox.
sandbox.uploadSource=''
advancedTaxaField = "taxa" // used in advanced form for the 4 taxa query inputs

alerts.myannotation.enabled = false
clubRoleForHub = "ROLE_ADMIN"
// whether map or list is the default tab to show - empty for list and "mapView" for map
defaultListView = "" // 'mapView' or 'listView'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ class AdminController {

def clearAllCaches() {
def message = doClearAllCaches()
flash.message = message.replaceAll("\n","<br/>")
redirect(action:'index')
flash.message = message.replaceAll("\n", "<br/>")
redirect(action: 'index')
}

private String doClearAllCaches() {
Expand All @@ -47,22 +47,22 @@ class AdminController {

def clearCollectoryCache() {
flash.message = webServicesService.doClearCollectoryCache()
redirect(action:'index')
redirect(action: 'index')
}

def clearLongTermCache() {
flash.message = webServicesService.doClearLongTermCache()
redirect(action:'index')
redirect(action: 'index')
}

def clearFacetsCache() {
flash.message = doClearFacetsCache()
redirect(action:'index')
redirect(action: 'index')
}

def clearPropertiesCache() {
flash.message = doClearPropertiesCache()
redirect(action:'index')
redirect(action: 'index')
}

def clearRecordCountCache() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ class AdminInterceptor {
// old-style AUTH config - bypass
true
} else if (!authService?.userInRole(grailsApplication.config.getProperty("auth.admin_role", String, "ROLE_ADMIN"))) {
log.debug "User not authorised to access the page: ${params.controller}/${params.action?:''}. Redirecting to index."
flash.message = "You are not authorised to access the page: ${params.controller}/${params.action?:''}."
log.debug "User not authorised to access the page: ${params.controller}/${params.action ?: ''}. Redirecting to index."
flash.message = "You are not authorised to access the page: ${params.controller}/${params.action ?: ''}."
redirect(controller: "home", action: "index")
false
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class AssertionsController {
JSONArray qualityAssertions = webServicesService.getQueryAssertions(id)
Boolean hasClubView = request.isUserInRole("${grailsApplication.config.clubRoleForHub}")
String userAssertionStatus = webServicesService.getRecord(id, hasClubView)?.raw.userAssertionStatus
Map combined = [userAssertions: userAssertions?:[], assertionQueries: qualityAssertions?:[], userAssertionStatus: userAssertionStatus?:"" ]
Map combined = [userAssertions: userAssertions ?: [], assertionQueries: qualityAssertions ?: [], userAssertionStatus: userAssertionStatus ?: ""]
render combined as JSON
}

Expand All @@ -49,9 +49,9 @@ class AssertionsController {
def addAssertion() {
String recordUuid = params.recordUuid
String code = params.code
String comment = params.comment?:''
String userAssertionStatus = params.userAssertionStatus?: ""
String assertionUuid = params.assertionUuid?: ""
String comment = params.comment ?: ''
String userAssertionStatus = params.userAssertionStatus ?: ""
String assertionUuid = params.assertionUuid ?: ""
String relatedRecordId = params.relatedRecordId ?: ''
String relatedRecordReason = params.relatedRecordReason ?: ''
UserDetails userDetails = authService?.userDetails() // will return null if not available/not logged in
Expand All @@ -70,8 +70,8 @@ class AssertionsController {
Map postResponse = webServicesService.addAssertion(recordUuid, code, comment, userDetails.userId, userDetails.displayName, userAssertionStatus, assertionUuid, relatedRecordId, relatedRecordReason)

if (postResponse.statusCode == 201) {
log.info("Called REST service. Assertion should be added" )
render(status: postResponse.statusCode, text:'Assertion added')
log.info("Called REST service. Assertion should be added")
render(status: postResponse.statusCode, text: 'Assertion added')
} else {
log.error "Unexpected error: ${postResponse.statusCode} (${postResponse.statusCode.class.name}) : ${postResponse.statusMsg}"
render(status: postResponse.statusCode, text: postResponse.statusMsg)
Expand All @@ -80,9 +80,9 @@ class AssertionsController {
def errorMsg = (!userDetails) ?
"User details not found" :
"Required parameters not provided: ${(!recordUuid) ? 'recordUuid' : ''} ${(!code) ? 'code' : ''}"
log.warn("Unable to add assertions. ${errorMsg}." )
log.warn("Unable to add assertions. ${errorMsg}.")

render(status:400, text: errorMsg)
render(status: 400, text: errorMsg)
}
}

Expand All @@ -100,17 +100,17 @@ class AssertionsController {
Map postResponse = webServicesService.deleteAssertion(recordUuid, assertionUuid)

if (postResponse.statusCode == 200) {
log.info("Called REST service. Assertion should be deleted" )
render(status: postResponse.statusCode, text:'Assertion deleted')
log.info("Called REST service. Assertion should be deleted")
render(status: postResponse.statusCode, text: 'Assertion deleted')
} else {
log.error "Unexpected error: ${postResponse.statusCode} (${postResponse.statusCode.class.name}) : ${postResponse.statusMsg}"
render(status: postResponse.statusCode, text: postResponse.statusMsg)
}
} else {
def errorMsg = "Required parameters not provided: ${(!recordUuid) ? 'recordUuid' : ''} ${(!assertionUuid) ? 'assertionUuid' : ''}"
log.warn("Unable to add assertions. ${errorMsg}." )
log.warn("Unable to add assertions. ${errorMsg}.")

render(status:400, text: errorMsg)
render(status: 400, text: errorMsg)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ class BiocacheHubsUrlMappings {
"/explore/your-area"(controller: 'occurrence', action: 'exploreYourArea')
"/search"(controller: 'home')
"/advancedSearch"(controller: 'home', action: 'advancedSearch')
"/simpleSearch"(controller: 'home', action: 'simpleSearch')
"/proxy/$path**" (controller: 'proxy'){
action = [POST:'doPost']
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class DataQualityController {
def webServicesService

static responseFormats = [
list: ['json']
list: ['json']
]

def index() {
Expand All @@ -38,5 +38,4 @@ class DataQualityController {
def allCodes() {
render webServicesService.getAllCodes() as JSON
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ class HelpController {
}

def help() {}

def data() {}

def termsOfUse() {}
}
Loading

0 comments on commit 60f14bd

Please sign in to comment.