Sort out recipe saving

This commit is contained in:
Jeremy Wall 2023-02-04 12:06:16 -05:00
parent b95b297deb
commit 2f6375e381
3 changed files with 34 additions and 44 deletions

View File

@ -67,7 +67,6 @@ pub enum Message {
RemoveExtra(usize), RemoveExtra(usize),
UpdateExtra(usize, String, String), UpdateExtra(usize, String, String),
SaveRecipe(RecipeEntry, Option<Box<dyn FnOnce()>>), SaveRecipe(RecipeEntry, Option<Box<dyn FnOnce()>>),
SetRecipe(String, Recipe),
RemoveRecipe(String, Option<Box<dyn FnOnce()>>), RemoveRecipe(String, Option<Box<dyn FnOnce()>>),
UpdateCategory(String, String, Option<Box<dyn FnOnce()>>), UpdateCategory(String, String, Option<Box<dyn FnOnce()>>),
ResetInventory, ResetInventory,
@ -101,9 +100,6 @@ impl Debug for Message {
.field(arg2) .field(arg2)
.finish(), .finish(),
Self::SaveRecipe(arg0, _) => f.debug_tuple("SaveRecipe").field(arg0).finish(), Self::SaveRecipe(arg0, _) => f.debug_tuple("SaveRecipe").field(arg0).finish(),
Self::SetRecipe(arg0, arg1) => {
f.debug_tuple("SetRecipe").field(arg0).field(arg1).finish()
}
Self::RemoveRecipe(arg0, _) => f.debug_tuple("SetCategoryMap").field(arg0).finish(), Self::RemoveRecipe(arg0, _) => f.debug_tuple("SetCategoryMap").field(arg0).finish(),
Self::UpdateCategory(i, c, _) => { Self::UpdateCategory(i, c, _) => {
f.debug_tuple("UpdateCategory").field(i).field(c).finish() f.debug_tuple("UpdateCategory").field(i).field(c).finish()
@ -197,7 +193,7 @@ impl StateMachine {
entry entry
.category() .category()
.cloned() .cloned()
.unwrap_or_else(|| "Unknown".to_owned()), .unwrap_or_else(|| "Entree".to_owned()),
) )
}) })
.collect::<BTreeMap<String, String>>(); .collect::<BTreeMap<String, String>>();
@ -357,22 +353,29 @@ impl MessageMapper<Message, AppState> for StateMachine {
&original_copy.extras, &original_copy.extras,
)) ))
} }
Message::SetRecipe(id, recipe) => {
original_copy.recipes.insert(id, recipe);
}
Message::SaveRecipe(entry, callback) => { Message::SaveRecipe(entry, callback) => {
let recipe = let recipe =
parse::as_recipe(entry.recipe_text()).expect("Failed to parse RecipeEntry"); parse::as_recipe(entry.recipe_text()).expect("Failed to parse RecipeEntry");
original_copy original_copy
.recipes .recipes
.insert(entry.recipe_id().to_owned(), recipe); .insert(entry.recipe_id().to_owned(), recipe);
original_copy if !original_copy.recipe_counts.contains_key(entry.recipe_id()) {
.recipe_counts original_copy
.insert(entry.recipe_id().to_owned(), 0); .recipe_counts
.insert(entry.recipe_id().to_owned(), 0);
}
if let Some(cat) = entry.category().cloned() {
original_copy
.recipe_categories
.entry(entry.recipe_id().to_owned())
.and_modify(|c| *c = cat.clone())
.or_insert(cat);
}
let store = self.store.clone(); let store = self.store.clone();
self.local_store.set_recipe_entry(&entry); self.local_store.set_recipe_entry(&entry);
spawn_local_scoped(cx, async move { spawn_local_scoped(cx, async move {
if let Err(e) = store.store_recipes(vec![entry]).await { if let Err(e) = store.store_recipes(vec![entry]).await {
// FIXME(jwall): We should have a global way to trigger error messages
error!(err=?e, "Unable to save Recipe"); error!(err=?e, "Unable to save Recipe");
} }
callback.map(|f| f()); callback.map(|f| f());

View File

@ -72,7 +72,14 @@ pub fn Editor<'ctx, G: Html>(cx: Scope<'ctx>, props: RecipeComponentProps<'ctx>)
let id = create_memo(cx, || recipe.get().recipe_id().to_owned()); let id = create_memo(cx, || recipe.get().recipe_id().to_owned());
let dirty = create_signal(cx, false); let dirty = create_signal(cx, false);
let ts = create_signal(cx, js_lib::get_ms_timestamp()); let ts = create_signal(cx, js_lib::get_ms_timestamp());
let category = create_signal(cx, recipe.get().category().cloned().unwrap_or_default()); let category = create_signal(
cx,
recipe
.get()
.category()
.cloned()
.unwrap_or_else(|| "Entree".to_owned()),
);
debug!("creating editor view"); debug!("creating editor view");
view! {cx, view! {cx,
@ -103,40 +110,21 @@ pub fn Editor<'ctx, G: Html>(cx: Scope<'ctx>, props: RecipeComponentProps<'ctx>)
return; return;
} }
debug!("Recipe text is changed"); debug!("Recipe text is changed");
spawn_local_scoped(cx, { let category = category.get_untracked();
let store = crate::api::HttpStore::get_from_context(cx); let category = if category.is_empty() {
let category = category.get_untracked(); None
let category = if category.is_empty() { } else {
None Some(category.as_ref().clone())
} else { };
Some(category.as_ref().clone()) let recipe_entry = RecipeEntry(
};
async move {
debug!("Attempting to save recipe");
if let Err(e) = store
.store_recipes(vec![RecipeEntry(
id.get_untracked().as_ref().clone(), id.get_untracked().as_ref().clone(),
text.get_untracked().as_ref().clone(), text.get_untracked().as_ref().clone(),
category, category,
)]) );
.await sh.dispatch(cx, Message::SaveRecipe(recipe_entry, None));
{ dirty.set(false);
error!(?e, "Failed to save recipe");
error_text.set(format!("{:?}", e));
} else {
// We also need to set recipe in our state
dirty.set(false);
if let Ok(recipe) = recipes::parse::as_recipe(text.get_untracked().as_ref()) {
sh.dispatch(
cx,
Message::SetRecipe(id.get_untracked().as_ref().to_owned(), recipe),
);
}
};
}
});
} else {
} }
// TODO(jwall): Show error message if trying to save when recipe doesn't parse.
}) { "Save" } " " }) { "Save" } " "
span(role="button", on:click=move |_| { span(role="button", on:click=move |_| {
sh.dispatch(cx, Message::RemoveRecipe(id.get_untracked().as_ref().to_owned(), Some(Box::new(|| sycamore_router::navigate("/ui/planning/plan"))))); sh.dispatch(cx, Message::RemoveRecipe(id.get_untracked().as_ref().to_owned(), Some(Box::new(|| sycamore_router::navigate("/ui/planning/plan")))));

View File

@ -14,7 +14,6 @@ use std::collections::BTreeMap;
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
use recipes::Recipe; use recipes::Recipe;
use reqwasm::websocket::State;
use sycamore::prelude::*; use sycamore::prelude::*;
use tracing::{debug, instrument}; use tracing::{debug, instrument};
@ -39,7 +38,7 @@ pub fn CategoryGroup<'ctx, G: Html>(
row_size, row_size,
}: CategoryGroupProps<'ctx>, }: CategoryGroupProps<'ctx>,
) -> View<G> { ) -> View<G> {
let rows = sh.get_selector(cx, move |state| { let rows = create_signal(cx, {
let mut rows = Vec::new(); let mut rows = Vec::new();
for row in recipes for row in recipes
.iter() .iter()