diff --git a/app/org/maproulette/framework/controller/TaskReviewController.scala b/app/org/maproulette/framework/controller/TaskReviewController.scala index 22bd58eb..9968e9cb 100644 --- a/app/org/maproulette/framework/controller/TaskReviewController.scala +++ b/app/org/maproulette/framework/controller/TaskReviewController.scala @@ -69,19 +69,21 @@ class TaskReviewController @Inject() ( * Gets and claims a task that needs to be reviewed. * * @param id Task id to work on + * @param includeTags If true, include MR tags on the returned task * @return */ - def startTaskReview(id: Long): Action[AnyContent] = Action.async { implicit request => - this.sessionManager.authenticatedRequest { implicit user => - val task = this.taskRepository.retrieve(id) match { - case Some(t) => t - case None => throw new NotFoundException(s"Task with $id not found, cannot start review.") - } + def startTaskReview(id: Long, includeTags: Boolean = false): Action[AnyContent] = + Action.async { implicit request => + this.sessionManager.authenticatedRequest { implicit user => + val task = this.taskRepository.retrieve(id) match { + case Some(t) => t + case None => throw new NotFoundException(s"Task with $id not found, cannot start review.") + } - val result = this.service.startTaskReview(user, task) - Ok(Json.toJson(result)) + val result = this.service.startTaskReview(user, task) + Ok(withTaskTagsIfRequested(result, includeTags)) + } } - } /** * Releases a claim on a task that needs to be reviewed. @@ -117,7 +119,8 @@ class TaskReviewController @Inject() ( order: String, lastTaskId: Long = -1, excludeOtherReviewers: Boolean = false, - asMetaReview: Boolean = false + asMetaReview: Boolean = false, + includeTags: Boolean = false ): Action[AnyContent] = Action.async { implicit request => this.sessionManager.authenticatedRequest { implicit user => SearchParameters.withSearch { implicit params => @@ -145,7 +148,7 @@ class TaskReviewController @Inject() ( ) val nextTask = result match { case Some(task) => - Ok(Json.toJson(this.service.startTaskReview(user, task))) + Ok(withTaskTagsIfRequested(this.service.startTaskReview(user, task), includeTags)) case None => throw new NotFoundException("No tasks found to review.") } @@ -155,6 +158,23 @@ class TaskReviewController @Inject() ( } } + /** + * Serializes a (possibly absent) Task and, when requested, injects the task's + * MR tags into the resulting JSON so the review UI can render them without + * an extra round-trip. + */ + private def withTaskTagsIfRequested(result: Option[Task], includeTags: Boolean): JsValue = { + if (!includeTags) { + Json.toJson(result) + } else { + result match { + case Some(task) => + Utils.insertIntoJson(Json.toJson(task), "tags", Json.toJson(this.getTags(task.id)), true) + case None => Json.toJson(result) + } + } + } + /** * Gets tasks where a review is requested * diff --git a/conf/v2_route/review.api b/conf/v2_route/review.api index 69ad110a..23404de4 100644 --- a/conf/v2_route/review.api +++ b/conf/v2_route/review.api @@ -14,8 +14,11 @@ # - name: id # in: path # description: The id of the task to fetch and claim +# - name: includeTags +# in: query +# description: If true, include MR tags on the returned task. Defaults to false. ### -GET /task/:id/review/start @org.maproulette.framework.controller.TaskReviewController.startTaskReview(id:Long) +GET /task/:id/review/start @org.maproulette.framework.controller.TaskReviewController.startTaskReview(id:Long, includeTags:Boolean ?= false) ### # tags: [ Review ] # operationId: review_cancels_a_claim_on_a_task_for_review @@ -177,8 +180,11 @@ GET /tasks/reviewed @org.maproulette.framework.cont # - name: r # in: query # description: The search string used to match the Reviewer names. (reviewed_by) +# - name: includeTags +# in: query +# description: If true, include MR tags on the returned task. Defaults to false. ### -GET /tasks/review/next @org.maproulette.framework.controller.TaskReviewController.nextTaskReview(onlySaved:Boolean ?= false, sort:String ?= "", order:String ?= "ASC", lastTaskId:Long ?= -1, excludeOtherReviewers:Boolean ?= false, asMetaReview: Boolean ?= false) +GET /tasks/review/next @org.maproulette.framework.controller.TaskReviewController.nextTaskReview(onlySaved:Boolean ?= false, sort:String ?= "", order:String ?= "ASC", lastTaskId:Long ?= -1, excludeOtherReviewers:Boolean ?= false, asMetaReview: Boolean ?= false, includeTags:Boolean ?= false) ### # tags: [ Review ] # operationId: review_retrieves_nearby_tasks