From 47fe90ee23d8ab04645ef3c7a17459ed40c5b765 Mon Sep 17 00:00:00 2001 From: Joris Date: Sun, 24 Apr 2022 16:31:49 +0200 Subject: Allow to attach categories to events --- src/gui/form/mod.rs | 54 +++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 44 insertions(+), 10 deletions(-) (limited to 'src/gui/form') diff --git a/src/gui/form/mod.rs b/src/gui/form/mod.rs index bb43ef5..cc77a19 100644 --- a/src/gui/form/mod.rs +++ b/src/gui/form/mod.rs @@ -15,7 +15,7 @@ use uuid::Uuid; use crate::{ db, gui::{update, update::Msg, App}, - model::{event, event::Event, repetition::Repetition}, + model::{category::Category, event, event::Event, repetition::Repetition}, }; pub async fn repetition_dialog(app: &App, date: NaiveDate, event: &Event) { @@ -148,6 +148,19 @@ pub async fn show(app: &App, target: Target) { column1.append(&utils::label("Fin")); column1.append(&end); + let dropdown_categories = get_dropdown_categories(&app.categories); + let category_dropdown = gtk::DropDown::from_strings( + &dropdown_categories + .iter() + .map(|s| s.as_str()) + .collect::>(), + ); + category_dropdown.set_margin_bottom(10); + let selected = get_selected_category(&event, &app.categories).unwrap_or_else(|| "".to_string()); + category_dropdown.set_selected(dropdown_categories.iter().position(|d| d == &selected).unwrap_or(0) as u32); + column1.append(&utils::label("Catégorie")); + column1.append(&category_dropdown); + // Second column let repetition = match target { @@ -174,7 +187,8 @@ pub async fn show(app: &App, target: Target) { lines.append(&button); let conn = app.conn.clone(); let tx = app.tx.clone(); - button.connect_clicked(glib::clone!(@weak dialog, @strong target, @strong event => move |_| { + let categories = app.categories.clone(); + button.connect_clicked(glib::clone!(@weak dialog, @strong target, @strong event, @strong categories => move |_| { let removed_occurences = match &target { Target::Update { event, .. } => { event.repetition.as_ref().map(|r| r.removed_occurences.clone()).unwrap_or_default() @@ -187,11 +201,15 @@ pub async fn show(app: &App, target: Target) { Target::Update {event} => event.id, _ => Uuid::new_v4(), }; - match event::validate(id, date.buffer().text(), name.buffer().text(), start.buffer().text(), end.buffer().text(), repetition) { + + // Find category id from selected id + let category = categories.iter().find(|c| c.name == dropdown_categories[category_dropdown.selected() as usize]).map(|c| c.id); + + match event::validate(id, date.buffer().text(), name.buffer().text(), start.buffer().text(), end.buffer().text(), repetition, category) { Some(new) => { match &target { Target::New {..} => { - match db::insert(&conn, &new) { + match db::events::insert(&conn, &new) { Ok(_) => { update::send(tx.clone(), Msg::AddEvent { new }); dialog.close() @@ -200,7 +218,7 @@ pub async fn show(app: &App, target: Target) { } } Target::Update {event} => { - match db::update(&conn, &new) { + match db::events::update(&conn, &new) { Ok(_) => { update::send(tx.clone(), Msg::UpdateEvent { old: event.clone(), new }); dialog.close() @@ -212,7 +230,7 @@ pub async fn show(app: &App, target: Target) { // TODO: improve intermediate error state match delete_repetition_occurence(&conn, event, *date) { Ok(occurence) => { - match db::insert(&conn, &new) { + match db::events::insert(&conn, &new) { Ok(_) => { update::send(tx.clone(), Msg::UpdateEventOccurence { event: event.clone(), @@ -231,7 +249,7 @@ pub async fn show(app: &App, target: Target) { Target::UpdateFromOccurence { date, event } => { match update_repetition_until(&conn, *date - Duration::days(1), event) { Ok(updated) => { - match db::insert(&conn, &new) { + match db::events::insert(&conn, &new) { Ok(_) => { update::send(tx.clone(), Msg::UpdateRepeatedFrom { old: event.clone(), @@ -288,7 +306,7 @@ pub async fn show(app: &App, target: Target) { } } _ => { - let operation = db::delete(&conn, &event.id); + let operation = db::events::delete(&conn, &event.id); if operation.is_ok() { update::send(tx.clone(), Msg::DeleteEvent { event: event.clone() }); dialog.close() @@ -301,6 +319,22 @@ pub async fn show(app: &App, target: Target) { dialog.run_future().await; } +fn get_dropdown_categories(categories: &[Category]) -> Vec { + let mut xs = categories + .iter() + .map(|c| c.name.clone()) + .collect::>(); + xs.push("".to_string()); + xs.sort(); + xs +} + +fn get_selected_category(event: &Option, categories: &[Category]) -> Option { + let id = event.as_ref()?.category?; + let category = categories.iter().find(|c| c.id == id)?; + Some(category.name.clone()) +} + #[derive(Error, Debug)] enum DeleteError { #[error("Repetition not found")] @@ -320,7 +354,7 @@ fn delete_repetition_occurence( let mut repetition = repetition.clone(); repetition.removed_occurences.insert(occurence); event.repetition = Some(repetition); - db::update(conn, &event).map(|_| occurence) + db::events::update(conn, &event).map(|_| occurence) } else { Err(anyhow::Error::new(DeleteError::OccurenceNotFound)) } @@ -336,6 +370,6 @@ fn update_repetition_until(conn: &Connection, date: NaiveDate, event: &Event) -> removed_occurences: r.removed_occurences.clone(), until: Some(date), }); - db::update(conn, &with_repetition_until)?; + db::events::update(conn, &with_repetition_until)?; Ok(with_repetition_until) } -- cgit v1.2.3