use std::sync::Arc; use axum::extract::Path; use axum::{extract::State, response::IntoResponse, Form}; use log::info; use crate::admin::domain::{AdminApp, AdminModel}; use crate::admin::state; use crate::service::templates; use serde::{Deserialize, Serialize}; use serde_json::Value; use super::domain::{RepositoryInfo, RepositoryList}; #[derive(Deserialize)] pub struct Question { question: String, } #[derive(Deserialize)] pub struct ExampleData { title: String, content: String, } #[derive(Serialize, Deserialize)] pub struct AdminRequest { pub path: String, } #[derive(Serialize)] pub struct AdminContext { pub language_code: Option, pub language_bidi: Option, pub user: Option, // Todo: user type pub admin_url: String, pub site_url: Option, pub docsroot: Option, pub messages: Vec, // Todo: message type pub title: Option, pub subtitle: Option, pub content: String, pub request: AdminRequest, pub available_apps: Vec, pub item_info: Option, pub item_list: RepositoryList, pub item: Option, } impl Default for AdminContext { fn default() -> Self { AdminContext { language_code: Some("en-us".to_string()), // Default language code language_bidi: Some(false), // Default language bidi user: None, //UserType::default(), // Assuming UserType has a Default impl admin_url: "/admin".to_owned(), site_url: None, docsroot: None, messages: Vec::new(), // Empty vector for messages title: None, subtitle: None, content: String::new(), // Empty string for content available_apps: Vec::new(), request: AdminRequest { path: "".to_owned(), }, item_info: None, item_list: RepositoryList::Empty, item: None, } } } pub async fn index( templates: State, registry: State>, ) -> impl IntoResponse { templates.render_html( "admin/index.html", AdminContext { available_apps: registry.get_apps(), ..Default::default() }, ) } // Index Action is POST to the index site. We can anchor some general business code here. pub async fn index_action(Form(example_data): Form) -> impl IntoResponse { "There is your answer!".to_owned() } pub async fn list_app( templates: State, Path(app_key): Path, ) -> impl IntoResponse { templates.render_html("admin/app_list.jinja", ()) } // List Items renders the entire list item page. pub async fn list_item_collection( templates: State, registry: State>, Path((app_key, model_key)): Path<(String, String)>, ) -> impl IntoResponse { info!("list_item_collection {} for model {}", app_key, model_key); let context = if let Ok(repo) = registry.get_repository(&model_key) { // we should consider using Vec instead in get_list. AdminContext { available_apps: registry.get_apps(), content: model_key.to_owned(), item_info: Some(repo.get_repo_info()), item_list: repo.get_list(), ..Default::default() } } else { AdminContext { available_apps: registry.get_apps(), ..Default::default() } }; templates.render_html("admin/items/item_list.jinja", context) } // Items Action is a POST to an item list. By default these are actions, that work on a list of items as input. pub async fn item_collection_action( Form(question): Form, Path((app_key, model_key)): Path<(String, String)>, ) -> impl IntoResponse { "There is your answer!".to_owned() } // Item Details shows one single dataset. pub async fn item_details( templates: State, Path((app_key, model_key, id)): Path<(String, String, String)>, ) -> impl IntoResponse { templates.render_html("admin/items/item_detail.jinja", ()) } // Item Action allows running an action on one single dataset. pub async fn item_action( Form(question): Form, Path((app_key, model_key, model_id)): Path<(String, String, String)>, ) -> impl IntoResponse { "There is your answer!".to_owned() } pub async fn debug_view(Path(data): Path) -> impl IntoResponse { println!("debug: {}", data); "Debug!".to_owned() }