Make amount for an ingredient optional.
This commit is contained in:
parent
3c9c94957f
commit
0dc2eb2e3c
4 changed files with 122 additions and 96 deletions
|
|
@ -3,25 +3,48 @@ import type {IngredientModel} from "../../models/IngredientModel"
|
||||||
import Button from "../basics/Button"
|
import Button from "../basics/Button"
|
||||||
import {ButtonType} from "../basics/BasicButtonDefinitions"
|
import {ButtonType} from "../basics/BasicButtonDefinitions"
|
||||||
|
|
||||||
/**
|
|
||||||
* Editor for handling the ingredient list
|
|
||||||
* Ingredients can be edited, added and removed
|
|
||||||
*/
|
|
||||||
type IngredientListEditorProps = {
|
type IngredientListEditorProps = {
|
||||||
ingredients: IngredientModel[]
|
ingredients: IngredientModel[]
|
||||||
onChange: (ingredients: IngredientModel[]) => void
|
onChange: (ingredients: IngredientModel[]) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Editor for handling the ingredient list
|
||||||
|
*
|
||||||
|
* Ingredients can be edited, added and removed
|
||||||
|
* @param ingredient List of IngredientModels describing the ingredient
|
||||||
|
* @param onChange Method to call on changing an ingredient.
|
||||||
|
*/
|
||||||
export function IngredientListEditor({ingredients, onChange}: IngredientListEditorProps) {
|
export function IngredientListEditor({ingredients, onChange}: IngredientListEditorProps) {
|
||||||
const handleUpdate = (index: number, field: keyof IngredientModel, value: string | number) => {
|
const handleUpdate = (
|
||||||
const updated = ingredients.map((ing, i) =>
|
index: number,
|
||||||
i === index ? {...ing, [field]: field === "amount" ? Number(value) : value} : ing
|
field: keyof IngredientModel,
|
||||||
)
|
value: string | number | undefined
|
||||||
onChange(updated)
|
) => {
|
||||||
|
const updated = ingredients.map((ing, i) => {
|
||||||
|
if (i !== index) return ing;
|
||||||
|
|
||||||
|
if (field === "amount") {
|
||||||
|
// Handle optional numeric value
|
||||||
|
if (value === undefined || value === "") {
|
||||||
|
const {amount, ...rest} = ing; // remove the field
|
||||||
|
return rest as IngredientModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// valid number
|
||||||
|
return {...ing, amount: Number(value)};
|
||||||
|
}
|
||||||
|
|
||||||
|
// handle other fields normally
|
||||||
|
return {...ing, [field]: value};
|
||||||
|
});
|
||||||
|
|
||||||
|
onChange(updated);
|
||||||
|
};
|
||||||
|
|
||||||
const handleAdd = () => {
|
const handleAdd = () => {
|
||||||
onChange([...ingredients, {name: "", amount: 0, unit: ""}])
|
onChange([...ingredients, {name: "", unit: ""}])
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleRemove = (index: number) => {
|
const handleRemove = (index: number) => {
|
||||||
|
|
@ -36,8 +59,11 @@ export function IngredientListEditor({ingredients, onChange}: IngredientListEdit
|
||||||
type="number"
|
type="number"
|
||||||
className="input-field"
|
className="input-field"
|
||||||
placeholder="Menge"
|
placeholder="Menge"
|
||||||
value={ing.amount}
|
value={ing.amount === undefined || ing.amount === null ? "" : ing.amount}
|
||||||
onChange={e => handleUpdate(index, "amount", e.target.value)}
|
onChange={e => {
|
||||||
|
const value = e.target.value;
|
||||||
|
handleUpdate(index, "amount", value === "" ? undefined : Number(value));
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
<input
|
<input
|
||||||
className="input-field w-20"
|
className="input-field w-20"
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,7 @@ export default function RecipeDetailPage() {
|
||||||
...ingGrp,
|
...ingGrp,
|
||||||
ingredientList: ingGrp.ingredientList.map((ing) => ({
|
ingredientList: ingGrp.ingredientList.map((ing) => ({
|
||||||
...ing,
|
...ing,
|
||||||
amount: ing.amount * factor,
|
amount: ing.amount !== undefined ? ing.amount * factor : ing.amount,
|
||||||
}))
|
}))
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
|
@ -121,7 +121,7 @@ export default function RecipeDetailPage() {
|
||||||
<ul className="default-list">
|
<ul className="default-list">
|
||||||
{group.ingredientList.map((ing, j) => (
|
{group.ingredientList.map((ing, j) => (
|
||||||
<li key={j}>
|
<li key={j}>
|
||||||
{ing.amount} {ing.unit ?? ""} {ing.name}
|
{ing.amount ?? ""} {ing.unit ?? ""} {ing.name}
|
||||||
</li>
|
</li>
|
||||||
))}
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import type { RecipeModel } from "../models/RecipeModel"
|
import type {RecipeModel} from "../models/RecipeModel"
|
||||||
import type { RecipeDto } from "../api/dtos/RecipeDto"
|
import type {RecipeDto} from "../api/dtos/RecipeDto"
|
||||||
import type { RecipeIngredientGroupDto } from "../api/dtos/RecipeIngredientGroupDto"
|
import type {RecipeIngredientGroupDto} from "../api/dtos/RecipeIngredientGroupDto"
|
||||||
import type { RecipeInstructionStepDto } from "../api/dtos/RecipeInstructionStepDto"
|
import type {RecipeInstructionStepDto} from "../api/dtos/RecipeInstructionStepDto"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maps a RecipeDto (as returned by the backend) to the Recipe model
|
* Maps a RecipeDto (as returned by the backend) to the Recipe model
|
||||||
|
|
@ -26,7 +26,7 @@ export function mapRecipeDtoToModel(dto: RecipeDto): RecipeModel {
|
||||||
* If, however, for some reason, it does not, add a UUID as sorting
|
* If, however, for some reason, it does not, add a UUID as sorting
|
||||||
* steps in teh GUI requires a unique identifier for each item.
|
* steps in teh GUI requires a unique identifier for each item.
|
||||||
*/
|
*/
|
||||||
internalId: step.id !== undefined? step.id : crypto.randomUUID()
|
internalId: step.id !== undefined ? step.id : crypto.randomUUID()
|
||||||
})
|
})
|
||||||
),
|
),
|
||||||
|
|
||||||
|
|
@ -40,7 +40,7 @@ export function mapRecipeDtoToModel(dto: RecipeDto): RecipeModel {
|
||||||
.map(ing => ({
|
.map(ing => ({
|
||||||
id: ing.id,
|
id: ing.id,
|
||||||
name: ing.name ?? "", // @todo ensure that name and amount are indeed present
|
name: ing.name ?? "", // @todo ensure that name and amount are indeed present
|
||||||
amount: ing.amount ?? 0,
|
amount: ing.amount,
|
||||||
unit: ing.unit,
|
unit: ing.unit,
|
||||||
//subtext: ing.subtext ?? undefined,
|
//subtext: ing.subtext ?? undefined,
|
||||||
})),
|
})),
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ export interface IngredientModel {
|
||||||
name: string
|
name: string
|
||||||
|
|
||||||
/** Quantity required (e.g. 200, 1.5) */
|
/** Quantity required (e.g. 200, 1.5) */
|
||||||
amount: number
|
amount?: number
|
||||||
|
|
||||||
/** Unit of measurement (e.g. "g", "tbsp", "cups").
|
/** Unit of measurement (e.g. "g", "tbsp", "cups").
|
||||||
* Optional for cases like "1 egg".
|
* Optional for cases like "1 egg".
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue