Working overview of klassen
This commit is contained in:
parent
a315bb84a4
commit
5c450ba16c
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -1001,6 +1001,7 @@ dependencies = [
|
||||
"rocket_contrib",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -10,6 +10,7 @@ edition = "2018"
|
||||
rocket = "0.4.5"
|
||||
diesel = { version = "1.4", features = ["sqlite"] }
|
||||
serde_derive = "1.0"
|
||||
serde_json = "1.0"
|
||||
serde = "1.0"
|
||||
|
||||
[dependencies.rocket_contrib]
|
||||
|
BIN
database.sqlite
BIN
database.sqlite
Binary file not shown.
@ -1,6 +1,6 @@
|
||||
-- Your SQL
|
||||
|
||||
CREATE TABLE Vertretungen
|
||||
CREATE TABLE vertretungen
|
||||
(
|
||||
id Integer PRIMARY KEY NOT NULL,
|
||||
klassen_id Integer NOT NULL,
|
||||
|
6
migrations/2020-07-25-085330_rename_id_columns/down.sql
Normal file
6
migrations/2020-07-25-085330_rename_id_columns/down.sql
Normal 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;
|
6
migrations/2020-07-25-085330_rename_id_columns/up.sql
Normal file
6
migrations/2020-07-25-085330_rename_id_columns/up.sql
Normal 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;
|
@ -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;
|
@ -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;
|
79
src/main.rs
79
src/main.rs
@ -8,11 +8,20 @@ extern crate rocket_contrib;
|
||||
extern crate diesel;
|
||||
#[macro_use]
|
||||
extern crate serde_derive;
|
||||
extern crate serde_json;
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
||||
pub mod models;
|
||||
pub mod schema;
|
||||
use crate::models::Klassen;
|
||||
use crate::diesel::GroupedBy;
|
||||
use crate::models::{Klasse, Stunde, Vertretung};
|
||||
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 rocket::request::{Form, FromParam};
|
||||
use rocket::response::Redirect;
|
||||
@ -42,21 +51,84 @@ struct DbConn(databases::diesel::SqliteConnection);
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
struct ListAllContext {
|
||||
klassen: Vec<Klassen>,
|
||||
klassen: Vec<(Klasse, Vec<Vertretung>)>,
|
||||
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("/")]
|
||||
fn index(conn: DbConn) -> Template {
|
||||
let combined_classes = query_all_classes(conn);
|
||||
Template::render(
|
||||
"uebersicht",
|
||||
ListAllContext {
|
||||
klassen: klassen::dsl::klassen.load(&*conn).expect("database acess"),
|
||||
klassen: combined_classes,
|
||||
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")]
|
||||
fn get_klasse_form() -> Template {
|
||||
Template::render("add_klasse_form", "")
|
||||
@ -91,6 +163,7 @@ fn main() {
|
||||
StaticFiles::from(concat!(env!("CARGO_MANIFEST_DIR"), "/static")),
|
||||
)
|
||||
.mount("/", routes![index])
|
||||
.mount("/", routes![klasse_view])
|
||||
.mount("/admin/", routes![get_klasse_form])
|
||||
.mount("/admin/", routes![post_klasse_form])
|
||||
.launch();
|
||||
|
@ -1,39 +1,43 @@
|
||||
use super::schema::{klassen, vertretungen};
|
||||
use std::cmp::Eq;
|
||||
|
||||
#[derive(Queryable, Debug, Serialize)]
|
||||
pub struct Stunden {
|
||||
pub id: i32,
|
||||
#[derive(Queryable, Debug, Serialize, Hash, PartialEq, Clone)]
|
||||
pub struct Stunde {
|
||||
pub stunden_id: i32,
|
||||
pub title: String,
|
||||
pub short: String,
|
||||
pub ordinal: i32,
|
||||
}
|
||||
|
||||
impl Eq for Stunde {}
|
||||
|
||||
#[derive(Identifiable, Queryable, Debug, Serialize, Associations)]
|
||||
#[belongs_to(Klassen)]
|
||||
#[belongs_to(Stunden)]
|
||||
#[belongs_to(Klasse)]
|
||||
#[belongs_to(Stunde)]
|
||||
#[table_name = "vertretungen"]
|
||||
pub struct Vertretungen {
|
||||
pub struct Vertretung {
|
||||
pub id: i32,
|
||||
pub klassen_id: i32,
|
||||
pub stunden_id: i32,
|
||||
pub klasse_id: i32,
|
||||
pub stunde_id: i32,
|
||||
pub fehlend: String,
|
||||
pub vertretung: String,
|
||||
pub kommentar: String,
|
||||
}
|
||||
|
||||
#[derive(Identifiable, Queryable, Debug, Serialize)]
|
||||
#[derive(Identifiable, Queryable, Debug, Serialize, Associations)]
|
||||
#[table_name = "klassen"]
|
||||
pub struct Klassen {
|
||||
pub id: i32,
|
||||
#[primary_key(klassen_id)]
|
||||
pub struct Klasse {
|
||||
pub klassen_id: i32,
|
||||
pub stufe: i32,
|
||||
pub gruppe: String,
|
||||
pub titel: Option<String>,
|
||||
pub ordnung: i32,
|
||||
}
|
||||
|
||||
#[derive(Insertable)]
|
||||
#[derive(Serialize, Insertable)]
|
||||
#[table_name = "klassen"]
|
||||
pub struct NewKlassen {
|
||||
pub struct NewKlasse {
|
||||
pub stufe: i32,
|
||||
pub gruppe: String,
|
||||
pub titel: Option<String>,
|
||||
|
@ -1,8 +1,8 @@
|
||||
table! {
|
||||
vertretungen (id) {
|
||||
id -> Integer,
|
||||
klassen_id -> Integer,
|
||||
stunden_id -> Integer,
|
||||
vertretungen (vertretungen_id) {
|
||||
vertretungen_id -> Integer,
|
||||
klasse_id -> Integer,
|
||||
stunde_id -> Integer,
|
||||
fehlend -> Text,
|
||||
vertretung -> Text,
|
||||
kommentar -> Text,
|
||||
@ -10,8 +10,8 @@ table! {
|
||||
}
|
||||
|
||||
table! {
|
||||
klassen (id) {
|
||||
id -> Integer,
|
||||
klassen (klassen_id) {
|
||||
klassen_id -> Integer,
|
||||
stufe -> Integer,
|
||||
gruppe -> Text,
|
||||
titel -> Nullable<Text>,
|
||||
@ -20,8 +20,8 @@ table! {
|
||||
}
|
||||
|
||||
table! {
|
||||
stunden (id) {
|
||||
id -> Integer,
|
||||
stunden (stunden_id) {
|
||||
stunden_id -> Integer,
|
||||
title -> Text,
|
||||
short -> Text,
|
||||
ordinal -> Integer,
|
||||
|
@ -19,27 +19,53 @@ a:hover {
|
||||
a:visited {
|
||||
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 {
|
||||
display: grid;
|
||||
grid-template-columns: auto auto auto auto;
|
||||
grid-gap: 30px;
|
||||
padding: 10px;
|
||||
background-color: #23272a;
|
||||
background-color: #005a9e;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.grid-item div {
|
||||
.grid-item {
|
||||
display: table-cell;
|
||||
border: 1px solid #ccc;
|
||||
font-size: 48px;
|
||||
box-shadow: 2px 2px 6px 0px rgba(0, 0, 0, 0.2);
|
||||
max-width: 100%;
|
||||
width: 215px;
|
||||
height: 200px;
|
||||
margin: auto;
|
||||
text-align: center;
|
||||
line-height: 200px;
|
||||
background-color: #2c2f33;
|
||||
/*line-height: 200px;*/
|
||||
background-color: #0050b8;
|
||||
}
|
||||
|
||||
.grid {
|
||||
|
27
templates/klasse.hbs
Normal file
27
templates/klasse.hbs
Normal 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)~}}
|
@ -1,10 +1,12 @@
|
||||
{{#* inline "page"}}
|
||||
<h1>Vertretungen</h1>
|
||||
<ul>
|
||||
<div class="grid-container">
|
||||
{{#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}}
|
||||
</ul>
|
||||
</div>
|
||||
{{/inline}}
|
||||
{{! remove whitespaces with ~ }}
|
||||
{{~> (parent)~}}
|
Loading…
Reference in New Issue
Block a user