From b4d2e2a20a423d8e2ac8766bebbff08401b8a8ff Mon Sep 17 00:00:00 2001 From: Bernd Bestel Date: Sat, 6 Jul 2019 20:34:01 +0200 Subject: [PATCH] Added the possibility to undo a task (closes #252) --- changelog/50_2.4.3_2019-xx-xx.md | 1 + controllers/TasksApiController.php | 13 ++++++++++++ grocy.openapi.json | 34 ++++++++++++++++++++++++++++++ localization/strings.pot | 3 +++ public/viewjs/tasks.js | 26 +++++++++++++++++++++++ routes.php | 1 + services/TasksService.php | 16 ++++++++++++++ views/tasks.blade.php | 10 ++++++++- 8 files changed, 103 insertions(+), 1 deletion(-) diff --git a/changelog/50_2.4.3_2019-xx-xx.md b/changelog/50_2.4.3_2019-xx-xx.md index 9a3a938d..0a0674f1 100644 --- a/changelog/50_2.4.3_2019-xx-xx.md +++ b/changelog/50_2.4.3_2019-xx-xx.md @@ -11,5 +11,6 @@ - Items can now be marked as "done" (new check mark button per item, when clicked, the item will be displayed greyed out, when clicked again the item will be displayed normally again) - Improved that products can now also be consumed as spoiled from the stock overview page (option in the more/context menu per line) - Added a "consume this recipe"-button to the meal plan (and also a button to consume all recipes for a whole week) +- Added the possibility to undo a task (new button per task, only visible when task is already completed) and also a corresponding API endpoint - Added a new `config.php` setting `DISABLE_AUTH` to be able to disable authentication / the login screen, defaults to `false` - Added a new `config.php` setting `CALENDAR_FIRST_DAY_OF_WEEK` to be able to change the first day of a week used for calendar views (meal plan for example) in the frontend, defaults to locale default diff --git a/controllers/TasksApiController.php b/controllers/TasksApiController.php index fa9c8606..af4edda1 100644 --- a/controllers/TasksApiController.php +++ b/controllers/TasksApiController.php @@ -39,4 +39,17 @@ class TasksApiController extends BaseApiController return $this->GenericErrorResponse($response, $ex->getMessage()); } } + + public function UndoTask(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args) + { + try + { + $this->TasksService->UndoTask($args['taskId']); + return $this->EmptyApiResponse($response); + } + catch (\Exception $ex) + { + return $this->GenericErrorResponse($response, $ex->getMessage()); + } + } } diff --git a/grocy.openapi.json b/grocy.openapi.json index 292b64da..15e009fd 100644 --- a/grocy.openapi.json +++ b/grocy.openapi.json @@ -2151,6 +2151,40 @@ } } }, + "/tasks/{taskId}/undo": { + "post": { + "summary": "Marks the given task as not completed", + "tags": [ + "Tasks" + ], + "parameters": [ + { + "in": "path", + "name": "taskId", + "required": true, + "description": "A valid task id", + "schema": { + "type": "integer" + } + } + ], + "responses": { + "204": { + "description": "The operation was successful" + }, + "400": { + "description": "The operation was not successful (possible errors are: Not existing task)", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GenericErrorResponse" + } + } + } + } + } + } + }, "/calendar/ical": { "get": { "summary": "Returns the calendar in iCal format", diff --git a/localization/strings.pot b/localization/strings.pot index 13c81bc9..a71486c5 100644 --- a/localization/strings.pot +++ b/localization/strings.pot @@ -1283,3 +1283,6 @@ msgstr "" msgid "Not all ingredients of recipe \"%s\" are in stock, nothing removed" msgstr "" + +msgid "Undo task \"%s\"" +msgstr "" diff --git a/public/viewjs/tasks.js b/public/viewjs/tasks.js index edbdd0c9..4b0f4220 100644 --- a/public/viewjs/tasks.js +++ b/public/viewjs/tasks.js @@ -102,6 +102,32 @@ $(document).on('click', '.do-task-button', function(e) ); }); +$(document).on('click', '.undo-task-button', function(e) +{ + e.preventDefault(); + + // Remove the focus from the current button + // to prevent that the tooltip stays until clicked anywhere else + document.activeElement.blur(); + + Grocy.FrontendHelpers.BeginUiBusy(); + + var taskId = $(e.currentTarget).attr('data-task-id'); + var taskName = $(e.currentTarget).attr('data-task-name'); + + Grocy.Api.Post('tasks/' + taskId + '/undo', { }, + function() + { + window.location.reload(); + }, + function(xhr) + { + Grocy.FrontendHelpers.EndUiBusy(); + console.error(xhr); + } + ); +}); + $(document).on('click', '.delete-task-button', function (e) { e.preventDefault(); diff --git a/routes.php b/routes.php index 38a24ab2..f32726ef 100644 --- a/routes.php +++ b/routes.php @@ -201,6 +201,7 @@ $app->group('/api', function() { $this->get('/tasks', '\Grocy\Controllers\TasksApiController:Current'); $this->post('/tasks/{taskId}/complete', '\Grocy\Controllers\TasksApiController:MarkTaskAsCompleted'); + $this->post('/tasks/{taskId}/undo', '\Grocy\Controllers\TasksApiController:UndoTask'); } // Calendar diff --git a/services/TasksService.php b/services/TasksService.php index a9262fdd..1219b4eb 100644 --- a/services/TasksService.php +++ b/services/TasksService.php @@ -26,6 +26,22 @@ class TasksService extends BaseService return true; } + public function UndoTask($taskId) + { + if (!$this->TaskExists($taskId)) + { + throw new \Exception('Task does not exist'); + } + + $taskRow = $this->Database->tasks()->where('id = :1', $taskId)->fetch(); + $taskRow->update(array( + 'done' => 0, + 'done_timestamp' => null + )); + + return true; + } + private function TaskExists($taskId) { $taskRow = $this->Database->tasks()->where('id = :1', $taskId)->fetch(); diff --git a/views/tasks.blade.php b/views/tasks.blade.php index 4c951a8a..b2fad076 100644 --- a/views/tasks.blade.php +++ b/views/tasks.blade.php @@ -73,11 +73,19 @@ @foreach($tasks as $task) - name) }}" + @if($task->done == 0) + name) }}" data-task-id="{{ $task->id }}" data-task-name="{{ $task->name }}"> + @else + name) }}" + data-task-id="{{ $task->id }}" + data-task-name="{{ $task->name }}"> + + + @endif