From 8a8030dc2b247da14962630bb3cdd51ec5990361 Mon Sep 17 00:00:00 2001 From: Dietrich Date: Fri, 6 Jan 2023 17:26:34 +0100 Subject: [PATCH] =?UTF-8?q?Zus=C3=A4tzliche=20modale=20anzeigen,=20sowie?= =?UTF-8?q?=20erste=20Zuweisung?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/types.rs | 2 +- src/zuordnung.rs | 264 +++++++++++++++++++++++++++++++++++++---------- 2 files changed, 210 insertions(+), 56 deletions(-) diff --git a/src/types.rs b/src/types.rs index be56a51..5e97888 100644 --- a/src/types.rs +++ b/src/types.rs @@ -16,7 +16,7 @@ pub struct GemüseAnfrage { pub user: Benutzer, } -#[derive(Serialize, Deserialize, Default, Debug, Clone, PartialEq, Hash, Eq)] +#[derive(Serialize, Deserialize, Default, Debug, Clone, PartialEq, Hash, Eq, Copy)] pub struct VpWunsch { pub id: i32, pub anfrage_id: i32, diff --git a/src/zuordnung.rs b/src/zuordnung.rs index f15fe64..c0f9a85 100644 --- a/src/zuordnung.rs +++ b/src/zuordnung.rs @@ -39,6 +39,10 @@ pub enum ZuordnungMessage { ShowDialog(Dialog), /// A message indicating that the current dialog should be hidden. HideDialog, + AssignAll { + verteilpunkt: Verteilpunkt, + mitgliedschaften: Vec, + }, } pub struct Dialog { @@ -47,7 +51,9 @@ pub struct Dialog { } pub enum DialogContent { - Wunschliste(Vec), + Wunschliste(Verteilpunkt, Vec), + Vorjahr(Vec), + Geplant(HashMap), } #[derive(Properties, PartialEq, Default)] @@ -66,7 +72,7 @@ pub struct ZuordnungApp { /// The assignments made for the previous year. zuordnung_vorjahr: Option, /// The planned assignments for the current year. - geplante_zuordnung: HashMap, + geplante_zuordnung: HashMap>, /// The currently displayed dialog. dialog: Option, } @@ -137,6 +143,12 @@ impl Component for ZuordnungApp { NetworkObjekte::Verteilpunkt(v) => { log!("Verteilpunkte geparsed"); self.verteilpunkte = v; + for vp in self.verteilpunkte.iter() { + log!(format!( + "{:?}", + self.geplante_zuordnung.insert(*vp.0, HashMap::new()) + )); + } true } NetworkObjekte::Wunsch(v) => { @@ -163,6 +175,26 @@ impl Component for ZuordnungApp { self.dialog = None; true } + ZuordnungMessage::AssignAll { + verteilpunkt, + mitgliedschaften, + } => { + log!(format!("{:?}", mitgliedschaften)); + if let Some(liste) = self.geplante_zuordnung.get_mut(&verteilpunkt.id) { + for m in mitgliedschaften { + liste.insert( + m.anfrage_id, + GeplanteVpZuordnung { + mitgliedschaft_id: m.anfrage_id, + user_mitgliedsnummer: m.user_id, + verteilpunkt_id: m.verteilpunkt_id, + }, + ); + } + }; + log!(format!("{:?}", self.geplante_zuordnung)); + true + } } } @@ -185,8 +217,8 @@ impl Component for ZuordnungApp { .map(|(id, v)| html! { {self.verteilpunkt_name(v)} - {self.aktuelle_mitglieder(v, &self.zuordnung_vorjahr)} - {self.zukünftige_mitglieder(v)} + {self.aktuelle_mitglieder(v, ctx)} + {self.zukünftige_mitglieder(v, ctx)} {self.count_wünsche(*id, ctx)} }) @@ -198,6 +230,9 @@ impl Component for ZuordnungApp { } } impl ZuordnungApp { + /** + Erstelle Die Tabellenzellen für die 1. 2. und n. Wünsche. + */ fn count_wünsche(&self, verteilpunkt_id: i32, ctx: &yew::Context) -> Html { // Erst wenn die Wünsche geladen sind wird etwas angezeigt. if let Some(wünsche) = &self.wünsche { @@ -206,6 +241,7 @@ impl ZuordnungApp { .wünsche .iter() .filter(|(_, wunsch)| wunsch.verteilpunkt_id == verteilpunkt_id); + // A mapping from priority values to lists of wishes. let counts: HashMap> = wünsche .prioritäten @@ -214,11 +250,19 @@ impl ZuordnungApp { .collect(); let counts: HashMap> = filtered.fold(counts, |mut counts, (_, wunsch)| { - counts - .entry(wunsch.prioritaet) - .or_insert_with(Vec::new) - .push(wunsch.clone()); - counts + if self + .geplante_zuordnung + .iter() + .any(|(_, v)| v.contains_key(&wunsch.anfrage_id)) + { + counts + } else { + counts + .entry(wunsch.prioritaet) + .or_insert_with(Vec::new) + .push(*wunsch); + counts + } }); // sortiere nach Priorität let sorted_and_grouped_by_priority = counts.into_iter().sorted_by_key(|x| x.0); @@ -230,14 +274,12 @@ impl ZuordnungApp { let verteilpunkte = self.verteilpunkte.clone(); let onclick = ctx.link().callback(move |_| { + let vp = verteilpunkte + .get(&verteilpunkt_id) + .expect("should allways be there"); ZuordnungMessage::ShowDialog(Dialog { - title: { - let vp = verteilpunkte - .get(&verteilpunkt_id) - .expect("should allways be there"); - format!("Wünsche für {}", vp.name) - }, - content: DialogContent::Wunschliste(wunsch.clone()), + title: { format!("Wünsche für {}", vp.name) }, + content: DialogContent::Wunschliste(vp.clone(), wunsch.clone()), }) }); html! {{length}} @@ -294,69 +336,112 @@ impl ZuordnungApp { } } + /** + Count the number of items in the zuordnungen map with the matching verteilpunkt_id + */ + fn count_zuordnungen( + v: &Verteilpunkt, + zuordnungen: &HashMap, + ) -> Vec { + zuordnungen + .iter() + .filter_map(|(_, zuo)| { + if v.id == zuo.verteilpunkt_id { + Some(zuo.clone()) + } else { + None + } + }) + .collect() + } - fn aktuelle_mitglieder(&self, v: &Verteilpunkt, z: &Option) -> Html { - // Count the number of items in the zuordnungen map with the matching verteilpunkt_id - fn count_zuordnungen(v: &Verteilpunkt, zuordnungen: &HashMap) -> usize { - zuordnungen - .iter() - .filter(|(_, zuo)| v.id == zuo.verteilpunkt_id) - .count() - } - - match z { + fn aktuelle_mitglieder( + &self, + verteilpunkt: &Verteilpunkt, + ctx: &yew::Context, + ) -> Html { + match &self.zuordnung_vorjahr { Some(z) => { // Render the count and the kapazitaet as "X/Y" - let count = count_zuordnungen(v, &z.zuordnungen); - html! {<>{count}{"/"} {v.kapazitaet}} + let liste = Self::count_zuordnungen(verteilpunkt, &z.zuordnungen); + let count = liste.len(); + let title = format!("Aktuelle Mitglieder am VP {}", verteilpunkt.name); + let onclick = ctx.link().callback(move |_| { + ZuordnungMessage::ShowDialog(Dialog { + title: title.clone(), + content: DialogContent::Vorjahr(liste.clone()), + }) + }); + + html! {{count}{"/"} {verteilpunkt.kapazitaet}} } None => html!(), } } - - fn zukünftige_mitglieder(&self, verteilpunkt: &Verteilpunkt) -> Html { + /** + Count the number of items in the zuordnungen map with the matching verteilpunkt_id + */ + fn count_geplante_zuordnungen( + v: &Verteilpunkt, + zuordnungen: &HashMap>, + ) -> HashMap { + zuordnungen.get(&v.id).cloned().unwrap_or_default() + } + /** + Zeige die Anzahl und Kappazität der zukünftigen Mitglieder an diesem Verteilpunkt. + */ + fn zukünftige_mitglieder( + &self, + verteilpunkt: &Verteilpunkt, + ctx: &yew::Context, + ) -> Html { // Count the number of items in the z map with the matching verteilpunkt_id - let count = &self - .geplante_zuordnung - .iter() - .filter(|(_, zuo)| verteilpunkt.id == zuo.verteilpunkt_id) - .count(); + let liste = Self::count_geplante_zuordnungen(verteilpunkt, &self.geplante_zuordnung); + let count = liste.len(); + let title = format!("Geplante Mitglieder am VP {}", verteilpunkt.name); + let onclick = ctx.link().callback(move |_| { + ZuordnungMessage::ShowDialog(Dialog { + title: title.clone(), + content: DialogContent::Geplant(liste.clone()), + }) + }); // Render the count and the kapazitaet as "X/Y" - html! {<>{count}{"/"} {verteilpunkt.kapazitaet}} + html! {
{count}{"/"} {verteilpunkt.kapazitaet}
} } fn show_dialog(&self, ctx: &yew::Context) -> Html { match &self.dialog { Some(dialog) => { - // Create a callback that calls the HideDialog function when triggered - let onclick = ctx.link().callback(|_| ZuordnungMessage::HideDialog); - html! { - // Render the dialog container with the onclick callback attached -