From f35739e732282d0ec70d40a96a00014cf9ef4fcc Mon Sep 17 00:00:00 2001 From: jableader Date: Sun, 2 Nov 2025 19:41:33 +1100 Subject: [PATCH] ingredient debounce --- frontend-spec.md | 8 ++ .../ingredients/EditableIngredientsPanel.vue | 4 + src/components/ingredients/IngredientLine.vue | 16 ++++ src/components/meals/EditMealPage.vue | 96 ++++++++++++++++--- 4 files changed, 109 insertions(+), 15 deletions(-) diff --git a/frontend-spec.md b/frontend-spec.md index 91aaa40..ce641f1 100644 --- a/frontend-spec.md +++ b/frontend-spec.md @@ -303,3 +303,11 @@ Google OAuth is planned next. - Remove now-unused legacy stubs from SDK/composable in a cleanup pass (non-functional, safe to delete). - Remove the legacy username login shim (`login(username: string)`) and any fallback UI; standardize on email/password (and Google) only. - Rollout flag: default `VUE_APP_MULTITENANT_ENABLED` to true across environments and plan removal of legacy flat routes and related tests once stable. + +--- + +## Ingredients & Sides UX (Updated Nov 2, 2025) + +- Controlled inputs: The parent meal edit page owns the latest extra ingredient line text immediately as the user types. Preview parsing still occurs on blur/Enter. +- Partial parse on Save: Only lines edited since the last parse are sent to `GET /ingredients/parse?lines=...`. Existing parsed lines are not re-parsed. Empty rows are dropped and a final guard filters zero-quantity items. +- Outcome: You can click Save mid-typing without losing changes or hitting validation errors, and we avoid unnecessary parsing work. diff --git a/src/components/ingredients/EditableIngredientsPanel.vue b/src/components/ingredients/EditableIngredientsPanel.vue index 1af3050..31aeaa5 100644 --- a/src/components/ingredients/EditableIngredientsPanel.vue +++ b/src/components/ingredients/EditableIngredientsPanel.vue @@ -38,6 +38,7 @@

@@ -73,11 +74,13 @@ const emit = defineEmits<{ (e: 'on-add'): void (e: 'on-delete', ingredient: Ingredient): void (e: 'on-update-ingredient', ingredient: Ingredient, newIngredient: Ingredient): void + (e: 'on-update-line', ingredient: Ingredient, newLine: string): void (e: 'on-editing', isEditing: boolean): void }>() const editing = ref(props.editOnly ?? false) + async function updateProduct(): Promise { // parseProduct is not available in v2 API; ignore for now } @@ -92,6 +95,7 @@ function toggleEditing() { editing.value = !editing.value emit('on-editing', editing.value) } +