use actix_web::{web, HttpRequest, Responder, HttpResponse}; use crate::TERA; use crate::tera_ext::TeraExt; use yopa::{Storage, StorageError}; use serde::{Deserialize, Serialize}; use yopa::model::{PropertyModel, RelationModel, ObjectModel}; use std::ops::DerefMut; use actix_session::Session; use crate::session_ext::SessionExt; #[derive(Serialize, Debug)] struct ObjectModelDisplay<'a> { id : yopa::ID, name : &'a str, properties: Vec<&'a PropertyModel>, relations: Vec>, } #[derive(Serialize, Debug)] struct RelationModelDisplay<'a> { model : &'a RelationModel, related_name : &'a str, properties: Vec<&'a PropertyModel>, } #[get("/")] pub(crate) async fn index(session : Session, store : crate::YopaStoreWrapper) -> actix_web::Result { let rg = store.read().await; let models_iter = rg.get_object_models(); // object and relation props let mut model_props = rg.get_grouped_prop_models(); let mut model_relations = rg.get_grouped_relation_models(); let mut models = vec![]; for om in models_iter { let mut oprops = model_props.remove(&om.id).unwrap_or_default(); let mut relations = model_relations.remove(&om.id).unwrap_or_default(); let rel_displays = relations.into_iter().map(|rm| { let mut rprops = model_props.remove(&rm.id).unwrap_or_default(); rprops.sort_by_key(|m| &m.name); RelationModelDisplay { model: rm, related_name: rg.get_model_name(rm.related), properties: rprops } }).collect::>(); oprops.sort_by_key(|m| &m.name); models.push(ObjectModelDisplay { id: om.id, name: &om.name, properties: oprops, relations: rel_displays, }) } models.sort_by_key(|m| m.name); let mut ctx = tera::Context::new(); ctx.insert("models", &models); session.render_flash(&mut ctx); TERA.build_response("index", &ctx) } #[get("/model/object/create")] pub(crate) async fn object_model_create_form(session : Session) -> actix_web::Result { let mut context = tera::Context::new(); session.render_flash(&mut context); TERA.build_response("model_create", &context) } #[derive(Deserialize)] pub(crate) struct ObjectModelCreate { pub name : String, } #[post("/model/object/create")] pub(crate) async fn object_model_create( form : web::Form, store : crate::YopaStoreWrapper, session : Session ) -> actix_web::Result { let mut wg = store.write().await; let form = form.into_inner(); match wg.define_object(ObjectModel { id: Default::default(), name: form.name.clone() }) { Ok(_id) => { debug!("Object created, redirecting to root"); session.flash_success(format!("Object model \"{}\" created.", form.name)); Ok(HttpResponse::SeeOther() .header("location", "/") .finish()) } Err(e) => { warn!("Error creating model: {}", e); session.flash_error(e.to_string()); // Redirect back Ok(HttpResponse::SeeOther() .header("location", "/model/object/create") .finish()) } } }