From 47183b6e7a374bb588a10762b8809f2ea219e759 Mon Sep 17 00:00:00 2001 From: Jeremy Wall Date: Wed, 18 Jan 2023 19:29:44 -0500 Subject: [PATCH] Add plan deletion to the UI --- kitchen/src/web/mod.rs | 4 +++- web/src/api.rs | 20 ++++++++++++++++++++ web/src/app_state.rs | 24 ++++++++++++++++++++++++ web/src/components/plan_list.rs | 5 +++++ web/src/components/recipe_selection.rs | 2 +- 5 files changed, 53 insertions(+), 2 deletions(-) diff --git a/kitchen/src/web/mod.rs b/kitchen/src/web/mod.rs index 7c3b626..9cccadf 100644 --- a/kitchen/src/web/mod.rs +++ b/kitchen/src/web/mod.rs @@ -519,7 +519,9 @@ fn mk_v2_routes() -> Router { .route("/plan/since/:date", get(api_plan_since)) .route( "/plan/at/:date", - get(api_plan_for_date).post(api_save_plan_for_date), + get(api_plan_for_date) + .post(api_save_plan_for_date) + .delete(api_delete_plan_for_date), ) .route("/plan/all", get(api_all_plans)) .route( diff --git a/web/src/api.rs b/web/src/api.rs index 10d6f97..848e7a8 100644 --- a/web/src/api.rs +++ b/web/src/api.rs @@ -257,6 +257,13 @@ impl LocalStore { } } + pub fn delete_plan_for_date(&self, date: &NaiveDate) { + self.store.delete("plan").expect("Failed to delete plan"); + self.store + .delete("inventory") + .expect("Failed to delete inventory data"); + } + pub fn set_plan_date(&self, date: &NaiveDate) { self.store .set( @@ -664,6 +671,19 @@ impl HttpStore { } } + pub async fn delete_plan_for_date(&self, date: &NaiveDate) -> Result<(), Error> { + let mut path = self.v2_path(); + path.push_str("/plan"); + path.push_str("/at"); + path.push_str(&format!("/{}", date)); + let resp = reqwasm::http::Request::delete(&path).send().await?; + if resp.status() != 200 { + Err(format!("Status: {}", resp.status()).into()) + } else { + Ok(()) + } + } + pub async fn fetch_plan_for_date( &self, date: &NaiveDate, diff --git a/web/src/app_state.rs b/web/src/app_state.rs index 4aac4a3..105a3b9 100644 --- a/web/src/app_state.rs +++ b/web/src/app_state.rs @@ -75,6 +75,7 @@ pub enum Message { SaveState(Option>), LoadState(Option>), UpdateStaples(String, Option>), + DeletePlan(NaiveDate, Option>), SelectPlanDate(NaiveDate, Option>), } @@ -117,6 +118,7 @@ impl Debug for Message { Self::LoadState(_) => write!(f, "LoadState"), Self::UpdateStaples(arg, _) => f.debug_tuple("UpdateStaples").field(arg).finish(), Self::SelectPlanDate(arg, _) => f.debug_tuple("SelectPlanDate").field(arg).finish(), + Self::DeletePlan(arg, _) => f.debug_tuple("DeletePlan").field(arg).finish(), } } } @@ -484,6 +486,28 @@ impl MessageMapper for StateMachine { // the original signal. return; } + Message::DeletePlan(date, callback) => { + let store = self.store.clone(); + let local_store = self.local_store.clone(); + spawn_local_scoped(cx, async move { + store + .delete_plan_for_date(&date) + .await + .expect("Failed to delete meal plan for date"); + local_store.delete_plan_for_date(&date); + + original_copy.plan_dates.remove(&date); + // Reset all meal planning state; + let _ = original_copy.recipe_counts.iter_mut().map(|(_, v)| *v = 0); + original_copy.filtered_ingredients = BTreeSet::new(); + original_copy.modified_amts = BTreeMap::new(); + original_copy.extras = Vec::new(); + original.set(original_copy); + + callback.map(|f| f()); + }); + return; + } } original.set(original_copy); } diff --git a/web/src/components/plan_list.rs b/web/src/components/plan_list.rs index 277f1db..c7e8fb6 100644 --- a/web/src/components/plan_list.rs +++ b/web/src/components/plan_list.rs @@ -42,6 +42,11 @@ pub fn PlanList<'ctx, G: Html>(cx: Scope<'ctx>, props: PlanListProps<'ctx>) -> V sh.dispatch(cx, Message::SelectPlanDate(date, None)) }) { (date_display) } } + td() { + span(role="button", class="destructive", on:click=move |_| { + sh.dispatch(cx, Message::DeletePlan(date, None)) + }) { "Delete Plan" } + } } } }, diff --git a/web/src/components/recipe_selection.rs b/web/src/components/recipe_selection.rs index 7eb379d..8c0f5d3 100644 --- a/web/src/components/recipe_selection.rs +++ b/web/src/components/recipe_selection.rs @@ -50,7 +50,7 @@ pub fn RecipeSelection<'ctx, G: Html>( .get() .recipe_counts .get(id_for_count.as_ref()) - .unwrap() + .unwrap_or(&0) }); let count = create_signal(cx, format!("{}", *current_count.get_untracked())); create_effect(cx, || {