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 | |
|
||||
| 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;
|
||||
|
||||
pub mod domain;
|
||||
pub mod example;
|
||||
pub mod state;
|
||||
pub mod views;
|
||||
|
||||
|
@ -36,32 +36,48 @@ impl AdminRegistry {
|
||||
.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 {
|
||||
name: name.to_owned(),
|
||||
key: node.key.to_owned(),
|
||||
app_url: name.to_owned().to_lowercase(),
|
||||
models: vec![],
|
||||
name: key.to_owned(),
|
||||
key: node.name.to_owned(),
|
||||
app_url: key.to_owned(),
|
||||
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);
|
||||
self.apps.insert(
|
||||
key.to_owned(),
|
||||
internal::AdminApp {
|
||||
key: key,
|
||||
key: key.to_owned(),
|
||||
name: name.to_owned(),
|
||||
},
|
||||
);
|
||||
key
|
||||
}
|
||||
|
||||
fn get_key(&self, name: &str) -> String {
|
||||
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> {
|
||||
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> {
|
||||
@ -69,13 +85,7 @@ impl AdminRegistry {
|
||||
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.
|
||||
Some(AdminModel {
|
||||
key: internal_model.model_key.clone(),
|
||||
name: internal_model.model_key.clone(),
|
||||
admin_url: "".to_owned(),
|
||||
view_only: false,
|
||||
add_url: None,
|
||||
})
|
||||
Some(self.model_from_internal(internal_model))
|
||||
}
|
||||
|
||||
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) {
|
||||
return Err(format!("Model {} already exists", local_config_name));
|
||||
}
|
||||
if let Some(local_config) = self.models.insert(local_config_name, local_config) {
|
||||
return Ok(local_config.model_key);
|
||||
}
|
||||
Err("Model could not be added!".to_owned())
|
||||
let model_key = local_config.model_key.clone();
|
||||
self.models.insert(local_config_name, local_config);
|
||||
Ok(model_key)
|
||||
}
|
||||
|
||||
pub fn register_model<R: AdminRepository + 'static>(
|
||||
|
@ -62,45 +62,12 @@ impl Default for AdminContext {
|
||||
|
||||
pub async fn index(
|
||||
templates: State<templates::Templates>,
|
||||
administration: State<Arc<state::AdminRegistry>>,
|
||||
registry: State<Arc<state::AdminRegistry>>,
|
||||
) -> 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(
|
||||
"admin/index.html",
|
||||
AdminContext {
|
||||
available_apps: available,
|
||||
available_apps: registry.get_apps(),
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
|
@ -3,6 +3,7 @@ mod howto;
|
||||
mod service;
|
||||
mod state;
|
||||
|
||||
use crate::admin::example;
|
||||
use crate::service::{handlers, templates};
|
||||
use crate::state::AppState;
|
||||
use axum::{
|
||||
@ -32,8 +33,7 @@ async fn main() {
|
||||
// Prepare App State
|
||||
let tmpl = templates::Templates::initialize().expect("Template Engine could not be loaded.");
|
||||
let mut admin = admin::state::AdminRegistry::new("admin");
|
||||
admin.register_app("auth", "Authorities", "auth");
|
||||
//let admin_router = admin.generate_router();
|
||||
example::register_example(&mut admin);
|
||||
|
||||
let state: AppState = AppState {
|
||||
templates: tmpl,
|
||||
|
Loading…
Reference in New Issue
Block a user