diff --git a/src/routes/create_or_edit_get.rs b/src/routes/create_or_edit_get.rs index 41f5b00..bbd7123 100644 --- a/src/routes/create_or_edit_get.rs +++ b/src/routes/create_or_edit_get.rs @@ -6,11 +6,13 @@ use crate::ActixAdminNotification; use crate::prelude::*; use crate::TERA; +use super::DEFAULT_ENTITIES_PER_PAGE; +use super::Params; use super::{ add_auth_context, user_can_access_page, render_unauthorized}; pub async fn create_get( session: Session, - _req: HttpRequest, + req: HttpRequest, data: web::Data, _body: web::Payload, _text: String, @@ -18,12 +20,12 @@ pub async fn create_get( let db = &data.get_db(); let model = ActixAdminModel::create_empty(); - create_or_edit_get::(&session, &data, db, Ok(model)).await + create_or_edit_get::(&session, req, &data, db, Ok(model)).await } pub async fn edit_get( session: Session, - _req: HttpRequest, + req: HttpRequest, data: web::Data, _text: String, id: web::Path @@ -31,10 +33,10 @@ pub async fn edit_get( let db = &data.get_db(); let model = E::get_entity(db, id.into_inner()).await; - create_or_edit_get::(&session, &data, db, model).await + create_or_edit_get::(&session, req, &data, db, model).await } -async fn create_or_edit_get(session: &Session, data: &web::Data, db: &sea_orm::DatabaseConnection, model_result: Result) -> Result{ +async fn create_or_edit_get(session: &Session, req: HttpRequest, data: &web::Data, db: &sea_orm::DatabaseConnection, model_result: Result) -> Result{ let actix_admin = &data.get_actix_admin(); let mut ctx = Context::new(); add_auth_context(&session, actix_admin, &mut ctx); @@ -68,11 +70,28 @@ async fn create_or_edit_get::from_query(req.query_string()).unwrap(); + + let page = params.page.unwrap_or(1); + let entities_per_page = params + .entities_per_page + .unwrap_or(DEFAULT_ENTITIES_PER_PAGE); + let render_partial = params.render_partial.unwrap_or(false); + let search = params.search.clone().unwrap_or(String::new()); + let sort_by = params.sort_by.clone().unwrap_or(view_model.primary_key.to_string()); + let sort_order = params.sort_order.as_ref().unwrap_or(&SortOrder::Asc); + ctx.insert("view_model", &ActixAdminViewModelSerializable::from(view_model.clone())); ctx.insert("select_lists", &E::get_select_lists(db).await?); ctx.insert("base_path", &E::get_base_path(&entity_name)); ctx.insert("model", &model); ctx.insert("notifications", ¬ifications); + ctx.insert("entities_per_page", &entities_per_page); + ctx.insert("render_partial", &render_partial); + ctx.insert("search", &search); + ctx.insert("sort_by", &sort_by); + ctx.insert("sort_order", &sort_order); + ctx.insert("page", &page); let body = TERA .render("create_or_edit.html", &ctx) diff --git a/src/routes/create_or_edit_post.rs b/src/routes/create_or_edit_post.rs index 57a6f21..8bb02d4 100644 --- a/src/routes/create_or_edit_post.rs +++ b/src/routes/create_or_edit_post.rs @@ -1,4 +1,5 @@ use super::{render_unauthorized, user_can_access_page}; +use super::{Params, DEFAULT_ENTITIES_PER_PAGE}; use crate::prelude::*; use crate::ActixAdminError; use crate::ActixAdminNotification; @@ -7,26 +8,32 @@ use actix_multipart::Multipart; use actix_multipart::MultipartError; use actix_session::Session; use actix_web::http::header; -use actix_web::{error, web, Error, HttpResponse}; +use actix_web::{error, web, Error, HttpRequest, HttpResponse}; use std::collections::HashMap; use tera::Context; pub async fn create_post( session: Session, + req: HttpRequest, data: web::Data, payload: Multipart, ) -> Result { let actix_admin = data.get_actix_admin(); let model = ActixAdminModel::create_from_payload( payload, - &format!("{}/{}", actix_admin.configuration.file_upload_directory, E::get_entity_name()) + &format!( + "{}/{}", + actix_admin.configuration.file_upload_directory, + E::get_entity_name() + ), ) .await; - create_or_edit_post::(&session, &data, model, None, actix_admin).await + create_or_edit_post::(&session, req, &data, model, None, actix_admin).await } pub async fn edit_post( session: Session, + req: HttpRequest, data: web::Data, payload: Multipart, id: web::Path, @@ -34,14 +41,27 @@ pub async fn edit_post( let actix_admin = data.get_actix_admin(); let model = ActixAdminModel::create_from_payload( payload, - &format!("{}/{}", actix_admin.configuration.file_upload_directory, E::get_entity_name()), + &format!( + "{}/{}", + actix_admin.configuration.file_upload_directory, + E::get_entity_name() + ), ) .await; - create_or_edit_post::(&session, &data, model, Some(id.into_inner()), actix_admin).await + create_or_edit_post::( + &session, + req, + &data, + model, + Some(id.into_inner()), + actix_admin, + ) + .await } pub async fn create_or_edit_post( session: &Session, + req: HttpRequest, data: &web::Data, model_res: Result, id: Option, @@ -64,7 +84,16 @@ pub async fn create_or_edit_post(actix_admin, view_model, db, entity_name, &model, errors).await + render_form::( + req, + actix_admin, + view_model, + db, + entity_name, + &model, + errors, + ) + .await } else { let res = match id { Some(id) => E::edit_entity(db, id, model.clone()).await, @@ -72,21 +101,47 @@ pub async fn create_or_edit_post Ok(HttpResponse::SeeOther() + Ok(_) => { + let params = web::Query::::from_query(req.query_string()).unwrap(); + + let page = params.page.unwrap_or(1); + let entities_per_page = params + .entities_per_page + .unwrap_or(DEFAULT_ENTITIES_PER_PAGE); + let _render_partial = params.render_partial.unwrap_or(false); + let search = params.search.clone().unwrap_or(String::new()); + let sort_by = params + .sort_by + .clone() + .unwrap_or(view_model.primary_key.to_string()); + let sort_order = params.sort_order.as_ref().unwrap_or(&SortOrder::Asc); + + Ok(HttpResponse::SeeOther() .append_header(( header::LOCATION, - format!("/admin/{}/list", view_model.entity_name), + format!("/admin/{0}/list?page={1}&search={2}&sort_by={3}&sort_order={4}&entities_per_page={5}", view_model.entity_name, page, search, sort_by, sort_order, entities_per_page), )) - .finish()), + .finish()) + } Err(e) => { errors.push(e); - render_form::(actix_admin, view_model, db, entity_name, &model, errors).await + render_form::( + req, + actix_admin, + view_model, + db, + entity_name, + &model, + errors, + ) + .await } } } } async fn render_form( + req: HttpRequest, actix_admin: &ActixAdmin, view_model: &ActixAdminViewModel, db: &&sea_orm::DatabaseConnection, @@ -95,6 +150,28 @@ async fn render_form( errors: Vec, ) -> Result { let mut ctx = Context::new(); + + let params = web::Query::::from_query(req.query_string()).unwrap(); + + let page = params.page.unwrap_or(1); + let entities_per_page = params + .entities_per_page + .unwrap_or(DEFAULT_ENTITIES_PER_PAGE); + let render_partial = params.render_partial.unwrap_or(false); + let search = params.search.clone().unwrap_or(String::new()); + let sort_by = params + .sort_by + .clone() + .unwrap_or(view_model.primary_key.to_string()); + let sort_order = params.sort_order.as_ref().unwrap_or(&SortOrder::Asc); + + ctx.insert("entities_per_page", &entities_per_page); + ctx.insert("render_partial", &render_partial); + ctx.insert("search", &search); + ctx.insert("sort_by", &sort_by); + ctx.insert("sort_order", &sort_order); + ctx.insert("page", &page); + ctx.insert("entity_names", &actix_admin.entity_names); ctx.insert( "view_model", diff --git a/src/routes/list.rs b/src/routes/list.rs index ac85423..4768eb2 100644 --- a/src/routes/list.rs +++ b/src/routes/list.rs @@ -1,3 +1,5 @@ +use std::fmt; + use actix_web::{error, web, Error, HttpRequest, HttpResponse}; use serde::Serialize; use serde::{Deserialize}; @@ -10,19 +12,7 @@ use crate::ActixAdminModel; use crate::ActixAdminNotification; use crate::TERA; use actix_session::{Session}; -use super::{ add_auth_context, user_can_access_page, render_unauthorized}; - -const DEFAULT_ENTITIES_PER_PAGE: u64 = 10; - -#[derive(Debug, Deserialize)] -pub struct Params { - page: Option, - entities_per_page: Option, - render_partial: Option, - search: Option, - sort_by: Option, - sort_order: Option -} +use super::{ add_auth_context, user_can_access_page, render_unauthorized, Params, DEFAULT_ENTITIES_PER_PAGE}; #[derive(Debug, Serialize, Deserialize, PartialEq, Eq)] pub enum SortOrder { @@ -30,6 +20,15 @@ pub enum SortOrder { Desc, } +impl fmt::Display for SortOrder { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + SortOrder::Asc => write!(f, "Asc"), + SortOrder::Desc => write!(f, "Desc"), + } + } +} + pub async fn list( session: Session, req: HttpRequest, diff --git a/src/routes/mod.rs b/src/routes/mod.rs index 52a96d7..9ce55c9 100644 --- a/src/routes/mod.rs +++ b/src/routes/mod.rs @@ -20,4 +20,17 @@ mod helpers; pub use helpers::{ add_auth_context, user_can_access_page, render_unauthorized }; mod file; -pub use file::{download, delete_file}; \ No newline at end of file +pub use file::{download, delete_file}; + +use serde::{Deserialize}; +#[derive(Debug, Deserialize)] +pub struct Params { + page: Option, + entities_per_page: Option, + render_partial: Option, + search: Option, + sort_by: Option, + sort_order: Option +} + +const DEFAULT_ENTITIES_PER_PAGE: u64 = 10; \ No newline at end of file diff --git a/src/routes/show.rs b/src/routes/show.rs index 71b910a..1455815 100644 --- a/src/routes/show.rs +++ b/src/routes/show.rs @@ -1,3 +1,4 @@ +use actix_web::HttpRequest; use actix_web::{error, web, Error, HttpResponse}; use actix_session::{Session}; use tera::{Context}; @@ -6,9 +7,10 @@ use crate::ActixAdminNotification; use crate::prelude::*; use crate::TERA; +use super::{Params, DEFAULT_ENTITIES_PER_PAGE}; use super::{ add_auth_context, user_can_access_page, render_unauthorized}; -pub async fn show(session: Session, data: web::Data, id: web::Path) -> Result { +pub async fn show(session: Session, req: HttpRequest, data: web::Data, id: web::Path) -> Result { let actix_admin = data.get_actix_admin(); let db = &data.get_db(); @@ -40,11 +42,28 @@ pub async fn show(sessio .map(|err| ActixAdminNotification::from(err)) .collect(); + let params = web::Query::::from_query(req.query_string()).unwrap(); + + let page = params.page.unwrap_or(1); + let entities_per_page = params + .entities_per_page + .unwrap_or(DEFAULT_ENTITIES_PER_PAGE); + let render_partial = params.render_partial.unwrap_or(false); + let search = params.search.clone().unwrap_or(String::new()); + let sort_by = params.sort_by.clone().unwrap_or(view_model.primary_key.to_string()); + let sort_order = params.sort_order.as_ref().unwrap_or(&SortOrder::Asc); + ctx.insert("model", &model); ctx.insert("view_model", &ActixAdminViewModelSerializable::from(view_model.clone())); ctx.insert("base_path", &E::get_base_path(&entity_name)); ctx.insert("entity_names", &actix_admin.entity_names); ctx.insert("notifications", ¬ifications); + ctx.insert("entities_per_page", &entities_per_page); + ctx.insert("render_partial", &render_partial); + ctx.insert("search", &search); + ctx.insert("sort_by", &sort_by); + ctx.insert("sort_order", &sort_order); + ctx.insert("page", &page); add_auth_context(&session, actix_admin, &mut ctx); diff --git a/src/templates/create_or_edit.html b/src/templates/create_or_edit.html index d02937f..5834806 100644 --- a/src/templates/create_or_edit.html +++ b/src/templates/create_or_edit.html @@ -2,6 +2,11 @@ {% block content %}
+ + + + + {% for model_field in view_model.fields -%}
diff --git a/src/templates/list.html b/src/templates/list.html index 28c56bb..67196b2 100644 --- a/src/templates/list.html +++ b/src/templates/list.html @@ -66,14 +66,14 @@
{% include "loader.html" %}
- - - - - - - + hx-vals='{ "render_partial" : "true" }' hx-target="#{{ entity_name }}table"> + + + + + +
+ - {% for model_field in view_model.fields | filter(attribute="list_hide_column", value=false) | sort(attribute="list_sort_position") -%} + {% for model_field in view_model.fields | filter(attribute="list_hide_column", value=false) | + sort(attribute="list_sort_position") -%} - - - - {% for entity in entities -%} - - - - {% for model_field in view_model.fields | filter(attribute="list_hide_column", value=false) | sort(attribute="list_sort_position") -%} - {% if model_field.field_type == "Checkbox" %} - - {% elif model_field.field_type == "FileUpload" %} - - {% else %} - - {% endif %} - {%- endfor %} - - - {%- endfor %} - - - - - - + + + + {% for entity in entities -%} + + + + {% for model_field in view_model.fields | filter(attribute="list_hide_column", value=false) | + sort(attribute="list_sort_position") -%} + {% if model_field.field_type == "Checkbox" %} + + {% elif model_field.field_type == "FileUpload" %} + + {% else %} + + {% endif %} + {%- endfor %} + + + {%- endfor %} + + + + + +
@@ -88,7 +88,8 @@ {% endif %} {% endif %} {{ model_field.field_name | split(pat="_") | join(sep=" ") | title }} {% if sort_by == model_field.field_name %} @@ -105,70 +106,82 @@
- - {{ entity.primary_key }} - - {{ entity.values | get(key=model_field.field_name) | get_icon | safe }}{{ - entity.values - | get(key=model_field.field_name) }}{{ entity.values | get(key=model_field.field_name) }} - - -
-
+ + {{ entity.primary_key }} + + {{ entity.values | get(key=model_field.field_name) | get_icon | safe }}{{ + entity.values + | get(key=model_field.field_name) }}{{ entity.values | get(key=model_field.field_name) }} + + + + + + +
+
- +
-