diff --git a/Cargo.toml b/Cargo.toml index e2e5c68..bcfecc0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ name = "actix-admin" description = "An admin interface for actix-web" license = "MIT OR Apache-2.0" -version = "0.4.0" +version = "0.5.0" repository = "https://github.com/mgugger/actix-admin" edition = "2021" exclude = [ @@ -32,7 +32,7 @@ itertools = "^0.10.5" serde = "^1.0.164" serde_derive = "^1.0.164" sea-orm = { version = "^0.11.3", features = [], default-features = false } -actix-admin-macros = { version = "0.4.0", path = "actix_admin_macros" } +actix-admin-macros = { version = "0.5.0", path = "actix_admin_macros" } derive_more = "0.99.17" regex = "1.8.4" urlencoding = "2.1.2" diff --git a/actix_admin_macros/Cargo.toml b/actix_admin_macros/Cargo.toml index eead9a8..a9c466b 100644 --- a/actix_admin_macros/Cargo.toml +++ b/actix_admin_macros/Cargo.toml @@ -3,7 +3,7 @@ name = "actix-admin-macros" description = "macros to be used with actix-admin crate" license = "MIT OR Apache-2.0" repository = "https://github.com/mgugger/actix-admin" -version = "0.4.0" +version = "0.5.0" edition = "2021" exclude = [ "tests/*" diff --git a/actix_admin_macros/src/lib.rs b/actix_admin_macros/src/lib.rs index 0fea694..24dd1b2 100644 --- a/actix_admin_macros/src/lib.rs +++ b/actix_admin_macros/src/lib.rs @@ -98,13 +98,22 @@ pub fn derive_actix_admin_view_model(input: proc_macro::TokenStream) -> proc_mac Ok(model) } - async fn get_viewmodel_filter() -> HashMap { - Entity::get_filter().iter().map(|f| - (f.name.to_string(), ActixAdminViewModelFilter { - name: f.name.to_string(), - value: None - }) - ).collect() + async fn get_viewmodel_filter(db: &DatabaseConnection) -> HashMap { + let mut hashmap: HashMap = HashMap::new(); + + for filter in Entity::get_filter() { + hashmap.insert( + filter.name.to_string(), + ActixAdminViewModelFilter { + name: filter.name.to_string(), + value: None, + values: Entity::get_filter_values(&filter, db).await, + filter_type: Some(filter.filter_type) + } + ); + }; + + hashmap } async fn get_entity(db: &DatabaseConnection, id: i32) -> Result { diff --git a/docs/content/_index.md b/docs/content/_index.md index f9579c0..6b34159 100644 --- a/docs/content/_index.md +++ b/docs/content/_index.md @@ -24,7 +24,7 @@ Check the [examples](https://github.com/mgugger/actix-admin/tree/main/examples) [package] name = "actix-admin-example" description = "An admin interface for actix-web" -version = "0.4.0" +version = "0.5.0" edition = "2021" [[bin]] @@ -40,6 +40,6 @@ chrono = "0.4.23" tera = "^1.17.1" serde = "^1.0.152" serde_derive = "^1.0.152" -actix-admin = { version = "0.4.0", path = "../../" } +actix-admin = { version = "0.5.0", path = "../../" } regex = "1.7.1" ``` \ No newline at end of file diff --git a/docs/content/docs/custom-filters.md b/docs/content/docs/custom-filters.md new file mode 100644 index 0000000..d6f3940 --- /dev/null +++ b/docs/content/docs/custom-filters.md @@ -0,0 +1,8 @@ +--- +title: "Custom Filters" +date: 2023-01-17T11:44:56+01:00 +draft: false +weight: 6 +--- + +# Custom Filters \ No newline at end of file diff --git a/docs/content/docs/getting-started.md b/docs/content/docs/getting-started.md index 1f31449..0331a9c 100644 --- a/docs/content/docs/getting-started.md +++ b/docs/content/docs/getting-started.md @@ -12,7 +12,7 @@ weight: 1 Cargo.toml: ```cargo [dependencies] -actix-admin = "0.4.0" +actix-admin = "0.5.0" ``` ## Build the Actix-Admin Configuration @@ -50,7 +50,7 @@ let app = App::new() .app_data(web::Data::new(conn.clone())) .app_data(web::Data::new(actix_admin_builder.get_actix_admin())) .service( - actix_admin_builder.get_scope::() + actix_admin_builder.get_scope() ) .wrap(middleware::Logger::default()) ``` diff --git a/examples/basic/entity/comment.rs b/examples/basic/entity/comment.rs index 211cf1d..cbce784 100644 --- a/examples/basic/entity/comment.rs +++ b/examples/basic/entity/comment.rs @@ -1,7 +1,7 @@ use sea_orm::entity::prelude::*; use serde::{Deserialize, Serialize}; use actix_admin::{prelude::*}; -use super::Post; +use super::{Post, post}; #[derive(Clone, Debug, PartialEq, DeriveEntityModel, Deserialize, Serialize, DeriveActixAdmin, DeriveActixAdminModel, DeriveActixAdminViewModel)] #[sea_orm(table_name = "comment")] @@ -51,22 +51,61 @@ impl ActixAdminModelValidationTrait for Entity { } } +#[async_trait] impl ActixAdminModelFilterTrait for Entity { fn get_filter() -> Vec> { vec![ - ActixAdminModelFilter:: { - name: "Id".to_string(), - filter: |q: sea_orm::Select, v| -> sea_orm::Select { - q.apply_if(v, | query, val: String| query.filter(Column::Id.eq(val))) - } - }, ActixAdminModelFilter:: { name: "User".to_string(), + filter_type: ActixAdminModelFilterType::Text, filter: |q: sea_orm::Select, v| -> sea_orm::Select { q.apply_if(v, | query, val: String| query.filter(Column::User.eq(val))) - } + }, + values: None + }, + ActixAdminModelFilter:: { + name: "Insert Date After".to_string(), + filter_type: ActixAdminModelFilterType::DateTime, + filter: |q: sea_orm::Select, v| -> sea_orm::Select { + q.apply_if(v, | query, val: String| query.filter(Column::InsertDate.gte(val))) + }, + values: None + }, + ActixAdminModelFilter:: { + name: "Insert Date After".to_string(), + filter_type: ActixAdminModelFilterType::DateTime, + filter: |q: sea_orm::Select, v| -> sea_orm::Select { + q.apply_if(v, | query, val: String| query.filter(Column::InsertDate.gte(val))) + }, + values: None + }, + ActixAdminModelFilter:: { + name: "Is Visible".to_string(), + filter_type: ActixAdminModelFilterType::Checkbox, + filter: |q: sea_orm::Select, v| -> sea_orm::Select { + q.apply_if(v, | query, val: String| query.filter(Column::IsVisible.eq(val))) + }, + values: None + }, + ActixAdminModelFilter:: { + name: "Post".to_string(), + filter_type: ActixAdminModelFilterType::SelectList, + filter: |q: sea_orm::Select, v| -> sea_orm::Select { + q.apply_if(v, | query, val: String| query.filter(Column::PostId.eq(val))) + }, + values: None } ] } + + async fn get_filter_values(filter: &ActixAdminModelFilter, db: &DatabaseConnection) -> Option> { + match filter.name.as_str() { + "Post" => Some({ + Post::find().order_by_asc(post::Column::Id).all(db).await.unwrap() + .iter().map(|p| (p.id.to_string(), p.title.to_string())).collect() + }), + _ => None + } + } } diff --git a/src/lib.rs b/src/lib.rs index 5707648..d18ba3c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -24,7 +24,7 @@ pub mod view_model; pub mod prelude { pub use crate::builder::{ActixAdminBuilder, ActixAdminBuilderTrait}; - pub use crate::model::{ActixAdminModel, ActixAdminModelTrait, ActixAdminModelValidationTrait, ActixAdminModelFilter, ActixAdminModelFilterTrait}; + pub use crate::model::{ActixAdminModel, ActixAdminModelTrait, ActixAdminModelValidationTrait, ActixAdminModelFilter, ActixAdminModelFilterTrait, ActixAdminModelFilterType}; pub use crate::routes::{create_or_edit_post, get_admin_ctx, SortOrder}; pub use crate::view_model::{ ActixAdminViewModel, ActixAdminViewModelField, ActixAdminViewModelFieldType, diff --git a/src/model.rs b/src/model.rs index 09cbaca..0a3ce39 100644 --- a/src/model.rs +++ b/src/model.rs @@ -36,20 +36,37 @@ pub trait ActixAdminModelValidationTrait { pub struct ActixAdminModelFilter { pub name: String, - pub filter: fn(sea_orm::Select, Option) -> sea_orm::Select + pub filter_type: ActixAdminModelFilterType, + pub filter: fn(sea_orm::Select, Option) -> sea_orm::Select, + pub values: Option> } +#[derive(Clone, Debug, Serialize)] +pub enum ActixAdminModelFilterType { + Text, + SelectList, + Date, + DateTime, + Checkbox +} + +#[async_trait] pub trait ActixAdminModelFilterTrait { fn get_filter() -> Vec> { Vec::new() } + async fn get_filter_values(_filter: &ActixAdminModelFilter, _db: &DatabaseConnection)-> Option> { + None + } } impl From> for ActixAdminViewModelFilter { fn from(filter: ActixAdminModelFilter) -> Self { ActixAdminViewModelFilter { name: filter.name, - value: None + value: None, + values: None, + filter_type: Some(filter.filter_type) } } } diff --git a/src/routes/list.rs b/src/routes/list.rs index cc45af5..74e40ad 100644 --- a/src/routes/list.rs +++ b/src/routes/list.rs @@ -90,6 +90,8 @@ pub async fn list( let af = ActixAdminViewModelFilter { name: kv.next().unwrap().strip_prefix("filter_").unwrap_or_default().to_string(), value: kv.next().map(|s| s.to_string()).filter(|f| !f.is_empty()), + values: None, + filter_type: None }; af }).collect(); @@ -143,7 +145,7 @@ pub async fn list( ctx.insert("notifications", ¬ifications); ctx.insert("entities_per_page", &entities_per_page); ctx.insert("render_partial", &render_partial); - ctx.insert("viewmodel_filter", &E::get_viewmodel_filter().await); + ctx.insert("viewmodel_filter", &E::get_viewmodel_filter(&db).await); ctx.insert( "view_model", &ActixAdminViewModelSerializable::from(view_model.clone()), diff --git a/src/templates/list.html b/src/templates/list.html index 6a5a07d..3ab533d 100644 --- a/src/templates/list.html +++ b/src/templates/list.html @@ -7,11 +7,42 @@