feat: list sorting #42

Merged
matous-volf merged 9 commits from feat/list-sorting into main 2024-09-09 17:09:22 +00:00
3 changed files with 45 additions and 16 deletions
Showing only changes of commit 253fb4f8e3 - Show all commits

View File

@ -53,6 +53,13 @@ impl From<diesel::result::Error> for SubtaskError {
} }
} }
impl From<ErrorVec<Error>> for ErrorVec<SubtaskError> {
fn from(error_vec: ErrorVec<Error>) -> Self {
Vec::from(error_vec).into_iter()
.map(SubtaskError::Error).collect::<Vec<SubtaskError>>().into()
}
coderabbitai[bot] commented 2024-09-09 17:00:59 +00:00 (Migrated from github.com)
Review

Approved: Conversion from ErrorVec<Error> to ErrorVec<SubtaskError>.

The implementation is correct and enhances the error handling capabilities by allowing seamless integration of generic errors into SubtaskError. This is a valuable addition for robust error management.

Consider adding error logging at this conversion point to aid in debugging and maintaining error traceability.

**Approved: Conversion from `ErrorVec<Error>` to `ErrorVec<SubtaskError>`.** The implementation is correct and enhances the error handling capabilities by allowing seamless integration of generic errors into `SubtaskError`. This is a valuable addition for robust error management. Consider adding error logging at this conversion point to aid in debugging and maintaining error traceability. <!-- This is an auto-generated comment by CodeRabbit -->
}
// Has to be implemented for Dioxus server functions. // Has to be implemented for Dioxus server functions.
impl Display for SubtaskError { impl Display for SubtaskError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {

View File

@ -6,6 +6,7 @@ use crate::server::database_connection::establish_database_connection;
use diesel::{ExpressionMethods, QueryDsl, RunQueryDsl, SelectableHelper}; use diesel::{ExpressionMethods, QueryDsl, RunQueryDsl, SelectableHelper};
use dioxus::prelude::*; use dioxus::prelude::*;
use validator::Validate; use validator::Validate;
use crate::server::tasks::trigger_task_updated_at;
#[server] #[server]
pub(crate) async fn create_subtask(new_subtask: NewSubtask) 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()) .returning(Subtask::as_returning())
.get_result(&mut connection) .get_result(&mut connection)
.map_err::<ErrorVec<SubtaskError>, _>(|error| vec![error.into()].into())?; .map_err::<ErrorVec<SubtaskError>, _>(|error| vec![error.into()].into())?;
trigger_task_updated_at(new_subtask.task_id).await
.map_err::<ErrorVec<SubtaskError>, _>(|error_vec| error_vec.into())?;
Ok(created_subtask) Ok(created_subtask)
} }
@ -35,17 +39,13 @@ pub(crate) async fn get_subtasks_of_task(filtered_task_id: i32)
use crate::schema::subtasks::dsl::*; use crate::schema::subtasks::dsl::*;
let mut connection = establish_database_connection() let mut connection = establish_database_connection()
.map_err::<ErrorVec<Error>, _>( .map_err::<ErrorVec<Error>, _>(|_| vec![Error::ServerInternal].into())?;
|_| vec![Error::ServerInternal].into()
)?;
let results = subtasks let results = subtasks
.select(Subtask::as_select()) .select(Subtask::as_select())
.filter(task_id.eq(filtered_task_id)) .filter(task_id.eq(filtered_task_id))
.load::<Subtask>(&mut connection) .load::<Subtask>(&mut connection)
.map_err::<ErrorVec<Error>, _>( .map_err::<ErrorVec<Error>, _>(|_| vec![Error::ServerInternal].into())?;
|_| vec![Error::ServerInternal].into()
)?;
Ok(results) Ok(results)
} }
@ -73,27 +73,28 @@ pub(crate) async fn edit_subtask(subtask_id: i32, new_subtask: NewSubtask)
.get_result(&mut connection) .get_result(&mut connection)
.map_err::<ErrorVec<SubtaskError>, _>(|error| vec![error.into()].into())?; .map_err::<ErrorVec<SubtaskError>, _>(|error| vec![error.into()].into())?;
trigger_task_updated_at(new_subtask.task_id).await
.map_err::<ErrorVec<SubtaskError>, _>(|error_vec| error_vec.into())?;
Ok(updated_task) Ok(updated_task)
} }
#[server] #[server]
pub(crate) async fn restore_subtasks_of_task(filtered_task_id: i32) -> Result< pub(crate) async fn restore_subtasks_of_task(filtered_task_id: i32) -> Result<
Vec<Subtask>, Vec<Subtask>,
ServerFnError<ErrorVec<SubtaskError>> ServerFnError<ErrorVec<Error>>
> { > {
use crate::schema::subtasks::dsl::*; use crate::schema::subtasks::dsl::*;
let mut connection = establish_database_connection() let mut connection = establish_database_connection()
.map_err::<ErrorVec<SubtaskError>, _>( .map_err::<ErrorVec<Error>, _>(|_| vec![Error::ServerInternal].into())?;
|_| vec![SubtaskError::Error(Error::ServerInternal)].into()
)?;
let updated_subtasks = diesel::update(subtasks) let updated_subtasks = diesel::update(subtasks)
.filter(task_id.eq(filtered_task_id)) .filter(task_id.eq(filtered_task_id))
.set(is_completed.eq(false)) .set(is_completed.eq(false))
.returning(Subtask::as_returning()) .returning(Subtask::as_returning())
.get_results(&mut connection) .get_results(&mut connection)
.map_err::<ErrorVec<SubtaskError>, _>(|error| vec![error.into()].into())?; .map_err::<ErrorVec<Error>, _>(|error| vec![error.into()].into())?;
Ok(updated_subtasks) Ok(updated_subtasks)
} }
@ -108,8 +109,12 @@ pub(crate) async fn delete_subtask(subtask_id: i32)
let mut connection = establish_database_connection() let mut connection = establish_database_connection()
.map_err::<ErrorVec<Error>, _>(|_| vec![Error::ServerInternal].into())?; .map_err::<ErrorVec<Error>, _>(|_| 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::<ErrorVec<Error>, _>(|error| vec![error.into()].into())?; .map_err::<ErrorVec<Error>, _>(|error| vec![error.into()].into())?;
coderabbitai[bot] commented 2024-09-09 17:01:00 +00:00 (Migrated from github.com)
Review

Tip

Codebase Verification

Inconsistent error handling in delete_subtask.

The error handling for trigger_task_updated_at in create_subtask and edit_subtask is consistent, using map_err to convert the error type. However, delete_subtask does not follow this pattern, which may lead to inconsistencies in error handling across the codebase. Consider reviewing and aligning the error handling in delete_subtask with the other functions.

  • src/server/subtasks.rs: Review error handling in delete_subtask.
Analysis chain

Approve timestamp update integration, suggest verifying error handling.

The integration of trigger_task_updated_at in edit_subtask is consistent with the changes made in create_subtask, ensuring that the parent task's timestamp is updated upon subtask modification. The error handling appears correct, but consistency across the system should be verified.

Run the following script to verify the error handling consistency:

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify error handling consistency for `trigger_task_updated_at`.

# Test: Search for error handling patterns. Expect: Consistent error mapping.
rg --type rust -A 5 $'trigger_task_updated_at'

Length of output: 1617

> [!TIP] > Codebase Verification **Inconsistent error handling in `delete_subtask`.** The error handling for `trigger_task_updated_at` in `create_subtask` and `edit_subtask` is consistent, using `map_err` to convert the error type. However, `delete_subtask` does not follow this pattern, which may lead to inconsistencies in error handling across the codebase. Consider reviewing and aligning the error handling in `delete_subtask` with the other functions. - `src/server/subtasks.rs`: Review error handling in `delete_subtask`. <details> <summary>Analysis chain</summary> **Approve timestamp update integration, suggest verifying error handling.** The integration of `trigger_task_updated_at` in `edit_subtask` is consistent with the changes made in `create_subtask`, ensuring that the parent task's timestamp is updated upon subtask modification. The error handling appears correct, but consistency across the system should be verified. Run the following script to verify the error handling consistency: </details> <details> <summary>Scripts executed</summary> The following scripts were executed for the analysis: Script: ```shell #!/bin/bash # Description: Verify error handling consistency for `trigger_task_updated_at`. # Test: Search for error handling patterns. Expect: Consistent error mapping. rg --type rust -A 5 $'trigger_task_updated_at' ``` Length of output: 1617 </details> <!-- This is an auto-generated comment by CodeRabbit -->
trigger_task_updated_at(deleted_subtask.task_id()).await?;
Ok(()) Ok(())
} }

