a small relational database with user-editable schema for manual data entry
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
yopa/yopa-web/src/routes/object_model.rs

143 lines
4.3 KiB

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<RelationModelDisplay<'a>>,
pub(crate) reciprocal_relations: Vec<RelationModelDisplay<'a>>,
}
#[get("/model/object/create")]
pub(crate) async fn create_form(session: Session) -> actix_web::Result<impl Responder> {
let mut context = tera::Context::new();
session.render_flash(&mut context);
// Re-fill old values
if let Ok(Some(form)) = session.take::<ObjectModelForm>("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<ObjectModelForm>,
store: crate::YopaStoreWrapper,
session: Session,
) -> actix_web::Result<impl Responder> {
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<ID>,
store: crate::YopaStoreWrapper,
session: Session,
) -> actix_web::Result<impl Responder> {
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::<ObjectModelForm>("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<ID>,
form: web::Form<ObjectModelForm>,
store: crate::YopaStoreWrapper,
session: Session,
) -> actix_web::Result<impl Responder> {
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<String>,
store: crate::YopaStoreWrapper,
session: Session,
) -> actix_web::Result<impl Responder> {
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?
}
}
}