Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v7.20.5 #3643

Merged
merged 107 commits into from
Sep 3, 2024
Merged

v7.20.5 #3643

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
107 commits
Select commit Hold shift + click to select a range
32163aa
moves tag example images to a common dir
misaugstad Aug 6, 2024
8c00b3f
updates cursor on tag list in new Validate
misaugstad Aug 6, 2024
fdea14f
adds example image tooltips to tags in new Validate
misaugstad Aug 6, 2024
43ef0b1
adds initial set of tooltips to disagree/unsure buttons in Validate
misaugstad Aug 7, 2024
6e8f413
fixes extra comment box showing up when switching validations
misaugstad Aug 7, 2024
0b3d5b3
adds tooltips for all disagree/unsure reason buttons in new Validate
misaugstad Aug 9, 2024
f5811b6
Add keyboard shortcuts for agree, disagree, unsure on gallery expande…
jsomeara Aug 11, 2024
09b2e81
Better comments
jsomeara Aug 11, 2024
811ed38
Deactivate google's default keybinds
jsomeara Aug 11, 2024
0495717
Gallery expanded view: Add keybindings for arrow left and arrow right
jsomeara Aug 12, 2024
1fe82c3
Use self.open or modal.open instead of checking the selector each time.
jsomeara Aug 12, 2024
b9c01fc
Gallery keyboard shortcuts: dedicated Keyboard.js file
jsomeara Aug 12, 2024
582f3fb
Add keyboard shortcut logging for validate in expanded view gallery
jsomeara Aug 12, 2024
513d4bf
add logging for next/prev label expanded gallery view
jsomeara Aug 12, 2024
202a2f0
Merge branch 'develop' into 3612-add-shortcuts-expanded-gallery
jsomeara Aug 20, 2024
5e89f49
Remove semi colons from end of functions
jsomeara Aug 21, 2024
d051c4a
Use key up instead of key down event for gallery shortcuts
jsomeara Aug 21, 2024
cd92c5d
Switch to using event.key instead of event.code for gallery shortcuts
jsomeara Aug 21, 2024
f8eb4ae
Modify self.open in openModal function
jsomeara Aug 21, 2024
b06a8e2
Shorter comment message in Validation Menu
jsomeara Aug 21, 2024
00c3087
Restruction Keyboard system. Centralize keybindings in Gallery Keyboa…
jsomeara Aug 21, 2024
3b0e08f
Merge branch '3612-add-shortcuts-expanded-gallery' of https://github.…
jsomeara Aug 21, 2024
4112465
Merge branch 'develop' into 3612-add-shortcuts-expanded-gallery
jsomeara Aug 21, 2024
b64deb7
Make gallery expanded view description scrollable
jsomeara Aug 22, 2024
9b39028
Gallery expanded view scrollable description - default margin bottom
jsomeara Aug 22, 2024
489ee5f
add comments
jsomeara Aug 22, 2024
2be6bd1
Add additional lastPage check.
jsomeara Aug 22, 2024
e3d8a4d
Merge branch 'develop' into 3621-proper-end-detection-gallery-expanded
jsomeara Aug 23, 2024
10ea910
Merge branch 'develop' into 3622-gallery-expanded-view-scrollable-des…
jsomeara Aug 23, 2024
8ccf0a5
Merge branch 'develop' into 3612-add-shortcuts-expanded-gallery
jsomeara Aug 23, 2024
087ec9a
Add 15px padding to bottom desc and reduce height of tags container f…
jsomeara Aug 24, 2024
99625a6
Use text content instead of raw html
jsomeara Aug 24, 2024
235fd5e
Add username restrictions
jsomeara Aug 24, 2024
0877361
adds tool from ASSETS 2024 to list of validation methods
misaugstad Aug 26, 2024
340dd72
On validate endpoint, delete label's validation if already exists for…
jsomeara Aug 27, 2024
b6c19d2
Add comments
jsomeara Aug 27, 2024
6ed13f5
More accurate function comment
jsomeara Aug 27, 2024
73956dd
Merge branch 'develop' into 3612-add-shortcuts-expanded-gallery
jsomeara Aug 27, 2024
de4f21e
Merge branch 'develop' into 3622-gallery-expanded-view-scrollable-des…
jsomeara Aug 27, 2024
6752f41
Merge branch 'develop' into 3621-proper-end-detection-gallery-expanded
jsomeara Aug 27, 2024
3087146
Merge branch 'develop' into avoid-raw-html-code
jsomeara Aug 27, 2024
086c7cf
Merge branch 'develop' into 3629-update-validation-properly
jsomeara Aug 27, 2024
4c92cfa
Properly truncate long gallery tags
jsomeara Aug 27, 2024
f8a2f41
Merge pull request #3625 from ProjectSidewalk/3621-proper-end-detecti…
misaugstad Aug 27, 2024
f7faa37
Minor fix in truncating gallery card tags
jsomeara Aug 27, 2024
c9dbd8a
Add max height to tags
jsomeara Aug 27, 2024
208bedd
Reduce gallery modal tags font size
jsomeara Aug 27, 2024
04969ec
Fix gallery scrollable description race condition
jsomeara Aug 27, 2024
f13c491
Merge branch 'develop' into 3622-gallery-expanded-view-scrollable-des…
jsomeara Aug 27, 2024
46d6728
Merge pull request #3634 from ProjectSidewalk/3464-truncate-gallery-t…
misaugstad Aug 27, 2024
4e9fc7b
Add DB evolution to delete existing duplicate validations
jsomeara Aug 28, 2024
5c4ac5d
Add constraint to evolution
jsomeara Aug 28, 2024
39e94a8
Match constraint naming scheme
jsomeara Aug 28, 2024
e16dcb3
Follow constraint naming scheme - minor fix
jsomeara Aug 28, 2024
57d003c
Follow constraint naming scheme - minor fix x2
jsomeara Aug 28, 2024
ebba03e
Add constraint to slick
jsomeara Aug 28, 2024
1e7a38e
Replace hacky setTimeout fix with proper fix
jsomeara Aug 28, 2024
719eeca
Prevent constraint from attempting to be created again
jsomeara Aug 28, 2024
cab78d8
Decrease font size for all text in expanded view info using vw.
jsomeara Aug 28, 2024
323f8e6
Use CSS instead of JS
jsomeara Aug 28, 2024
7fc3868
Merge branch 'develop' into 3622-gallery-expanded-view-scrollable-des…
jsomeara Aug 28, 2024
4cd8694
Add Downs to evolution
jsomeara Aug 28, 2024
0fe953e
Further remove unecessary scripting
jsomeara Aug 28, 2024
b531a99
Merge branch '3622-gallery-expanded-view-scrollable-description' of h…
jsomeara Aug 28, 2024
4f8f4d3
Don't fill space fully because this messes up short tags
jsomeara Aug 28, 2024
158d987
Merge branch 'develop' into 3612-add-shortcuts-expanded-gallery
jsomeara Aug 28, 2024
05dd996
Merge pull request #3637 from ProjectSidewalk/3636-short-gallery-tags
misaugstad Aug 29, 2024
feba455
Merge branch 'develop' of https://github.com/ProjectSidewalk/Sidewalk…
misaugstad Aug 29, 2024
54fa95c
adds severity tooltips for Crosswalk label type
misaugstad Aug 29, 2024
a964423
replaces example image for very long crossing tag
misaugstad Aug 29, 2024
ac0c881
adds severity example images from Explore page to new Validate page
misaugstad Aug 29, 2024
e590718
Explore page no longer attempts to get severity images for Other labe…
misaugstad Aug 29, 2024
b32b58b
tooltips on new Validate now correctly change for new missions w diff…
misaugstad Aug 29, 2024
c133332
consolidates code for disagree & unsure buttons on new Validate
misaugstad Aug 30, 2024
a56fbea
Added escape sequence for double quotes
mxbastidasr Aug 30, 2024
d6db06d
Merge pull request #3641 from ProjectSidewalk/3580-new-validate-tooltips
misaugstad Aug 30, 2024
e1fb0b8
Gallery tags closer to tags header & minimum of two rows
jsomeara Aug 31, 2024
3a6bb9a
Merge branch 'develop' into 3622-gallery-expanded-view-scrollable-des…
jsomeara Aug 31, 2024
7397bf4
Fix bug with gallery-modal-info height
jsomeara Aug 31, 2024
1d175cb
Increase gallery severity icon viewbox
jsomeara Aug 31, 2024
67424c3
More ideal distance between gallery tags and tags header
jsomeara Aug 31, 2024
34d4dee
Merge branch 'develop' into 3612-add-shortcuts-expanded-gallery
jsomeara Sep 1, 2024
4dae1ca
Expand viewbox horizontally slightly in gallery severity smiley icons
jsomeara Sep 1, 2024
b5d3e4d
Add logging events for NextPage and PrevPage
jsomeara Sep 1, 2024
2862fd7
Add e.key check for undefined
jsomeara Sep 1, 2024
f2a906c
Remove formatter's changes
jsomeara Sep 2, 2024
bedd7f8
Merge branch 'develop' into avoid-raw-html-code
jsomeara Sep 2, 2024
68edeb9
Merge branch 'develop' into 3629-update-validation-properly
jsomeara Sep 2, 2024
63242e5
Merge pull request #3613 from jsomeara/3612-add-shortcuts-expanded-ga…
misaugstad Sep 2, 2024
9c4003d
fixes padding for Gallery expanded view thumbs
misaugstad Sep 2, 2024
6699af4
Merge pull request #3624 from ProjectSidewalk/3622-gallery-expanded-v…
misaugstad Sep 2, 2024
4564528
Minor changes to evolution 242
jsomeara Sep 2, 2024
eb26bf0
Merge branch '3629-update-validation-properly' of https://github.com/…
jsomeara Sep 2, 2024
1268f64
Make countValidationsFromUserAndLabel a one-liner
jsomeara Sep 2, 2024
b288205
Merge branch 'develop' into 3629-update-validation-properly
jsomeara Sep 2, 2024
e556929
Merge pull request #3632 from ProjectSidewalk/3629-update-validation-…
misaugstad Sep 2, 2024
5c44c90
Merge pull request #3640 from ProjectSidewalk/3630-CSV-Parse-Double-Q…
misaugstad Sep 2, 2024
fa83e5e
Display clear error message on navbar sign up for invalid username
jsomeara Sep 3, 2024
353a7dd
Check for invalid username before checking for existing users.
jsomeara Sep 3, 2024
1ac2986
move _escapeHTML to Utilities.js
jsomeara Sep 3, 2024
6a8f380
Set first child href attribute instead of td element
jsomeara Sep 3, 2024
c6d0de5
Merge branch 'develop' into avoid-raw-html-code
jsomeara Sep 3, 2024
a591058
small style cleanup
misaugstad Sep 3, 2024
67eb88d
Merge pull request #3631 from ProjectSidewalk/avoid-raw-html-code
misaugstad Sep 3, 2024
fcd2d6c
Merge branch 'master' of https://github.com/ProjectSidewalk/SidewalkW…
misaugstad Sep 3, 2024
85cf801
adds escape char for quotes in CSVs for raw labels API
misaugstad Sep 3, 2024
9d44e41
7.20.4 -> 7.20.5
misaugstad Sep 3, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ module.exports = function(grunt) {
'public/javascripts/Gallery/src/cards/*.js',
'public/javascripts/Gallery/src/data/*.js',
'public/javascripts/Gallery/src/filter/*.js',
'public/javascripts/Gallery/src/keyboard/*.js',
'public/javascripts/Gallery/src/validation/*.js',
'public/javascripts/Gallery/src/displays/*.js',
'public/javascripts/Gallery/src/modal/*.js',
Expand Down
179 changes: 95 additions & 84 deletions app/controllers/SignUpController.scala
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,13 @@ class SignUpController @Inject() (
extends Silhouette[User, SessionAuthenticator] with ProvidesHeader {


/**
* Helper function to check if username contain invalid characters.
*/
private def containsInvalidCharacters(username: String): Boolean = {
username.exists(c => c == '"' || c == '\'' || c == '<' || c == '>' || c == '&')
}

/**
* Registers a new user.
*/
Expand All @@ -60,91 +67,95 @@ class SignUpController @Inject() (
// If they are getting community service hours, make sure they redirect to the instructions page.
val serviceHoursUser: Boolean = data.serviceHours == Messages("yes.caps")
val nextUrl: Option[String] = if (serviceHoursUser && url.isDefined) Some("/serviceHoursInstructions") else url
// Check presence of user by username.
UserTable.find(data.username) match {
case Some(user) =>
WebpageActivityTable.save(WebpageActivity(0, oldUserId, ipAddress, "Duplicate_Username_Error", timestamp))
// Future.successful(Redirect(routes.UserController.signUp()).flashing("error" -> Messages("authenticate.error.username.exists")))
Future.successful(Status(409)(Messages("authenticate.error.username.exists")))
case None =>

// Check presence of user by email.
UserTable.findEmail(data.email.toLowerCase) match {
case Some(user) =>
WebpageActivityTable.save(WebpageActivity(0, oldUserId, ipAddress, "Duplicate_Email_Error", timestamp))
// Future.successful(Redirect(routes.UserController.signUp()).flashing("error" -> Messages("authenticate.error.email.exists")))
Future.successful(Status(409)(Messages("authenticate.error.email.exists")))
case None =>
// Check if passwords match and are at least 6 characters.
if (data.password != data.passwordConfirm) {
Future.successful(Redirect(routes.UserController.signUp()).flashing("error" -> Messages("authenticate.error.password.mismatch")))
} else if (data.password.length < 6) {
Future.successful(Redirect(routes.UserController.signUp()).flashing("error" -> Messages("authenticate.error.password.length")))
} else {
val authInfo = passwordHasher.hash(data.password)
val user = User(
userId = request.identity.map(_.userId).getOrElse(UUID.randomUUID()),
loginInfo = LoginInfo(CredentialsProvider.ID, data.email.toLowerCase),
username = data.username,
email = data.email.toLowerCase,
role = None
)

val newAuthenticator: Future[SessionAuthenticator] = for {
user <- userService.save(user)
authInfo <- authInfoService.save(user.loginInfo, authInfo)
authenticator <- env.authenticatorService.create(user.loginInfo)
} yield {
// Set the user role, assign the neighborhood to audit, and add to the user_stat table.
UserRoleTable.setRole(user.userId, "Registered", Some(serviceHoursUser))
UserCurrentRegionTable.assignRegion(user.userId)
UserStatTable.addUserStatIfNew(user.userId)

// Log the sign up/in.
val timestamp: Timestamp = new Timestamp(Instant.now.toEpochMilli)
WebpageActivityTable.save(WebpageActivity(0, user.userId.toString, ipAddress, "SignUp", timestamp))
WebpageActivityTable.save(WebpageActivity(0, user.userId.toString, ipAddress, "SignIn", timestamp))

env.eventBus.publish(SignUpEvent(user, request, request2lang))
env.eventBus.publish(LoginEvent(user, request, request2lang))
authenticator
}
request.authenticator match {
case Some(oldAuthenticator) =>
// If someone was already authenticated (i.e., they were signed into an anon user account), Play
// doesn't let us sign one account out and the other back in in one response header. So we start
// by redirecting to the "/finishSignUp" endpoint, discarding the old authenticator info and
// sending the new authenticator info in a temp element in the session cookie. The "/finishSignUp"
// endpoint will then move authenticator we put in "temp-authenticator" over to "authenticator"
// where it belongs, finally completing the sign up.
val redirectURL: String = nextUrl match {
case Some(u) => "/finishSignUp?url=" + u
case None => "/finishSignUp"
}
val result = newAuthenticator.map { newAuth =>
// When we encrypt/serialize, we're doing the work of init, serialize, and embed. Found here:
// https://github.com/mohiva/play-silhouette/blob/2.0.x/silhouette/app/com/mohiva/play/silhouette/impl/authenticators/SessionAuthenticator.scala
val authSerialized: String = Crypto.encryptAES(Json.toJson(newAuth).toString())
Redirect(redirectURL).withSession("temp-authenticator" -> authSerialized)
}
oldAuthenticator.discard(result)

case None =>
// If no account was signed in before, we can skip the "/finishSignUp" endpoint step. Instead, we
// embed the authenticator into the session cookie in the normal way and either forward to the
// new URL or simply send the newly authenticated user object.
val result = nextUrl match {
case Some(u) => Future.successful(Redirect(u))
case None => Future.successful(Ok(Json.toJson(user)))
}
for {
newA <- newAuthenticator
value <- env.authenticatorService.init(newA)
resultWithAuth <- env.authenticatorService.embed(value, result)
} yield resultWithAuth
if (containsInvalidCharacters(data.username)) {
WebpageActivityTable.save(WebpageActivity(0, oldUserId, ipAddress, "Invalid_Username_Characters_Error", timestamp))
Future.successful(Status(400)(Messages("authenticate.error.username.invalid")))
} else {
// Check presence of user by username.
UserTable.find(data.username) match {
case Some(user) =>
WebpageActivityTable.save(WebpageActivity(0, oldUserId, ipAddress, "Duplicate_Username_Error", timestamp))
// Future.successful(Redirect(routes.UserController.signUp()).flashing("error" -> Messages("authenticate.error.username.exists")))
Future.successful(Status(409)(Messages("authenticate.error.username.exists")))
case None =>
// Check presence of user by email.
UserTable.findEmail(data.email.toLowerCase) match {
case Some(user) =>
WebpageActivityTable.save(WebpageActivity(0, oldUserId, ipAddress, "Duplicate_Email_Error", timestamp))
// Future.successful(Redirect(routes.UserController.signUp()).flashing("error" -> Messages("authenticate.error.email.exists")))
Future.successful(Status(409)(Messages("authenticate.error.email.exists")))
case None =>
// Check if passwords match and are at least 6 characters.
if (data.password != data.passwordConfirm) {
Future.successful(Redirect(routes.UserController.signUp()).flashing("error" -> Messages("authenticate.error.password.mismatch")))
} else if (data.password.length < 6) {
Future.successful(Redirect(routes.UserController.signUp()).flashing("error" -> Messages("authenticate.error.password.length")))
} else {
val authInfo = passwordHasher.hash(data.password)
val user = User(
userId = request.identity.map(_.userId).getOrElse(UUID.randomUUID()),
loginInfo = LoginInfo(CredentialsProvider.ID, data.email.toLowerCase),
username = data.username,
email = data.email.toLowerCase,
role = None
)

val newAuthenticator: Future[SessionAuthenticator] = for {
user <- userService.save(user)
authInfo <- authInfoService.save(user.loginInfo, authInfo)
authenticator <- env.authenticatorService.create(user.loginInfo)
} yield {
// Set the user role, assign the neighborhood to audit, and add to the user_stat table.
UserRoleTable.setRole(user.userId, "Registered", Some(serviceHoursUser))
UserCurrentRegionTable.assignRegion(user.userId)
UserStatTable.addUserStatIfNew(user.userId)

// Log the sign up/in.
val timestamp: Timestamp = new Timestamp(Instant.now.toEpochMilli)
WebpageActivityTable.save(WebpageActivity(0, user.userId.toString, ipAddress, "SignUp", timestamp))
WebpageActivityTable.save(WebpageActivity(0, user.userId.toString, ipAddress, "SignIn", timestamp))

env.eventBus.publish(SignUpEvent(user, request, request2lang))
env.eventBus.publish(LoginEvent(user, request, request2lang))
authenticator
}
request.authenticator match {
case Some(oldAuthenticator) =>
// If someone was already authenticated (i.e., they were signed into an anon user account), Play
// doesn't let us sign one account out and the other back in in one response header. So we start
// by redirecting to the "/finishSignUp" endpoint, discarding the old authenticator info and
// sending the new authenticator info in a temp element in the session cookie. The "/finishSignUp"
// endpoint will then move authenticator we put in "temp-authenticator" over to "authenticator"
// where it belongs, finally completing the sign up.
val redirectURL: String = nextUrl match {
case Some(u) => "/finishSignUp?url=" + u
case None => "/finishSignUp"
}
val result = newAuthenticator.map { newAuth =>
// When we encrypt/serialize, we're doing the work of init, serialize, and embed. Found here:
// https://github.com/mohiva/play-silhouette/blob/2.0.x/silhouette/app/com/mohiva/play/silhouette/impl/authenticators/SessionAuthenticator.scala
val authSerialized: String = Crypto.encryptAES(Json.toJson(newAuth).toString())
Redirect(redirectURL).withSession("temp-authenticator" -> authSerialized)
}
oldAuthenticator.discard(result)

case None =>
// If no account was signed in before, we can skip the "/finishSignUp" endpoint step. Instead, we
// embed the authenticator into the session cookie in the normal way and either forward to the
// new URL or simply send the newly authenticated user object.
val result = nextUrl match {
case Some(u) => Future.successful(Redirect(u))
case None => Future.successful(Ok(Json.toJson(user)))
}
for {
newA <- newAuthenticator
value <- env.authenticatorService.init(newA)
resultWithAuth <- env.authenticatorService.embed(value, result)
} yield resultWithAuth
}
}
}
}
}
}
}
}
)
Expand Down
6 changes: 6 additions & 0 deletions app/controllers/ValidationTaskController.scala
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,12 @@ class ValidationTaskController @Inject() (implicit val env: Environment[User, Se
val mission: Mission =
MissionTable.resumeOrCreateNewValidationMission(userId, 0.0D, 0.0D, "labelmapValidation", labelTypeId).get

// Check if user already has a validation for this label.
if(LabelValidationTable.countValidationsFromUserAndLabel(userId, submission.labelId) != 0) {
// Delete the user's old label.
LabelValidationTable.deleteLabelValidation(submission.labelId, userId.toString)
}

// Insert a label_validation entry for this label.
val newValId: Int = LabelValidationTable.insert(LabelValidation(0, submission.labelId,
submission.validationResult, submission.oldSeverity, submission.newSeverity, submission.oldTags,
Expand Down
6 changes: 3 additions & 3 deletions app/formats/json/APIFormats.scala
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ object APIFormats {
s"""${LabelPointTable.canvasWidth},${LabelPointTable.canvasHeight},"${l.gsvUrl}",${l.imageLabelDates._1},""" +
s"${l.imageLabelDates._2},${l.labelSeverity.getOrElse("NA")},${l.labelTemporary}," +
s"${l.agreeDisagreeUnsureCount._1},${l.agreeDisagreeUnsureCount._2},${l.agreeDisagreeUnsureCount._3}," +
s""""[${l.labelTags.mkString(",")}]","${l.labelDescription.getOrElse("NA")}",${l.userId}"""
s""""[${l.labelTags.mkString(",")}]","${l.labelDescription.getOrElse("NA").replace("\"", "\"\"")}",${l.userId}"""
}

def rawLabelMetadataToJSON(l: LabelAllMetadata): JsObject = {
Expand Down Expand Up @@ -245,8 +245,8 @@ object APIFormats {

def rawLabelMetadataToCSVRow(l: LabelAllMetadata): String = {
s"${l.labelId},${l.geom.lat},${l.geom.lng},${l.userId},${l.panoId},${l.labelType},${l.severity.getOrElse("NA")}," +
s""""[${l.tags.mkString(",")}]",${l.temporary},"${l.description.getOrElse("NA")}",${l.timeCreated},""" +
s"${l.streetEdgeId},${l.osmStreetId},${l.neighborhoodName},${l.validationInfo.correct.getOrElse("NA")}," +
s""""[${l.tags.mkString(",")}]",${l.temporary},"${l.description.getOrElse("NA").replace("\"", "\"\"")}",""" +
s"${l.timeCreated},${l.streetEdgeId},${l.osmStreetId},${l.neighborhoodName},${l.validationInfo.correct.getOrElse("NA")}," +
s"${l.validationInfo.agreeCount},${l.validationInfo.disagreeCount},${l.validationInfo.unsureCount}," +
s""""[${l.validations.map(v => s"{user_id: ${v._1}, validation: ${LabelValidationTable.validationOptions(v._2)}")}]",""" +
s"${l.auditTaskId},${l.missionId},${l.imageCaptureDate},${l.pov.heading},${l.pov.pitch},${l.pov.zoom}," +
Expand Down
2 changes: 1 addition & 1 deletion app/models/label/LabelHistory.scala
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import scala.slick.lifted.ForeignKeyQuery

case class LabelHistory(labelHistoryId: Int, labelId: Int, severity: Option[Int], tags: List[String], editedBy: String,
editTime: Timestamp, source: String, labelValidationId: Option[Int]) {
require(List("Explore", "ValidateDesktop", "ValidateDesktopNew", "ValidateMobile", "LabelMap", "GalleryImage", "GalleryExpandedImage", "GalleryThumbs", "AdminUserDashboard", "AdminLabelSearchTab").contains(source), "Invalid source for Label History table.")
require(List("Explore", "ValidateDesktop", "ValidateDesktopNew", "ValidateMobile", "LabelMap", "GalleryImage", "GalleryExpandedImage", "GalleryThumbs", "AdminUserDashboard", "AdminLabelSearchTab", "ExternalTagValidationASSETS2024").contains(source), "Invalid source for Label History table.")
}

class LabelHistoryTable(tag: slick.lifted.Tag) extends Table[LabelHistory](tag, "label_history") {
Expand Down
16 changes: 15 additions & 1 deletion app/models/label/LabelValidationTable.scala
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import models.user.{RoleTable, UserRoleTable, UserStatTable}
import play.api.Play.current
import play.api.libs.json.{JsObject, Json}
import scala.slick.jdbc.{StaticQuery => Q}
import scala.slick.lifted.ForeignKeyQuery
import scala.slick.lifted.{ForeignKeyQuery, Index}

case class LabelValidation(labelValidationId: Int,
labelId: Int,
Expand Down Expand Up @@ -71,6 +71,8 @@ class LabelValidationTable (tag: slick.lifted.Tag) extends Table[LabelValidation

def mission: ForeignKeyQuery[MissionTable, Mission] =
foreignKey("label_validation_mission_id_fkey", missionId, TableQuery[MissionTable])(_.missionId)

def userLabelUnique: Index = index("label_validation_user_id_label_id_unique", (userId, labelId), unique = true)
}

/**
Expand All @@ -87,6 +89,18 @@ object LabelValidationTable {

val validationOptions: Map[Int, String] = Map(1 -> "Agree", 2 -> "Disagree", 3 -> "Unsure")

/**
* A function to count all validations by the given user for the given label.
* There should only ever be a maximum of one.
*
* @param userId
* @param labelId The ID of the label
* @return An integer with the count
*/
def countValidationsFromUserAndLabel(userId: UUID, labelId: Int): Int = db.withSession { implicit session =>
validationLabels.filter(v => v.userId === userId.toString && v.labelId === labelId).length.run
}

/**
* Returns how many agree, disagree, or unsure validations a user entered for a given mission.
*
Expand Down
10 changes: 5 additions & 5 deletions app/views/gallery.scala.html
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,19 @@
@* These are templates and are not visible on the screen directly. *@
@* JS clones them, adjusts the attributes and then appends to DOM. *@
<div class="severity-filter-image severity-1 template">
<svg viewBox="0 0 150 150"><use xlink:href="#smiley-neutral"></use></svg>
<svg viewBox="0 0 155 155"><use xlink:href="#smiley-neutral"></use></svg>
</div>
<div class="severity-filter-image severity-2 template">
<svg viewBox="0 0 150 150"><use xlink:href="#smiley-frown-1"></use></svg>
<svg viewBox="0 0 155 155"><use xlink:href="#smiley-frown-1"></use></svg>
</div>
<div class="severity-filter-image severity-3 template">
<svg viewBox="0 0 150 150"><use xlink:href="#smiley-frown-2"></use></svg>
<svg viewBox="0 0 155 155"><use xlink:href="#smiley-frown-2"></use></svg>
</div>
<div class="severity-filter-image severity-4 template">
<svg viewBox="0 0 150 150"><use xlink:href="#smiley-frown-3"></use></svg>
<svg viewBox="0 0 155 155"><use xlink:href="#smiley-frown-3"></use></svg>
</div>
<div class="severity-filter-image severity-5 template">
<svg viewBox="0 0 150 150"><use xlink:href="#smiley-frown-4"></use></svg>
<svg viewBox="0 0 155 155"><use xlink:href="#smiley-frown-4"></use></svg>
</div>

<div id="gallery">
Expand Down
3 changes: 3 additions & 0 deletions app/views/navbar.scala.html
Original file line number Diff line number Diff line change
Expand Up @@ -569,6 +569,9 @@ <h4 class="modal-title" id="sign-up-label">@Messages("authenticate.signup")</h4>
errorMessage = "@Messages("authenticate.error.username.exists")"
}
}
else if(e.status === 400){
errorMessage = e.responseText
}
else { // Some other Bad Request.
errorMessage = '@Messages("authenticate.error.generic")'
}
Expand Down
2 changes: 1 addition & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import play.PlayScala

name := """sidewalk-webpage"""

version := "7.20.4"
version := "7.20.5"

scalaVersion := "2.10.7"

Expand Down
Loading