store actix_admin in appstate
This commit is contained in:
parent
9923ae6a69
commit
b5f55487fa
@ -40,8 +40,9 @@ pub fn derive_crud_fns(_input: proc_macro::TokenStream) -> proc_macro::TokenStre
|
|||||||
async fn list<T: AppDataTrait>(req: HttpRequest, data: web::Data<T>) -> Result<HttpResponse, Error> {
|
async fn list<T: AppDataTrait>(req: HttpRequest, data: web::Data<T>) -> Result<HttpResponse, Error> {
|
||||||
let db = &data.get_db();
|
let db = &data.get_db();
|
||||||
let entities = Entity::list_db(db, 1, 5);
|
let entities = Entity::list_db(db, 1, 5);
|
||||||
|
let entity_names = &data.get_actix_admin().entity_names;
|
||||||
let model = ActixAdminViewModel::from(Entity);
|
let model = ActixAdminViewModel::from(Entity);
|
||||||
actix_admin::list_model(req, model)
|
actix_admin::list_model(req, &data, model, entity_names)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use actix_web::error::ErrorBadRequest;
|
use actix_web::error::ErrorBadRequest;
|
||||||
use actix_web::{dev, App, FromRequest};
|
use actix_web::{dev, App, FromRequest, Route};
|
||||||
use actix_web::{error, guard, web, Error, HttpRequest, HttpResponse};
|
use actix_web::{error, guard, web, Error, HttpRequest, HttpResponse};
|
||||||
use futures::future::{err, ok, Ready};
|
use futures::future::{err, ok, Ready};
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
@ -18,7 +18,7 @@ pub use actix_admin_macros::DeriveActixAdminModel;
|
|||||||
|
|
||||||
const DEFAULT_POSTS_PER_PAGE: usize = 5;
|
const DEFAULT_POSTS_PER_PAGE: usize = 5;
|
||||||
|
|
||||||
// templates
|
// globals
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
static ref TERA: Tera =
|
static ref TERA: Tera =
|
||||||
Tera::new(concat!(env!("CARGO_MANIFEST_DIR"), "/templates/**/*")).unwrap();
|
Tera::new(concat!(env!("CARGO_MANIFEST_DIR"), "/templates/**/*")).unwrap();
|
||||||
@ -40,6 +40,7 @@ pub enum Field {
|
|||||||
// AppDataTrait
|
// AppDataTrait
|
||||||
pub trait AppDataTrait {
|
pub trait AppDataTrait {
|
||||||
fn get_db(&self) -> &DatabaseConnection;
|
fn get_db(&self) -> &DatabaseConnection;
|
||||||
|
fn get_actix_admin(&self) -> &ActixAdmin;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ActixAdminModel
|
// ActixAdminModel
|
||||||
@ -61,22 +62,29 @@ pub trait ActixAdminViewModelTrait {
|
|||||||
|
|
||||||
#[derive(Clone, Debug, Serialize)]
|
#[derive(Clone, Debug, Serialize)]
|
||||||
pub struct ActixAdminViewModel {
|
pub struct ActixAdminViewModel {
|
||||||
pub entity_name: String
|
pub entity_name: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
// ActixAdminController
|
// ActixAdminController
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct ActixAdmin {
|
pub struct ActixAdmin {
|
||||||
|
pub entity_names: Vec<String>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ActixAdmin {
|
impl ActixAdmin {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
let actix_admin = ActixAdmin {
|
let actix_admin = ActixAdmin {
|
||||||
|
entity_names: Vec::new()
|
||||||
};
|
};
|
||||||
actix_admin
|
actix_admin
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_scope<T: AppDataTrait + 'static>(self, _app_state: &T) -> actix_web::Scope {
|
pub fn add_entity<T: AppDataTrait + 'static>(mut self, view_model: &ActixAdminViewModel) -> Self {
|
||||||
|
self.entity_names.push(view_model.entity_name.to_string());
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn create_scope<T: AppDataTrait + 'static>(&self) -> actix_web::Scope {
|
||||||
let scope = web::scope("/admin").route("/", web::get().to(index::<T>));
|
let scope = web::scope("/admin").route("/", web::get().to(index::<T>));
|
||||||
|
|
||||||
scope
|
scope
|
||||||
@ -85,9 +93,9 @@ impl ActixAdmin {
|
|||||||
|
|
||||||
async fn index<T: AppDataTrait>(data: web::Data<T>) -> Result<HttpResponse, Error> {
|
async fn index<T: AppDataTrait>(data: web::Data<T>) -> Result<HttpResponse, Error> {
|
||||||
|
|
||||||
let view_models: Vec<&str> = Vec::new();
|
let entity_names = &data.get_actix_admin().entity_names;
|
||||||
let mut ctx = Context::new();
|
let mut ctx = Context::new();
|
||||||
ctx.insert("view_models", &view_models);
|
ctx.insert("entity_names", &entity_names);
|
||||||
|
|
||||||
let body = TERA
|
let body = TERA
|
||||||
.render("index.html", &ctx)
|
.render("index.html", &ctx)
|
||||||
@ -95,7 +103,7 @@ async fn index<T: AppDataTrait>(data: web::Data<T>) -> Result<HttpResponse, Erro
|
|||||||
Ok(HttpResponse::Ok().content_type("text/html").body(body))
|
Ok(HttpResponse::Ok().content_type("text/html").body(body))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn list_model(req: HttpRequest, view_model: ActixAdminViewModel) -> Result<HttpResponse, Error> {
|
pub fn list_model<T: AppDataTrait>(req: HttpRequest, data: &web::Data<T>, view_model: ActixAdminViewModel, entity_names: &Vec<String>) -> Result<HttpResponse, Error> {
|
||||||
let params = web::Query::<Params>::from_query(req.query_string()).unwrap();
|
let params = web::Query::<Params>::from_query(req.query_string()).unwrap();
|
||||||
|
|
||||||
let page = params.page.unwrap_or(1);
|
let page = params.page.unwrap_or(1);
|
||||||
@ -104,10 +112,9 @@ pub fn list_model(req: HttpRequest, view_model: ActixAdminViewModel) -> Result<H
|
|||||||
let columns: Vec<String> = Vec::new();
|
let columns: Vec<String> = Vec::new();
|
||||||
|
|
||||||
let entities: Vec<&str> = Vec::new(); // view_model.get_entities()
|
let entities: Vec<&str> = Vec::new(); // view_model.get_entities()
|
||||||
let view_models: Vec<&str> = Vec::new();
|
|
||||||
|
|
||||||
let mut ctx = Context::new();
|
let mut ctx = Context::new();
|
||||||
ctx.insert("view_models", &view_models);
|
ctx.insert("entity_names", &entity_names);
|
||||||
ctx.insert("posts", &entities);
|
ctx.insert("posts", &entities);
|
||||||
ctx.insert("page", &page);
|
ctx.insert("page", &page);
|
||||||
ctx.insert("posts_per_page", &posts_per_page);
|
ctx.insert("posts_per_page", &posts_per_page);
|
||||||
|
@ -4,8 +4,8 @@
|
|||||||
<li>Actix Admin</li>
|
<li>Actix Admin</li>
|
||||||
</ul>
|
</ul>
|
||||||
<ul>
|
<ul>
|
||||||
{% for view_model in view_models -%}
|
{% for entity_name in entity_names -%}
|
||||||
<li><a href="/admin/{{ view_model.entity_name}}/list" class="secondary">{{ view_model.entity_name }}</a></li>
|
<li><a href="/admin/{{ entity_name }}/list" class="secondary">{{ entity_name }}</a></li>
|
||||||
{%- endfor %}
|
{%- endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
|
@ -66,7 +66,7 @@ impl AzureAuth {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_scope<T: AppDataTrait + 'static>(self, _app_state: &T) -> actix_web::Scope {
|
pub fn create_scope<T: AppDataTrait + 'static>(self) -> actix_web::Scope {
|
||||||
let scope = web::scope("/auth")
|
let scope = web::scope("/auth")
|
||||||
.route("/login", web::get().to(login::<T>))
|
.route("/login", web::get().to(login::<T>))
|
||||||
.route("/logout", web::get().to(logout))
|
.route("/logout", web::get().to(logout))
|
||||||
|
30
src/main.rs
30
src/main.rs
@ -1,15 +1,14 @@
|
|||||||
extern crate serde_derive;
|
extern crate serde_derive;
|
||||||
|
|
||||||
use actix_session::{Session, CookieSession};
|
use actix_session::{Session, CookieSession};
|
||||||
use actix_web::{web, App, HttpResponse, HttpServer, HttpRequest, Error};
|
use actix_web::{web, App, HttpResponse, HttpServer};
|
||||||
use tera::{ Tera, Context};
|
use tera::{ Tera, Context};
|
||||||
use oauth2::basic::BasicClient;
|
use oauth2::basic::BasicClient;
|
||||||
use oauth2::{ RedirectUrl };
|
use oauth2::{ RedirectUrl };
|
||||||
use std::time::{Duration};
|
use std::time::{Duration};
|
||||||
use std::env;
|
use std::env;
|
||||||
use sea_orm::{{ DatabaseConnection, ConnectOptions }};
|
use sea_orm::{{ DatabaseConnection, ConnectOptions }};
|
||||||
use std::any::Any;
|
use actix_admin::{ AppDataTrait as ActixAdminAppDataTrait, ActixAdminViewModel, ActixAdmin, ActixAdminViewModelTrait };
|
||||||
use actix_admin::{ AppDataTrait as ActixAdminAppDataTrait, ActixAdminViewModelTrait };
|
|
||||||
use azure_auth::{ AzureAuth, UserInfo, AppDataTrait as AzureAuthAppDataTrait };
|
use azure_auth::{ AzureAuth, UserInfo, AppDataTrait as AzureAuthAppDataTrait };
|
||||||
|
|
||||||
mod entity;
|
mod entity;
|
||||||
@ -20,12 +19,16 @@ pub struct AppState {
|
|||||||
pub oauth: BasicClient,
|
pub oauth: BasicClient,
|
||||||
pub tmpl: Tera,
|
pub tmpl: Tera,
|
||||||
pub db: DatabaseConnection,
|
pub db: DatabaseConnection,
|
||||||
|
pub actix_admin: ActixAdmin
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ActixAdminAppDataTrait for AppState {
|
impl ActixAdminAppDataTrait for AppState {
|
||||||
fn get_db(&self) -> &DatabaseConnection {
|
fn get_db(&self) -> &DatabaseConnection {
|
||||||
&self.db
|
&self.db
|
||||||
}
|
}
|
||||||
|
fn get_actix_admin(&self) -> &ActixAdmin {
|
||||||
|
&self.actix_admin
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AzureAuthAppDataTrait for AppState {
|
impl AzureAuthAppDataTrait for AppState {
|
||||||
@ -76,10 +79,17 @@ async fn main() {
|
|||||||
let conn = sea_orm::Database::connect(opt).await.unwrap();
|
let conn = sea_orm::Database::connect(opt).await.unwrap();
|
||||||
let _ = entity::create_post_table(&conn).await;
|
let _ = entity::create_post_table(&conn).await;
|
||||||
|
|
||||||
|
let post_view_model = ActixAdminViewModel::from(Post);
|
||||||
|
let comment_view_model = ActixAdminViewModel::from(Comment);
|
||||||
|
let actix_admin = ActixAdmin::new()
|
||||||
|
.add_entity::<AppState>(&post_view_model)
|
||||||
|
.add_entity::<AppState>(&comment_view_model);
|
||||||
|
|
||||||
let app_state = AppState {
|
let app_state = AppState {
|
||||||
oauth: client,
|
oauth: client,
|
||||||
tmpl: tera,
|
tmpl: tera,
|
||||||
db: conn,
|
db: conn,
|
||||||
|
actix_admin: actix_admin.clone()
|
||||||
};
|
};
|
||||||
|
|
||||||
HttpServer::new(move || {
|
HttpServer::new(move || {
|
||||||
@ -87,12 +97,18 @@ async fn main() {
|
|||||||
.app_data(web::Data::new(app_state.clone()))
|
.app_data(web::Data::new(app_state.clone()))
|
||||||
.wrap(CookieSession::signed(&[0; 32]).secure(false))
|
.wrap(CookieSession::signed(&[0; 32]).secure(false))
|
||||||
.route("/", web::get().to(index))
|
.route("/", web::get().to(index))
|
||||||
.service(azure_auth.clone().create_scope(&app_state))
|
.service(azure_auth.clone().create_scope::<AppState>())
|
||||||
.service(
|
.service(
|
||||||
actix_admin::ActixAdmin::new()
|
// TODO: Generate this with a Macro accepting Tuples of (Entity, viewmodel)
|
||||||
.create_scope(&app_state)
|
actix_admin
|
||||||
|
.create_scope::<AppState>()
|
||||||
.service(
|
.service(
|
||||||
web::scope(&format!("/{}", "posts")).route("/list", web::get().to(Post::list::<AppState>)),
|
web::scope(&format!("/{}", post_view_model.entity_name))
|
||||||
|
.route("/list", web::get().to(Post::list::<AppState>)),
|
||||||
|
)
|
||||||
|
.service(
|
||||||
|
web::scope(&format!("/{}", comment_view_model.entity_name))
|
||||||
|
.route("/list", web::get().to(Comment::list::<AppState>)),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
Loading…
Reference in New Issue
Block a user