RecipeIngredientEditor use v-model instead of prop and turn into script setup

This commit is contained in:
Kuchenpirat 2025-06-19 10:10:02 +00:00
commit d1b892ec9b
2 changed files with 69 additions and 99 deletions

View file

@ -34,7 +34,7 @@
<RecipePageEditorToolbar v-if="isEditForm" v-model="recipe" /> <RecipePageEditorToolbar v-if="isEditForm" v-model="recipe" />
</div> </div>
<div> <div>
<RecipePageIngredientEditor v-if="isEditForm" :recipe="recipe" /> <RecipePageIngredientEditor v-if="isEditForm" v-model="recipe" />
</div> </div>
<div> <div>
<RecipePageScale v-model:scale="scale" :recipe="recipe" /> <RecipePageScale v-model:scale="scale" :recipe="recipe" />

View file

@ -77,65 +77,48 @@
</div> </div>
</template> </template>
<script lang="ts"> <script setup lang="ts">
import { VueDraggable } from "vue-draggable-plus"; import { VueDraggable } from "vue-draggable-plus";
import { usePageState, usePageUser } from "~/composables/recipe-page/shared-state";
import type { NoUndefinedField } from "~/lib/api/types/non-generated"; import type { NoUndefinedField } from "~/lib/api/types/non-generated";
import type { Recipe } from "~/lib/api/types/recipe"; import type { Recipe } from "~/lib/api/types/recipe";
import RecipeIngredientEditor from "~/components/Domain/Recipe/RecipeIngredientEditor.vue"; import RecipeIngredientEditor from "~/components/Domain/Recipe/RecipeIngredientEditor.vue";
import RecipeDialogBulkAdd from "~/components/Domain/Recipe/RecipeDialogBulkAdd.vue"; import RecipeDialogBulkAdd from "~/components/Domain/Recipe/RecipeDialogBulkAdd.vue";
import { uuid4 } from "~/composables/use-utils"; import { uuid4 } from "~/composables/use-utils";
export default defineNuxtComponent({ const recipe = defineModel<NoUndefinedField<Recipe>>({ required: true });
components: { const i18n = useI18n();
VueDraggable, const $auth = useMealieAuth();
RecipeDialogBulkAdd,
RecipeIngredientEditor,
},
props: {
recipe: {
type: Object as () => NoUndefinedField<Recipe>,
required: true,
},
},
setup(props) {
const { user } = usePageUser();
const { imageKey } = usePageState(props.recipe.slug);
const i18n = useI18n();
const $auth = useMealieAuth(); // Using useMealieAuth directly
const drag = ref(false); const drag = ref(false);
const route = useRoute(); const route = useRoute();
// Note: $auth.user is a ref, so we need to use .value to access its properties const groupSlug = computed(() => route.params.groupSlug as string || $auth.user.value?.groupSlug || "");
const groupSlug = computed(() => route.params.groupSlug as string || $auth.user.value?.groupSlug || "");
const hasFoodOrUnit = computed(() => { const hasFoodOrUnit = computed(() => {
if (!props.recipe) { if (!recipe.value) {
return false; return false;
} }
if (props.recipe.recipeIngredient) { if (recipe.value.recipeIngredient) {
for (const ingredient of props.recipe.recipeIngredient) { for (const ingredient of recipe.value.recipeIngredient) {
if (ingredient.food || ingredient.unit) { if (ingredient.food || ingredient.unit) {
return true; return true;
} }
} }
} }
return false; return false;
}); });
const parserToolTip = computed(() => { const parserToolTip = computed(() => {
if (props.recipe.settings.disableAmount) { if (recipe.value.settings.disableAmount) {
return i18n.t("recipe.enable-ingredient-amounts-to-use-this-feature"); return i18n.t("recipe.enable-ingredient-amounts-to-use-this-feature");
} }
else if (hasFoodOrUnit.value) { else if (hasFoodOrUnit.value) {
return i18n.t("recipe.recipes-with-units-or-foods-defined-cannot-be-parsed"); return i18n.t("recipe.recipes-with-units-or-foods-defined-cannot-be-parsed");
} }
return i18n.t("recipe.parse-ingredients"); return i18n.t("recipe.parse-ingredients");
}); });
function addIngredient(ingredients: Array<string> | null = null) { function addIngredient(ingredients: Array<string> | null = null) {
if (ingredients?.length) { if (ingredients?.length) {
const newIngredients = ingredients.map((x) => { const newIngredients = ingredients.map((x) => {
return { return {
@ -151,11 +134,11 @@ export default defineNuxtComponent({
if (newIngredients) { if (newIngredients) {
// @ts-expect-error - prop can be null-type by NoUndefinedField type forces it to be set // @ts-expect-error - prop can be null-type by NoUndefinedField type forces it to be set
props.recipe.recipeIngredient.push(...newIngredients); recipe.value.recipeIngredient.push(...newIngredients);
} }
} }
else { else {
props.recipe.recipeIngredient.push({ recipe.value.recipeIngredient.push({
referenceId: uuid4(), referenceId: uuid4(),
title: "", title: "",
note: "", note: "",
@ -167,10 +150,10 @@ export default defineNuxtComponent({
quantity: 1, quantity: 1,
}); });
} }
} }
function insertNewIngredient(dest: number) { function insertNewIngredient(dest: number) {
props.recipe.recipeIngredient.splice(dest, 0, { recipe.value.recipeIngredient.splice(dest, 0, {
referenceId: uuid4(), referenceId: uuid4(),
title: "", title: "",
note: "", note: "",
@ -181,18 +164,5 @@ export default defineNuxtComponent({
disableAmount: true, disableAmount: true,
quantity: 1, quantity: 1,
}); });
} }
return {
user,
groupSlug,
addIngredient,
parserToolTip,
hasFoodOrUnit,
imageKey,
drag,
insertNewIngredient,
};
},
});
</script> </script>