Add ingredient editor rows to recipe form - #1203
Merged
Merged
Conversation
dgee2
force-pushed
the
issue-1120-recipe-ingredient-editor
branch
from
August 3, 2026 08:19
47f8cb9 to
158d615
Compare
dgee2
force-pushed
the
issue-1120-recipe-ingredient-editor
branch
from
August 3, 2026 20:11
158d615 to
58cfda4
Compare
dgee2
force-pushed
the
issue-1120-recipe-ingredient-editor
branch
from
August 4, 2026 07:05
58cfda4 to
2b9be76
Compare
dgee2
force-pushed
the
issue-1120-recipe-ingredient-editor
branch
from
August 4, 2026 07:59
2b9be76 to
4c55d70
Compare
dgee2
marked this pull request as ready for review
August 4, 2026 18:46
Contributor
There was a problem hiding this comment.
Pull request overview
Adds an ingredient-row editing experience to the recipe creation form, aligning the UI with the recipe-editor epic by introducing reusable form atoms/molecules and Storybook coverage for validation and row operations.
Changes:
- Introduced a reusable
IngredientRowEditorcomponent and integrated it intonew-recipe-form.vueas an add/remove/reorderable ingredients list. - Added/updated form atoms (
TextFieldrules/type support, newNumberField) and wired up recipe metadata fields + form-level validation behavior (greedy). - Expanded Storybook stories and MSW handlers to cover new form behavior, validation, and error state rendering.
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| ui/menu-website/src/components/organisms/recipe/new-recipe-form.vue | Adds metadata fields, ingredients list editing, and submission logic integrated with the recipe service. |
| ui/menu-website/src/components/organisms/recipe/new-recipe-form.stories.ts | Adds Storybook interaction tests for validation, ingredient row add/remove/reorder, and submit failure UI. |
| ui/menu-website/src/components/molecules/recipe/ingredient-row-editor.vue | New ingredient row editor molecule with required-field validation and row controls. |
| ui/menu-website/src/components/molecules/recipe/ingredient-row-editor.stories.ts | Storybook coverage for rendering, editing, and control event emission/disabled states. |
| ui/menu-website/src/components/molecules/recipe/fields/recipe-name-field.vue | Adds required validation for recipe title and updates v-model typing. |
| ui/menu-website/src/components/atoms/form/text-field.vue | Extends text field to support rules and textarea mode; updates model typing to allow null. |
| ui/menu-website/src/components/atoms/form/number-field.vue | New number input atom with numeric coercion and validation rule support. |
| ui/menu-website/src/components/atoms/form/number-field.stories.ts | Storybook tests validating number field input, hint rendering, and prefilled values. |
| ui/menu-website/.storybook/msw-handlers.ts | Adds MSW handlers for recipe create success/error scenarios. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Adds a reusable IngredientRowEditor molecule (measure, ingredient, preparation, section, optional toggle) and wires it into new-recipe-form.vue as a dynamic list with add/remove/reorder controls, replacing the hardcoded empty ingredients array from the previous PR. Ingredient/measure text are required per row. Also adds `greedy` to the form's <q-form>: Quasar's QForm.validate() defaults to sequential validation that stops at the first invalid field, so without it only the first invalid row would ever show its error on submit, silently leaving other invalid rows unmarked. Part of #1100. Closes #1120.
dgee2
force-pushed
the
issue-1120-recipe-ingredient-editor
branch
from
August 4, 2026 18:58
4c55d70 to
80e5e39
Compare
Fixes Copilot review feedback on #1203: keying the reorderable ingredient list on array index caused Vue to reuse component instances (and their internal validation/focus state) for the wrong row after moveIngredient(). Each row now gets a stable crypto.randomUUID() rowId at creation, used as the v-for key; sortOrder is still recomputed from array position at submit time. Co-authored-by: Claude <noreply@anthropic.com>
|
dgee2
added a commit
that referenced
this pull request
Aug 4, 2026
Adds a rowId to step rows (matching the ingredient editor's pattern from #1203) so :key isn't the array index, which could cause Vue to misattribute DOM/validation state to the wrong row across a reorder. Also adds new-recipe-form unit tests asserting the submitted steps payload (fields, recomputed sortOrder, and that the internal rowId never leaks into the request), closing a gap flagged in review where this behavior was only covered by Storybook. Co-authored-by: Claude <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Summary
Adds a reusable
IngredientRowEditormolecule (measure, ingredient, preparation, section, optional toggle, plus reorder/remove controls) and wires it intonew-recipe-form.vueas a dynamic list, replacing the hardcoded emptyingredients: []from #1119.ingredientText/measureTextare required per row.sortOrderis recomputed from array index at submit time.greedyto the form's<q-form>: Quasar'sQForm.validate()defaults to sequential validation that stops at the first invalid field (confirmed by reading the Quasar source), so without it, submitting a form with multiple invalid fields (e.g. an empty title and an empty ingredient row) would only ever show the first error, silently leaving the rest unmarked.Test plan
pnpm build(type-check + production build)pnpm lintpnpm test:storybook— 21 files / 52 tests passing, including new stories for the row editor (render, edit, move-up/down disabled at boundaries, remove/reorder events) and form-level add/edit/remove/reorder/required-validation coveragegreedyfix)Part of #1100.
Closes #1120.