Fix missing state for extra ingredients

This commit is contained in:
Jeremy Wall 2022-10-25 15:44:56 -04:00
parent e77af193aa
commit 29b92e5e12
2 changed files with 26 additions and 20 deletions

View File

@ -37,6 +37,7 @@ impl Default for Routes {
pub struct State { pub struct State {
pub recipe_counts: RcSignal<BTreeMap<String, usize>>, pub recipe_counts: RcSignal<BTreeMap<String, usize>>,
pub extras: RcSignal<Vec<(usize, (RcSignal<String>, RcSignal<String>))>>,
pub staples: RcSignal<Option<Recipe>>, pub staples: RcSignal<Option<Recipe>>,
pub recipes: RcSignal<BTreeMap<String, Recipe>>, pub recipes: RcSignal<BTreeMap<String, Recipe>>,
pub category_map: RcSignal<BTreeMap<String, String>>, pub category_map: RcSignal<BTreeMap<String, String>>,
@ -46,6 +47,7 @@ impl State {
pub fn new() -> Self { pub fn new() -> Self {
Self { Self {
recipe_counts: create_rc_signal(BTreeMap::new()), recipe_counts: create_rc_signal(BTreeMap::new()),
extras: create_rc_signal(Vec::new()),
staples: create_rc_signal(None), staples: create_rc_signal(None),
recipes: create_rc_signal(BTreeMap::new()), recipes: create_rc_signal(BTreeMap::new()),
category_map: create_rc_signal(BTreeMap::new()), category_map: create_rc_signal(BTreeMap::new()),

View File

@ -71,11 +71,15 @@ fn make_ingredients_rows<'ctx, G: Html>(
fn make_extras_rows<'ctx, G: Html>( fn make_extras_rows<'ctx, G: Html>(
cx: Scope<'ctx>, cx: Scope<'ctx>,
extras: &'ctx Signal<Vec<(usize, (&'ctx Signal<String>, &'ctx Signal<String>))>>, extras: RcSignal<Vec<(usize, (RcSignal<String>, RcSignal<String>))>>,
) -> View<G> { ) -> View<G> {
let extras_read_signal = create_memo(cx, {
let extras = extras.clone();
move || extras.get().as_ref().clone()
});
view! {cx, view! {cx,
Indexed( Indexed(
iterable=extras, iterable=extras_read_signal,
view= move |cx, (idx, (amt, name))| { view= move |cx, (idx, (amt, name))| {
view! {cx, view! {cx,
tr { tr {
@ -83,13 +87,15 @@ fn make_extras_rows<'ctx, G: Html>(
input(bind:value=amt, type="text") input(bind:value=amt, type="text")
} }
td { td {
input(type="button", class="no-print destructive", value="X", on:click=move |_| { input(type="button", class="no-print destructive", value="X", on:click={
extras.set(extras.get().iter() let extras = extras.clone();
.filter(|(i, _)| *i != idx) move |_| {
.map(|(_, v)| v.clone()) extras.set(extras.get().iter()
.enumerate() .filter(|(i, _)| *i != idx)
.collect()) .map(|(_, v)| v.clone())
}) .enumerate()
.collect())
}})
} }
td { td {
input(bind:value=name, type="text") input(bind:value=name, type="text")
@ -106,7 +112,7 @@ fn make_shopping_table<'ctx, G: Html>(
cx: Scope<'ctx>, cx: Scope<'ctx>,
ingredients: &'ctx ReadSignal<Vec<(IngredientKey, (Ingredient, BTreeSet<String>))>>, ingredients: &'ctx ReadSignal<Vec<(IngredientKey, (Ingredient, BTreeSet<String>))>>,
modified_amts: &'ctx Signal<BTreeMap<IngredientKey, RcSignal<String>>>, modified_amts: &'ctx Signal<BTreeMap<IngredientKey, RcSignal<String>>>,
extras: &'ctx Signal<Vec<(usize, (&'ctx Signal<String>, &'ctx Signal<String>))>>, extras: RcSignal<Vec<(usize, (RcSignal<String>, RcSignal<String>))>>,
filtered_keys: RcSignal<BTreeSet<IngredientKey>>, filtered_keys: RcSignal<BTreeSet<IngredientKey>>,
) -> View<G> { ) -> View<G> {
let extra_rows_view = make_extras_rows(cx, extras); let extra_rows_view = make_extras_rows(cx, extras);
@ -133,10 +139,6 @@ fn make_shopping_table<'ctx, G: Html>(
pub fn ShoppingList<G: Html>(cx: Scope) -> View<G> { pub fn ShoppingList<G: Html>(cx: Scope) -> View<G> {
let filtered_keys: RcSignal<BTreeSet<IngredientKey>> = create_rc_signal(BTreeSet::new()); let filtered_keys: RcSignal<BTreeSet<IngredientKey>> = create_rc_signal(BTreeSet::new());
let ingredients_map = create_rc_signal(BTreeMap::new()); let ingredients_map = create_rc_signal(BTreeMap::new());
let extras = create_signal(
cx,
Vec::<(usize, (&Signal<String>, &Signal<String>))>::new(),
);
let modified_amts = create_signal(cx, BTreeMap::new()); let modified_amts = create_signal(cx, BTreeMap::new());
let show_staples = create_signal(cx, true); let show_staples = create_signal(cx, true);
create_effect(cx, { create_effect(cx, {
@ -166,13 +168,14 @@ pub fn ShoppingList<G: Html>(cx: Scope) -> View<G> {
let table_view = create_signal(cx, View::empty()); let table_view = create_signal(cx, View::empty());
create_effect(cx, { create_effect(cx, {
let filtered_keys = filtered_keys.clone(); let filtered_keys = filtered_keys.clone();
let state = crate::app_state::State::get_from_context(cx);
move || { move || {
if (ingredients.get().len() > 0) || (extras.get().len() > 0) { if (ingredients.get().len() > 0) || (state.extras.get().len() > 0) {
table_view.set(make_shopping_table( table_view.set(make_shopping_table(
cx, cx,
ingredients, ingredients,
modified_amts.clone(), modified_amts.clone(),
extras.clone(), state.extras.clone(),
filtered_keys.clone(), filtered_keys.clone(),
)); ));
} else { } else {
@ -180,15 +183,16 @@ pub fn ShoppingList<G: Html>(cx: Scope) -> View<G> {
} }
} }
}); });
let state = crate::app_state::State::get_from_context(cx);
view! {cx, view! {cx,
h1 { "Shopping List " } h1 { "Shopping List " }
label(for="show_staples_cb") { "Show staples" } label(for="show_staples_cb") { "Show staples" }
input(id="show_staples_cb", type="checkbox", bind:checked=show_staples) input(id="show_staples_cb", type="checkbox", bind:checked=show_staples)
(table_view.get().as_ref().clone()) (table_view.get().as_ref().clone())
input(type="button", value="Add Item", class="no-print", on:click=move |_| { input(type="button", value="Add Item", class="no-print", on:click=move |_| {
let mut cloned_extras: Vec<(&Signal<String>, &Signal<String>)> = (*extras.get()).iter().map(|(_, tpl)| *tpl).collect(); let mut cloned_extras: Vec<(RcSignal<String>, RcSignal<String>)> = (*state.extras.get()).iter().map(|(_, tpl)| tpl.clone()).collect();
cloned_extras.push((create_signal(cx, "".to_owned()), create_signal(cx, "".to_owned()))); cloned_extras.push((create_rc_signal("".to_owned()), create_rc_signal("".to_owned())));
extras.set(cloned_extras.drain(0..).enumerate().collect()); state.extras.set(cloned_extras.drain(0..).enumerate().collect());
}) })
input(type="button", value="Reset", class="no-print", on:click={ input(type="button", value="Reset", class="no-print", on:click={
let state = crate::app_state::State::get_from_context(cx); let state = crate::app_state::State::get_from_context(cx);
@ -198,7 +202,7 @@ pub fn ShoppingList<G: Html>(cx: Scope) -> View<G> {
// clear the filter_signal // clear the filter_signal
filtered_keys.set(BTreeSet::new()); filtered_keys.set(BTreeSet::new());
modified_amts.set(BTreeMap::new()); modified_amts.set(BTreeMap::new());
extras.set(Vec::new()); state.extras.set(Vec::new());
} }
}) })
} }