add categories to group entities in a dropdown in the navbar

This commit is contained in:
manuel 2022-09-12 21:22:25 +02:00
parent 4fc35d0e97
commit f64a0a5003
5 changed files with 75 additions and 15 deletions

View File

@ -113,14 +113,17 @@ fn create_actix_admin_builder() -> ActixAdminBuilder {
};
let mut admin_builder = ActixAdminBuilder::new(configuration);
admin_builder.add_entity::<AppState, Post>(&post_view_model);
admin_builder.add_entity::<AppState, Comment>(&comment_view_model);
admin_builder.add_custom_handler_for_index::<AppState>(
web::get().to(custom_index::<AppState>)
);
admin_builder.add_custom_handler_for_entity::<AppState, Comment>(
admin_builder.add_entity::<AppState, Post>(&post_view_model);
let some_category = "Some Category";
admin_builder.add_entity_to_category::<AppState, Comment>(&comment_view_model, some_category);
admin_builder.add_custom_handler_for_entity_in_category::<AppState, Comment>(
"/custom_handler",
web::get().to(custom_handler::<AppState, Comment>)
web::get().to(custom_handler::<AppState, Comment>),
some_category
);
admin_builder

View File

@ -1,6 +1,5 @@
use actix_web::{ web, Route };
use std::collections::HashMap;
use crate::prelude::*;
use crate::routes::{create_get, create_post, delete, delete_many, edit_get, edit_post, index, list, show};
@ -19,11 +18,22 @@ pub trait ActixAdminBuilderTrait {
&mut self,
view_model: &ActixAdminViewModel,
);
fn add_entity_to_category<T: ActixAdminAppDataTrait + 'static, E: ActixAdminViewModelTrait + 'static>(
&mut self,
view_model: &ActixAdminViewModel,
category_name: &str
);
fn add_custom_handler_for_entity<T: ActixAdminAppDataTrait + 'static, E: ActixAdminViewModelTrait + 'static>(
&mut self,
path: &str,
route: Route
);
fn add_custom_handler_for_entity_in_category<T: ActixAdminAppDataTrait + 'static, E: ActixAdminViewModelTrait + 'static>(
&mut self,
path: &str,
route: Route,
category_name: &str
);
fn add_custom_handler_for_index<T: ActixAdminAppDataTrait + 'static>(
&mut self,
route: Route
@ -36,7 +46,7 @@ impl ActixAdminBuilderTrait for ActixAdminBuilder {
fn new(configuration: ActixAdminConfiguration) -> Self {
ActixAdminBuilder {
actix_admin: ActixAdmin {
entity_names: Vec::new(),
entity_names: HashMap::new(),
view_models: HashMap::new(),
configuration: configuration
},
@ -48,6 +58,14 @@ impl ActixAdminBuilderTrait for ActixAdminBuilder {
fn add_entity<T: ActixAdminAppDataTrait + 'static, E: ActixAdminViewModelTrait + 'static>(
&mut self,
view_model: &ActixAdminViewModel,
) {
let _ = &self.add_entity_to_category::<T, E>(view_model, "");
}
fn add_entity_to_category<T: ActixAdminAppDataTrait + 'static, E: ActixAdminViewModelTrait + 'static>(
&mut self,
view_model: &ActixAdminViewModel,
category_name: &str
) {
self.scopes.insert(
E::get_entity_name(),
@ -62,7 +80,16 @@ impl ActixAdminBuilderTrait for ActixAdminBuilder {
.route("/show/{id}", web::get().to(show::<T, E>))
);
self.actix_admin.entity_names.push(E::get_entity_name());
let category = self.actix_admin.entity_names.get_mut(category_name);
match category {
Some(entity_list) => entity_list.push(E::get_entity_name()),
None => {
let mut entity_list = Vec::new();
entity_list.push(E::get_entity_name());
self.actix_admin.entity_names.insert(category_name.to_string(), entity_list);
}
}
let key = E::get_entity_name();
self.actix_admin.view_models.insert(key, view_model.clone());
}
@ -78,6 +105,15 @@ impl ActixAdminBuilderTrait for ActixAdminBuilder {
&mut self,
path: &str,
route: Route
) {
let _ = &self.add_custom_handler_for_entity_in_category::<T,E>(path, route, "");
}
fn add_custom_handler_for_entity_in_category<T: ActixAdminAppDataTrait + 'static, E: ActixAdminViewModelTrait + 'static>(
&mut self,
path: &str,
route: Route,
category_name: &str
) {
let existing_scope = self.scopes.remove(&E::get_entity_name());
match existing_scope {
@ -93,8 +129,14 @@ impl ActixAdminBuilderTrait for ActixAdminBuilder {
}
}
if !self.actix_admin.entity_names.contains(&E::get_entity_name()) {
self.actix_admin.entity_names.push(E::get_entity_name());
let category = self.actix_admin.entity_names.get_mut(category_name);
match category {
Some(entity_list) => {
if !entity_list.contains(&E::get_entity_name()) {
entity_list.push(E::get_entity_name());
}
}
_ => (),
}
}
@ -104,7 +146,9 @@ impl ActixAdminBuilderTrait for ActixAdminBuilder {
_ => web::get().to(index::<T>)
};
let mut admin_scope = web::scope("/admin").route("/", index_handler);
for entity_name in self.actix_admin.entity_names {
let entities = self.actix_admin.entity_names.into_iter().map(|(_k, v)| v).flatten();
for entity_name in entities {
let scope = self.scopes.remove(&entity_name).unwrap();
admin_scope = admin_scope.service(scope);
}

View File

@ -224,7 +224,7 @@ pub struct ActixAdminConfiguration {
#[derive(Clone)]
pub struct ActixAdmin {
pub entity_names: Vec<String>,
pub entity_names: HashMap<String, Vec<String>>,
pub view_models: HashMap<String, ActixAdminViewModel>,
pub configuration: ActixAdminConfiguration
}

View File

@ -13,10 +13,24 @@
<div id="navbarBasicExample" class="navbar-menu">
<div class="navbar-start">
{% for entity_name in entity_names -%}
<a href="/admin/{{ entity_name }}/list" class="navbar-item">{{ entity_name | title }}</a>
{% for category, entities in entity_names %}
{% if category == "" %}
{% for entity_name in entities %}
<a href="/admin/{{ entity_name }}/list" class="navbar-item">{{ entity_name | title }}</a>
{%- endfor %}
{% else %}
<div class="navbar-item has-dropdown is-hoverable">
<a class="navbar-link">
{{ category }}
</a>
<div class="navbar-dropdown">
{% for entity_name in entities %}
<a href="/admin/{{ entity_name }}/list" class="navbar-item">{{ entity_name | title }}</a>
{%- endfor %}
</div>
</div>
{% endif %}
{%- endfor %}
</div>
<div class="navbar-end">

View File

@ -87,7 +87,6 @@ async fn edit_post_from_plaintext<
text: String,
id: web::Path<i32>,
) -> Result<HttpResponse, Error> {
println!("ok");
let model = ActixAdminModel::from(text);
create_or_edit_post::<T, E>(&session, &data, model, Some(id.into_inner())).await
}