Skip to content

Commit

Permalink
add disable task confirmation feature
Browse files Browse the repository at this point in the history
  • Loading branch information
jschwarz2030 committed Jan 7, 2025
1 parent 7801e6f commit 97aab16
Show file tree
Hide file tree
Showing 11 changed files with 78 additions and 37 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ class ProjectController @Inject() (
jsonBody = Utils.insertIntoJson(jsonBody, "featured", false)(BooleanWrites)
jsonBody = Utils.insertIntoJson(jsonBody, "enabled", true)(BooleanWrites)
jsonBody = Utils.insertIntoJson(jsonBody, "isArchived", false)(BooleanWrites)
jsonBody = Utils.insertIntoJson(jsonBody, "requireComment", false)(BooleanWrites)
jsonBody
.validate[Project]
.fold(
Expand Down
3 changes: 2 additions & 1 deletion app/org/maproulette/framework/model/Challenge.scala
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,8 @@ case class ChallengeExtra(
taskWidgetLayout: Option[JsValue] = None,
datasetUrl: Option[String] = None,
systemArchivedAt: Option[DateTime] = None,
presets: Option[List[String]] = None
presets: Option[List[String]] = None,
requireComment: Boolean = false
) extends DefaultWrites

case class ChallengeListing(
Expand Down
3 changes: 2 additions & 1 deletion app/org/maproulette/framework/model/Project.scala
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ case class Project(
deleted: Boolean = false,
isVirtual: Option[Boolean] = Some(false),
featured: Boolean = false,
isArchived: Boolean = false
isArchived: Boolean = false,
requireComment: Boolean = false
) extends CacheObject[Long]
with Identifiable {
def grantsToType(granteeType: ItemType) =
Expand Down
3 changes: 2 additions & 1 deletion app/org/maproulette/framework/model/User.scala
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,8 @@ case class UserSettings(
allowFollowing: Option[Boolean] = None,
theme: Option[Int] = None,
customBasemaps: Option[List[CustomBasemap]] = None,
seeTagFixSuggestions: Option[Boolean] = None
seeTagFixSuggestions: Option[Boolean] = None,
disableTaskConfirm: Option[Boolean] = None
) {
def getTheme: String = theme match {
case Some(t) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,7 @@ object ChallengeRepository {
get[Boolean]("challenges.is_archived") ~
get[Int]("challenges.review_setting") ~
get[Option[String]]("challenges.dataset_url") ~
get[Boolean]("challenges.require_comment") ~
get[Option[JsValue]]("challenges.task_widget_layout") ~
get[Option[DateTime]]("challenges.system_archived_at") map {
case id ~ name ~ created ~ modified ~ description ~ infoLink ~ ownerId ~ parentId ~ instruction ~
Expand All @@ -273,7 +274,7 @@ object ChallengeRepository {
mediumPriorityRule ~ lowPriorityRule ~ defaultZoom ~ minZoom ~ maxZoom ~ defaultBasemap ~ defaultBasemapId ~
customBasemap ~ updateTasks ~ exportableProperties ~ osmIdProperty ~ taskBundleIdProperty ~ preferredTags ~ preferredReviewTags ~
limitTags ~ limitReviewTags ~ taskStyles ~ lastTaskRefresh ~ dataOriginDate ~ requiresLocal ~ location ~ bounding ~
deleted ~ virtualParents ~ isArchived ~ reviewSetting ~ datasetUrl ~ taskWidgetLayout ~ systemArchivedAt =>
deleted ~ virtualParents ~ isArchived ~ reviewSetting ~ datasetUrl ~ requireComment ~ taskWidgetLayout ~ systemArchivedAt =>
val hpr = highPriorityRule match {
case Some(c) if StringUtils.isEmpty(c) || StringUtils.equals(c, "{}") => None
case r => r
Expand Down Expand Up @@ -332,7 +333,8 @@ object ChallengeRepository {
reviewSetting,
taskWidgetLayout,
datasetUrl,
systemArchivedAt
systemArchivedAt,
requireComment = requireComment
),
status,
statusMessage,
Expand Down
37 changes: 21 additions & 16 deletions app/org/maproulette/framework/repository/ProjectRepository.scala
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,8 @@ class ProjectRepository @Inject() (override val db: Database, grantService: Gran
*/
def create(project: Project)(implicit c: Option[Connection] = None): Project = {
this.withMRTransaction { implicit c =>
SQL("""INSERT INTO projects (name, owner_id, display_name, description, enabled, is_virtual, featured)
VALUES ({name}, {ownerId}, {displayName}, {description}, {enabled}, {virtual}, {featured})
SQL("""INSERT INTO projects (name, owner_id, display_name, description, enabled, is_virtual, featured, require_comment)
VALUES ({name}, {ownerId}, {displayName}, {description}, {enabled}, {virtual}, {featured}, {requireComment})
RETURNING *""")
.on(
Symbol("name") -> project.name,
Expand All @@ -88,7 +88,8 @@ class ProjectRepository @Inject() (override val db: Database, grantService: Gran
Symbol("description") -> project.description.getOrElse(""),
Symbol("enabled") -> project.enabled,
Symbol("virtual") -> project.isVirtual.getOrElse(false),
Symbol("featured") -> project.featured
Symbol("featured") -> project.featured,
Symbol("requireComment") -> project.requireComment
)
.as(this.parser.*)
.head
Expand All @@ -112,20 +113,22 @@ class ProjectRepository @Inject() (override val db: Database, grantService: Gran
enabled = {enabled},
is_virtual = {virtual},
featured = {featured},
is_archived = {isArchived}
is_archived = {isArchived},
require_comment = {requireComment}
WHERE id = {id}
RETURNING *
""")
.on(
Symbol("name") -> project.name,
Symbol("ownerId") -> project.owner,
Symbol("displayName") -> project.displayName,
Symbol("description") -> project.description,
Symbol("enabled") -> project.enabled,
Symbol("virtual") -> project.isVirtual,
Symbol("featured") -> project.featured,
Symbol("isArchived") -> project.isArchived,
Symbol("id") -> project.id
Symbol("name") -> project.name,
Symbol("ownerId") -> project.owner,
Symbol("displayName") -> project.displayName,
Symbol("description") -> project.description,
Symbol("enabled") -> project.enabled,
Symbol("virtual") -> project.isVirtual,
Symbol("featured") -> project.featured,
Symbol("isArchived") -> project.isArchived,
Symbol("requireComment") -> project.requireComment,
Symbol("id") -> project.id
)
.as(this.parser.*)
.headOption
Expand Down Expand Up @@ -400,8 +403,9 @@ object ProjectRepository extends Readers {
get[Boolean]("projects.deleted") ~
get[Boolean]("projects.is_virtual") ~
get[Boolean]("projects.featured") ~
get[Boolean]("projects.is_archived") map {
case id ~ ownerId ~ name ~ created ~ modified ~ description ~ enabled ~ displayName ~ deleted ~ isVirtual ~ featured ~ isArchived =>
get[Boolean]("projects.is_archived") ~
get[Boolean]("projects.require_comment") map {
case id ~ ownerId ~ name ~ created ~ modified ~ description ~ enabled ~ displayName ~ deleted ~ isVirtual ~ featured ~ isArchived ~ requireComment =>
new Project(
id,
ownerId,
Expand All @@ -415,7 +419,8 @@ object ProjectRepository extends Readers {
deleted,
Some(isVirtual),
featured,
isArchived
isArchived,
requireComment
)
}
}
Expand Down
14 changes: 9 additions & 5 deletions app/org/maproulette/framework/repository/UserRepository.scala
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ class UserRepository @Inject() (
default_basemap = {defaultBasemap}, default_basemap_id = {defaultBasemapId},
locale = {locale}, email = {email}, email_opt_in = {emailOptIn}, leaderboard_opt_out = {leaderboardOptOut},
needs_review = {needsReview}, is_reviewer = {isReviewer}, theme = {theme}, allow_following = {allowFollowing},
properties = {properties}, see_tag_fix_suggestions = {seeTagFixSuggestions}
properties = {properties}, see_tag_fix_suggestions = {seeTagFixSuggestions}, disable_task_confirm = {disableTaskConfirm}
WHERE id = {id} RETURNING ${UserRepository.standardColumns},
(SELECT score FROM user_metrics um WHERE um.user_id = ${user.id}) as score,
(SELECT achievements FROM user_metrics um WHERE um.user_id = ${user.id}) as achievements"""
Expand All @@ -134,7 +134,8 @@ class UserRepository @Inject() (
Symbol("theme") -> user.settings.theme,
Symbol("allowFollowing") -> user.settings.allowFollowing,
Symbol("properties") -> user.properties,
Symbol("seeTagFixSuggestions") -> user.settings.seeTagFixSuggestions
Symbol("seeTagFixSuggestions") -> user.settings.seeTagFixSuggestions,
Symbol("disableTaskConfirm") -> user.settings.disableTaskConfirm
)
.as(this.parser().*)
.head
Expand Down Expand Up @@ -514,12 +515,14 @@ object UserRepository {
get[Option[Boolean]]("users.allow_following") ~
get[Option[Long]]("users.following_group") ~
get[Option[Long]]("users.followers_group") ~
get[Option[Boolean]]("users.see_tag_fix_suggestions") map {
get[Option[Boolean]]("users.see_tag_fix_suggestions") ~
get[Option[Boolean]]("users.disable_task_confirm") map {
case id ~ osmId ~ created ~ modified ~ osmCreated ~ displayName ~ description ~ avatarURL ~
homeLocation ~ apiKey ~ oauthToken ~ defaultEditor ~ defaultBasemap ~
defaultBasemapId ~ customBasemapList ~
email ~ emailOptIn ~ leaderboardOptOut ~ needsReview ~ isReviewer ~ locale ~ theme ~
properties ~ score ~ achievements ~ allowFollowing ~ followingGroupId ~ followersGroupId ~ seeTagFixSuggestions =>
properties ~ score ~ achievements ~ allowFollowing ~ followingGroupId ~ followersGroupId ~
seeTagFixSuggestions ~ disableTaskConfirm =>
val locationWKT = homeLocation match {
case Some(wkt) => new WKTReader().read(wkt).asInstanceOf[Point]
case None => new GeometryFactory().createPoint(new Coordinate(0, 0))
Expand Down Expand Up @@ -565,7 +568,8 @@ object UserRepository {
allowFollowing,
theme,
customBasemaps,
seeTagFixSuggestions
seeTagFixSuggestions,
disableTaskConfirm
),
properties,
score,
Expand Down
5 changes: 4 additions & 1 deletion app/org/maproulette/framework/service/ProjectService.scala
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,8 @@ class ProjectService @Inject() (
}
val isVirtual = cachedItem.isVirtual // Don't allow updates to virtual status
val isArchived = (updates \ "isArchived").asOpt[Boolean].getOrElse(cachedItem.isArchived)
val requireComment =
(updates \ "requireComment").asOpt[Boolean].getOrElse(cachedItem.requireComment)

this.repository.update(
Project(
Expand All @@ -315,7 +317,8 @@ class ProjectService @Inject() (
enabled = enabled,
isVirtual = isVirtual,
featured = featured,
isArchived = isArchived
isArchived = isArchived,
requireComment = requireComment
)
)
}(id = id)
Expand Down
6 changes: 5 additions & 1 deletion app/org/maproulette/framework/service/UserService.scala
Original file line number Diff line number Diff line change
Expand Up @@ -459,6 +459,9 @@ class UserService @Inject() (
val seeTagFixSuggestions = (value \ "settings" \ "seeTagFixSuggestions")
.asOpt[Boolean]
.getOrElse(cachedItem.settings.seeTagFixSuggestions.getOrElse(true))
val disableTaskConfirm = (value \ "settings" \ "disableTaskConfirm")
.asOpt[Boolean]
.getOrElse(cachedItem.settings.disableTaskConfirm.getOrElse(false))
val theme = (value \ "settings" \ "theme")
.asOpt[Int]
.getOrElse(cachedItem.settings.theme.getOrElse(-1))
Expand Down Expand Up @@ -502,7 +505,8 @@ class UserService @Inject() (
Some(allowFollowing),
Some(theme),
customBasemaps,
Some(seeTagFixSuggestions)
Some(seeTagFixSuggestions),
Some(disableTaskConfirm)
),
properties = Some(properties)
),
Expand Down
28 changes: 19 additions & 9 deletions app/org/maproulette/models/dal/ChallengeDAL.scala
Original file line number Diff line number Diff line change
Expand Up @@ -125,15 +125,17 @@ class ChallengeDAL @Inject() (
get[Option[String]]("challenges.dataset_url") ~
get[Option[JsValue]]("challenges.task_widget_layout") ~
get[Option[Int]]("challenges.completion_percentage") ~
get[Option[Int]]("challenges.tasks_remaining") map {
get[Option[Int]]("challenges.tasks_remaining") ~
get[Boolean]("challenges.require_comment") map {
case id ~ name ~ created ~ modified ~ description ~ infoLink ~ ownerId ~ parentId ~ instruction ~
difficulty ~ blurb ~ enabled ~ featured ~ cooperativeType ~ popularity ~ checkin_comment ~
checkin_source ~ overpassql ~ remoteGeoJson ~ overpassTargetType ~ status ~ statusMessage ~
defaultPriority ~ highPriorityRule ~ mediumPriorityRule ~ lowPriorityRule ~ defaultZoom ~
minZoom ~ maxZoom ~ defaultBasemap ~ defaultBasemapId ~ customBasemap ~ updateTasks ~
exportableProperties ~ osmIdProperty ~ taskBundleIdProperty ~ preferredTags ~ preferredReviewTags ~
limitTags ~ limitReviewTags ~ taskStyles ~ lastTaskRefresh ~ dataOriginDate ~ location ~ bounding ~
requiresLocal ~ deleted ~ isArchived ~ reviewSetting ~ datasetUrl ~ taskWidgetLayout ~ completionPercentage ~ tasksRemaining =>
requiresLocal ~ deleted ~ isArchived ~ reviewSetting ~ datasetUrl ~ taskWidgetLayout ~ completionPercentage ~
tasksRemaining ~ requireComment =>
val hpr = highPriorityRule match {
case Some(c) if StringUtils.isEmpty(c) || StringUtils.equals(c, "{}") => None
case r => r
Expand Down Expand Up @@ -191,7 +193,8 @@ class ChallengeDAL @Inject() (
isArchived,
reviewSetting,
taskWidgetLayout,
datasetUrl
datasetUrl,
requireComment = requireComment
),
status,
statusMessage,
Expand Down Expand Up @@ -265,7 +268,8 @@ class ChallengeDAL @Inject() (
get[Option[JsValue]]("challenges.task_widget_layout") ~
get[Option[DateTime]]("challenges.system_archived_at") ~
get[Option[Int]]("challenges.completion_percentage") ~
get[Option[Int]]("challenges.tasks_remaining") map {
get[Option[Int]]("challenges.tasks_remaining") ~
get[Boolean]("challenges.require_comment") map {
case id ~ name ~ created ~ modified ~ description ~ infoLink ~ ownerId ~ parentId ~ instruction ~
difficulty ~ blurb ~ enabled ~ featured ~ cooperativeType ~ popularity ~
checkin_comment ~ checkin_source ~ overpassql ~ remoteGeoJson ~ overpassTargetType ~
Expand All @@ -274,7 +278,8 @@ class ChallengeDAL @Inject() (
customBasemap ~ updateTasks ~ exportableProperties ~ osmIdProperty ~ taskBundleIdProperty ~ preferredTags ~
preferredReviewTags ~ limitTags ~ limitReviewTags ~ taskStyles ~ lastTaskRefresh ~
dataOriginDate ~ location ~ bounding ~ requiresLocal ~ deleted ~ virtualParents ~
presets ~ isArchived ~ reviewSetting ~ datasetUrl ~ taskWidgetLayout ~ systemArchivedAt ~ completionPercentage ~ tasksRemaining =>
presets ~ isArchived ~ reviewSetting ~ datasetUrl ~ taskWidgetLayout ~ systemArchivedAt ~ completionPercentage ~
tasksRemaining ~ requireComment =>
val hpr = highPriorityRule match {
case Some(c) if StringUtils.isEmpty(c) || StringUtils.equals(c, "{}") => None
case r => r
Expand Down Expand Up @@ -334,7 +339,8 @@ class ChallengeDAL @Inject() (
taskWidgetLayout,
datasetUrl,
systemArchivedAt,
presets
presets,
requireComment = requireComment
),
status,
statusMessage,
Expand Down Expand Up @@ -485,7 +491,7 @@ class ChallengeDAL @Inject() (
medium_priority_rule, low_priority_rule, default_zoom, min_zoom, max_zoom,
default_basemap, default_basemap_id, custom_basemap, updatetasks, exportable_properties,
osm_id_property, task_bundle_id_property, last_task_refresh, data_origin_date, preferred_tags, preferred_review_tags,
limit_tags, limit_review_tags, task_styles, requires_local, is_archived, review_setting, dataset_url, task_widget_layout)
limit_tags, limit_review_tags, task_styles, requires_local, is_archived, review_setting, dataset_url, require_comment, task_widget_layout)
VALUES (${challenge.name}, ${challenge.general.owner}, ${challenge.general.parent}, ${challenge.general.difficulty},
${challenge.description}, ${challenge.infoLink}, ${challenge.general.blurb}, ${challenge.general.instruction},
${challenge.general.enabled}, ${challenge.general.featured},
Expand All @@ -499,7 +505,7 @@ class ChallengeDAL @Inject() (
${challenge.dataOriginDate.getOrElse(DateTime.now()).toString}::timestamptz,
${challenge.extra.preferredTags}, ${challenge.extra.preferredReviewTags}, ${challenge.extra.limitTags},
${challenge.extra.limitReviewTags}, ${challenge.extra.taskStyles}, ${challenge.general.requiresLocal}, ${challenge.extra.isArchived},
${challenge.extra.reviewSetting}, ${challenge.extra.datasetUrl},
${challenge.extra.reviewSetting}, ${challenge.extra.datasetUrl}, ${challenge.extra.requireComment},
${asJson(challenge.extra.taskWidgetLayout.getOrElse(Json.parse("{}")))}
) ON CONFLICT(parent_id, LOWER(name)) DO NOTHING RETURNING #${this.retrieveColumns}"""
.as(this.parser.*)
Expand Down Expand Up @@ -691,6 +697,10 @@ class ChallengeDAL @Inject() (
.asOpt[String]
.getOrElse(cachedItem.extra.datasetUrl)

val requireComment = (updates \ "requireComment")
.asOpt[Boolean]
.getOrElse(cachedItem.extra.requireComment)

val taskWidgetLayout = (updates \ "taskWidgetLayout")
.asOpt[JsValue]
.getOrElse(cachedItem.extra.taskWidgetLayout.getOrElse(Json.parse("{}")))
Expand All @@ -704,7 +714,7 @@ class ChallengeDAL @Inject() (
description = $description, info_link = $infoLink, blurb = $blurb, instruction = $instruction,
enabled = $enabled, featured = $featured, checkin_comment = $checkinComment, checkin_source = $checkinSource, overpass_ql = $overpassQL,
remote_geo_json = $remoteGeoJson, overpass_target_type = $overpassTargetType, status = $status, status_message = $statusMessage, default_priority = $defaultPriority,
data_origin_date = ${dataOriginDate.toString()}::timestamptz,
data_origin_date = ${dataOriginDate.toString()}::timestamptz, require_comment = $requireComment,
high_priority_rule = ${if (StringUtils.isEmpty(highPriorityRule)) {
Option.empty[String]
} else {
Expand Down
9 changes: 9 additions & 0 deletions conf/evolutions/default/98.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# --- !Ups
ALTER TABLE users ADD COLUMN disable_task_confirm BOOLEAN DEFAULT false;;
ALTER TABLE challenges ADD COLUMN require_comment BOOLEAN DEFAULT false;;
ALTER TABLE projects ADD COLUMN require_comment BOOLEAN DEFAULT false;;

# --- !Downs
ALTER TABLE IF EXISTS users DROP COLUMN disable_task_confirm;;
ALTER TABLE IF EXISTS challenges DROP COLUMN require_comment;;
ALTER TABLE IF EXISTS projects DROP COLUMN require_comment;;

0 comments on commit 97aab16

Please sign in to comment.