|
|
|
use actix_session::Session;
|
|
|
|
use actix_web::{web, Responder};
|
|
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
|
|
|
|
use yopa::model::{PropertyModel, RelationModel};
|
|
|
|
use yopa::ID;
|
|
|
|
|
|
|
|
use crate::session_ext::SessionExt;
|
|
|
|
use crate::tera_ext::TeraExt;
|
|
|
|
use crate::utils::{redirect, StorageErrorIntoResponseError};
|
|
|
|
use crate::TERA;
|
|
|
|
|
|
|
|
#[derive(Serialize, Debug)]
|
|
|
|
pub(crate) struct RelationModelDisplay<'a> {
|
|
|
|
pub(crate) model: &'a RelationModel,
|
|
|
|
pub(crate) related_name: &'a str,
|
|
|
|
pub(crate) properties: Vec<&'a PropertyModel>,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[get("/model/relation/create/{object_id}")]
|
|
|
|
pub(crate) async fn create_form(
|
|
|
|
object_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;
|
|
|
|
|
|
|
|
debug!("ID = {}", object_id);
|
|
|
|
|
|
|
|
if let Ok(Some(form)) = session.take::<RelationModelCreateForm>("old") {
|
|
|
|
context.insert("old", &form);
|
|
|
|
} else {
|
|
|
|
context.insert(
|
|
|
|
"old",
|
|
|
|
&RelationModelCreateForm {
|
|
|
|
object: Default::default(),
|
|
|
|
name: "".to_string(),
|
|
|
|
reciprocal_name: "".to_string(),
|
|
|
|
optional: false,
|
|
|
|
multiple: false,
|
|
|
|
related: Default::default(),
|
|
|
|
},
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
let object = rg
|
|
|
|
.get_object_model(*object_id)
|
|
|
|
.ok_or_else(|| actix_web::error::ErrorNotFound("No such source object"))?;
|
|
|
|
|
|
|
|
let mut models: Vec<_> = rg.get_object_models().collect();
|
|
|
|
|
|
|
|
models.sort_by_key(|m| &m.name);
|
|
|
|
|
|
|
|
context.insert("models", &models);
|
|
|
|
context.insert("object", &object);
|
|
|
|
|
|
|
|
TERA.build_response("models/relation_create", &context)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize)]
|
|
|
|
pub(crate) struct RelationModelCreateForm {
|
|
|
|
pub object: ID,
|
|
|
|
pub name: String,
|
|
|
|
pub reciprocal_name: String,
|
|
|
|
#[serde(default)]
|
|
|
|
pub optional: bool,
|
|
|
|
#[serde(default)]
|
|
|
|
pub multiple: bool,
|
|
|
|
pub related: ID,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[post("/model/relation/create")]
|
|
|
|
pub(crate) async fn create(
|
|
|
|
form: web::Form<RelationModelCreateForm>,
|
|
|
|
store: crate::YopaStoreWrapper,
|
|
|
|
session: Session,
|
|
|
|
) -> actix_web::Result<impl Responder> {
|
|
|
|
let mut wg = store.write().await;
|
|
|
|
let form = form.into_inner();
|
|
|
|
match wg.define_relation(RelationModel {
|
|
|
|
id: Default::default(),
|
|
|
|
object: form.object,
|
|
|
|
name: form.name.clone(),
|
|
|
|
reciprocal_name: form.reciprocal_name.clone(),
|
|
|
|
optional: form.optional,
|
|
|
|
multiple: form.multiple,
|
|
|
|
related: form.related,
|
|
|
|
}) {
|
|
|
|
Ok(_id) => {
|
|
|
|
wg.persist().err_to_500()?;
|
|
|
|
debug!("Relation created, redirecting to root");
|
|
|
|
session.flash_success(format!("Relation model \"{}\" created.", form.name));
|
|
|
|
redirect("/models")
|
|
|
|
}
|
|
|
|
Err(e) => {
|
|
|
|
warn!("Error creating relation model: {}", e);
|
|
|
|
session.flash_error(e.to_string());
|
|
|
|
session.set("old", &form).unwrap();
|
|
|
|
redirect(format!("/model/relation/create/{}", form.object))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Serialize, Debug)]
|
|
|
|
pub(crate) struct ObjectOrRelationModelDisplay {
|
|
|
|
pub(crate) id: ID,
|
|
|
|
pub(crate) describe: String,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[get("/model/relation/delete/{id}")]
|
|
|
|
pub(crate) async fn delete(
|
|
|
|
id: web::Path<ID>,
|
|
|
|
store: crate::YopaStoreWrapper,
|
|
|
|
session: Session,
|
|
|
|
) -> actix_web::Result<impl Responder> {
|
|
|
|
let mut wg = store.write().await;
|
|
|
|
match wg.undefine_relation(*id) {
|
|
|
|
Ok(rm) => {
|
|
|
|
wg.persist().err_to_500()?;
|
|
|
|
debug!("Relation deleted, redirecting to root");
|
|
|
|
session.flash_success(format!("Relation model \"{}\" deleted.", rm.name));
|
|
|
|
redirect("/models")
|
|
|
|
}
|
|
|
|
Err(e) => {
|
|
|
|
warn!("Error deleting relation model: {}", e);
|
|
|
|
session.flash_error(e.to_string());
|
|
|
|
redirect("/models") // back?
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize)]
|
|
|
|
pub(crate) struct RelationModelEditForm {
|
|
|
|
pub name: String,
|
|
|
|
pub reciprocal_name: String,
|
|
|
|
#[serde(default)]
|
|
|
|
pub optional: bool,
|
|
|
|
#[serde(default)]
|
|
|
|
pub multiple: bool,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[get("/model/relation/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_relation_model(*model_id)
|
|
|
|
.ok_or_else(|| actix_web::error::ErrorNotFound("No such model"))?;
|
|
|
|
|
|
|
|
// Re-fill old values
|
|
|
|
if let Ok(Some(form)) = session.take::<RelationModelEditForm>("old") {
|
|
|
|
let mut model = model.clone();
|
|
|
|
model.name = form.name;
|
|
|
|
model.optional = form.optional; // TODO try if regular bools cant be used
|
|
|
|
model.multiple = form.multiple;
|
|
|
|
context.insert("model", &model);
|
|
|
|
} else {
|
|
|
|
context.insert("model", model);
|
|
|
|
}
|
|
|
|
|
|
|
|
TERA.build_response("models/relation_update", &context)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[post("/model/relation/update/{model_id}")]
|
|
|
|
pub(crate) async fn update(
|
|
|
|
model_id: web::Path<ID>,
|
|
|
|
form: web::Form<RelationModelEditForm>,
|
|
|
|
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_relation_model(RelationModel {
|
|
|
|
id,
|
|
|
|
object: Default::default(), // dummy
|
|
|
|
name: form.name.clone(),
|
|
|
|
reciprocal_name: form.reciprocal_name.to_string(),
|
|
|
|
optional: form.optional,
|
|
|
|
multiple: form.multiple,
|
|
|
|
related: Default::default(), // dummy
|
|
|
|
}) {
|
|
|
|
Ok(_id) => {
|
|
|
|
wg.persist().err_to_500()?;
|
|
|
|
debug!("Relation updated, redirecting to root");
|
|
|
|
session.flash_success(format!("Relation model \"{}\" updated.", form.name));
|
|
|
|
redirect("/models")
|
|
|
|
}
|
|
|
|
Err(e) => {
|
|
|
|
warn!("Error updating model: {}", e);
|
|
|
|
session.flash_error(e.to_string());
|
|
|
|
session.set("old", form).unwrap();
|
|
|
|
redirect(format!("/model/relation/update/{}", id))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|