use actix_session::Session; use actix_web::{Responder, web}; use serde::{Deserialize, Serialize}; use yopa::ID; use yopa::model::{ObjectModel, PropertyModel}; use crate::routes::relation_model::RelationModelDisplay; use crate::session_ext::SessionExt; use crate::TERA; use crate::tera_ext::TeraExt; use crate::utils::redirect; #[derive(Serialize, Debug)] pub(crate) struct ObjectModelDisplay<'a> { pub(crate) id: yopa::ID, pub(crate) name: &'a str, pub(crate) properties: Vec<&'a PropertyModel>, pub(crate) relations: Vec>, pub(crate) reciprocal_relations: Vec>, } #[get("/model/object/create")] pub(crate) async fn create_form(session: Session) -> actix_web::Result { let mut context = tera::Context::new(); session.render_flash(&mut context); // Re-fill old values if let Ok(Some(form)) = session.take::("old") { context.insert("old", &form); } else { context.insert("old", &ObjectModelForm::default()); } TERA.build_response("model_create", &context) } #[derive(Default, Debug, Clone, Serialize, Deserialize)] pub(crate) struct ObjectModelForm { pub name: String, } #[post("/model/object/create")] pub(crate) async fn 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)); redirect("/") } Err(e) => { warn!("Error creating model: {:?}", e); session.flash_error(e.to_string()); session.set("old", form); redirect("/model/object/create") } } } #[get("/model/object/update/{model_id}")] pub(crate) async fn update_form( model_id: web::Path, store: crate::YopaStoreWrapper, session: Session, ) -> actix_web::Result { let mut context = tera::Context::new(); session.render_flash(&mut context); let rg = store.read().await; let model = rg.get_object_model(*model_id) .ok_or_else(|| actix_web::error::ErrorNotFound("No such model"))?; // Re-fill old values if let Ok(Some(form)) = session.take::("old") { let mut model = model.clone(); model.name = form.name; context.insert("model", &model); } else { context.insert("model", model); } TERA.build_response("model_update", &context) } #[post("/model/object/update/{model_id}")] pub(crate) async fn update( model_id: web::Path, form: web::Form, store: crate::YopaStoreWrapper, session: Session, ) -> actix_web::Result { let mut wg = store.write().await; let form = form.into_inner(); let id = model_id.into_inner(); match wg.update_object(ObjectModel { id, name: form.name.clone(), }) { Ok(_id) => { debug!("Object updated, redirecting to root"); session.flash_success(format!("Object model \"{}\" updated.", form.name)); redirect("/") } Err(e) => { warn!("Error updating model: {:?}", e); session.flash_error(e.to_string()); session.set("old", form); redirect(format!("/model/object/update/{}", id)) } } } #[get("/model/object/delete/{id}")] pub(crate) async fn delete( id: web::Path, store: crate::YopaStoreWrapper, session: Session, ) -> actix_web::Result { let mut wg = store.write().await; match wg.undefine_object(id.parse().map_err(|e| actix_web::error::ErrorBadRequest(e))?) { Ok(om) => { debug!("Object model deleted, redirecting to root"); session.flash_success(format!("Object model \"{}\" deleted.", om.name)); redirect("/") } Err(e) => { warn!("Error deleting object model: {:?}", e); session.flash_error(e.to_string()); redirect("/") // back? } } }