fancy station view; Fixes #33
This commit is contained in:
parent
4cbd5269d6
commit
75c2bc9bbb
@ -121,11 +121,18 @@ impl Station {
|
|||||||
|
|
||||||
let waiting_teams: Vec<&Team> = teams.waiting.iter().map(|(team, _)| team).collect();
|
let waiting_teams: Vec<&Team> = teams.waiting.iter().map(|(team, _)| team).collect();
|
||||||
let doing_teams: Vec<&Team> = teams.doing.iter().map(|(team, _)| team).collect();
|
let doing_teams: Vec<&Team> = teams.doing.iter().map(|(team, _)| team).collect();
|
||||||
let finished_teams: Vec<&Team> = teams.left.iter().map(|(team, _)| team).collect();
|
let finished_teams: Vec<&Team> = teams
|
||||||
|
.left_not_yet_rated
|
||||||
|
.iter()
|
||||||
|
.map(|(team, _)| team)
|
||||||
|
.collect();
|
||||||
|
let finished_and_rated_teams: Vec<&Team> =
|
||||||
|
teams.left_and_rated.iter().map(|(team, _)| team).collect();
|
||||||
|
|
||||||
if !waiting_teams.contains(&team)
|
if !waiting_teams.contains(&team)
|
||||||
&& !doing_teams.contains(&team)
|
&& !doing_teams.contains(&team)
|
||||||
&& !finished_teams.contains(&team)
|
&& !finished_teams.contains(&team)
|
||||||
|
&& !finished_and_rated_teams.contains(&team)
|
||||||
{
|
{
|
||||||
return Err(
|
return Err(
|
||||||
"Es können nur Teams bewertet werden, die zumindest schon bei der Station sind."
|
"Es können nur Teams bewertet werden, die zumindest schon bei der Station sind."
|
||||||
@ -242,9 +249,15 @@ impl Station {
|
|||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
let teams = TeamsAtStationLocation::for_station(db, self).await;
|
let teams = TeamsAtStationLocation::for_station(db, self).await;
|
||||||
|
|
||||||
let left_teams: Vec<&Team> = teams.left.iter().map(|(team, _)| team).collect();
|
let left_and_rated_teams: Vec<&Team> =
|
||||||
|
teams.left_and_rated.iter().map(|(team, _)| team).collect();
|
||||||
|
let left_not_yet_rated_teams: Vec<&Team> = teams
|
||||||
|
.left_not_yet_rated
|
||||||
|
.iter()
|
||||||
|
.map(|(team, _)| team)
|
||||||
|
.collect();
|
||||||
|
|
||||||
if !left_teams.contains(&team) {
|
if !left_and_rated_teams.contains(&team) && !left_not_yet_rated_teams.contains(&team) {
|
||||||
return Err(format!(
|
return Err(format!(
|
||||||
"Team kann nicht zur Arbeitsposition hinzugefügt werden, weil das Team {} aktuell nicht feritg ist",
|
"Team kann nicht zur Arbeitsposition hinzugefügt werden, weil das Team {} aktuell nicht feritg ist",
|
||||||
team.name
|
team.name
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use crate::{Station, admin::team::Team};
|
use crate::{admin::team::Team, Station};
|
||||||
use chrono::{DateTime, Local, NaiveDateTime, Utc};
|
use chrono::{DateTime, Local, NaiveDateTime, Utc};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use sqlx::{FromRow, SqlitePool};
|
use sqlx::{FromRow, SqlitePool};
|
||||||
@ -123,7 +123,8 @@ pub(crate) struct TeamsAtStationLocation {
|
|||||||
pub(crate) not_yet_here: Vec<Team>,
|
pub(crate) not_yet_here: Vec<Team>,
|
||||||
pub(crate) waiting: Vec<(Team, Rating)>,
|
pub(crate) waiting: Vec<(Team, Rating)>,
|
||||||
pub(crate) doing: Vec<(Team, Rating)>,
|
pub(crate) doing: Vec<(Team, Rating)>,
|
||||||
pub(crate) left: Vec<(Team, Rating)>,
|
pub(crate) left_not_yet_rated: Vec<(Team, Rating)>,
|
||||||
|
pub(crate) left_and_rated: Vec<(Team, Rating)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TeamsAtStationLocation {
|
impl TeamsAtStationLocation {
|
||||||
@ -134,13 +135,18 @@ impl TeamsAtStationLocation {
|
|||||||
let mut not_yet_here = Vec::new();
|
let mut not_yet_here = Vec::new();
|
||||||
let mut waiting = Vec::new();
|
let mut waiting = Vec::new();
|
||||||
let mut doing = Vec::new();
|
let mut doing = Vec::new();
|
||||||
let mut left = Vec::new();
|
let mut left_not_yet_rated = Vec::new();
|
||||||
|
let mut left_and_rated = Vec::new();
|
||||||
|
|
||||||
for team in teams {
|
for team in teams {
|
||||||
match Rating::find_by_team_and_station(db, &team, station).await {
|
match Rating::find_by_team_and_station(db, &team, station).await {
|
||||||
Some(rating) => {
|
Some(rating) => {
|
||||||
if rating.left_at.is_some() {
|
if rating.left_at.is_some() {
|
||||||
left.push((team, rating));
|
if rating.points.is_some() {
|
||||||
|
left_and_rated.push((team, rating));
|
||||||
|
} else {
|
||||||
|
left_not_yet_rated.push((team, rating));
|
||||||
|
}
|
||||||
} else if rating.started_at.is_some() {
|
} else if rating.started_at.is_some() {
|
||||||
doing.push((team, rating));
|
doing.push((team, rating));
|
||||||
} else {
|
} else {
|
||||||
@ -156,7 +162,8 @@ impl TeamsAtStationLocation {
|
|||||||
not_yet_here,
|
not_yet_here,
|
||||||
waiting,
|
waiting,
|
||||||
doing,
|
doing,
|
||||||
left,
|
left_not_yet_rated,
|
||||||
|
left_and_rated,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
298
src/station.rs
298
src/station.rs
@ -8,7 +8,7 @@ use axum::{
|
|||||||
routing::{get, post},
|
routing::{get, post},
|
||||||
Form, Router,
|
Form, Router,
|
||||||
};
|
};
|
||||||
use maud::{html, Markup};
|
use maud::{html, Markup, PreEscaped};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use sqlx::SqlitePool;
|
use sqlx::SqlitePool;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
@ -112,159 +112,189 @@ async fn view(
|
|||||||
" Teams zu deiner Station kommen."
|
" Teams zu deiner Station kommen."
|
||||||
progress value=(teams.total_teams-teams.not_yet_here.len() as i64) max=(teams.total_teams) {}
|
progress value=(teams.total_teams-teams.not_yet_here.len() as i64) max=(teams.total_teams) {}
|
||||||
}
|
}
|
||||||
h2 { "Teams aktuell bei dir" }
|
@if !teams.not_yet_here.is_empty() {
|
||||||
@if !teams.waiting.is_empty() {
|
form action=(format!("/s/{id}/{code}/new-waiting")) method="post" {
|
||||||
(teams.waiting.len())
|
fieldset role="group" {
|
||||||
" Teams warten an deiner Station:"
|
select name="team_id" aria-label="Team auswählen" required {
|
||||||
ol {
|
@for team in &teams.not_yet_here {
|
||||||
@for (team, rating) in teams.waiting {
|
option value=(team.id) {
|
||||||
li {
|
(team.name)
|
||||||
(team.name)
|
|
||||||
" (seit "
|
|
||||||
(rating.local_time_arrived_at())
|
|
||||||
")"
|
|
||||||
details {
|
|
||||||
summary { "✏️" }
|
|
||||||
article {
|
|
||||||
form action=(format!("/s/{id}/{code}/team-update/{}", team.id)) method="post" {
|
|
||||||
label {
|
|
||||||
"Notizen"
|
|
||||||
@if let Some(notes) = &rating.notes {
|
|
||||||
input type="text" name="notes" value=(notes);
|
|
||||||
} @else {
|
|
||||||
input type="text" name="notes";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
input type="submit" value="Notizen speichern";
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
input type="submit" value="Neues Team da";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
h2 { "Teams bei dir" }
|
||||||
|
@if !teams.doing.is_empty() {
|
||||||
|
@for (team, rating) in teams.doing {
|
||||||
|
article {
|
||||||
|
details {
|
||||||
|
summary {
|
||||||
|
em data-tooltip="Aktiv" { "🎬 " }
|
||||||
|
(team.name)
|
||||||
|
small {
|
||||||
|
" (seit "
|
||||||
|
(rating.local_time_doing())
|
||||||
|
")"
|
||||||
|
}
|
||||||
|
"✏️"
|
||||||
|
a href=(format!("/s/{id}/{code}/team-finished/{}", team.id)) {
|
||||||
|
button { "Team fertig" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
form action=(format!("/s/{id}/{code}/team-update/{}", team.id)) method="post" {
|
||||||
|
label {
|
||||||
|
"Notizen"
|
||||||
|
@if let Some(notes) = &rating.notes {
|
||||||
|
input type="text" name="notes" value=(notes);
|
||||||
|
} @else {
|
||||||
|
input type="text" name="notes";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
input type="submit" value="Notizen speichern";
|
||||||
|
}
|
||||||
|
a href=(format!("/s/{id}/{code}/remove-doing/{}", team.id))
|
||||||
|
onclick="return confirm('Bist du sicher, dass das Team noch nicht bei dir arbeitet? Das Team wird zurück auf die Warte-Position gesetzt');" {
|
||||||
|
"🗑️"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@if !teams.waiting.is_empty() {
|
||||||
|
@for (team, rating) in teams.waiting {
|
||||||
|
article {
|
||||||
|
details {
|
||||||
|
summary {
|
||||||
|
em data-tooltip="Wartend" { "⏳ " }
|
||||||
|
(team.name)
|
||||||
|
small {
|
||||||
|
" (seit "
|
||||||
|
(rating.local_time_arrived_at())
|
||||||
|
")"
|
||||||
|
}
|
||||||
|
"✏️"
|
||||||
|
a href=(format!("/s/{id}/{code}/team-starting/{}", team.id)) {
|
||||||
|
button { "Team startet" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
form action=(format!("/s/{id}/{code}/team-update/{}", team.id)) method="post" {
|
||||||
|
label {
|
||||||
|
"Notizen"
|
||||||
|
@if let Some(notes) = &rating.notes {
|
||||||
|
input type="text" name="notes" value=(notes);
|
||||||
|
} @else {
|
||||||
|
input type="text" name="notes";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
input type="submit" value="Notizen speichern";
|
||||||
|
}
|
||||||
a href=(format!("/s/{id}/{code}/remove-waiting/{}", team.id))
|
a href=(format!("/s/{id}/{code}/remove-waiting/{}", team.id))
|
||||||
onclick="return confirm('Bist du sicher, dass das Team noch nicht bei dir ist? Das kann _NICHT_ mehr rückgängig gemacht werden.');" {
|
onclick="return confirm('Bist du sicher, dass das Team noch nicht bei dir ist? Das kann _NICHT_ mehr rückgängig gemacht werden.');" {
|
||||||
"🗑️"
|
"🗑️"
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
a href=(format!("/s/{id}/{code}/team-starting/{}", team.id)) {
|
|
||||||
button { "Team startet" }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@if !teams.not_yet_here.is_empty() {
|
@if !teams.left_not_yet_rated.is_empty() {
|
||||||
form action=(format!("/s/{id}/{code}/new-waiting")) method="post" {
|
h2 { "Noch zu Bewerten" }
|
||||||
fieldset role="group" {
|
article class="warning" {
|
||||||
select name="team_id" aria-label="Team auswählen" required {
|
"Noch keine Punkte für diese Gruppe vergeben ⤵️"
|
||||||
@for team in &teams.not_yet_here {
|
|
||||||
option value=(team.id) {
|
|
||||||
(team.name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
input type="submit" value="Neues Team da";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
@for (team, rating) in teams.left_not_yet_rated {
|
||||||
@if !teams.doing.is_empty() {
|
article {
|
||||||
(teams.doing.len())
|
em data-tooltip="Zu bewerten" { "☐ " }
|
||||||
" Teams arbeiten an deiner Station:"
|
(team.name)
|
||||||
ol {
|
small {
|
||||||
@for (team, rating) in teams.doing {
|
" (um "
|
||||||
li {
|
(rating.local_time_left())
|
||||||
(team.name)
|
" gegangen)"
|
||||||
" (seit "
|
|
||||||
(rating.local_time_doing())
|
|
||||||
")"
|
|
||||||
details {
|
|
||||||
summary { "✏️" }
|
|
||||||
article {
|
|
||||||
form action=(format!("/s/{id}/{code}/team-update/{}", team.id)) method="post" {
|
|
||||||
label {
|
|
||||||
"Notizen"
|
|
||||||
@if let Some(notes) = &rating.notes {
|
|
||||||
input type="text" name="notes" value=(notes);
|
|
||||||
} @else {
|
|
||||||
input type="text" name="notes";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
input type="submit" value="Notizen speichern";
|
|
||||||
}
|
|
||||||
a href=(format!("/s/{id}/{code}/remove-doing/{}", team.id))
|
|
||||||
onclick="return confirm('Bist du sicher, dass das Team noch nicht bei dir arbeitet? Das Team wird zurück auf die Warte-Position gesetzt');" {
|
|
||||||
"🗑️"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
a href=(format!("/s/{id}/{code}/team-finished/{}", team.id)) {
|
|
||||||
button { "Team fertig" }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
form action=(format!("/s/{id}/{code}/team-update/{}", team.id)) method="post" {
|
||||||
|
label {
|
||||||
|
@if let Some(points) = rating.points {
|
||||||
|
span { (points) " Punkte" }
|
||||||
|
input type="range" name="points" min="0" max="10" value=(points)
|
||||||
|
onchange="if(!confirm('Du hast die Gruppe bereits bewertet. Bist du sicher, dass du deine Bewertung nochmal ändern möchtest?')) { this.value = this.defaultValue; this.previousElementSibling.textContent = this.defaultValue + ' Punkte'; }"
|
||||||
|
oninput="this.previousElementSibling.textContent = this.value + ' Punkte'" {}
|
||||||
|
} @else {
|
||||||
|
span { "0 Punkte" }
|
||||||
|
input type="range" name="points" min="0" max="10" value="0" oninput="this.previousElementSibling.textContent = this.value + ' Punkte'" {}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
"Notizen"
|
||||||
|
@if let Some(notes) = &rating.notes {
|
||||||
|
input type="text" name="notes" value=(notes);
|
||||||
|
} @else {
|
||||||
|
input type="text" name="notes";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
input type="submit" value="Speichern";
|
||||||
|
}
|
||||||
|
a href=(format!("/s/{id}/{code}/remove-left/{}", team.id))
|
||||||
|
onclick="return confirm('Bist du sicher, dass das Team noch nicht bei dir fertig ist? Das Team wird zurück auf die Arbeits-Position gesetzt');" {
|
||||||
|
"🗑️"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@if !teams.left.is_empty() {
|
|
||||||
h2 { "Teams die bei dir waren" }
|
|
||||||
(teams.left.len())
|
h2 { "Was bisher geschah" }
|
||||||
" Teams waren schon bei dir"
|
@if !teams.left_and_rated.is_empty() {
|
||||||
ol {
|
@for (team, rating) in teams.left_and_rated {
|
||||||
@for (team, rating) in teams.left {
|
article {
|
||||||
li {
|
details {
|
||||||
(team.name)
|
summary {
|
||||||
" (gegangen um "
|
em data-tooltip="Schon bewertet" { "✅ " }
|
||||||
(rating.local_time_left())
|
(team.name)
|
||||||
@if let Some(points) = rating.points {
|
(PreEscaped(" → "))
|
||||||
", "
|
(rating.points.unwrap())
|
||||||
(points)
|
|
||||||
" Punkte"
|
" Punkte"
|
||||||
}
|
}
|
||||||
@if let Some(notes) = &rating.notes{
|
small {
|
||||||
", Notizen: "
|
" (um "
|
||||||
(notes)
|
(rating.local_time_arrived_at())
|
||||||
|
" eingetroffen, um "
|
||||||
|
(rating.local_time_doing())
|
||||||
|
" gestartet und um "
|
||||||
|
(rating.local_time_left())
|
||||||
|
" gegangen)"
|
||||||
}
|
}
|
||||||
")"
|
form action=(format!("/s/{id}/{code}/team-update/{}", team.id)) method="post" {
|
||||||
|
label {
|
||||||
|
@if let Some(points) = rating.points {
|
||||||
|
span { (points) " Punkte" }
|
||||||
|
input type="range" name="points" min="0" max="10" value=(points)
|
||||||
|
onchange="if(!confirm('Du hast die Gruppe bereits bewertet. Bist du sicher, dass du deine Bewertung nochmal ändern möchtest?')) { this.value = this.defaultValue; this.previousElementSibling.textContent = this.defaultValue + ' Punkte'; }"
|
||||||
|
oninput="this.previousElementSibling.textContent = this.value + ' Punkte'" {}
|
||||||
|
}
|
||||||
|
|
||||||
details open[rating.points.is_none()] {
|
}
|
||||||
summary { "✏️" }
|
label {
|
||||||
article {
|
"Notizen"
|
||||||
@if rating.points.is_none() {
|
@if let Some(notes) = &rating.notes {
|
||||||
article class="warning" {
|
input type="text" name="notes" value=(notes);
|
||||||
"Noch keine Punkte für diese Gruppe vergeben. Gib sie hier ein und drücke dann auf "
|
} @else {
|
||||||
em { "Speichern" }
|
input type="text" name="notes";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
form action=(format!("/s/{id}/{code}/team-update/{}", team.id)) method="post" {
|
input type="submit" value="Speichern";
|
||||||
label {
|
}
|
||||||
@if let Some(points) = rating.points {
|
a href=(format!("/s/{id}/{code}/remove-left/{}", team.id))
|
||||||
span { (points) " Punkte" }
|
onclick="return confirm('Bist du sicher, dass das Team noch nicht bei dir fertig ist? Das Team wird zurück auf die Arbeits-Position gesetzt');" {
|
||||||
input type="range" name="points" min="0" max="10" value=(points)
|
"🗑️"
|
||||||
onchange="if(!confirm('Du hast die Gruppe bereits bewertet. Bist du sicher, dass du deine Bewertung nochmal ändern möchtest?')) { this.value = this.defaultValue; this.previousElementSibling.textContent = this.defaultValue + ' Punkte'; }"
|
|
||||||
oninput="this.previousElementSibling.textContent = this.value + ' Punkte'" {}
|
|
||||||
} @else {
|
|
||||||
span { "0 Punkte" }
|
|
||||||
input type="range" name="points" min="0" max="10" value="0" oninput="this.previousElementSibling.textContent = this.value + ' Punkte'" {}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
label {
|
|
||||||
"Notizen"
|
|
||||||
@if let Some(notes) = &rating.notes {
|
|
||||||
input type="text" name="notes" value=(notes);
|
|
||||||
} @else {
|
|
||||||
input type="text" name="notes";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
input type="submit" value="Speichern";
|
|
||||||
}
|
|
||||||
|
|
||||||
a href=(format!("/s/{id}/{code}/remove-left/{}", team.id))
|
|
||||||
onclick="return confirm('Bist du sicher, dass das Team noch nicht bei dir fertig ist? Das Team wird zurück auf die Arbeits-Position gesetzt');" {
|
|
||||||
"🗑️"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} @else {
|
||||||
|
"Du hast bisher noch keine Teams bewertet."
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user