refactor menu element to allow adding arbitrary elements to the navbar
This commit is contained in:
parent
5729ecee29
commit
0b293b5807
@ -121,6 +121,7 @@ fn create_actix_admin_builder() -> ActixAdminBuilder {
|
|||||||
let some_category = "Some Category";
|
let some_category = "Some Category";
|
||||||
admin_builder.add_entity_to_category::<AppState, Comment>(&comment_view_model, 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>(
|
admin_builder.add_custom_handler_for_entity_in_category::<AppState, Comment>(
|
||||||
|
"My custom handler",
|
||||||
"/custom_handler",
|
"/custom_handler",
|
||||||
web::get().to(custom_handler::<AppState, Comment>),
|
web::get().to(custom_handler::<AppState, Comment>),
|
||||||
some_category
|
some_category
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use actix_web::{ web, Route };
|
use actix_web::{ web, Route };
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use crate::prelude::*;
|
use crate::{prelude::*, ActixAdminMenuElement};
|
||||||
|
|
||||||
use crate::routes::{create_get, create_post, delete, delete_many, edit_get, edit_post, index, list, show};
|
use crate::routes::{create_get, create_post, delete, delete_many, edit_get, edit_post, index, list, show};
|
||||||
|
|
||||||
@ -25,11 +25,13 @@ pub trait ActixAdminBuilderTrait {
|
|||||||
);
|
);
|
||||||
fn add_custom_handler_for_entity<T: ActixAdminAppDataTrait + 'static, E: ActixAdminViewModelTrait + 'static>(
|
fn add_custom_handler_for_entity<T: ActixAdminAppDataTrait + 'static, E: ActixAdminViewModelTrait + 'static>(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
menu_element_name: &str,
|
||||||
path: &str,
|
path: &str,
|
||||||
route: Route
|
route: Route
|
||||||
);
|
);
|
||||||
fn add_custom_handler_for_entity_in_category<T: ActixAdminAppDataTrait + 'static, E: ActixAdminViewModelTrait + 'static>(
|
fn add_custom_handler_for_entity_in_category<T: ActixAdminAppDataTrait + 'static, E: ActixAdminViewModelTrait + 'static>(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
menu_element_name: &str,
|
||||||
path: &str,
|
path: &str,
|
||||||
route: Route,
|
route: Route,
|
||||||
category_name: &str
|
category_name: &str
|
||||||
@ -81,11 +83,18 @@ impl ActixAdminBuilderTrait for ActixAdminBuilder {
|
|||||||
);
|
);
|
||||||
|
|
||||||
let category = self.actix_admin.entity_names.get_mut(category_name);
|
let category = self.actix_admin.entity_names.get_mut(category_name);
|
||||||
|
let menu_element = ActixAdminMenuElement {
|
||||||
|
name: E::get_entity_name(),
|
||||||
|
link: E::get_entity_name(),
|
||||||
|
is_custom_handler: false
|
||||||
|
};
|
||||||
match category {
|
match category {
|
||||||
Some(entity_list) => entity_list.push(E::get_entity_name()),
|
Some(entity_list) => {
|
||||||
|
entity_list.push(menu_element)
|
||||||
|
},
|
||||||
None => {
|
None => {
|
||||||
let mut entity_list = Vec::new();
|
let mut entity_list = Vec::new();
|
||||||
entity_list.push(E::get_entity_name());
|
entity_list.push(menu_element);
|
||||||
self.actix_admin.entity_names.insert(category_name.to_string(), entity_list);
|
self.actix_admin.entity_names.insert(category_name.to_string(), entity_list);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -103,54 +112,61 @@ impl ActixAdminBuilderTrait for ActixAdminBuilder {
|
|||||||
|
|
||||||
fn add_custom_handler_for_entity<T: ActixAdminAppDataTrait + 'static, E: ActixAdminViewModelTrait + 'static>(
|
fn add_custom_handler_for_entity<T: ActixAdminAppDataTrait + 'static, E: ActixAdminViewModelTrait + 'static>(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
menu_element_name: &str,
|
||||||
path: &str,
|
path: &str,
|
||||||
route: Route
|
route: Route
|
||||||
) {
|
) {
|
||||||
let _ = &self.add_custom_handler_for_entity_in_category::<T,E>(path, route, "");
|
let _ = &self.add_custom_handler_for_entity_in_category::<T,E>(menu_element_name ,path, route, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_custom_handler_for_entity_in_category<T: ActixAdminAppDataTrait + 'static, E: ActixAdminViewModelTrait + 'static>(
|
fn add_custom_handler_for_entity_in_category<T: ActixAdminAppDataTrait + 'static, E: ActixAdminViewModelTrait + 'static>(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
menu_element_name: &str,
|
||||||
path: &str,
|
path: &str,
|
||||||
route: Route,
|
route: Route,
|
||||||
category_name: &str
|
category_name: &str
|
||||||
) {
|
) {
|
||||||
|
let menu_element = ActixAdminMenuElement {
|
||||||
|
name: menu_element_name.to_string(),
|
||||||
|
link: format!("{}{}", E::get_entity_name(), path),
|
||||||
|
is_custom_handler: true
|
||||||
|
};
|
||||||
|
|
||||||
let existing_scope = self.scopes.remove(&E::get_entity_name());
|
let existing_scope = self.scopes.remove(&E::get_entity_name());
|
||||||
|
|
||||||
match existing_scope {
|
match existing_scope {
|
||||||
Some(scope) => {
|
Some(scope) => {
|
||||||
let existing_scope = scope.route(path, route);
|
let existing_scope = scope.route(path, route);
|
||||||
self.scopes.insert(E::get_entity_name(), existing_scope);
|
self.scopes.insert(menu_element.link.to_string(), existing_scope);
|
||||||
},
|
},
|
||||||
_ => {
|
_ => {
|
||||||
let new_scope =
|
let new_scope =
|
||||||
web::scope(&format!("/{}", E::get_entity_name()))
|
web::scope(&format!("/{}", E::get_entity_name()))
|
||||||
.route(path, route);
|
.route(path, route);
|
||||||
self.scopes.insert(E::get_entity_name(), new_scope);
|
self.scopes.insert(menu_element.link.to_string(), new_scope);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let category = self.actix_admin.entity_names.get_mut(category_name);
|
let category = self.actix_admin.entity_names.get_mut(category_name);
|
||||||
match category {
|
match category {
|
||||||
Some(entity_list) => {
|
Some(entity_list) => {
|
||||||
if !entity_list.contains(&E::get_entity_name()) {
|
if !entity_list.contains(&menu_element) {
|
||||||
entity_list.push(E::get_entity_name());
|
entity_list.push(menu_element);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_scope<T: ActixAdminAppDataTrait + 'static>(mut self) -> actix_web::Scope {
|
fn get_scope<T: ActixAdminAppDataTrait + 'static>(self) -> actix_web::Scope {
|
||||||
let index_handler = match self.custom_index {
|
let index_handler = match self.custom_index {
|
||||||
Some(handler) => handler,
|
Some(handler) => handler,
|
||||||
_ => web::get().to(index::<T>)
|
_ => web::get().to(index::<T>)
|
||||||
};
|
};
|
||||||
let mut admin_scope = web::scope("/admin").route("/", index_handler);
|
let mut admin_scope = web::scope("/admin").route("/", index_handler);
|
||||||
let entities = self.actix_admin.entity_names.into_iter().map(|(_k, v)| v).flatten();
|
|
||||||
|
for (_entity, scope) in self.scopes {
|
||||||
for entity_name in entities {
|
admin_scope = admin_scope.service(scope);
|
||||||
let scope = self.scopes.remove(&entity_name).unwrap();
|
|
||||||
admin_scope = admin_scope.service(scope);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
admin_scope
|
admin_scope
|
||||||
|
10
src/lib.rs
10
src/lib.rs
@ -116,6 +116,7 @@
|
|||||||
|
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
use sea_orm::DatabaseConnection;
|
use sea_orm::DatabaseConnection;
|
||||||
|
use serde::Serialize;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use tera::{Tera, Result, to_value, try_get_value };
|
use tera::{Tera, Result, to_value, try_get_value };
|
||||||
use std::{ hash::BuildHasher};
|
use std::{ hash::BuildHasher};
|
||||||
@ -224,7 +225,14 @@ pub struct ActixAdminConfiguration {
|
|||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct ActixAdmin {
|
pub struct ActixAdmin {
|
||||||
pub entity_names: HashMap<String, Vec<String>>,
|
pub entity_names: HashMap<String, Vec<ActixAdminMenuElement>>,
|
||||||
pub view_models: HashMap<String, ActixAdminViewModel>,
|
pub view_models: HashMap<String, ActixAdminViewModel>,
|
||||||
pub configuration: ActixAdminConfiguration
|
pub configuration: ActixAdminConfiguration
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(PartialEq, Eq, Clone, Serialize)]
|
||||||
|
pub struct ActixAdminMenuElement {
|
||||||
|
pub name: String,
|
||||||
|
pub link: String,
|
||||||
|
pub is_custom_handler: bool
|
||||||
|
}
|
||||||
|
@ -15,8 +15,12 @@
|
|||||||
<div class="navbar-start">
|
<div class="navbar-start">
|
||||||
{% for category, entities in entity_names %}
|
{% for category, entities in entity_names %}
|
||||||
{% if category == "" %}
|
{% if category == "" %}
|
||||||
{% for name in entities %}
|
{% for menu_element in entities %}
|
||||||
<a href="/admin/{{ name }}/list" class="navbar-item {% if entity_name and entity_name == name %}is-active{% endif %}">{{ name | title }}</a>
|
{% if menu_element.is_custom_handler %}
|
||||||
|
<a href="/admin/{{ menu_element.link }}" class="navbar-item {% if entity_name and entity_name == menu_element.name %}is-active{% endif %}">{{ menu_element.name }}</a>
|
||||||
|
{% else %}
|
||||||
|
<a href="/admin/{{ menu_element.link }}/list" class="navbar-item {% if entity_name and entity_name == menu_element.name %}is-active{% endif %}">{{ menu_element.name | title }}</a>
|
||||||
|
{% endif %}
|
||||||
{%- endfor %}
|
{%- endfor %}
|
||||||
{% else %}
|
{% else %}
|
||||||
<div class="navbar-item has-dropdown is-hoverable">
|
<div class="navbar-item has-dropdown is-hoverable">
|
||||||
@ -24,8 +28,12 @@
|
|||||||
{{ category }}
|
{{ category }}
|
||||||
</a>
|
</a>
|
||||||
<div class="navbar-dropdown">
|
<div class="navbar-dropdown">
|
||||||
{% for name in entities %}
|
{% for menu_element in entities %}
|
||||||
<a href="/admin/{{ name }}/list" class="navbar-item {% if entity_name and entity_name == name %}is-active{% endif %}">{{ name | title }}</a>
|
{% if menu_element.is_custom_handler %}
|
||||||
|
<a href="/admin/{{ menu_element.link }}" class="navbar-item {% if entity_name and entity_name == menu_element.name %}is-active{% endif %}">{{ menu_element.name }}</a>
|
||||||
|
{% else %}
|
||||||
|
<a href="/admin/{{ menu_element.link }}/list" class="navbar-item {% if entity_name and entity_name == menu_element.name %}is-active{% endif %}">{{ menu_element.name | title }}</a>
|
||||||
|
{% endif %}
|
||||||
{%- endfor %}
|
{%- endfor %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -48,18 +48,22 @@ pub fn create_actix_admin_builder() -> ActixAdminBuilder {
|
|||||||
admin_builder.add_entity::<AppState, Comment>(&comment_view_model);
|
admin_builder.add_entity::<AppState, Comment>(&comment_view_model);
|
||||||
|
|
||||||
admin_builder.add_custom_handler_for_entity::<AppState, Comment>(
|
admin_builder.add_custom_handler_for_entity::<AppState, Comment>(
|
||||||
|
"Create Post From Plaintext",
|
||||||
"/create_post_from_plaintext",
|
"/create_post_from_plaintext",
|
||||||
web::post().to(create_post_from_plaintext::<AppState, Comment>));
|
web::post().to(create_post_from_plaintext::<AppState, Comment>));
|
||||||
|
|
||||||
admin_builder.add_custom_handler_for_entity::<AppState, Post>(
|
admin_builder.add_custom_handler_for_entity::<AppState, Post>(
|
||||||
|
"Create Post From Plaintext",
|
||||||
"/create_post_from_plaintext",
|
"/create_post_from_plaintext",
|
||||||
web::post().to(create_post_from_plaintext::<AppState, Post>));
|
web::post().to(create_post_from_plaintext::<AppState, Post>));
|
||||||
|
|
||||||
admin_builder.add_custom_handler_for_entity::<AppState, Post>(
|
admin_builder.add_custom_handler_for_entity::<AppState, Post>(
|
||||||
|
"Create Post From Plaintext",
|
||||||
"/edit_post_from_plaintext/{id}",
|
"/edit_post_from_plaintext/{id}",
|
||||||
web::post().to(edit_post_from_plaintext::<AppState, Post>));
|
web::post().to(edit_post_from_plaintext::<AppState, Post>));
|
||||||
|
|
||||||
admin_builder.add_custom_handler_for_entity::<AppState, Comment>(
|
admin_builder.add_custom_handler_for_entity::<AppState, Comment>(
|
||||||
|
"Create Post From Plaintext",
|
||||||
"/edit_post_from_plaintext/{id}",
|
"/edit_post_from_plaintext/{id}",
|
||||||
web::post().to(edit_post_from_plaintext::<AppState, Comment>));
|
web::post().to(edit_post_from_plaintext::<AppState, Comment>));
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user