Working overview of klassen

This commit is contained in:
Dietrich 2020-07-26 11:36:54 +02:00
parent a315bb84a4
commit 5c450ba16c
14 changed files with 191 additions and 39 deletions

1
Cargo.lock generated
View File

@ -1001,6 +1001,7 @@ dependencies = [
"rocket_contrib", "rocket_contrib",
"serde", "serde",
"serde_derive", "serde_derive",
"serde_json",
] ]
[[package]] [[package]]

View File

@ -10,6 +10,7 @@ edition = "2018"
rocket = "0.4.5" rocket = "0.4.5"
diesel = { version = "1.4", features = ["sqlite"] } diesel = { version = "1.4", features = ["sqlite"] }
serde_derive = "1.0" serde_derive = "1.0"
serde_json = "1.0"
serde = "1.0" serde = "1.0"
[dependencies.rocket_contrib] [dependencies.rocket_contrib]

Binary file not shown.

View File

@ -1,6 +1,6 @@
-- Your SQL -- Your SQL
CREATE TABLE Vertretungen CREATE TABLE vertretungen
( (
id Integer PRIMARY KEY NOT NULL, id Integer PRIMARY KEY NOT NULL,
klassen_id Integer NOT NULL, klassen_id Integer NOT NULL,

View File

@ -0,0 +1,6 @@
-- This file should undo anything in `up.sql`
ALTER TABLE klassen RENAME COLUMN klassen_id TO id;
ALTER TABLE vertretungen RENAME COLUMN vertretungen_id TO id;
ALTER TABLE vertretungen RENAME COLUMN klassen_id TO klasse_id;
ALTER TABLE vertretungen RENAME COLUMN stunden_id TO stunde_id;
ALTER TABLE stunden RENAME COLUMN stunden_id TO id;

View File

@ -0,0 +1,6 @@
-- Your SQL goes here
ALTER TABLE klassen RENAME COLUMN id TO klassen_id;
ALTER TABLE vertretungen RENAME COLUMN id TO vertretungen_id;
ALTER TABLE vertretungen RENAME COLUMN klasse_id TO klassen_id;
ALTER TABLE vertretungen RENAME COLUMN stunde_id TO stunden_id;
ALTER TABLE stunden RENAME COLUMN id TO stunden_id;

View File

@ -0,0 +1,3 @@
-- This file should undo anything in `up.sql`
ALTER TABLE vertretungen RENAME COLUMN klasse_id TO klassen_id;
ALTER TABLE vertretungen RENAME COLUMN stunde_id TO stunden_id;

View File

@ -0,0 +1,3 @@
-- Your SQL goes here
ALTER TABLE vertretungen RENAME COLUMN klassen_id TO klasse_id;
ALTER TABLE vertretungen RENAME COLUMN stunden_id TO stunde_id;

View File

@ -8,11 +8,20 @@ extern crate rocket_contrib;
extern crate diesel; extern crate diesel;
#[macro_use] #[macro_use]
extern crate serde_derive; extern crate serde_derive;
extern crate serde_json;
use std::collections::HashMap;
pub mod models; pub mod models;
pub mod schema; pub mod schema;
use crate::models::Klassen; use crate::diesel::GroupedBy;
use crate::models::{Klasse, Stunde, Vertretung};
use crate::schema::klassen; use crate::schema::klassen;
use crate::schema::stunden;
use crate::schema::vertretungen;
use diesel::prelude::*;
use diesel::BelongingToDsl;
use diesel::QueryDsl;
use diesel::RunQueryDsl; use diesel::RunQueryDsl;
use rocket::request::{Form, FromParam}; use rocket::request::{Form, FromParam};
use rocket::response::Redirect; use rocket::response::Redirect;
@ -42,21 +51,84 @@ struct DbConn(databases::diesel::SqliteConnection);
#[derive(Debug, Serialize)] #[derive(Debug, Serialize)]
struct ListAllContext { struct ListAllContext {
klassen: Vec<Klassen>, klassen: Vec<(Klasse, Vec<Vertretung>)>,
parent: String, parent: String,
} }
enum QueryClasses {
All,
KlassenId(i32),
}
fn query_all_classes(conn: DbConn) -> Vec<(Klasse, Vec<Vertretung>)> {
let all_classes = klassen::table
.load::<Klasse>(&*conn)
.expect("database acess classes");
let and_substitutions = Vertretung::belonging_to(&all_classes)
.load::<Vertretung>(&*conn)
.expect("database acess Vertretungen")
.grouped_by(&all_classes);
let combined_classes = all_classes
.into_iter()
.zip(and_substitutions)
.filter(|x| x.1.len() > 0)
.collect::<Vec<_>>();
combined_classes
}
fn query_one_class<'a>(
conn: DbConn,
id: i32,
) -> (Klasse, HashMap<String, (Stunde, Vec<Vertretung>)>) {
let mut ret: HashMap<String, (Stunde, Vec<Vertretung>)> = HashMap::new();
let class = klassen::dsl::klassen
.filter(klassen::dsl::klassen_id.eq(id))
.first::<Klasse>(&*conn)
.expect("database acess classes");
//let stund: Vec<Stunde> = stunden::table.load(&*conn).expect("Loading Stunden");
let times: Vec<(Vertretung, Stunde)> = Vertretung::belonging_to(&class)
.inner_join(stunden::table.on(vertretungen::stunde_id.eq(stunden::stunden_id)))
.load(&*conn)
.expect("database access Stunden");
for (vert, stun) in times {
let stun_ord = stun.ordinal.to_string();
let verts = ret.entry(stun_ord).or_insert((stun, Vec::new()));
verts.1.push(vert);
}
(class, ret)
}
#[get("/")] #[get("/")]
fn index(conn: DbConn) -> Template { fn index(conn: DbConn) -> Template {
let combined_classes = query_all_classes(conn);
Template::render( Template::render(
"uebersicht", "uebersicht",
ListAllContext { ListAllContext {
klassen: klassen::dsl::klassen.load(&*conn).expect("database acess"), klassen: combined_classes,
parent: "base".to_string(), parent: "base".to_string(),
}, },
) )
} }
#[derive(Debug, Serialize)]
struct ListOneContext {
klasse: Klasse,
vertretungen: HashMap<String, (Stunde, Vec<Vertretung>)>,
parent: String,
}
#[get("/klasse/<class_id>")]
fn klasse_view(conn: DbConn, class_id: i32) -> Template {
let class = query_one_class(conn, class_id);
let (klasse, vertretungen) = class;
let cont = ListOneContext {
klasse: klasse,
vertretungen: vertretungen,
parent: "base".to_string(),
};
Template::render("klasse", cont)
}
#[get("/add/klasse")] #[get("/add/klasse")]
fn get_klasse_form() -> Template { fn get_klasse_form() -> Template {
Template::render("add_klasse_form", "") Template::render("add_klasse_form", "")
@ -91,6 +163,7 @@ fn main() {
StaticFiles::from(concat!(env!("CARGO_MANIFEST_DIR"), "/static")), StaticFiles::from(concat!(env!("CARGO_MANIFEST_DIR"), "/static")),
) )
.mount("/", routes![index]) .mount("/", routes![index])
.mount("/", routes![klasse_view])
.mount("/admin/", routes![get_klasse_form]) .mount("/admin/", routes![get_klasse_form])
.mount("/admin/", routes![post_klasse_form]) .mount("/admin/", routes![post_klasse_form])
.launch(); .launch();

View File

@ -1,39 +1,43 @@
use super::schema::{klassen, vertretungen}; use super::schema::{klassen, vertretungen};
use std::cmp::Eq;
#[derive(Queryable, Debug, Serialize)] #[derive(Queryable, Debug, Serialize, Hash, PartialEq, Clone)]
pub struct Stunden { pub struct Stunde {
pub id: i32, pub stunden_id: i32,
pub title: String, pub title: String,
pub short: String, pub short: String,
pub ordinal: i32, pub ordinal: i32,
} }
impl Eq for Stunde {}
#[derive(Identifiable, Queryable, Debug, Serialize, Associations)] #[derive(Identifiable, Queryable, Debug, Serialize, Associations)]
#[belongs_to(Klassen)] #[belongs_to(Klasse)]
#[belongs_to(Stunden)] #[belongs_to(Stunde)]
#[table_name = "vertretungen"] #[table_name = "vertretungen"]
pub struct Vertretungen { pub struct Vertretung {
pub id: i32, pub id: i32,
pub klassen_id: i32, pub klasse_id: i32,
pub stunden_id: i32, pub stunde_id: i32,
pub fehlend: String, pub fehlend: String,
pub vertretung: String, pub vertretung: String,
pub kommentar: String, pub kommentar: String,
} }
#[derive(Identifiable, Queryable, Debug, Serialize)] #[derive(Identifiable, Queryable, Debug, Serialize, Associations)]
#[table_name = "klassen"] #[table_name = "klassen"]
pub struct Klassen { #[primary_key(klassen_id)]
pub id: i32, pub struct Klasse {
pub klassen_id: i32,
pub stufe: i32, pub stufe: i32,
pub gruppe: String, pub gruppe: String,
pub titel: Option<String>, pub titel: Option<String>,
pub ordnung: i32, pub ordnung: i32,
} }
#[derive(Insertable)] #[derive(Serialize, Insertable)]
#[table_name = "klassen"] #[table_name = "klassen"]
pub struct NewKlassen { pub struct NewKlasse {
pub stufe: i32, pub stufe: i32,
pub gruppe: String, pub gruppe: String,
pub titel: Option<String>, pub titel: Option<String>,

View File

@ -1,8 +1,8 @@
table! { table! {
vertretungen (id) { vertretungen (vertretungen_id) {
id -> Integer, vertretungen_id -> Integer,
klassen_id -> Integer, klasse_id -> Integer,
stunden_id -> Integer, stunde_id -> Integer,
fehlend -> Text, fehlend -> Text,
vertretung -> Text, vertretung -> Text,
kommentar -> Text, kommentar -> Text,
@ -10,8 +10,8 @@ table! {
} }
table! { table! {
klassen (id) { klassen (klassen_id) {
id -> Integer, klassen_id -> Integer,
stufe -> Integer, stufe -> Integer,
gruppe -> Text, gruppe -> Text,
titel -> Nullable<Text>, titel -> Nullable<Text>,
@ -20,8 +20,8 @@ table! {
} }
table! { table! {
stunden (id) { stunden (stunden_id) {
id -> Integer, stunden_id -> Integer,
title -> Text, title -> Text,
short -> Text, short -> Text,
ordinal -> Integer, ordinal -> Integer,

View File

@ -19,27 +19,53 @@ a:hover {
a:visited { a:visited {
color: #fcb6b6; color: #fcb6b6;
} }
div.erkl {
margin-top: 10px;
font-size: 0.7em;
color: #74787c;
}
div.vert {
width:100%;
text-align: center;
margin-top: 5px;
}
table.vertretungsplan {
padding: 15px;
border-spacing: 10px;
}
table.vertretungsplan td, table.vertretungsplan th {
padding: 15px;
width: 130px;
height: 100px;
border: 1px solid rgb(255, 255, 255);
}
.grid-container { .grid-container {
display: grid; display: grid;
grid-template-columns: auto auto auto auto; grid-template-columns: auto auto auto auto;
grid-gap: 30px; grid-gap: 30px;
padding: 10px; padding: 10px;
background-color: #23272a; background-color: #005a9e;
align-items: stretch; align-items: stretch;
} }
.grid-item div { .grid-item {
display: table-cell; display: table-cell;
border: 1px solid #ccc; border: 1px solid #ccc;
font-size: 48px;
box-shadow: 2px 2px 6px 0px rgba(0, 0, 0, 0.2); box-shadow: 2px 2px 6px 0px rgba(0, 0, 0, 0.2);
max-width: 100%; max-width: 100%;
width: 215px; width: 215px;
height: 200px; height: 200px;
margin: auto; margin: auto;
text-align: center; text-align: center;
line-height: 200px; /*line-height: 200px;*/
background-color: #2c2f33; background-color: #0050b8;
} }
.grid { .grid {

27
templates/klasse.hbs Normal file
View File

@ -0,0 +1,27 @@
{{#* inline "page"}}
<h1>Klasse {{klasse.stufe}}{{klasse.gruppe}}</h1>
<table class="vertretungsplan">
{{#each vertretungen}}
<tr>
<th class="stunden">
Stunde: {{this.0.title}}
</th>
{{#each this.1}}
<td class="vertretung">
<div>
<div class="erkl">Vertretung für:</div>
<div class="vert">{{this.fehlend}}</div>
</div>
<div>
<div class="erkl">Vertretung durch:</div>
<div class="vert">{{this.vertretung}}</div>
</div>
</td>
{{/each}}
</tr>
{{/each}}
</table>
{{/inline}}
{{! remove whitespaces with ~ }}
{{~> (parent)~}}

View File

@ -1,10 +1,12 @@
{{#* inline "page"}} {{#* inline "page"}}
<h1>Vertretungen</h1> <h1>Vertretungen</h1>
<ul> <div class="grid-container">
{{#each klassen}} {{#each klassen}}
<li>{{this.id}}. {{this.stufe}}{{this.gruppe}}</li> <div class="grid-item">
<h2>{{this.0.klassen_id}}. {{this.0.stufe}}{{this.0.gruppe}} <br />{{this.1}}</h2>
</div>
{{/each}} {{/each}}
</ul> </div>
{{/inline}} {{/inline}}
{{! remove whitespaces with ~ }} {{! remove whitespaces with ~ }}
{{~> (parent)~}} {{~> (parent)~}}