Skip to content

Commit

Permalink
Merge pull request #1591 from AtlasOfLivingAustralia/feature/hcat
Browse files Browse the repository at this point in the history
Feature/hcat
  • Loading branch information
jack-brinkman authored Apr 28, 2024
2 parents 07731c7 + 242bb11 commit 0b99dfe
Show file tree
Hide file tree
Showing 10 changed files with 197 additions and 7 deletions.
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
biocollectVersion=6.8-LOGIN-SNAPSHOT
biocollectVersion=6.8-REFASSESS-SNAPSHOT
grailsVersion=5.1.9
grailsGradlePluginVersion=5.1.5
assetPipelineVersion=3.3.4
Expand Down
1 change: 1 addition & 0 deletions grails-app/assets/javascripts/hubs.js
Original file line number Diff line number Diff line change
Expand Up @@ -480,6 +480,7 @@ function ContentViewModel(config) {
self.hideBreadCrumbs = ko.observable(config.hideBreadCrumbs || false);
self.hideProjectAndSurvey = ko.observable(config.hideProjectAndSurvey || false);
self.hideCancelButtonOnForm = ko.observable(config.hideCancelButtonOnForm || false);
self.hideNewButtonOnRecordView = ko.observable(config.hideNewButtonOnRecordView || false);
self.showNote = ko.observable(config.showNote || false);
self.recordNote = ko.observable(config.recordNote || '');
self.industries = ko.observable(config.industries || false);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
package au.org.ala.biocollect

import au.org.ala.biocollect.merit.*
import grails.converters.JSON
import grails.web.servlet.mvc.GrailsParameterMap

import java.time.Instant

class ReferenceAssessmentController {
UserService userService
ProjectActivityService projectActivityService
ActivityService activityService


private def createAssessmentRecordFromReference(Object referenceActivity, Object assessProjectActivity, boolean deIdentify) {
def refDoc = referenceActivity.documents[0]

def baseUrl = ''
if (!refDoc["url"].startsWith('http')) {
baseUrl = grailsApplication.config.getProperty("grails.serverURL", String)
}

def assessPhoto = [
licence: refDoc["licence"],
notes: refDoc["notes"],
filesize: refDoc["filesize"],
staged: true,
url: baseUrl + refDoc["url"],
filename: refDoc["filename"],
attribution: referenceActivity.outputs[0].data["imageAttribution"],
name: refDoc["name"],
documentId: '',
contentType: refDoc["contentType"],
dateTaken: refDoc["dateTaken"],
formattedSize: refDoc["formattedSize"],
thumbnailUrl: baseUrl + refDoc["thumbnailUrl"],
status: "active"
]

def assessActivity = [
outputs: [
[
outputId: "",
outputNotCompleted: false,
data: [
recordedBy: userService.getCurrentUserDisplayName(),
upperConditionBound: "0",
lowerConditionBound: "0",
overallConditionBestEstimate: "0",
mvgGroup: referenceActivity.outputs[0].data.vegetationStructureGroup,
huchinsonGroup: referenceActivity.outputs[0].data.huchinsonGroup,
sitePhoto: [assessPhoto],
deIdentify: deIdentify ? "Yes" : "No"
],
name: assessProjectActivity["pActivityFormName"]
]
],
projectActivityId: assessProjectActivity["projectActivityId"],
userId: userService.getCurrentUserId(),
projectStage: "",
embargoed: false,
type: assessProjectActivity["pActivityFormName"],
projectId: assessProjectActivity["projectId"],
mainTheme: ""
]

// Create the new assessment activity record
activityService.update("", assessActivity)

// Update the numTimesReferenced field on the reference record
referenceActivity.outputs[0].data.numTimesReferenced =
referenceActivity.outputs[0].data.numTimesReferenced as Integer + 1
activityService.update(referenceActivity.activityId, referenceActivity)

// Return the assessment activity
assessActivity
}

def requestRecords() {
def config = grailsApplication.config.getProperty("refAssess", Map)
def body = request.JSON
def result

// Ensure BioCollect is configured for reference assessment projects
if (!config) {
response.status = 500
result = [message: 'The application is not configured for reference assessment projects']
render result as JSON
return
}

// Ensure the body of the request contains the required fields
if (!body['vegetationStructureGroups'] || !body['climateGroups'] || !body.keySet().contains('deIdentify')) {
response.status = 400
result = [message: 'Please ensure the assessment record request contains all relevant fields']
render result as JSON
return
}

// Ensure the user is authenticated
if (!userService.getCurrentUserId()) {
response.status = 403
result = [message: 'User is not authenticated']
render result as JSON
return
}

// Get the activity records for the reference survey
def refActivitiesSearch = activityService.search([
projectActivityId: config.reference.projectActivityId
])
def refActivities = refActivitiesSearch.resp.activities
def maxRecordsToCreate = config.assessment.maxRecordsToCreate as Integer

// Ensure the reference records exist
def numRefActivities = refActivities?.size()
if (numRefActivities == 0) {
response.status = 404
result = [message: 'No reference records found in reference survey']
render result as JSON
return
}

// Filter out any records without data or documents
refActivities = refActivities.findAll {
it.outputs[0].keySet().contains('data') &&
it.documents.size() > 0
}

// Filter out reference activities by the supplied vegetation structure groups & climate groups
refActivities = refActivities.findAll {
body["vegetationStructureGroups"].contains(it.outputs[0].data["vegetationStructureGroup"]) &&
body["climateGroups"].contains(it.outputs[0].data["huchinsonGroup"])
}

// Split & sort the reference activities into:
// Priority records (assessed <= 3 times), prioritising records assessed the MOST
// Other records (assessed > 3 times), prioritising records assessed the LEAST

def priorityRecords = refActivities
.findAll { it.outputs[0].data.numTimesReferenced as Integer <= 3 }
.sort{ -(it.outputs[0].data.numTimesReferenced as Integer) }
def otherRecords = refActivities
.findAll { it.outputs[0].data.numTimesReferenced as Integer > 3 }
.sort{ it.outputs[0].data.numTimesReferenced as Integer }

// Combine the two lists
refActivities = priorityRecords + otherRecords

// Ensure there are reference records after filtering
if (refActivities.size() == 0) {
response.status = 400
result = [message: "No reference images matching your criteria could be found."]
render result as JSON
return
}

def assessProjectActivity = projectActivityService.get(config.assessment.projectActivityId)
def assessActivities = []
for (
int projectIndex = 0;
projectIndex < Math.min(maxRecordsToCreate, refActivities.size());
projectIndex++
) {
assessActivities.push(
createAssessmentRecordFromReference(
refActivities[projectIndex],
assessProjectActivity,
body['deIdentify']
)
)
}

response.status = 200
result = [message: "Found ${assessActivities.size()} images for assessment, please standby..."]
render result as JSON
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
package au.org.ala.biocollect

import au.org.ala.biocollect.merit.SettingService
import au.org.ala.web.AlaSecured
import au.org.ala.biocollect.merit.UserService
import au.org.ala.biocollect.merit.hub.HubSettings
import au.org.ala.web.NoSSO
import au.org.ala.web.SSO

@SSO
class StaticPageController {
SettingService settingService
UserService userService
@NoSSO
def index() {
String page = params.page;
Expand Down Expand Up @@ -44,13 +46,14 @@ class StaticPageController {
/**
* Save static page text
*/
@AlaSecured(value = ['ROLE_ADMIN'])
def saveTextAreaSetting() {
String text = params.textValue
String settingKey = params.settingKey
String returnUrl = params.returnUrl ?: g.createLink(controller: 'staticPage', action: 'index', absolute: true, params: [page: settingKey])

if (settingKey) {
if (!userService.doesUserHaveHubRole("admin")) {
flash.errorMessage = "You do not have correct permissions to perform this action"
} else if (settingKey) {
settingService.setSettingText(settingKey, text)
flash.message = "Successfully saved."
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -167,11 +167,14 @@ class UrlMappings {
format = 'json'
}

"/referenceAssessment/requestRecords"(controller: "referenceAssessment", action: [POST: "requestRecords"])

"500"(controller:'error', action:'response500')
"404"(controller:'error', action:'response404')


// Following api's are used by external mobile clients

"/ws/project/search"(controller: "project", action: 'search')
"/ws/survey/list/$id"(controller: "project", action: 'listSurveys')
"/ws/attachment/upload"(controller: "image", action: 'upload')
Expand Down
6 changes: 5 additions & 1 deletion grails-app/views/admin/editHub.gsp
Original file line number Diff line number Diff line change
Expand Up @@ -486,7 +486,11 @@

<h5>Data entry page</h5>
<div class="checkbox">
<input type="checkbox" data-bind="checked: hideCancelButtonOnForm"> Hide cancel button on form create page
<input type="checkbox" data-bind="checked: hideCancelButtonOnForm"> Hide 'Cancel' button on form create page
</div>
<h5>Record view page</h5>
<div class="checkbox">
<input type="checkbox" data-bind="checked: hideNewButtonOnRecordView"> Hide 'Add new record' button on form create page
</div>
<!-- /ko -->
<h3>Quick links</h3>
Expand Down
2 changes: 1 addition & 1 deletion grails-app/views/bioActivity/index.gsp
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@
<g:if test="${hasEditRights}">
<a class="btn btn-primary-dark btn-lg" href="${createLink(controller: 'bioActivity', action: 'edit')}/${activity.activityId}"><span class="fas fa-pencil-alt"></span> Edit</a>
</g:if>
<g:if test="${userIsProjectMember}">
<g:if test="${userIsProjectMember && (!hubConfig.content?.hideNewButtonOnRecordView)}">
<a class="btn btn-primary-dark btn-lg" href="${createLink(controller: 'bioActivity', action: 'create')}/${pActivity.projectActivityId}"><span class="fas fa-plus"></span> Add new record</a>
</g:if>
</div>
Expand Down
1 change: 0 additions & 1 deletion grails-app/views/project/_CSAdmin.gsp
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,6 @@
</div>
</g:if>
</g:if>

</div>
</div>
</div>
Expand Down
1 change: 1 addition & 0 deletions grails-app/views/staticPage/index.gsp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
<head>
<meta name="layout" content="${mobile ? "mobile" : "bs4"}"/>
<title></title>
<asset:javascript src="common.js"/>
</head>

<body>
Expand Down
1 change: 1 addition & 0 deletions src/integration-test/resources/data/alaHub.js
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ var alaHub = {
"hideProjectSurveyDownloadXLSX" : false,
"hideBreadCrumbs" : false,
"hideCancelButtonOnForm" : false,
"hideNewButtonOnRecordView" : false,
"industries" : true,
"enablePartialSearch" : false,
"overriddenLabels" : [
Expand Down

0 comments on commit 0b99dfe

Please sign in to comment.