From 89e6ca773b750930bccc88c2b505be74d211c12d Mon Sep 17 00:00:00 2001 From: Sebastian Pravda Date: Wed, 15 Feb 2023 15:08:56 +0100 Subject: [PATCH] feat: application sorting --- api/src/routes/admin.rs | 5 ++-- core/src/database/query/application.rs | 32 +++++++++++++++++++++++- core/src/models/application.rs | 3 +++ core/src/services/application_service.rs | 3 ++- core/src/services/candidate_service.rs | 4 +-- 5 files changed, 41 insertions(+), 6 deletions(-) diff --git a/api/src/routes/admin.rs b/api/src/routes/admin.rs index 8de69b6..c316fb4 100644 --- a/api/src/routes/admin.rs +++ b/api/src/routes/admin.rs @@ -120,12 +120,13 @@ pub async fn create_candidate( } #[allow(unused_variables)] -#[get("/candidates?&")] +#[get("/candidates?&&")] pub async fn list_candidates( conn: Connection<'_, Db>, session: AdminAuth, field: Option, page: Option, + sort: Option, ) -> Result>, Custom> { let db = conn.into_inner(); let private_key = session.get_private_key(); @@ -135,7 +136,7 @@ pub async fn list_candidates( } } - let candidates = ApplicationService::list_applications(&private_key, db, field, page) + let candidates = ApplicationService::list_applications(&private_key, db, field, page, sort) .await.map_err(to_custom_error)?; Ok( diff --git a/core/src/database/query/application.rs b/core/src/database/query/application.rs index 95705de..9b73569 100644 --- a/core/src/database/query/application.rs +++ b/core/src/database/query/application.rs @@ -1,3 +1,4 @@ +use chrono::NaiveDateTime; use entity::{application, candidate}; use sea_orm::{EntityTrait, DbErr, DbConn, ModelTrait, FromQueryResult, QuerySelect, JoinType, RelationTrait, QueryFilter, ColumnTrait, QueryOrder, PaginatorTrait}; @@ -13,10 +14,32 @@ pub struct ApplicationCandidateJoin { pub email: Option, pub telephone: Option, pub field_of_study: Option, + pub created_at: NaiveDateTime, } use crate::{Query}; +fn get_ordering(sort: String) -> (application::Column, sea_orm::Order) +{ + let mut split = sort.split("_"); + let column = split.next(); + let order = split.next(); + + let column = match column { + Some("id") => application::Column::Id, + Some("createdAt") => application::Column::CreatedAt, + _ => application::Column::Id + }; + + let order = match order { + Some("asc") => sea_orm::Order::Asc, + Some("desc") => sea_orm::Order::Desc, + _ => sea_orm::Order::Asc, + }; + + (column, order) +} + impl Query { pub async fn find_application_by_id( db: &DbConn, @@ -41,14 +64,20 @@ impl Query { db: &DbConn, field_of_study: Option, page: Option, + sort: Option, ) -> Result, DbErr> { let select = application::Entity::find(); + let (column, order) = if let Some(sort) = sort { + get_ordering(sort) + } else { + (application::Column::Id, sea_orm::Order::Asc) + }; let query = if let Some(field) = field_of_study { select.filter(application::Column::FieldOfStudy.eq(field)) } else { select } - .order_by(application::Column::Id, sea_orm::Order::Asc) + .order_by(column, order) .join(JoinType::InnerJoin, application::Relation::Candidate.def()) .column_as(application::Column::Id, "application_id") .column_as(candidate::Column::Id, "candidate_id") @@ -56,6 +85,7 @@ impl Query { .column_as(candidate::Column::Surname, "surname") .column_as(candidate::Column::Email, "email") .column_as(candidate::Column::Telephone, "telephone") + .column_as(candidate::Column::CreatedAt, "created_at") .into_model::(); if let Some(page) = page { diff --git a/core/src/models/application.rs b/core/src/models/application.rs index a4b436b..271b008 100644 --- a/core/src/models/application.rs +++ b/core/src/models/application.rs @@ -1,3 +1,4 @@ +use chrono::NaiveDateTime; use serde::{Serialize, Deserialize}; use crate::{database::query::application::ApplicationCandidateJoin, error::ServiceError}; @@ -16,6 +17,7 @@ pub struct ApplicationResponse { pub email: String, pub telephone: String, pub field_of_study: Option, + pub created_at: NaiveDateTime, } impl ApplicationResponse { @@ -40,6 +42,7 @@ impl ApplicationResponse { email: email.unwrap_or_default(), telephone: telephone.unwrap_or_default(), field_of_study: c.field_of_study, + created_at: c.created_at, } ) } diff --git a/core/src/services/application_service.rs b/core/src/services/application_service.rs index 0176dae..6a7c970 100644 --- a/core/src/services/application_service.rs +++ b/core/src/services/application_service.rs @@ -267,8 +267,9 @@ impl ApplicationService { db: &DbConn, field_of_study: Option, page: Option, + sort: Option, ) -> Result, ServiceError> { - let applications = Query::list_applications(db, field_of_study, page).await?; + let applications = Query::list_applications(db, field_of_study, page, sort).await?; futures::future::try_join_all( applications diff --git a/core/src/services/candidate_service.rs b/core/src/services/candidate_service.rs index 628b6be..a1970ef 100644 --- a/core/src/services/candidate_service.rs +++ b/core/src/services/candidate_service.rs @@ -79,12 +79,12 @@ pub mod tests { let db = get_memory_sqlite_connection().await; let admin = create_admin(&db).await; let private_key = crypto::decrypt_password(admin.private_key, "admin".to_string()).await.unwrap(); - let candidates = ApplicationService::list_applications(&private_key, &db, None, None).await.unwrap(); + let candidates = ApplicationService::list_applications(&private_key, &db, None, None, None).await.unwrap(); assert_eq!(candidates.len(), 0); put_user_data(&db).await; - let candidates = ApplicationService::list_applications(&private_key, &db, None, None).await.unwrap(); + let candidates = ApplicationService::list_applications(&private_key, &db, None, None, None).await.unwrap(); assert_eq!(candidates.len(), 1); }