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.
144 lines
4.2 KiB
144 lines
4.2 KiB
4 years ago
|
use actix_session::Session;
|
||
|
use actix_web::{Responder, web, HttpResponse};
|
||
|
use crate::session_ext::SessionExt;
|
||
4 years ago
|
use crate::routes::models::object::ObjectModelForm;
|
||
4 years ago
|
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;
|
||
4 years ago
|
use itertools::Itertools;
|
||
|
use yopa::model::ObjectModel;
|
||
|
use heck::TitleCase;
|
||
4 years ago
|
|
||
|
// 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())
|
||
|
//
|
||
4 years ago
|
|
||
4 years ago
|
let mut wg = store.write().await;
|
||
|
let form = form.into_inner();
|
||
|
let name = form.name.clone();
|
||
4 years ago
|
|
||
|
let model_name = wg.get_model_name(form.model_id).to_owned().to_title_case();
|
||
|
|
||
4 years ago
|
match wg.insert_object(form) {
|
||
|
Ok(_id) => {
|
||
|
debug!("Object created, redirecting to root");
|
||
4 years ago
|
session.flash_success(format!("{} \"{}\" created.", model_name, name));
|
||
4 years ago
|
Ok(HttpResponse::Ok().finish())
|
||
|
}
|
||
|
Err(e) => {
|
||
|
warn!("Error creating model: {}", e);
|
||
|
Ok(HttpResponse::BadRequest().body(e.to_string()))
|
||
|
}
|
||
|
}
|
||
|
}
|
||
4 years ago
|
|
||
|
#[derive(Debug, Serialize, Clone)]
|
||
|
struct ModelWithObjects<'a> {
|
||
|
model : &'a ObjectModel,
|
||
|
objects: Vec<&'a Object>
|
||
|
}
|
||
|
|
||
|
#[get("/objects")]
|
||
|
pub(crate) async fn list(session: Session, store: crate::YopaStoreWrapper) -> actix_web::Result<impl Responder> {
|
||
|
list_inner(session, store).await
|
||
|
}
|
||
|
|
||
|
pub(crate) async fn list_inner(session: Session, store: crate::YopaStoreWrapper) -> actix_web::Result<HttpResponse> {
|
||
|
let rg = store.read().await;
|
||
|
|
||
|
let mut objects_by_model = rg.get_grouped_objects();
|
||
|
|
||
|
let mut models : Vec<_> = rg.get_object_models()
|
||
|
.sorted_by_key(|m| &m.name)
|
||
|
.map(|model| {
|
||
|
let mut objects = objects_by_model.remove(&model.id).unwrap_or_default();
|
||
|
objects.sort_by_key(|o| &o.name);
|
||
|
ModelWithObjects {
|
||
|
model,
|
||
|
objects
|
||
|
}
|
||
|
}).collect();
|
||
|
|
||
|
let mut ctx = tera::Context::new();
|
||
|
ctx.insert("models", &models);
|
||
|
session.render_flash(&mut ctx);
|
||
|
|
||
|
TERA.build_response("objects/index", &ctx)
|
||
|
}
|