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.rs

102 lines
3.0 KiB

use actix_session::Session;
use actix_web::{Responder, web, HttpResponse};
use crate::session_ext::SessionExt;
use crate::routes::object_model::ObjectModelForm;
use crate::TERA;
use crate::tera_ext::TeraExt;
use yopa::{ID, model};
use yopa::data::Object;
use serde::{Serialize,Deserialize};
use yopa::insert::InsertObj;
use crate::utils::redirect;
use actix_web::web::Json;
use serde_json::Value;
// we only need references here, Context serializes everything to Value.
// cloning would be a waste of cycles
#[derive(Debug, Default, Serialize, Clone)]
pub struct Schema<'a> {
pub obj_models: Vec<&'a model::ObjectModel>,
pub rel_models: Vec<&'a model::RelationModel>,
pub prop_models: Vec<&'a model::PropertyModel>,
}
#[derive(Serialize,Debug,Clone)]
pub struct ObjectCreateData<'a> {
pub model_id: ID,
pub schema: Schema<'a>,
pub objects: Vec<&'a Object>,
}
#[get("/object/create/{model_id}")]
pub(crate) async fn create_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"))?;
context.insert("model", model);
let relations : Vec<_> = rg.get_relation_models_for_object(model.id).collect();
let mut prop_object_ids : Vec<ID> = relations.iter().map(|r| r.id).collect();
prop_object_ids.push(model.id);
prop_object_ids.sort();
prop_object_ids.dedup();
let mut related_ids : Vec<_> = relations.iter().map(|r| r.related).collect();
related_ids.sort();
related_ids.dedup();
let form_data = ObjectCreateData {
model_id: model.id,
schema: Schema {
obj_models: rg.get_object_models().collect(), // TODO get only the ones that matter here
rel_models: relations,
prop_models: rg.get_property_models_for_parents(&prop_object_ids).collect()
},
objects: rg.get_objects_of_type(&related_ids).collect()
};
context.insert("form_data", &form_data);
TERA.build_response("objects/object_create", &context)
}
#[post("/object/create")]
pub(crate) async fn create(
form: web::Json<InsertObj>,
store: crate::YopaStoreWrapper,
session: Session,
) -> actix_web::Result<impl Responder> {
warn!("{:?}", form);
// let des : InsertObj = serde_json::from_value(form.into_inner()).unwrap();
//
// Ok(HttpResponse::Ok().finish())
//
let mut wg = store.write().await;
let form = form.into_inner();
let name = form.name.clone();
match wg.insert_object(form) {
Ok(_id) => {
debug!("Object created, redirecting to root");
session.flash_success(format!("Object \"{}\" created.", name));
Ok(HttpResponse::Ok().finish())
}
Err(e) => {
warn!("Error creating model: {}", e);
Ok(HttpResponse::BadRequest().body(e.to_string()))
}
}
}