Sort the shopping list by category.

Completes issue #6
This commit is contained in:
Jeremy Wall 2022-04-29 16:19:26 -04:00
parent 5df20b1d23
commit 27d4f3cd28
2 changed files with 27 additions and 16 deletions

View File

@ -13,9 +13,8 @@
// limitations under the License. // limitations under the License.
use crate::service::AppService; use crate::service::AppService;
use std::collections::HashMap; use std::collections::HashMap;
use std::collections::{BTreeMap, BTreeSet, HashSet}; use std::collections::{BTreeMap, HashSet};
use recipes::{Ingredient, IngredientKey};
use sycamore::{context::use_context, prelude::*}; use sycamore::{context::use_context, prelude::*};
#[component(ShoppingList<G>)] #[component(ShoppingList<G>)]
@ -28,12 +27,16 @@ pub fn shopping_list() -> View<G> {
ingredients_map.set(app_service.get_shopping_list()); ingredients_map.set(app_service.get_shopping_list());
})); }));
let ingredients = create_memo(cloned!((ingredients_map, filtered_keys) => move || { let ingredients = create_memo(cloned!((ingredients_map, filtered_keys) => move || {
ingredients_map let mut ingredients = Vec::new();
.get() // This has the effect of sorting the ingredients by category
.iter() for (_, ingredients_list) in ingredients_map.get().iter() {
.map(|(k, v)| (k.clone(), v.clone())) for (i, recipes) in ingredients_list.iter() {
.filter(|(k, _v)| !filtered_keys.get().contains(k)) if !filtered_keys.get().contains(&i.key()) {
.collect::<Vec<(IngredientKey, (Ingredient, BTreeSet<String>))>>() ingredients.push((i.key(), (i.clone(), recipes.clone())));
}
}
}
ingredients
})); }));
let table_view = Signal::new(View::empty()); let table_view = Signal::new(View::empty());
create_effect( create_effect(

View File

@ -19,7 +19,7 @@ use reqwasm::http;
use sycamore::prelude::*; use sycamore::prelude::*;
use web_sys::{window, Storage}; use web_sys::{window, Storage};
use recipes::{parse, Ingredient, IngredientAccumulator, IngredientKey, Recipe}; use recipes::{parse, Ingredient, IngredientAccumulator, Recipe};
#[derive(Clone)] #[derive(Clone)]
pub struct AppService { pub struct AppService {
@ -179,7 +179,7 @@ impl AppService {
self.recipes.get().get(idx).map(|(_, r)| r.clone()) self.recipes.get().get(idx).map(|(_, r)| r.clone())
} }
pub fn get_shopping_list(&self) -> BTreeMap<IngredientKey, (Ingredient, BTreeSet<String>)> { pub fn get_shopping_list(&self) -> BTreeMap<String, Vec<(Ingredient, BTreeSet<String>)>> {
let mut acc = IngredientAccumulator::new(); let mut acc = IngredientAccumulator::new();
let recipe_counts = self.menu_list.get(); let recipe_counts = self.menu_list.get();
for (idx, count) in recipe_counts.iter() { for (idx, count) in recipe_counts.iter() {
@ -191,16 +191,24 @@ impl AppService {
acc.accumulate_from(staples); acc.accumulate_from(staples);
} }
let mut ingredients = acc.ingredients(); let mut ingredients = acc.ingredients();
let mut groups = BTreeMap::new();
self.category_map.get().as_ref().as_ref().map(|cm| { self.category_map.get().as_ref().as_ref().map(|cm| {
for (_, (i, _)) in ingredients.iter_mut() { for (_, (i, recipes)) in ingredients.iter_mut() {
if let Some(cat) = cm.get(&i.name) { let category = if let Some(cat) = cm.get(&i.name) {
i.category = cat.clone(); cat.clone()
} } else {
"other".to_owned()
};
i.category = category.clone();
groups
.entry(category)
.or_insert(vec![])
.push((i.clone(), recipes.clone()));
} }
}); });
console_debug!("{:?}", self.category_map); console_debug!("{:?}", self.category_map);
// TODO(jwall): Sort by categories and names. // FIXM(jwall): Sort by categories and names.
ingredients groups
} }
pub fn set_recipe_count_by_index(&mut self, i: usize, count: usize) { pub fn set_recipe_count_by_index(&mut self, i: usize, count: usize) {