From ed65215723cca4fe28972b3cdeb032e1e322d8c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Hru=C5=A1ka?= Date: Mon, 30 Dec 2019 09:02:08 +0100 Subject: [PATCH] add index page with a cards list --- src/main.rs | 76 ++++++++++++----- src/store/form.rs | 2 + templates/_fields.html.tera | 33 ++++++++ ...acros.html.tera => _form_macros.html.tera} | 0 .../{layout.html.tera => _layout.html.tera} | 7 +- templates/add.html.tera | 22 +++++ templates/index.html.tera | 83 +++++++++---------- templates/static/style.css | 43 ++++++++++ 8 files changed, 199 insertions(+), 67 deletions(-) create mode 100644 templates/_fields.html.tera rename templates/{form_macros.html.tera => _form_macros.html.tera} (100%) rename templates/{layout.html.tera => _layout.html.tera} (57%) create mode 100644 templates/add.html.tera diff --git a/src/main.rs b/src/main.rs index 8f47340..ac18fdb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,7 +3,7 @@ #[macro_use] extern crate rocket; #[macro_use] extern crate serde; -use serde_json::json; +use serde_json::{json, Value}; //use rocket::request::FromSegments; //use rocket::http::uri::Segments; @@ -21,37 +21,72 @@ use std::collections::HashMap; use std::env; use crate::store::form::RenderedField; -#[derive(Serialize)] -struct FormContext<'a> { +fn render_empty_fields<'a>(store : &'a Store) -> Vec> { + let indexes = &store.index; + + store.model.fields.iter().map(|(key, field)| { + RenderedField::from_template_field(key, field, None, indexes) + }).collect() +} + +#[derive(Serialize,Debug)] +struct RenderedCard<'a> { pub fields : Vec>, + pub id : usize, +} + +fn render_card_fields<'a>(store : &'a Store, values : &'a serde_json::Map) -> Vec> { + let indexes = &store.index; + + store.model.fields.iter().map(|(key, field)| { + RenderedField::from_template_field(key, field, values.get(key), indexes) + }).collect() +} + +#[derive(Serialize,Debug)] +struct ListContext<'a> { + pub fields : Vec>, + pub cards : Vec>, } #[get("/")] fn index(store : State>) -> Template { - let rg = store.read(); - let tags = json!(["foo", "bar"]); + let rg = store.read(); - let indexes = &rg.index; - let context = FormContext { - fields: rg.model.fields.iter().map(|(key, field)| { - let value = if key == "tags" { - Some(&tags) + let context = ListContext { + fields: render_empty_fields(&rg), + cards: rg.items.iter().filter_map(|(id, card)| { + if let Value::Object(map) = card { + Some(RenderedCard { + fields: render_card_fields(&rg, map), + id: *id, + }) } else { None - }; - RenderedField::from_template_field(key, field, value, indexes) - }).collect() + } + }).collect(), }; Template::render("index", context) } -//#[post("/add", data="")] -//fn add_part(store : State>, record : Form) -> Redirect { -// store.write().add(record.into_inner()); -// Redirect::to(uri!(index)) -//} +#[derive(Serialize)] +struct AddCardContext<'a> { + pub fields : Vec>, +} + +#[get("/add")] +fn add(store : State>) -> Template { + + let rg = store.read(); + + let context = AddCardContext { + fields: render_empty_fields(&rg) + }; + + Template::render("add", context) +} fn main() { let cwd = env::current_dir().unwrap(); @@ -62,5 +97,8 @@ fn main() { .attach(Template::fairing()) .manage(RwLock::new(store)) .mount("/", StaticFiles::from(cwd.join("templates/static/"))) - .mount("/", routes![index]).launch(); + .mount("/", routes![ + index, + add, + ]).launch(); } diff --git a/src/store/form.rs b/src/store/form.rs index d2ec6e6..55cb339 100644 --- a/src/store/form.rs +++ b/src/store/form.rs @@ -102,6 +102,8 @@ impl<'a> RenderedField<'a> { if let Some(Value::String(s)) = value { rendered.value = Cow::Borrowed(&s.as_str()); + } else if let Some(def) = default { + rendered.value = def.to_owned().into(); } } FieldKind::FreeEnum { enum_group } => { diff --git a/templates/_fields.html.tera b/templates/_fields.html.tera new file mode 100644 index 0000000..652f7e7 --- /dev/null +++ b/templates/_fields.html.tera @@ -0,0 +1,33 @@ +{%- for field in fields %} + +
+ {%- if field.kind == "string" -%} + {{ form::text(field=field) }} + + {%- elif field.kind == "text" -%} + {{ form::longtext(field=field) }} + + {%- elif field.kind == "number" -%} + {{ form::number(field=field) }} + + {%- elif field.kind == "bool" -%} + {{ form::checkbox(field=field) }} + + {%- elif field.kind == "select" -%} + {{ form::select(field=field) }} + + {%- elif field.kind == "free_select" -%} + {{ form::free_select(field=field) }} + + {%- elif field.kind == "tags" -%} + {{ form::tags(field=field) }} + + {%- elif field.kind == "free_tags" -%} + {{ form::free_tags(field=field) }} + + {%- else -%} + TODO {{ field.key }} + + {%- endif -%} +
+{%- endfor %} diff --git a/templates/form_macros.html.tera b/templates/_form_macros.html.tera similarity index 100% rename from templates/form_macros.html.tera rename to templates/_form_macros.html.tera diff --git a/templates/layout.html.tera b/templates/_layout.html.tera similarity index 57% rename from templates/layout.html.tera rename to templates/_layout.html.tera index bc53197..76a489b 100644 --- a/templates/layout.html.tera +++ b/templates/_layout.html.tera @@ -2,12 +2,15 @@ - {% block title %}{% endblock title %} + {% block title %}{% endblock title %} • Inventory -{% block content %}{% endblock content %} + +{% block content %}{% endblock %} diff --git a/templates/add.html.tera b/templates/add.html.tera new file mode 100644 index 0000000..352f4e2 --- /dev/null +++ b/templates/add.html.tera @@ -0,0 +1,22 @@ +{% extends "_layout" %} +{% import "_form_macros" as form %} + +{% block title -%} + Add Record +{%- endblock %} + +{% block nav -%} + Index +{%- endblock %} + +{% block content -%} +
+
+