View File

@ -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::Error;
use crate::errors::error_vec::ErrorVec; use crate::errors::error_vec::ErrorVec;
use crate::models::task::{NewTask, Task, TaskWithSubtasks}; 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<ErrorVec<Error>> ServerFnError<ErrorVec<Error>>
> { > {
use crate::schema::tasks; use crate::schema::tasks;
let mut connection = establish_database_connection() let mut connection = establish_database_connection()
.map_err::<ErrorVec<Error>, _>(|_| vec![Error::ServerInternal].into())?; .map_err::<ErrorVec<Error>, _>(|_| vec![Error::ServerInternal].into())?;
@ -160,8 +160,7 @@ pub(crate) async fn complete_task(task_id: i32) -> Result<Task, ServerFnError<Er
).unwrap() ).unwrap()
} }
} }
restore_subtasks_of_task(task_id).await restore_subtasks_of_task(task_id).await?;
.map_err::<ErrorVec<Error>, _>(|_| vec![Error::ServerInternal].into())?;
} else { } else {
new_task.category = Category::Done; new_task.category = Category::Done;
} }
@ -187,3 +186,21 @@ pub(crate) async fn delete_task(task_id: i32)
Ok(()) Ok(())
} }
pub(crate) async fn trigger_task_updated_at(task_id: i32) -> Result<Task, ErrorVec<Error>> {
use crate::schema::tasks::dsl::*;
let mut connection = establish_database_connection()
.map_err::<ErrorVec<Error>, _>(
|_| 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::<ErrorVec<Error>, _>(|error| vec![error.into()].into())?;
Ok(updated_task)
}