mirror of
https://github.com/hay-kot/mealie.git
synced 2025-08-21 05:53:36 -07:00
feat: group recipe ingredients by section titles
Group ingredients under their respective section titles in the recipe page, improving organization and clarity. Added logic to compute and map section titles for used and unused ingredients. Updated related components to display grouped ingredients accordingly.
This commit is contained in:
parent
591c96e52b
commit
fa72b808b2
3 changed files with 99 additions and 15 deletions
|
@ -29,32 +29,49 @@
|
|||
{{ activeText }}
|
||||
</p>
|
||||
<v-divider class="mb-4" />
|
||||
<v-checkbox-btn
|
||||
v-for="ing in unusedIngredients"
|
||||
:key="ing.referenceId"
|
||||
v-model="activeRefs"
|
||||
:value="ing.referenceId"
|
||||
>
|
||||
<template #label>
|
||||
<RecipeIngredientHtml :markup="parseIngredientText(ing)" />
|
||||
</template>
|
||||
</v-checkbox-btn>
|
||||
|
||||
<template v-if="usedIngredients.length > 0">
|
||||
<template v-if="Object.keys(groupedUnusedIngredients).length > 0">
|
||||
<h4 class="py-3 ml-1">
|
||||
{{ $t("recipe.linked-to-other-step") }}
|
||||
{{ $t("recipe.unlinked") }}
|
||||
</h4>
|
||||
<template v-for="(ingredients, title) in groupedUnusedIngredients" :key="title">
|
||||
<h4 v-if="title" class="py-3 ml-1 pl-4">
|
||||
{{ title }}
|
||||
</h4>
|
||||
<v-checkbox-btn
|
||||
v-for="ing in usedIngredients"
|
||||
v-for="ing in ingredients"
|
||||
:key="ing.referenceId"
|
||||
v-model="activeRefs"
|
||||
:value="ing.referenceId"
|
||||
class="ml-4"
|
||||
>
|
||||
<template #label>
|
||||
<RecipeIngredientHtml :markup="parseIngredientText(ing)" />
|
||||
</template>
|
||||
</v-checkbox-btn>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<template v-if="Object.keys(groupedUsedIngredients).length > 0">
|
||||
<h4 class="py-3 ml-1">
|
||||
{{ $t("recipe.linked-to-other-step") }}
|
||||
</h4>
|
||||
<template v-for="(ingredients, title) in groupedUsedIngredients" :key="title">
|
||||
<h4 v-if="title" class="py-3 ml-1 pl-4">
|
||||
{{ title }}
|
||||
</h4>
|
||||
<v-checkbox-btn
|
||||
v-for="ing in ingredients"
|
||||
:key="ing.referenceId"
|
||||
v-model="activeRefs"
|
||||
:value="ing.referenceId"
|
||||
class="ml-4"
|
||||
>
|
||||
<template #label>
|
||||
<RecipeIngredientHtml :markup="parseIngredientText(ing)" />
|
||||
</template>
|
||||
</v-checkbox-btn>
|
||||
</template>
|
||||
</template>
|
||||
</v-card-text>
|
||||
|
||||
<v-divider />
|
||||
|
@ -565,6 +582,71 @@ const ingredientLookup = computed(() => {
|
|||
}, results);
|
||||
});
|
||||
|
||||
// Map each ingredient's referenceId to its section title
|
||||
const ingredientSectionTitles = computed(() => {
|
||||
const titleMap: { [key: string]: string } = {};
|
||||
let currentTitle = "";
|
||||
|
||||
// Go through all ingredients in order
|
||||
props.recipe.recipeIngredient.forEach((ingredient) => {
|
||||
if (ingredient.referenceId === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If this ingredient has a title, update the current title
|
||||
if (ingredient.title) {
|
||||
currentTitle = ingredient.title;
|
||||
}
|
||||
|
||||
// Assign the current title to this ingredient
|
||||
titleMap[ingredient.referenceId] = currentTitle;
|
||||
});
|
||||
|
||||
return titleMap;
|
||||
});
|
||||
|
||||
const groupedUnusedIngredients = computed(() => {
|
||||
const groups: { [key: string]: RecipeIngredient[] } = {};
|
||||
|
||||
// Group ingredients by section title
|
||||
unusedIngredients.value.forEach((ingredient) => {
|
||||
if (ingredient.referenceId === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Use the section title from the mapping, or fallback to the ingredient's own title
|
||||
const title = ingredientSectionTitles.value[ingredient.referenceId] || ingredient.title || "";
|
||||
|
||||
if (!groups[title]) {
|
||||
groups[title] = [];
|
||||
}
|
||||
groups[title].push(ingredient);
|
||||
});
|
||||
|
||||
return groups;
|
||||
});
|
||||
|
||||
const groupedUsedIngredients = computed(() => {
|
||||
const groups: { [key: string]: RecipeIngredient[] } = {};
|
||||
|
||||
// Group ingredients by section title
|
||||
usedIngredients.value.forEach((ingredient) => {
|
||||
if (ingredient.referenceId === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Use the section title from the mapping, or fallback to the ingredient's own title
|
||||
const title = ingredientSectionTitles.value[ingredient.referenceId] || ingredient.title || "";
|
||||
|
||||
if (!groups[title]) {
|
||||
groups[title] = [];
|
||||
}
|
||||
groups[title].push(ingredient);
|
||||
});
|
||||
|
||||
return groups;
|
||||
});
|
||||
|
||||
function getIngredientByRefId(refId: string | undefined) {
|
||||
if (refId === undefined) {
|
||||
return "";
|
||||
|
|
|
@ -37,7 +37,7 @@ function useUnitName(unit: CreateIngredientUnit | IngredientUnit | undefined, us
|
|||
}
|
||||
|
||||
export function useParsedIngredientText(ingredient: RecipeIngredient, scale = 1, includeFormating = true) {
|
||||
const { quantity, food, unit, note } = ingredient;
|
||||
const { quantity, food, unit, note, title } = ingredient;
|
||||
const usePluralUnit = quantity !== undefined && ((quantity || 0) * scale > 1 || (quantity || 0) * scale === 0);
|
||||
const usePluralFood = (!quantity) || quantity * scale > 1;
|
||||
|
||||
|
@ -66,6 +66,7 @@ export function useParsedIngredientText(ingredient: RecipeIngredient, scale = 1,
|
|||
const foodName = useFoodName(food || undefined, usePluralFood);
|
||||
|
||||
return {
|
||||
title: title ? sanitizeIngredientHTML(title) : undefined,
|
||||
quantity: returnQty ? sanitizeIngredientHTML(returnQty) : undefined,
|
||||
unit: unitName && quantity ? sanitizeIngredientHTML(unitName) : undefined,
|
||||
name: foodName ? sanitizeIngredientHTML(foodName) : undefined,
|
||||
|
|
|
@ -559,6 +559,7 @@
|
|||
"see-original-text": "See Original Text",
|
||||
"original-text-with-value": "Original Text: {originalText}",
|
||||
"ingredient-linker": "Ingredient Linker",
|
||||
"unlinked": "Not linked yet",
|
||||
"linked-to-other-step": "Linked to other step",
|
||||
"auto": "Auto",
|
||||
"cook-mode": "Cook Mode",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue