mirror of
https://github.com/mealie-recipes/mealie.git
synced 2025-12-23 10:45:20 -05:00
fix: Consistant Shopping List Recipe State (#6758)
This commit is contained in:
@@ -6,7 +6,7 @@
|
|||||||
:title="$t('recipe.add-to-list')"
|
:title="$t('recipe.add-to-list')"
|
||||||
:icon="$globals.icons.cartCheck"
|
:icon="$globals.icons.cartCheck"
|
||||||
>
|
>
|
||||||
<v-container v-if="!shoppingListChoices.length">
|
<v-container v-if="!filteredShoppingLists.length">
|
||||||
<BasePageTitle>
|
<BasePageTitle>
|
||||||
<template #title>
|
<template #title>
|
||||||
{{ $t('shopping-list.no-shopping-lists-found') }}
|
{{ $t('shopping-list.no-shopping-lists-found') }}
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
</v-container>
|
</v-container>
|
||||||
<v-card-text>
|
<v-card-text>
|
||||||
<v-card
|
<v-card
|
||||||
v-for="list in shoppingListChoices"
|
v-for="list in filteredShoppingLists"
|
||||||
:key="list.id"
|
:key="list.id"
|
||||||
hover
|
hover
|
||||||
class="my-2 left-border"
|
class="my-2 left-border"
|
||||||
@@ -222,6 +222,10 @@ const api = useUserApi();
|
|||||||
const preferences = useShoppingListPreferences();
|
const preferences = useShoppingListPreferences();
|
||||||
const ready = ref(false);
|
const ready = ref(false);
|
||||||
|
|
||||||
|
// Capture values at initialization to avoid reactive updates
|
||||||
|
const currentHouseholdSlug = ref("");
|
||||||
|
const filteredShoppingLists = ref<ShoppingListSummary[]>([]);
|
||||||
|
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
shoppingListDialog: true,
|
shoppingListDialog: true,
|
||||||
shoppingListIngredientDialog: false,
|
shoppingListIngredientDialog: false,
|
||||||
@@ -230,31 +234,25 @@ const state = reactive({
|
|||||||
|
|
||||||
const { shoppingListDialog, shoppingListIngredientDialog, shoppingListShowAllToggled: _shoppingListShowAllToggled } = toRefs(state);
|
const { shoppingListDialog, shoppingListIngredientDialog, shoppingListShowAllToggled: _shoppingListShowAllToggled } = toRefs(state);
|
||||||
|
|
||||||
const userHousehold = computed(() => {
|
|
||||||
return $auth.user.value?.householdSlug || "";
|
|
||||||
});
|
|
||||||
|
|
||||||
const shoppingListChoices = computed(() => {
|
|
||||||
return props.shoppingLists.filter(list => preferences.value.viewAllLists || list.userId === $auth.user.value?.id);
|
|
||||||
});
|
|
||||||
|
|
||||||
const recipeIngredientSections = ref<ShoppingListRecipeIngredientSection[]>([]);
|
const recipeIngredientSections = ref<ShoppingListRecipeIngredientSection[]>([]);
|
||||||
const selectedShoppingList = ref<ShoppingListSummary | null>(null);
|
const selectedShoppingList = ref<ShoppingListSummary | null>(null);
|
||||||
|
|
||||||
watchEffect(
|
watch(dialog, (newVal, oldVal) => {
|
||||||
() => {
|
if (newVal && !oldVal) {
|
||||||
if (shoppingListChoices.value.length === 1 && !state.shoppingListShowAllToggled) {
|
currentHouseholdSlug.value = $auth.user.value?.householdSlug || "";
|
||||||
selectedShoppingList.value = shoppingListChoices.value[0];
|
filteredShoppingLists.value = props.shoppingLists.filter(
|
||||||
|
list => preferences.value.viewAllLists || list.userId === $auth.user.value?.id,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (filteredShoppingLists.value.length === 1 && !state.shoppingListShowAllToggled) {
|
||||||
|
selectedShoppingList.value = filteredShoppingLists.value[0];
|
||||||
openShoppingListIngredientDialog(selectedShoppingList.value);
|
openShoppingListIngredientDialog(selectedShoppingList.value);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ready.value = true;
|
ready.value = true;
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
);
|
else if (!newVal) {
|
||||||
|
|
||||||
watch(dialog, (val) => {
|
|
||||||
if (!val) {
|
|
||||||
initState();
|
initState();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -274,22 +272,26 @@ async function consolidateRecipesIntoSections(recipes: RecipeWithScale[]) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(recipe.id && recipe.name && recipe.recipeIngredient)) {
|
// Create a local copy to avoid mutating props
|
||||||
const { data } = await api.recipes.getOne(recipe.slug);
|
let recipeData = { ...recipe };
|
||||||
|
if (!(recipeData.id && recipeData.name && recipeData.recipeIngredient)) {
|
||||||
|
const { data } = await api.recipes.getOne(recipeData.slug);
|
||||||
if (!data?.recipeIngredient?.length) {
|
if (!data?.recipeIngredient?.length) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
recipe.id = data.id || "";
|
recipeData = {
|
||||||
recipe.name = data.name || "";
|
...recipeData,
|
||||||
recipe.recipeIngredient = data.recipeIngredient;
|
id: data.id || "",
|
||||||
|
name: data.name || "",
|
||||||
|
recipeIngredient: data.recipeIngredient,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
else if (!recipe.recipeIngredient.length) {
|
else if (!recipeData.recipeIngredient.length) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const shoppingListIngredients: ShoppingListIngredient[] = [];
|
const shoppingListIngredients: ShoppingListIngredient[] = [];
|
||||||
function flattenRecipeIngredients(ing: RecipeIngredient, parentTitle = ""): ShoppingListIngredient[] {
|
function flattenRecipeIngredients(ing: RecipeIngredient, parentTitle = ""): ShoppingListIngredient[] {
|
||||||
const householdsWithFood = ing.food?.householdsWithIngredientFood || [];
|
|
||||||
if (ing.referencedRecipe) {
|
if (ing.referencedRecipe) {
|
||||||
// Recursively flatten all ingredients in the referenced recipe
|
// Recursively flatten all ingredients in the referenced recipe
|
||||||
return (ing.referencedRecipe.recipeIngredient ?? []).flatMap((subIng) => {
|
return (ing.referencedRecipe.recipeIngredient ?? []).flatMap((subIng) => {
|
||||||
@@ -303,8 +305,9 @@ async function consolidateRecipesIntoSections(recipes: RecipeWithScale[]) {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Regular ingredient
|
// Regular ingredient
|
||||||
|
const householdsWithFood = ing.food?.householdsWithIngredientFood || [];
|
||||||
return [{
|
return [{
|
||||||
checked: !householdsWithFood.includes(userHousehold.value),
|
checked: !householdsWithFood.includes(currentHouseholdSlug.value),
|
||||||
ingredient: {
|
ingredient: {
|
||||||
...ing,
|
...ing,
|
||||||
title: ing.title || parentTitle,
|
title: ing.title || parentTitle,
|
||||||
@@ -313,7 +316,7 @@ async function consolidateRecipesIntoSections(recipes: RecipeWithScale[]) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
recipe.recipeIngredient.forEach((ing) => {
|
recipeData.recipeIngredient.forEach((ing) => {
|
||||||
const flattened = flattenRecipeIngredients(ing, "");
|
const flattened = flattenRecipeIngredients(ing, "");
|
||||||
shoppingListIngredients.push(...flattened);
|
shoppingListIngredients.push(...flattened);
|
||||||
});
|
});
|
||||||
@@ -343,7 +346,7 @@ async function consolidateRecipesIntoSections(recipes: RecipeWithScale[]) {
|
|||||||
|
|
||||||
// Store the on-hand ingredients for later
|
// Store the on-hand ingredients for later
|
||||||
const householdsWithFood = (ing.ingredient?.food?.householdsWithIngredientFood || []);
|
const householdsWithFood = (ing.ingredient?.food?.householdsWithIngredientFood || []);
|
||||||
if (householdsWithFood.includes(userHousehold.value)) {
|
if (householdsWithFood.includes(currentHouseholdSlug.value)) {
|
||||||
onHandIngs.push(ing);
|
onHandIngs.push(ing);
|
||||||
return sections;
|
return sections;
|
||||||
}
|
}
|
||||||
@@ -357,9 +360,9 @@ async function consolidateRecipesIntoSections(recipes: RecipeWithScale[]) {
|
|||||||
shoppingListIngredientSections[shoppingListIngredientSections.length - 1].ingredients.push(...onHandIngs);
|
shoppingListIngredientSections[shoppingListIngredientSections.length - 1].ingredients.push(...onHandIngs);
|
||||||
|
|
||||||
recipeSectionMap.set(recipe.slug, {
|
recipeSectionMap.set(recipe.slug, {
|
||||||
recipeId: recipe.id,
|
recipeId: recipeData.id,
|
||||||
recipeName: recipe.name,
|
recipeName: recipeData.name,
|
||||||
recipeScale: recipe.scale,
|
recipeScale: recipeData.scale,
|
||||||
ingredientSections: shoppingListIngredientSections,
|
ingredientSections: shoppingListIngredientSections,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user