add object detail page but inserting relations doesnt work anymore
This commit is contained in:
@@ -37,6 +37,9 @@ window.Yopa = {
|
||||
|
||||
onLoad(() => {
|
||||
setTimeout(() => {
|
||||
document.getElementsByClassName('toast')[0].style.display = 'none';
|
||||
let toasts = document.getElementsByClassName('toast');
|
||||
if (toasts.length) {
|
||||
toasts[0].style.display = 'none';
|
||||
}
|
||||
}, 3000)
|
||||
})
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,64 @@
|
||||
{% extends "_layout" %}
|
||||
|
||||
{% block title -%}
|
||||
{{object.name}}
|
||||
{%- endblock %}
|
||||
|
||||
{% block nav -%}
|
||||
<a href="/">Home</a>
|
||||
{%- endblock %}
|
||||
|
||||
{% block content -%}
|
||||
|
||||
<h1>{{kind}} "{{object.name}}"</h1>
|
||||
|
||||
<table>
|
||||
{% for property in properties %}
|
||||
{% for value in property.values %}
|
||||
<tr>
|
||||
{% if loop.first %}
|
||||
<th rowspan="{{property.values | length}}">
|
||||
{{ property.model.name }}
|
||||
</th>
|
||||
{% endif %}
|
||||
<td title="{{value.id}}">
|
||||
{{ value.value | print_typed_value }}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
</table>
|
||||
|
||||
{% for relation in relations %}
|
||||
<h3>{{relation.model.name}}</h3>
|
||||
|
||||
<ul>
|
||||
{% for instance in relation.instances %}
|
||||
<li>
|
||||
<b>{{instance.related.name}}</b>
|
||||
|
||||
{% if instance.properties %}
|
||||
<br>
|
||||
<small>
|
||||
{% for property in instance.properties %}
|
||||
{%- if 0 != loop.index0 -%}
|
||||
;
|
||||
{%- endif -%}
|
||||
{% for value in property.values %}
|
||||
{%- if loop.first -%}
|
||||
<i>{{ property.model.name }}:</i>
|
||||
{%- else -%}
|
||||
,
|
||||
{% endif -%}
|
||||
{{ value.value | print_typed_value }}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
</small>
|
||||
{% endif %}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
{% endfor %}
|
||||
|
||||
{%- endblock %}
|
||||
@@ -156,7 +156,8 @@ async fn main() -> std::io::Result<()> {
|
||||
.service(routes::objects::list)
|
||||
.service(routes::objects::create_form)
|
||||
.service(routes::objects::create)
|
||||
|
||||
.service(routes::objects::detail)
|
||||
//
|
||||
.service(static_files)
|
||||
.default_service(web::to(|| HttpResponse::NotFound().body("File or endpoint not found")))
|
||||
})
|
||||
|
||||
@@ -12,7 +12,7 @@ use crate::utils::redirect;
|
||||
use actix_web::web::Json;
|
||||
use serde_json::Value;
|
||||
use itertools::Itertools;
|
||||
use yopa::model::ObjectModel;
|
||||
use yopa::model::{ObjectModel, PropertyModel, RelationModel};
|
||||
use heck::TitleCase;
|
||||
|
||||
// we only need references here, Context serializes everything to Value.
|
||||
@@ -48,7 +48,7 @@ pub(crate) async fn create_form(
|
||||
|
||||
context.insert("model", model);
|
||||
|
||||
let relations : Vec<_> = rg.get_relation_models_for_object(model.id).collect();
|
||||
let relations : Vec<_> = rg.get_relation_models_for_object_model(model.id).collect();
|
||||
|
||||
let mut prop_object_ids : Vec<ID> = relations.iter().map(|r| r.id).collect();
|
||||
prop_object_ids.push(model.id);
|
||||
@@ -141,3 +141,114 @@ pub(crate) async fn list_inner(session: Session, store: crate::YopaStoreWrapper)
|
||||
|
||||
TERA.build_response("objects/index", &ctx)
|
||||
}
|
||||
|
||||
#[derive(Debug,Serialize)]
|
||||
struct PropertyView<'a> {
|
||||
model : &'a PropertyModel,
|
||||
values: Vec<&'a yopa::data::Value>
|
||||
}
|
||||
|
||||
#[derive(Debug,Serialize)]
|
||||
struct RelationView<'a> {
|
||||
model : &'a RelationModel,
|
||||
related_name: &'a str,
|
||||
instances: Vec<RelationInstanceView<'a>>
|
||||
}
|
||||
|
||||
#[derive(Debug,Serialize)]
|
||||
struct RelationInstanceView<'a> {
|
||||
related: &'a Object,
|
||||
properties: Vec<PropertyView<'a>>
|
||||
}
|
||||
|
||||
|
||||
#[get("/object/detail/{id}")]
|
||||
pub(crate) async fn detail(
|
||||
id: web::Path<ID>,
|
||||
store: crate::YopaStoreWrapper
|
||||
) -> actix_web::Result<impl Responder> {
|
||||
let object_id = *id;
|
||||
|
||||
let mut context = tera::Context::new();
|
||||
|
||||
let rg = store.read().await;
|
||||
|
||||
let object = rg.get_object(object_id)
|
||||
.ok_or_else(|| actix_web::error::ErrorNotFound("No such object"))?;
|
||||
|
||||
let model = rg.get_object_model(object.model)
|
||||
.ok_or_else(|| actix_web::error::ErrorNotFound("No such model"))?;
|
||||
|
||||
context.insert("object", object);
|
||||
context.insert("model", model);
|
||||
context.insert("kind", &rg.get_model_name(object.model));
|
||||
|
||||
let relations = rg.get_relations_for_object(object_id).collect_vec();
|
||||
|
||||
// values by parent ID
|
||||
let mut ids_to_get_values_for = relations.iter().map(|r| r.id).collect_vec();
|
||||
ids_to_get_values_for.push(object_id);
|
||||
let mut grouped_values = {
|
||||
rg.get_grouped_values_for_objects(&ids_to_get_values_for)
|
||||
};
|
||||
|
||||
// object's own properties
|
||||
{
|
||||
let mut object_values_by_model = grouped_values
|
||||
.remove(&object_id).unwrap_or_default().into_iter()
|
||||
.into_group_map_by(|value| value.model);
|
||||
|
||||
let mut view_object_properties = vec![];
|
||||
for (prop_model_id, values) in object_values_by_model {
|
||||
view_object_properties.push(PropertyView {
|
||||
model: rg.get_property_model(prop_model_id).unwrap(),
|
||||
values
|
||||
})
|
||||
}
|
||||
context.insert("properties", &view_object_properties);
|
||||
}
|
||||
|
||||
// go through relations
|
||||
{
|
||||
let grouped_relations = relations.iter()
|
||||
.into_group_map_by(|relation| relation.model);
|
||||
|
||||
let mut relation_views = vec![];
|
||||
for (model_id, relations) in grouped_relations {
|
||||
let mut instances = vec![];
|
||||
|
||||
for rel in relations {
|
||||
let related_obj = match rg.get_object(rel.related) {
|
||||
None => continue,
|
||||
Some(obj) => obj
|
||||
};
|
||||
|
||||
let mut rel_values_by_model = grouped_values
|
||||
.remove(&rel.id).unwrap_or_default().into_iter()
|
||||
.into_group_map_by(|value| value.model);
|
||||
|
||||
let mut view_rel_properties = vec![];
|
||||
for (prop_model_id, values) in rel_values_by_model {
|
||||
view_rel_properties.push(PropertyView {
|
||||
model: rg.get_property_model(prop_model_id).unwrap(),
|
||||
values
|
||||
})
|
||||
}
|
||||
|
||||
instances.push(RelationInstanceView {
|
||||
related: related_obj,
|
||||
properties: view_rel_properties
|
||||
})
|
||||
}
|
||||
|
||||
relation_views.push(RelationView {
|
||||
model: rg.get_relation_model(model_id).unwrap(),
|
||||
related_name: rg.get_model_name(model_id),
|
||||
instances
|
||||
})
|
||||
}
|
||||
context.insert("relations", &relation_views);
|
||||
}
|
||||
|
||||
TERA.build_response("objects/object_detail", &context)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user