New Record

+
+ {% include "_fields" %} +
+ +
+
+{%- endblock %} diff --git a/templates/index.html.tera b/templates/index.html.tera index de86908..d1b2428 100644 --- a/templates/index.html.tera +++ b/templates/index.html.tera @@ -1,50 +1,41 @@ -{% extends "layout" %} -{% import "form_macros" as form %} +{% extends "_layout" %} +{% import "_form_macros" as form %} {% block title -%} - Form -{%- endblock title %} + Inventory +{%- endblock %} -{% block content -%} -
-
-

New Record

-
-{%- for field in fields %} - -
- {%- if field.kind == "string" -%} - {{ form::text(field=field) }} - - {%- elif field.kind == "text" -%} - {{ form::longtext(field=field) }} - - {%- elif field.kind == "number" -%} - {{ form::number(field=field) }} - - {%- elif field.kind == "bool" -%} - {{ form::checkbox(field=field) }} - - {%- elif field.kind == "select" -%} - {{ form::select(field=field) }} +{% block nav -%} + Add +{%- endblock %} - {%- elif field.kind == "free_select" -%} - {{ form::free_select(field=field) }} - - {%- elif field.kind == "tags" -%} - {{ form::tags(field=field) }} - - {%- elif field.kind == "free_tags" -%} - {{ form::free_tags(field=field) }} - - {%- else -%} - {{ field.key }} - - {%- endif -%} -
-{%- endfor %} -
- -
-
-{%- endblock content %} +{% block content -%} + + + + {%- for field in fields %} + + {%- endfor %} + + + + {%- for card in cards %} + + {%- for field in card.fields %} + + {%- endfor %} + + {% endfor %} + +
{{ field.label }}
+ {%- if field.kind == "bool" -%} + {% if field.checked %} + ✔ + {% else %} + ✘ + {% endif %} + {%- else -%} + {{ field.value }} + {%- endif -%} +
+{%- endblock %} diff --git a/templates/static/style.css b/templates/static/style.css index 9a1d7df..5a880c1 100644 --- a/templates/static/style.css +++ b/templates/static/style.css @@ -12,6 +12,26 @@ html, textarea, select { margin: 0 auto; } +nav.top-nav { + margin: 0 auto; + margin-bottom: .5rem; + width: 900px; + border-bottom: 1px solid silver; +} + +nav.top-nav a { + display: inline-block; + padding: .75rem; + + color: gray; + text-decoration: none; +} + +nav.top-nav a:hover { + color: black; + text-decoration: underline; +} + .Form .Row { display: flex; padding: .25rem; @@ -85,3 +105,26 @@ textarea:focus, box-shadow: none; outline: 0 none !important; } + +.cards-table { + border-collapse: collapse; + margin: 0 auto; + margin-top: 1rem; +} + +.cards-table td, +.cards-table th { + padding: .5rem; +} + +.cards-table thead th { + border-bottom: 2px solid silver; +} + +.cards-table tbody td { + border-bottom: 1px solid silver; +} + +.cards-table tbody tr:last-child td { + border-bottom: 2px solid silver; +}