code: moving static example into a repository, and implementing app/model listing.
This commit is contained in:
parent
eef65cfdd0
commit
94845ecb0e
5
NOTES.md
5
NOTES.md
@ -130,3 +130,8 @@ As I started by quickly using a django admin template with CSS to jump start the
|
|||||||
| object_name\|lower | key, app_key, model_key | |
|
| object_name\|lower | key, app_key, model_key | |
|
||||||
| app_label | key, app_key | |
|
| app_label | key, app_key | |
|
||||||
|
|
||||||
|
### Next Steps:
|
||||||
|
|
||||||
|
- implement views for app
|
||||||
|
- implement a static implementation for repository
|
||||||
|
|
36
src/admin/example.rs
Normal file
36
src/admin/example.rs
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
// implementation of static repository
|
||||||
|
|
||||||
|
use super::state::{config::AdminModelConfig, AdminRegistry, AdminRepository};
|
||||||
|
use serde_json::{json, Value};
|
||||||
|
|
||||||
|
struct MyStaticRepository {}
|
||||||
|
|
||||||
|
impl AdminRepository for MyStaticRepository {
|
||||||
|
fn get_item(&self, id: usize) -> Option<Value> {
|
||||||
|
Some(json!({
|
||||||
|
"name": "Adam",
|
||||||
|
"age": id,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_list(&self) -> Value {
|
||||||
|
json!([
|
||||||
|
{"name": "Strange", "age": 150 },
|
||||||
|
{"name": "Adam", "age": 12}
|
||||||
|
])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn register_example(registry: &mut AdminRegistry) {
|
||||||
|
let app_key = registry.register_app("Example App");
|
||||||
|
let repo = MyStaticRepository {};
|
||||||
|
let model_config = AdminModelConfig {
|
||||||
|
app_key: app_key,
|
||||||
|
name: "ExampleModel".to_owned(),
|
||||||
|
};
|
||||||
|
let model_result = registry.register_model(model_config, repo);
|
||||||
|
match model_result {
|
||||||
|
Err(err) => panic!("{}", err),
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
|
}
|
@ -3,6 +3,7 @@ use axum::{routing::get, Router};
|
|||||||
use crate::state::AppState;
|
use crate::state::AppState;
|
||||||
|
|
||||||
pub mod domain;
|
pub mod domain;
|
||||||
|
pub mod example;
|
||||||
pub mod state;
|
pub mod state;
|
||||||
pub mod views;
|
pub mod views;
|
||||||
|
|
||||||
|
@ -36,32 +36,48 @@ impl AdminRegistry {
|
|||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_app(&self, name: &str, node: &internal::AdminApp) -> AdminApp {
|
fn get_app(&self, key: &str, node: &internal::AdminApp) -> AdminApp {
|
||||||
|
let my_models = self.get_models(key);
|
||||||
AdminApp {
|
AdminApp {
|
||||||
name: name.to_owned(),
|
name: key.to_owned(),
|
||||||
key: node.key.to_owned(),
|
key: node.name.to_owned(),
|
||||||
app_url: name.to_owned().to_lowercase(),
|
app_url: key.to_owned(),
|
||||||
models: vec![],
|
models: my_models,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn register_app(&mut self, name: &str, app_label: &str, app_url: &str) {
|
pub fn register_app(&mut self, name: &str) -> String {
|
||||||
let key = self.get_key(name);
|
let key = self.get_key(name);
|
||||||
self.apps.insert(
|
self.apps.insert(
|
||||||
key.to_owned(),
|
key.to_owned(),
|
||||||
internal::AdminApp {
|
internal::AdminApp {
|
||||||
key: key,
|
key: key.to_owned(),
|
||||||
name: name.to_owned(),
|
name: name.to_owned(),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
key
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_key(&self, name: &str) -> String {
|
fn get_key(&self, name: &str) -> String {
|
||||||
slug::slugify(name)
|
slug::slugify(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn model_from_internal(&self, internal_model: &internal::AdminModel) -> AdminModel {
|
||||||
|
AdminModel {
|
||||||
|
key: internal_model.model_key.clone(),
|
||||||
|
name: internal_model.model_key.clone(),
|
||||||
|
admin_url: "".to_owned(),
|
||||||
|
view_only: false,
|
||||||
|
add_url: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_models(&self, app_key: &str) -> Vec<AdminModel> {
|
pub fn get_models(&self, app_key: &str) -> Vec<AdminModel> {
|
||||||
vec![]
|
self.models
|
||||||
|
.iter()
|
||||||
|
.filter(|(key, _)| key.starts_with(&format!("{}.", app_key)))
|
||||||
|
.map(|(_, model)| self.model_from_internal(model))
|
||||||
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_model(&self, app_key: &str, model_key: &str) -> Option<AdminModel> {
|
pub fn get_model(&self, app_key: &str, model_key: &str) -> Option<AdminModel> {
|
||||||
@ -69,13 +85,7 @@ impl AdminRegistry {
|
|||||||
let internal_model = self.models.get(&full_model_key)?;
|
let internal_model = self.models.get(&full_model_key)?;
|
||||||
|
|
||||||
// unfinished: we need to think about model_key vs. model_id vs. entry_id, as "name" is ambiguous.
|
// unfinished: we need to think about model_key vs. model_id vs. entry_id, as "name" is ambiguous.
|
||||||
Some(AdminModel {
|
Some(self.model_from_internal(internal_model))
|
||||||
key: internal_model.model_key.clone(),
|
|
||||||
name: internal_model.model_key.clone(),
|
|
||||||
admin_url: "".to_owned(),
|
|
||||||
view_only: false,
|
|
||||||
add_url: None,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn register_model_config(&mut self, model: config::AdminModelConfig) -> Result<String, String> {
|
fn register_model_config(&mut self, model: config::AdminModelConfig) -> Result<String, String> {
|
||||||
@ -87,10 +97,9 @@ impl AdminRegistry {
|
|||||||
if self.models.contains_key(&local_config_name) {
|
if self.models.contains_key(&local_config_name) {
|
||||||
return Err(format!("Model {} already exists", local_config_name));
|
return Err(format!("Model {} already exists", local_config_name));
|
||||||
}
|
}
|
||||||
if let Some(local_config) = self.models.insert(local_config_name, local_config) {
|
let model_key = local_config.model_key.clone();
|
||||||
return Ok(local_config.model_key);
|
self.models.insert(local_config_name, local_config);
|
||||||
}
|
Ok(model_key)
|
||||||
Err("Model could not be added!".to_owned())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn register_model<R: AdminRepository + 'static>(
|
pub fn register_model<R: AdminRepository + 'static>(
|
||||||
|
@ -62,45 +62,12 @@ impl Default for AdminContext {
|
|||||||
|
|
||||||
pub async fn index(
|
pub async fn index(
|
||||||
templates: State<templates::Templates>,
|
templates: State<templates::Templates>,
|
||||||
administration: State<Arc<state::AdminRegistry>>,
|
registry: State<Arc<state::AdminRegistry>>,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
let models = vec![
|
|
||||||
AdminModel {
|
|
||||||
name: "User".to_owned(),
|
|
||||||
key: "user".to_owned(),
|
|
||||||
admin_url: "/admin/app/users/user".to_owned(),
|
|
||||||
view_only: false,
|
|
||||||
add_url: Some("/admin/users/user/add".to_owned()),
|
|
||||||
},
|
|
||||||
AdminModel {
|
|
||||||
name: "Group".to_owned(),
|
|
||||||
key: "group".to_owned(),
|
|
||||||
admin_url: "/admin/users/group".to_owned(),
|
|
||||||
view_only: false,
|
|
||||||
add_url: None,
|
|
||||||
},
|
|
||||||
AdminModel {
|
|
||||||
name: "Permission".to_owned(),
|
|
||||||
key: "permission".to_owned(),
|
|
||||||
admin_url: "/admin/users/permission".to_owned(),
|
|
||||||
view_only: true,
|
|
||||||
add_url: None,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
let core_app = AdminApp {
|
|
||||||
name: "Admin".to_owned(),
|
|
||||||
key: "admin".to_owned(),
|
|
||||||
app_url: "/admin/users/".to_owned(),
|
|
||||||
models: models,
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut available = vec![core_app];
|
|
||||||
available.extend(administration.get_apps());
|
|
||||||
|
|
||||||
templates.render_html(
|
templates.render_html(
|
||||||
"admin/index.html",
|
"admin/index.html",
|
||||||
AdminContext {
|
AdminContext {
|
||||||
available_apps: available,
|
available_apps: registry.get_apps(),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
@ -3,6 +3,7 @@ mod howto;
|
|||||||
mod service;
|
mod service;
|
||||||
mod state;
|
mod state;
|
||||||
|
|
||||||
|
use crate::admin::example;
|
||||||
use crate::service::{handlers, templates};
|
use crate::service::{handlers, templates};
|
||||||
use crate::state::AppState;
|
use crate::state::AppState;
|
||||||
use axum::{
|
use axum::{
|
||||||
@ -32,8 +33,7 @@ async fn main() {
|
|||||||
// Prepare App State
|
// Prepare App State
|
||||||
let tmpl = templates::Templates::initialize().expect("Template Engine could not be loaded.");
|
let tmpl = templates::Templates::initialize().expect("Template Engine could not be loaded.");
|
||||||
let mut admin = admin::state::AdminRegistry::new("admin");
|
let mut admin = admin::state::AdminRegistry::new("admin");
|
||||||
admin.register_app("auth", "Authorities", "auth");
|
example::register_example(&mut admin);
|
||||||
//let admin_router = admin.generate_router();
|
|
||||||
|
|
||||||
let state: AppState = AppState {
|
let state: AppState = AppState {
|
||||||
templates: tmpl,
|
templates: tmpl,
|
||||||
|
Loading…
Reference in New Issue
Block a user