From 253fb4f8e3963ac8e2dc9e66415ad232f11d2871 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matou=C5=A1=20Volf?= <66163112+matous-volf@users.noreply.github.com> Date: Mon, 9 Sep 2024 18:50:52 +0200 Subject: [PATCH] feat: set the updated at timestamp of tasks when updating their subtasks --- src/errors/subtask_error.rs | 7 +++++++ src/server/subtasks.rs | 29 +++++++++++++++++------------ src/server/tasks.rs | 25 +++++++++++++++++++++---- 3 files changed, 45 insertions(+), 16 deletions(-) diff --git a/src/errors/subtask_error.rs b/src/errors/subtask_error.rs index 3297208..505626d 100644 --- a/src/errors/subtask_error.rs +++ b/src/errors/subtask_error.rs @@ -53,6 +53,13 @@ impl From for SubtaskError { } } +impl From> for ErrorVec { + fn from(error_vec: ErrorVec) -> Self { + Vec::from(error_vec).into_iter() + .map(SubtaskError::Error).collect::>().into() + } +} + // Has to be implemented for Dioxus server functions. impl Display for SubtaskError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { diff --git a/src/server/subtasks.rs b/src/server/subtasks.rs index 6108575..844a7a3 100644 --- a/src/server/subtasks.rs +++ b/src/server/subtasks.rs @@ -6,6 +6,7 @@ use crate::server::database_connection::establish_database_connection; use diesel::{ExpressionMethods, QueryDsl, RunQueryDsl, SelectableHelper}; use dioxus::prelude::*; use validator::Validate; +use crate::server::tasks::trigger_task_updated_at; #[server] pub(crate) async fn create_subtask(new_subtask: NewSubtask) @@ -25,6 +26,9 @@ pub(crate) async fn create_subtask(new_subtask: NewSubtask) .returning(Subtask::as_returning()) .get_result(&mut connection) .map_err::, _>(|error| vec![error.into()].into())?; + + trigger_task_updated_at(new_subtask.task_id).await + .map_err::, _>(|error_vec| error_vec.into())?; Ok(created_subtask) } @@ -35,17 +39,13 @@ pub(crate) async fn get_subtasks_of_task(filtered_task_id: i32) use crate::schema::subtasks::dsl::*; let mut connection = establish_database_connection() - .map_err::, _>( - |_| vec![Error::ServerInternal].into() - )?; + .map_err::, _>(|_| vec![Error::ServerInternal].into())?; let results = subtasks .select(Subtask::as_select()) .filter(task_id.eq(filtered_task_id)) .load::(&mut connection) - .map_err::, _>( - |_| vec![Error::ServerInternal].into() - )?; + .map_err::, _>(|_| vec![Error::ServerInternal].into())?; Ok(results) } @@ -73,27 +73,28 @@ pub(crate) async fn edit_subtask(subtask_id: i32, new_subtask: NewSubtask) .get_result(&mut connection) .map_err::, _>(|error| vec![error.into()].into())?; + trigger_task_updated_at(new_subtask.task_id).await + .map_err::, _>(|error_vec| error_vec.into())?; + Ok(updated_task) } #[server] pub(crate) async fn restore_subtasks_of_task(filtered_task_id: i32) -> Result< Vec, - ServerFnError> + ServerFnError> > { use crate::schema::subtasks::dsl::*; let mut connection = establish_database_connection() - .map_err::, _>( - |_| vec![SubtaskError::Error(Error::ServerInternal)].into() - )?; + .map_err::, _>(|_| vec![Error::ServerInternal].into())?; let updated_subtasks = diesel::update(subtasks) .filter(task_id.eq(filtered_task_id)) .set(is_completed.eq(false)) .returning(Subtask::as_returning()) .get_results(&mut connection) - .map_err::, _>(|error| vec![error.into()].into())?; + .map_err::, _>(|error| vec![error.into()].into())?; Ok(updated_subtasks) } @@ -108,8 +109,12 @@ pub(crate) async fn delete_subtask(subtask_id: i32) let mut connection = establish_database_connection() .map_err::, _>(|_| vec![Error::ServerInternal].into())?; - diesel::delete(subtasks.filter(id.eq(subtask_id))).execute(&mut connection) + let deleted_subtask = diesel::delete(subtasks.filter(id.eq(subtask_id))) + .returning(Subtask::as_returning()) + .get_result(&mut connection) .map_err::, _>(|error| vec![error.into()].into())?; + trigger_task_updated_at(deleted_subtask.task_id()).await?; + Ok(()) } diff --git a/src/server/tasks.rs b/src/server/tasks.rs index fb1d747..192726f 100644 --- a/src/server/tasks.rs +++ b/src/server/tasks.rs @@ -1,4 +1,4 @@ -use chrono::{Datelike, Days, Months, NaiveDate}; +use chrono::{Datelike, Days, Local, Months, NaiveDate}; use crate::errors::error::Error; use crate::errors::error_vec::ErrorVec; use crate::models::task::{NewTask, Task, TaskWithSubtasks}; @@ -80,7 +80,7 @@ pub(crate) async fn get_tasks_with_subtasks_in_category(filtered_category: Categ ServerFnError> > { use crate::schema::tasks; - + let mut connection = establish_database_connection() .map_err::, _>(|_| vec![Error::ServerInternal].into())?; @@ -160,8 +160,7 @@ pub(crate) async fn complete_task(task_id: i32) -> Result, _>(|_| vec![Error::ServerInternal].into())?; + restore_subtasks_of_task(task_id).await?; } else { new_task.category = Category::Done; } @@ -187,3 +186,21 @@ pub(crate) async fn delete_task(task_id: i32) Ok(()) } + +pub(crate) async fn trigger_task_updated_at(task_id: i32) -> Result> { + use crate::schema::tasks::dsl::*; + + let mut connection = establish_database_connection() + .map_err::, _>( + |_| vec![Error::ServerInternal].into() + )?; + + let updated_task = diesel::update(tasks) + .filter(id.eq(task_id)) + .set(updated_at.eq(Local::now().naive_local())) + .returning(Task::as_returning()) + .get_result(&mut connection) + .map_err::, _>(|error| vec![error.into()].into())?; + + Ok(updated_task) +}