mirror of
https://github.com/hay-kot/mealie.git
synced 2025-08-21 05:53:36 -07:00
Merge remote-tracking branch 'upstream/mealie-next' into feat/remove-non-label-sort
This commit is contained in:
commit
6095e9d816
103 changed files with 338 additions and 471 deletions
|
@ -35,7 +35,7 @@ conventional_commits = true
|
|||
filter_unconventional = true
|
||||
# regex for preprocessing the commit messages
|
||||
commit_preprocessors = [
|
||||
{ pattern = '\((\w+\s)?#([0-9]+)\)', replace = "([#${2}](https://github.com/hay-kot/mealie/issues/${2}))"},
|
||||
{ pattern = '\((\w+\s)?#([0-9]+)\)', replace = "([#${2}](https://github.com/mealie-recipes/mealie/issues/${2}))"},
|
||||
]
|
||||
# regex for parsing and grouping commits
|
||||
commit_parsers = [
|
||||
|
|
|
@ -44,7 +44,6 @@ def recipe_data(name: str, slug: str, id: str, userId: str, groupId: str) -> dic
|
|||
"note": "1 cup unsalted butter, cut into cubes",
|
||||
"unit": None,
|
||||
"food": None,
|
||||
"disableAmount": True,
|
||||
"quantity": 1,
|
||||
"originalText": None,
|
||||
"referenceId": "ea3b6702-9532-4fbc-a40b-f99917831c26",
|
||||
|
@ -54,7 +53,6 @@ def recipe_data(name: str, slug: str, id: str, userId: str, groupId: str) -> dic
|
|||
"note": "1 cup light brown sugar",
|
||||
"unit": None,
|
||||
"food": None,
|
||||
"disableAmount": True,
|
||||
"quantity": 1,
|
||||
"originalText": None,
|
||||
"referenceId": "c5bbfefb-1e23-4ffd-af88-c0363a0fae82",
|
||||
|
@ -64,7 +62,6 @@ def recipe_data(name: str, slug: str, id: str, userId: str, groupId: str) -> dic
|
|||
"note": "1/2 cup granulated white sugar",
|
||||
"unit": None,
|
||||
"food": None,
|
||||
"disableAmount": True,
|
||||
"quantity": 1,
|
||||
"originalText": None,
|
||||
"referenceId": "034f481b-c426-4a17-b983-5aea9be4974b",
|
||||
|
@ -74,7 +71,6 @@ def recipe_data(name: str, slug: str, id: str, userId: str, groupId: str) -> dic
|
|||
"note": "2 large eggs",
|
||||
"unit": None,
|
||||
"food": None,
|
||||
"disableAmount": True,
|
||||
"quantity": 1,
|
||||
"originalText": None,
|
||||
"referenceId": "37c1f796-3bdb-4856-859f-dbec90bc27e4",
|
||||
|
@ -84,7 +80,6 @@ def recipe_data(name: str, slug: str, id: str, userId: str, groupId: str) -> dic
|
|||
"note": "2 tsp vanilla extract",
|
||||
"unit": None,
|
||||
"food": None,
|
||||
"disableAmount": True,
|
||||
"quantity": 1,
|
||||
"originalText": None,
|
||||
"referenceId": "85561ace-f249-401d-834c-e600a2f6280e",
|
||||
|
@ -94,7 +89,6 @@ def recipe_data(name: str, slug: str, id: str, userId: str, groupId: str) -> dic
|
|||
"note": "1/2 cup creamy peanut butter",
|
||||
"unit": None,
|
||||
"food": None,
|
||||
"disableAmount": True,
|
||||
"quantity": 1,
|
||||
"originalText": None,
|
||||
"referenceId": "ac91bda0-e8a8-491a-976a-ae4e72418cfd",
|
||||
|
@ -104,7 +98,6 @@ def recipe_data(name: str, slug: str, id: str, userId: str, groupId: str) -> dic
|
|||
"note": "1 tsp cornstarch",
|
||||
"unit": None,
|
||||
"food": None,
|
||||
"disableAmount": True,
|
||||
"quantity": 1,
|
||||
"originalText": None,
|
||||
"referenceId": "4d1256b3-115e-4475-83cd-464fbc304cb0",
|
||||
|
@ -114,7 +107,6 @@ def recipe_data(name: str, slug: str, id: str, userId: str, groupId: str) -> dic
|
|||
"note": "1 tsp baking soda",
|
||||
"unit": None,
|
||||
"food": None,
|
||||
"disableAmount": True,
|
||||
"quantity": 1,
|
||||
"originalText": None,
|
||||
"referenceId": "64627441-39f9-4ee3-8494-bafe36451d12",
|
||||
|
@ -124,7 +116,6 @@ def recipe_data(name: str, slug: str, id: str, userId: str, groupId: str) -> dic
|
|||
"note": "1/2 tsp salt",
|
||||
"unit": None,
|
||||
"food": None,
|
||||
"disableAmount": True,
|
||||
"quantity": 1,
|
||||
"originalText": None,
|
||||
"referenceId": "7ae212d0-3cd1-44b0-899e-ec5bd91fd384",
|
||||
|
@ -134,7 +125,6 @@ def recipe_data(name: str, slug: str, id: str, userId: str, groupId: str) -> dic
|
|||
"note": "1 cup cake flour",
|
||||
"unit": None,
|
||||
"food": None,
|
||||
"disableAmount": True,
|
||||
"quantity": 1,
|
||||
"originalText": None,
|
||||
"referenceId": "06967994-8548-4952-a8cc-16e8db228ebd",
|
||||
|
@ -144,7 +134,6 @@ def recipe_data(name: str, slug: str, id: str, userId: str, groupId: str) -> dic
|
|||
"note": "2 cups all-purpose flour",
|
||||
"unit": None,
|
||||
"food": None,
|
||||
"disableAmount": True,
|
||||
"quantity": 1,
|
||||
"originalText": None,
|
||||
"referenceId": "bdb33b23-c767-4465-acf8-3b8e79eb5691",
|
||||
|
@ -154,7 +143,6 @@ def recipe_data(name: str, slug: str, id: str, userId: str, groupId: str) -> dic
|
|||
"note": "2 cups peanut butter chips",
|
||||
"unit": None,
|
||||
"food": None,
|
||||
"disableAmount": True,
|
||||
"quantity": 1,
|
||||
"originalText": None,
|
||||
"referenceId": "12ba0af8-affd-4fb2-9cca-6f1b3e8d3aef",
|
||||
|
@ -164,7 +152,6 @@ def recipe_data(name: str, slug: str, id: str, userId: str, groupId: str) -> dic
|
|||
"note": "1½ cups Reese's Pieces candies",
|
||||
"unit": None,
|
||||
"food": None,
|
||||
"disableAmount": True,
|
||||
"quantity": 1,
|
||||
"originalText": None,
|
||||
"referenceId": "4bdc0598-a3eb-41ee-8af0-4da9348fbfe2",
|
||||
|
@ -221,7 +208,6 @@ def recipe_data(name: str, slug: str, id: str, userId: str, groupId: str) -> dic
|
|||
"showAssets": False,
|
||||
"landscapeView": False,
|
||||
"disableComments": False,
|
||||
"disableAmount": True,
|
||||
"locked": False,
|
||||
},
|
||||
"assets": [],
|
||||
|
|
|
@ -13,14 +13,14 @@ Steps:
|
|||
|
||||
#### 1. Get your API Token
|
||||
|
||||
Create an API token from Mealie's User Settings page (https://hay-kot.github.io/mealie/documentation/users-groups/user-settings/#api-key-generation)
|
||||
Create an API token from Mealie's User Settings page (https://docs.mealie.io/documentation/getting-started/api-usage/#getting-a-token)
|
||||
|
||||
#### 2. Create Home Assistant Sensors
|
||||
|
||||
Create REST sensors in home assistant to get the details of today's meal.
|
||||
We will create sensors to get the name and ID of the first meal in today's meal plan (note that this may not be what is wanted if there is more than one meal planned for the day). We need the ID as well as the name to be able to retrieve the image for the meal.
|
||||
|
||||
Make sure the url and port (`http://mealie:9000` ) matches your installation's address and _API_ port.
|
||||
Make sure the url and port (`http://mealie:9000`) matches your installation's address and _API_ port.
|
||||
|
||||
```yaml
|
||||
rest:
|
||||
|
|
|
@ -2,6 +2,3 @@
|
|||
|
||||
## Feature Requests
|
||||
[Please request new features on Github](https://github.com/mealie-recipes/mealie/discussions/new?category=feature-request)
|
||||
|
||||
## Progress
|
||||
See the [Github Projects page](https://github.com/users/hay-kot/projects/2) to see what is currently being worked on
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -351,7 +351,7 @@
|
|||
<!-- Custom narrow footer -->
|
||||
<div class="md-footer-meta__inner md-grid">
|
||||
<div class="md-footer-social">
|
||||
<a class="md-footer-social__link" href="https://github.com/hay-kot/mealie" rel="noopener" target="_blank"
|
||||
<a class="md-footer-social__link" href="https://github.com/mealie-recipes/mealie" rel="noopener" target="_blank"
|
||||
title="github.com">
|
||||
<svg style="width: 32px; height: 32px" viewBox="0 0 480 512" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
|
|
|
@ -79,11 +79,6 @@ const recipePreferences: Preference[] = [
|
|||
label: i18n.t("group.disable-users-from-commenting-on-recipes"),
|
||||
description: i18n.t("group.disable-users-from-commenting-on-recipes-description"),
|
||||
},
|
||||
{
|
||||
key: "recipeDisableAmount",
|
||||
label: i18n.t("group.disable-organizing-recipe-ingredients-by-units-and-food"),
|
||||
description: i18n.t("group.disable-organizing-recipe-ingredients-by-units-and-food-description"),
|
||||
},
|
||||
];
|
||||
|
||||
const allDays = [
|
||||
|
|
|
@ -130,20 +130,23 @@
|
|||
.ingredients[i]
|
||||
.checked"
|
||||
>
|
||||
<v-checkbox
|
||||
hide-details
|
||||
:model-value="ingredientData.checked"
|
||||
class="pt-0 my-auto py-auto"
|
||||
color="secondary"
|
||||
density="compact"
|
||||
/>
|
||||
<div :key="`${ingredientData.ingredient.quantity || 'no-qty'}-${i}`">
|
||||
<RecipeIngredientListItem
|
||||
:ingredient="ingredientData.ingredient"
|
||||
:disable-amount="ingredientData.disableAmount"
|
||||
:scale="recipeSection.recipeScale"
|
||||
/>
|
||||
</div>
|
||||
<v-container class="pa-0 ma-0">
|
||||
<v-row no-gutters>
|
||||
<v-checkbox
|
||||
hide-details
|
||||
:model-value="ingredientData.checked"
|
||||
class="pt-0 my-auto py-auto mr-2"
|
||||
color="secondary"
|
||||
density="compact"
|
||||
/>
|
||||
<div :key="`${ingredientData.ingredient.quantity || 'no-qty'}-${i}`" class="pa-auto my-auto">
|
||||
<RecipeIngredientListItem
|
||||
:ingredient="ingredientData.ingredient"
|
||||
:scale="recipeSection.recipeScale"
|
||||
/>
|
||||
</div>
|
||||
</v-row>
|
||||
</v-container>
|
||||
</v-list-item>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -188,7 +191,6 @@ export interface RecipeWithScale extends Recipe {
|
|||
export interface ShoppingListIngredient {
|
||||
checked: boolean;
|
||||
ingredient: RecipeIngredient;
|
||||
disableAmount: boolean;
|
||||
}
|
||||
|
||||
export interface ShoppingListIngredientSection {
|
||||
|
@ -290,7 +292,6 @@ async function consolidateRecipesIntoSections(recipes: RecipeWithScale[]) {
|
|||
return {
|
||||
checked: !householdsWithFood.includes(userHousehold.value),
|
||||
ingredient: ing,
|
||||
disableAmount: recipe.settings?.disableAmount || false,
|
||||
};
|
||||
});
|
||||
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
class="d-flex flex-wrap my-1"
|
||||
>
|
||||
<v-col
|
||||
v-if="!disableAmount"
|
||||
sm="12"
|
||||
md="2"
|
||||
cols="12"
|
||||
|
@ -42,7 +41,6 @@
|
|||
</v-text-field>
|
||||
</v-col>
|
||||
<v-col
|
||||
v-if="!disableAmount"
|
||||
sm="12"
|
||||
md="3"
|
||||
cols="12"
|
||||
|
@ -98,7 +96,6 @@
|
|||
|
||||
<!-- Foods Input -->
|
||||
<v-col
|
||||
v-if="!disableAmount"
|
||||
m="12"
|
||||
md="3"
|
||||
cols="12"
|
||||
|
@ -166,16 +163,7 @@
|
|||
:placeholder="$t('recipe.notes')"
|
||||
class="mb-auto"
|
||||
@click="$emit('clickIngredientField', 'note')"
|
||||
>
|
||||
<template #prepend>
|
||||
<v-icon
|
||||
v-if="disableAmount && $attrs && $attrs.delete"
|
||||
class="mr-n1 handle"
|
||||
>
|
||||
{{ $globals.icons.arrowUpDown }}
|
||||
</v-icon>
|
||||
</template>
|
||||
</v-text-field>
|
||||
/>
|
||||
<BaseButtonGroup
|
||||
hover
|
||||
:large="false"
|
||||
|
@ -216,10 +204,6 @@ import type { RecipeIngredient } from "~/lib/api/types/recipe";
|
|||
const model = defineModel<RecipeIngredient>({ required: true });
|
||||
|
||||
defineProps({
|
||||
disableAmount: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
unitError: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
|
|
|
@ -34,16 +34,14 @@ import { useParsedIngredientText } from "~/composables/recipes";
|
|||
|
||||
interface Props {
|
||||
ingredient: RecipeIngredient;
|
||||
disableAmount?: boolean;
|
||||
scale?: number;
|
||||
}
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
disableAmount: false,
|
||||
scale: 1,
|
||||
});
|
||||
|
||||
const parsedIng = computed(() => {
|
||||
return useParsedIngredientText(props.ingredient, props.disableAmount, props.scale);
|
||||
return useParsedIngredientText(props.ingredient, props.scale);
|
||||
});
|
||||
</script>
|
||||
|
||||
|
|
|
@ -43,7 +43,6 @@
|
|||
<v-list-item-title>
|
||||
<RecipeIngredientListItem
|
||||
:ingredient="ingredient"
|
||||
:disable-amount="disableAmount"
|
||||
:scale="scale"
|
||||
/>
|
||||
</v-list-item-title>
|
||||
|
@ -60,13 +59,11 @@ import type { RecipeIngredient } from "~/lib/api/types/recipe";
|
|||
|
||||
interface Props {
|
||||
value?: RecipeIngredient[];
|
||||
disableAmount?: boolean;
|
||||
scale?: number;
|
||||
isCookMode?: boolean;
|
||||
}
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
value: () => [],
|
||||
disableAmount: false,
|
||||
scale: 1,
|
||||
isCookMode: false,
|
||||
});
|
||||
|
@ -89,7 +86,7 @@ const ingredientCopyText = computed(() => {
|
|||
components.push(`[${ingredient.title}]`);
|
||||
}
|
||||
|
||||
components.push(parseIngredientText(ingredient, props.disableAmount, props.scale, false));
|
||||
components.push(parseIngredientText(ingredient, props.scale, false));
|
||||
});
|
||||
|
||||
return components.join("\n");
|
||||
|
|
|
@ -141,7 +141,6 @@
|
|||
<RecipeIngredients
|
||||
:value="notLinkedIngredients"
|
||||
:scale="scale"
|
||||
:disable-amount="recipe.settings.disableAmount"
|
||||
:is-cook-mode="isCookMode"
|
||||
/>
|
||||
</v-card>
|
||||
|
|
|
@ -1,9 +1,14 @@
|
|||
<!-- eslint-disable vue/no-mutating-props -->
|
||||
<template>
|
||||
<div>
|
||||
<h2 class="mb-4 text-h5 font-weight-medium opacity-80">
|
||||
{{ $t("recipe.ingredients") }}
|
||||
</h2>
|
||||
<div class="mb-4">
|
||||
<h2 class="mb-4 text-h5 font-weight-medium opacity-80">
|
||||
{{ $t("recipe.ingredients") }}
|
||||
</h2>
|
||||
<BannerWarning v-if="!hasFoodOrUnit">
|
||||
{{ $t("recipe.ingredients-not-parsed-description", { parse: $t('recipe.parse') }) }}
|
||||
</BannerWarning>
|
||||
</div>
|
||||
<VueDraggable
|
||||
v-if="recipe.recipeIngredient.length > 0"
|
||||
v-model="recipe.recipeIngredient"
|
||||
|
@ -27,7 +32,6 @@
|
|||
:key="ingredient.referenceId"
|
||||
v-model="recipe.recipeIngredient[index]"
|
||||
class="list-group-item"
|
||||
:disable-amount="recipe.settings.disableAmount"
|
||||
@delete="recipe.recipeIngredient.splice(index, 1)"
|
||||
@insert-above="insertNewIngredient(index)"
|
||||
@insert-below="insertNewIngredient(index + 1)"
|
||||
|
@ -49,7 +53,7 @@
|
|||
<span>
|
||||
<BaseButton
|
||||
class="mb-1"
|
||||
:disabled="recipe.settings.disableAmount || hasFoodOrUnit"
|
||||
:disabled="hasFoodOrUnit"
|
||||
color="accent"
|
||||
:to="`/g/${groupSlug}/r/${recipe.slug}/ingredient-parser`"
|
||||
v-bind="props"
|
||||
|
@ -109,10 +113,7 @@ const hasFoodOrUnit = computed(() => {
|
|||
});
|
||||
|
||||
const parserToolTip = computed(() => {
|
||||
if (recipe.value.settings.disableAmount) {
|
||||
return i18n.t("recipe.enable-ingredient-amounts-to-use-this-feature");
|
||||
}
|
||||
else if (hasFoodOrUnit.value) {
|
||||
if (hasFoodOrUnit.value) {
|
||||
return i18n.t("recipe.recipes-with-units-or-foods-defined-cannot-be-parsed");
|
||||
}
|
||||
return i18n.t("recipe.parse-ingredients");
|
||||
|
@ -127,7 +128,6 @@ function addIngredient(ingredients: Array<string> | null = null) {
|
|||
note: x,
|
||||
unit: undefined,
|
||||
food: undefined,
|
||||
disableAmount: true,
|
||||
quantity: 1,
|
||||
};
|
||||
});
|
||||
|
@ -146,7 +146,6 @@ function addIngredient(ingredients: Array<string> | null = null) {
|
|||
unit: undefined,
|
||||
// @ts-expect-error - prop can be null-type by NoUndefinedField type forces it to be set
|
||||
food: undefined,
|
||||
disableAmount: true,
|
||||
quantity: 1,
|
||||
});
|
||||
}
|
||||
|
@ -161,7 +160,6 @@ function insertNewIngredient(dest: number) {
|
|||
unit: undefined,
|
||||
// @ts-expect-error - prop can be null-type by NoUndefinedField type forces it to be set
|
||||
food: undefined,
|
||||
disableAmount: true,
|
||||
quantity: 1,
|
||||
});
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
<RecipeIngredients
|
||||
:value="recipe.recipeIngredient"
|
||||
:scale="scale"
|
||||
:disable-amount="recipe.settings.disableAmount"
|
||||
:is-cook-mode="isCookMode"
|
||||
/>
|
||||
<div v-if="!isEditMode && recipe.tools && recipe.tools.length > 0">
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
:value="ing.referenceId"
|
||||
>
|
||||
<template #label>
|
||||
<RecipeIngredientHtml :markup="parseIngredientText(ing, recipe.settings.disableAmount)" />
|
||||
<RecipeIngredientHtml :markup="parseIngredientText(ing)" />
|
||||
</template>
|
||||
</v-checkbox-btn>
|
||||
|
||||
|
@ -51,7 +51,7 @@
|
|||
:value="ing.referenceId"
|
||||
>
|
||||
<template #label>
|
||||
<RecipeIngredientHtml :markup="parseIngredientText(ing, recipe.settings.disableAmount)" />
|
||||
<RecipeIngredientHtml :markup="parseIngredientText(ing)" />
|
||||
</template>
|
||||
</v-checkbox-btn>
|
||||
</template>
|
||||
|
@ -323,7 +323,6 @@
|
|||
return step.ingredientReferences.map((ref) => ref.referenceId).includes(ing.referenceId || '')
|
||||
})"
|
||||
:scale="scale"
|
||||
:disable-amount="recipe.settings.disableAmount"
|
||||
:is-cook-mode="isCookMode"
|
||||
/>
|
||||
</div>
|
||||
|
@ -552,7 +551,6 @@ function autoSetReferences() {
|
|||
props.recipe.recipeIngredient,
|
||||
activeRefs.value,
|
||||
activeText.value,
|
||||
props.recipe.settings.disableAmount,
|
||||
).forEach((ingredient: string) => activeRefs.value.push(ingredient));
|
||||
}
|
||||
|
||||
|
@ -574,7 +572,7 @@ function getIngredientByRefId(refId: string | undefined) {
|
|||
|
||||
const ing = ingredientLookup.value[refId];
|
||||
if (!ing) return "";
|
||||
return parseIngredientText(ing, props.recipe.settings.disableAmount, props.scale);
|
||||
return parseIngredientText(ing, props.scale);
|
||||
}
|
||||
|
||||
// ===============================================================
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
v-if="!isEditMode"
|
||||
v-model.number="scale"
|
||||
:recipe-servings="recipeServings"
|
||||
:edit-scale="!recipe.settings.disableAmount && !isEditMode"
|
||||
:edit-scale="hasFoodOrUnit && !isEditMode"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -24,4 +24,15 @@ const { isEditMode } = usePageState(props.recipe.slug);
|
|||
const recipeServings = computed<number>(() => {
|
||||
return props.recipe.recipeServings || props.recipe.recipeYieldQuantity || 1;
|
||||
});
|
||||
|
||||
const hasFoodOrUnit = computed(() => {
|
||||
if (props.recipe.recipeIngredient) {
|
||||
for (const ingredient of props.recipe.recipeIngredient) {
|
||||
if (ingredient.food || ingredient.unit) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
});
|
||||
</script>
|
||||
|
|
|
@ -321,7 +321,7 @@ const hasNotes = computed(() => {
|
|||
});
|
||||
|
||||
function parseText(ingredient: RecipeIngredient) {
|
||||
return parseIngredientText(ingredient, props.recipe.settings?.disableAmount || false, props.scale);
|
||||
return parseIngredientText(ingredient, props.scale);
|
||||
}
|
||||
</script>
|
||||
|
||||
|
|
|
@ -31,7 +31,6 @@ const labels: Record<keyof RecipeSettings, string> = {
|
|||
showAssets: i18n.t("asset.show-assets"),
|
||||
landscapeView: i18n.t("recipe.landscape-view-coming-soon"),
|
||||
disableComments: i18n.t("recipe.disable-comments"),
|
||||
disableAmount: i18n.t("recipe.disable-amount"),
|
||||
locked: i18n.t("recipe.locked"),
|
||||
};
|
||||
</script>
|
||||
|
|
|
@ -22,10 +22,7 @@
|
|||
:class="listItem.checked ? 'strike-through' : ''"
|
||||
style="min-width: 0;"
|
||||
>
|
||||
<RecipeIngredientListItem
|
||||
:ingredient="listItem"
|
||||
:disable-amount="!(listItem.isFood || listItem.quantity !== 1)"
|
||||
/>
|
||||
<RecipeIngredientListItem :ingredient="listItem" />
|
||||
</div>
|
||||
</div>
|
||||
</v-col>
|
||||
|
@ -172,7 +169,6 @@
|
|||
@save="save"
|
||||
@cancel="toggleEdit(false)"
|
||||
@delete="$emit('delete')"
|
||||
@toggle-foods="localListItem.isFood = !localListItem.isFood"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<div>
|
||||
<v-card variant="outlined">
|
||||
<v-card-text class="pb-3 pt-1">
|
||||
<div v-if="listItem.isFood" class="d-md-flex align-center mb-2" style="gap: 20px">
|
||||
<div class="d-md-flex align-center mb-2" style="gap: 20px">
|
||||
<div>
|
||||
<InputQuantity v-model="listItem.quantity" />
|
||||
</div>
|
||||
|
@ -26,9 +26,6 @@
|
|||
/>
|
||||
</div>
|
||||
<div class="d-md-flex align-center" style="gap: 20px">
|
||||
<div v-if="!listItem.isFood">
|
||||
<InputQuantity v-model="listItem.quantity" />
|
||||
</div>
|
||||
<v-textarea
|
||||
v-model="listItem.note"
|
||||
hide-details
|
||||
|
@ -99,11 +96,6 @@
|
|||
text: $t('general.cancel'),
|
||||
event: 'cancel',
|
||||
},
|
||||
{
|
||||
icon: $globals.icons.foods,
|
||||
text: $t('shopping-list.toggle-food'),
|
||||
event: 'toggle-foods',
|
||||
},
|
||||
{
|
||||
icon: $globals.icons.save,
|
||||
text: $t('general.save'),
|
||||
|
@ -113,7 +105,6 @@
|
|||
@save="$emit('save')"
|
||||
@cancel="$emit('cancel')"
|
||||
@delete="$emit('delete')"
|
||||
@toggle-foods="listItem.isFood = !listItem.isFood"
|
||||
/>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
<v-btn
|
||||
color="white"
|
||||
icon
|
||||
href="https://github.com/hay-kot/mealie"
|
||||
href="https://github.com/mealie-recipes/mealie"
|
||||
target="_blank"
|
||||
>
|
||||
<v-icon>
|
||||
|
|
|
@ -18,8 +18,8 @@ function removeStartingPunctuation(word: string): string {
|
|||
return word.replace(punctuationAtBeginning, "");
|
||||
}
|
||||
|
||||
function ingredientMatchesWord(ingredient: RecipeIngredient, word: string, recipeIngredientAmountsDisabled: boolean) {
|
||||
const searchText = parseIngredientText(ingredient, recipeIngredientAmountsDisabled);
|
||||
function ingredientMatchesWord(ingredient: RecipeIngredient, word: string) {
|
||||
const searchText = parseIngredientText(ingredient);
|
||||
return searchText.toLowerCase().includes(word.toLowerCase());
|
||||
}
|
||||
|
||||
|
@ -39,7 +39,7 @@ function isBlackListedWord(word: string) {
|
|||
return blackListedText.includes(word) || word.match(blackListedRegexMatch);
|
||||
}
|
||||
|
||||
export function useExtractIngredientReferences(recipeIngredients: RecipeIngredient[], activeRefs: string[], text: string, recipeIngredientAmountsDisabled: boolean): Set<string> {
|
||||
export function useExtractIngredientReferences(recipeIngredients: RecipeIngredient[], activeRefs: string[], text: string): Set<string> {
|
||||
const availableIngredients = recipeIngredients
|
||||
.filter(ingredient => ingredient.referenceId !== undefined)
|
||||
.filter(ingredient => !activeRefs.includes(ingredient.referenceId as string));
|
||||
|
@ -50,7 +50,7 @@ export function useExtractIngredientReferences(recipeIngredients: RecipeIngredie
|
|||
.map(normalize)
|
||||
.filter(word => word.length > 2)
|
||||
.filter(word => !isBlackListedWord(word))
|
||||
.flatMap(word => availableIngredients.filter(ingredient => ingredientMatchesWord(ingredient, word, recipeIngredientAmountsDisabled)))
|
||||
.flatMap(word => availableIngredients.filter(ingredient => ingredientMatchesWord(ingredient, word)))
|
||||
.map(ingredient => ingredient.referenceId as string);
|
||||
// deduplicate
|
||||
|
||||
|
|
|
@ -16,33 +16,27 @@ describe(parseIngredientText.name, () => {
|
|||
...overrides,
|
||||
});
|
||||
|
||||
test("uses ingredient note if disableAmount: true", () => {
|
||||
const ingredient = createRecipeIngredient({ note: "foo" });
|
||||
|
||||
expect(parseIngredientText(ingredient, true)).toEqual("foo");
|
||||
});
|
||||
|
||||
test("adds note section if note present", () => {
|
||||
const ingredient = createRecipeIngredient({ note: "custom note" });
|
||||
|
||||
expect(parseIngredientText(ingredient, false)).toContain("custom note");
|
||||
expect(parseIngredientText(ingredient)).toContain("custom note");
|
||||
});
|
||||
|
||||
test("ingredient text with fraction", () => {
|
||||
const ingredient = createRecipeIngredient({ quantity: 1.5, unit: { fraction: true, id: "1", name: "cup" } });
|
||||
|
||||
expect(parseIngredientText(ingredient, false, 1, true)).contain("1<sup>1</sup>").and.to.contain("<sub>2</sub>");
|
||||
expect(parseIngredientText(ingredient, 1, true)).contain("1<sup>1</sup>").and.to.contain("<sub>2</sub>");
|
||||
});
|
||||
|
||||
test("ingredient text with fraction when unit is null", () => {
|
||||
const ingredient = createRecipeIngredient({ quantity: 1.5, unit: undefined });
|
||||
|
||||
expect(parseIngredientText(ingredient, false, 1, true)).contain("1<sup>1</sup>").and.to.contain("<sub>2</sub>");
|
||||
expect(parseIngredientText(ingredient, 1, true)).contain("1<sup>1</sup>").and.to.contain("<sub>2</sub>");
|
||||
});
|
||||
|
||||
test("ingredient text with fraction no formatting", () => {
|
||||
const ingredient = createRecipeIngredient({ quantity: 1.5, unit: { fraction: true, id: "1", name: "cup" } });
|
||||
const result = parseIngredientText(ingredient, false, 1, false);
|
||||
const result = parseIngredientText(ingredient, 1, false);
|
||||
|
||||
expect(result).not.contain("<");
|
||||
expect(result).not.contain(">");
|
||||
|
@ -52,7 +46,7 @@ describe(parseIngredientText.name, () => {
|
|||
test("sanitizes html", () => {
|
||||
const ingredient = createRecipeIngredient({ note: "<script>alert('foo')</script>" });
|
||||
|
||||
expect(parseIngredientText(ingredient, false)).not.toContain("<script>");
|
||||
expect(parseIngredientText(ingredient)).not.toContain("<script>");
|
||||
});
|
||||
|
||||
test("plural test : plural qty : use abbreviation", () => {
|
||||
|
@ -62,7 +56,7 @@ describe(parseIngredientText.name, () => {
|
|||
food: { id: "1", name: "diced onion", pluralName: "diced onions" },
|
||||
});
|
||||
|
||||
expect(parseIngredientText(ingredient, false)).toEqual("2 tbsps diced onions");
|
||||
expect(parseIngredientText(ingredient)).toEqual("2 tbsps diced onions");
|
||||
});
|
||||
|
||||
test("plural test : plural qty : not abbreviation", () => {
|
||||
|
@ -72,7 +66,7 @@ describe(parseIngredientText.name, () => {
|
|||
food: { id: "1", name: "diced onion", pluralName: "diced onions" },
|
||||
});
|
||||
|
||||
expect(parseIngredientText(ingredient, false)).toEqual("2 tablespoons diced onions");
|
||||
expect(parseIngredientText(ingredient)).toEqual("2 tablespoons diced onions");
|
||||
});
|
||||
|
||||
test("plural test : single qty : use abbreviation", () => {
|
||||
|
@ -82,7 +76,7 @@ describe(parseIngredientText.name, () => {
|
|||
food: { id: "1", name: "diced onion", pluralName: "diced onions" },
|
||||
});
|
||||
|
||||
expect(parseIngredientText(ingredient, false)).toEqual("1 tbsp diced onion");
|
||||
expect(parseIngredientText(ingredient)).toEqual("1 tbsp diced onion");
|
||||
});
|
||||
|
||||
test("plural test : single qty : not abbreviation", () => {
|
||||
|
@ -92,7 +86,7 @@ describe(parseIngredientText.name, () => {
|
|||
food: { id: "1", name: "diced onion", pluralName: "diced onions" },
|
||||
});
|
||||
|
||||
expect(parseIngredientText(ingredient, false)).toEqual("1 tablespoon diced onion");
|
||||
expect(parseIngredientText(ingredient)).toEqual("1 tablespoon diced onion");
|
||||
});
|
||||
|
||||
test("plural test : small qty : use abbreviation", () => {
|
||||
|
@ -102,7 +96,7 @@ describe(parseIngredientText.name, () => {
|
|||
food: { id: "1", name: "diced onion", pluralName: "diced onions" },
|
||||
});
|
||||
|
||||
expect(parseIngredientText(ingredient, false)).toEqual("0.5 tbsp diced onion");
|
||||
expect(parseIngredientText(ingredient)).toEqual("0.5 tbsp diced onion");
|
||||
});
|
||||
|
||||
test("plural test : small qty : not abbreviation", () => {
|
||||
|
@ -112,7 +106,7 @@ describe(parseIngredientText.name, () => {
|
|||
food: { id: "1", name: "diced onion", pluralName: "diced onions" },
|
||||
});
|
||||
|
||||
expect(parseIngredientText(ingredient, false)).toEqual("0.5 tablespoon diced onion");
|
||||
expect(parseIngredientText(ingredient)).toEqual("0.5 tablespoon diced onion");
|
||||
});
|
||||
|
||||
test("plural test : zero qty", () => {
|
||||
|
@ -122,7 +116,7 @@ describe(parseIngredientText.name, () => {
|
|||
food: { id: "1", name: "diced onion", pluralName: "diced onions" },
|
||||
});
|
||||
|
||||
expect(parseIngredientText(ingredient, false)).toEqual("diced onions");
|
||||
expect(parseIngredientText(ingredient)).toEqual("diced onions");
|
||||
});
|
||||
|
||||
test("plural test : single qty, scaled", () => {
|
||||
|
@ -132,6 +126,6 @@ describe(parseIngredientText.name, () => {
|
|||
food: { id: "1", name: "diced onion", pluralName: "diced onions" },
|
||||
});
|
||||
|
||||
expect(parseIngredientText(ingredient, false, 2)).toEqual("2 tablespoons diced onions");
|
||||
expect(parseIngredientText(ingredient, 2)).toEqual("2 tablespoons diced onions");
|
||||
});
|
||||
});
|
||||
|
|
|
@ -36,16 +36,7 @@ function useUnitName(unit: CreateIngredientUnit | IngredientUnit | undefined, us
|
|||
return returnVal;
|
||||
}
|
||||
|
||||
export function useParsedIngredientText(ingredient: RecipeIngredient, disableAmount: boolean, scale = 1, includeFormating = true) {
|
||||
if (disableAmount) {
|
||||
return {
|
||||
name: ingredient.note ? sanitizeIngredientHTML(ingredient.note) : undefined,
|
||||
quantity: undefined,
|
||||
unit: undefined,
|
||||
note: undefined,
|
||||
};
|
||||
}
|
||||
|
||||
export function useParsedIngredientText(ingredient: RecipeIngredient, scale = 1, includeFormating = true) {
|
||||
const { quantity, food, unit, note } = ingredient;
|
||||
const usePluralUnit = quantity !== undefined && ((quantity || 0) * scale > 1 || (quantity || 0) * scale === 0);
|
||||
const usePluralFood = (!quantity) || quantity * scale > 1;
|
||||
|
@ -82,8 +73,8 @@ export function useParsedIngredientText(ingredient: RecipeIngredient, disableAmo
|
|||
};
|
||||
}
|
||||
|
||||
export function parseIngredientText(ingredient: RecipeIngredient, disableAmount: boolean, scale = 1, includeFormating = true): string {
|
||||
const { quantity, unit, name, note } = useParsedIngredientText(ingredient, disableAmount, scale, includeFormating);
|
||||
export function parseIngredientText(ingredient: RecipeIngredient, scale = 1, includeFormating = true): string {
|
||||
const { quantity, unit, name, note } = useParsedIngredientText(ingredient, scale, includeFormating);
|
||||
|
||||
const text = `${quantity || ""} ${unit || ""} ${name || ""} ${note || ""}`.replace(/ {2,}/g, " ").trim();
|
||||
return sanitizeIngredientHTML(text);
|
||||
|
|
|
@ -587,6 +587,7 @@
|
|||
"api-extras-description": "Recipes extras are a key feature of the Mealie API. They allow you to create custom JSON key/value pairs within a recipe, to reference from 3rd party applications. You can use these keys to provide information, for example to trigger automations or custom messages to relay to your desired device.",
|
||||
"message-key": "Boodskap sleutel",
|
||||
"parse": "Verwerk",
|
||||
"ingredients-not-parsed-description": "It looks like your ingredients aren't parsed yet. Click the \"{parse}\" button below to parse your ingredients into structured foods.",
|
||||
"attach-images-hint": "Voeg prente by deur dit in die bewerker te sleep en los",
|
||||
"drop-image": "Drop image",
|
||||
"enable-ingredient-amounts-to-use-this-feature": "Skakel bestanddeelhoeveelhede aan om hierdie funksie te gebruik",
|
||||
|
|
|
@ -587,6 +587,7 @@
|
|||
"api-extras-description": "Recipes extras are a key feature of the Mealie API. They allow you to create custom JSON key/value pairs within a recipe, to reference from 3rd party applications. You can use these keys to provide information, for example to trigger automations or custom messages to relay to your desired device.",
|
||||
"message-key": "مفتاح الرساله",
|
||||
"parse": "تحليل",
|
||||
"ingredients-not-parsed-description": "It looks like your ingredients aren't parsed yet. Click the \"{parse}\" button below to parse your ingredients into structured foods.",
|
||||
"attach-images-hint": "Attach images by dragging & dropping them into the editor",
|
||||
"drop-image": "وضع الصورة",
|
||||
"enable-ingredient-amounts-to-use-this-feature": "Enable ingredient amounts to use this feature",
|
||||
|
|
|
@ -587,6 +587,7 @@
|
|||
"api-extras-description": "Екстрите за рецепти са ключова характеристика на Mealie API. Те Ви позволяват да създавате персонализирани JSON двойки ключ/стойност в рамките на рецепта, за да ги препращате към други приложения. Можете да използвате тези ключове, за да предоставите информация за задействане на автоматизация или персонализирани съобщения, за препращане към желаното от Вас устройство.",
|
||||
"message-key": "Ключ на съобщението",
|
||||
"parse": "Анализирай",
|
||||
"ingredients-not-parsed-description": "It looks like your ingredients aren't parsed yet. Click the \"{parse}\" button below to parse your ingredients into structured foods.",
|
||||
"attach-images-hint": "Прикачете снимки като ги влачете и пуснете в редактора",
|
||||
"drop-image": "Премахване на изображение",
|
||||
"enable-ingredient-amounts-to-use-this-feature": "Пуснете количествата на съставките за да използвате функционалността",
|
||||
|
|
|
@ -587,6 +587,7 @@
|
|||
"api-extras-description": "Els extres de receptes són una funcionalitat clau de l'API de Mealie. Permeten crear parells clau/valor JSON personalitzats dins una recepta, per referenciar-los des d'aplicacions de tercers. Pots emprar aquestes claus per proveir informació, per exemple per a desencadenar automatitzacions o missatges personlitzats per a propagar al teu dispositiu desitjat.",
|
||||
"message-key": "Clau del missatge",
|
||||
"parse": "Analitzar",
|
||||
"ingredients-not-parsed-description": "It looks like your ingredients aren't parsed yet. Click the \"{parse}\" button below to parse your ingredients into structured foods.",
|
||||
"attach-images-hint": "Afegeix imatges arrossegant i deixant anar la imatge a l'editor",
|
||||
"drop-image": "Deixa anar la imatge",
|
||||
"enable-ingredient-amounts-to-use-this-feature": "Habilita les quantitats d'ingredients per a poder fer servir aquesta característica",
|
||||
|
|
|
@ -587,6 +587,7 @@
|
|||
"api-extras-description": "Recepty jsou klíčovým rysem rozhraní pro API Mealie. Umožňují vytvářet vlastní klíče/hodnoty JSON v rámci receptu pro odkazy na aplikace třetích stran. Tyto klíče můžete použít pro poskytnutí informací, například pro aktivaci automatizace nebo vlastních zpráv pro přenos do požadovaného zařízení.",
|
||||
"message-key": "Klíč zprávy",
|
||||
"parse": "Analyzovat",
|
||||
"ingredients-not-parsed-description": "It looks like your ingredients aren't parsed yet. Click the \"{parse}\" button below to parse your ingredients into structured foods.",
|
||||
"attach-images-hint": "Přiložit obrázky přetažením jich do editoru",
|
||||
"drop-image": "Vložit obrázek",
|
||||
"enable-ingredient-amounts-to-use-this-feature": "Chcete-li tuto funkci používat, povolte množství ingrediencí",
|
||||
|
|
|
@ -587,6 +587,7 @@
|
|||
"api-extras-description": "Opskrifter ekstra er en central feature i Mealie API. De giver dig mulighed for at oprette brugerdefinerede JSON nøgle / værdi par inden for en opskrift, at henvise til fra 3. parts applikationer. Du kan bruge disse nøgler til at give oplysninger, for eksempel til at udløse automatiseringer eller brugerdefinerede beskeder til at videresende til din ønskede enhed.",
|
||||
"message-key": "Beskednøgle",
|
||||
"parse": "Behandl data",
|
||||
"ingredients-not-parsed-description": "It looks like your ingredients aren't parsed yet. Click the \"{parse}\" button below to parse your ingredients into structured foods.",
|
||||
"attach-images-hint": "Vedhæft billeder ved at trække dem ind i redigeringsværktøjet",
|
||||
"drop-image": "Slet billede",
|
||||
"enable-ingredient-amounts-to-use-this-feature": "Aktiver mængde af ingredienser for at bruge denne funktion",
|
||||
|
|
|
@ -472,7 +472,7 @@
|
|||
"comment": "Kommentar",
|
||||
"comments": "Kommentare",
|
||||
"delete-confirmation": "Bist du dir sicher, dass du dieses Rezept löschen möchtest?",
|
||||
"admin-delete-confirmation": "You're about to delete a recipe that isn't yours using admin permissions. Are you sure?",
|
||||
"admin-delete-confirmation": "Du bist dabei ein Rezept, welches nicht deins ist, mit Admin-Rechten zu löschen. Bist du sicher?",
|
||||
"delete-recipe": "Rezept löschen",
|
||||
"description": "Beschreibung",
|
||||
"disable-amount": "Zutatenmenge deaktivieren",
|
||||
|
@ -587,6 +587,7 @@
|
|||
"api-extras-description": "Rezepte-Extras sind ein Hauptmerkmal der Mealie API. Sie ermöglichen es dir, benutzerdefinierte JSON Key-Value-Paare zu einem Rezept zu erstellen, um Drittanbieter-Anwendungen zu steuern. Du kannst diese dazu verwenden, um Automatisierungen auszulösen oder benutzerdefinierte Nachrichten an bestimmte Geräte zu senden.",
|
||||
"message-key": "Nachrichten-Schlüssel",
|
||||
"parse": "Parsen",
|
||||
"ingredients-not-parsed-description": "It looks like your ingredients aren't parsed yet. Click the \"{parse}\" button below to parse your ingredients into structured foods.",
|
||||
"attach-images-hint": "Bilder durch Ziehen & Ablegen in den Editor hinzufügen",
|
||||
"drop-image": "Bild hier ablegen",
|
||||
"enable-ingredient-amounts-to-use-this-feature": "Aktiviere Zutatenmengen, um diese Funktion zu nutzen",
|
||||
|
@ -663,8 +664,8 @@
|
|||
"no-unit": "Keine Einheit",
|
||||
"missing-unit": "Fehlende Einheit erstellen: {unit}",
|
||||
"missing-food": "Fehlendes Lebensmittel erstellen: {food}",
|
||||
"this-unit-could-not-be-parsed-automatically": "This unit could not be parsed automatically",
|
||||
"this-food-could-not-be-parsed-automatically": "This food could not be parsed automatically",
|
||||
"this-unit-could-not-be-parsed-automatically": "Diese Einheit konnte nicht automatisch analysiert werden",
|
||||
"this-food-could-not-be-parsed-automatically": "Dieses Lebensmittel konnte nicht automatisch analysiert werden",
|
||||
"no-food": "Kein Lebensmittel"
|
||||
},
|
||||
"reset-servings-count": "Portionen zurücksetzen",
|
||||
|
|
|
@ -587,6 +587,7 @@
|
|||
"api-extras-description": "Τα extras συνταγών αποτελούν βασικό χαρακτηριστικό του Mealie API. Σας επιτρέπουν να δημιουργήσετε προσαρμοσμένα ζεύγη κλειδιού/τιμής JSON μέσα σε μια συνταγή, να παραπέμψετε σε εφαρμογές τρίτων. Μπορείτε να χρησιμοποιήσετε αυτά τα κλειδιά για την παροχή πληροφοριών, για παράδειγμα πυροδότηση αυτοματισμών ή μετάδοση προσαρμοσμένων μηνυμάτων στη συσκευή που επιθυμείτε.",
|
||||
"message-key": "Κλειδί Μηνύματος",
|
||||
"parse": "Ανάλυση",
|
||||
"ingredients-not-parsed-description": "Φαίνεται ότι τα συστατικά σας δεν έχουν αναλυθεί ακόμα. Κάντε κλικ στο κουμπί \"{parse}\" παρακάτω για να αναλύσετε τα συστατικά σας σε δομημένα τρόφιμα.",
|
||||
"attach-images-hint": "Επισυνάψτε εικόνες σύροντας τις & αφήνοντάς τις στον επεξεργαστή",
|
||||
"drop-image": "Απόθεση εικόνας",
|
||||
"enable-ingredient-amounts-to-use-this-feature": "Ενεργοποιήστε τις ποσότητες συστατικών για να χρησιμοποιήσετε αυτήν τη δυνατότητα",
|
||||
|
|
|
@ -587,6 +587,7 @@
|
|||
"api-extras-description": "Recipes extras are a key feature of the Mealie API. They allow you to create custom JSON key/value pairs within a recipe, to reference from 3rd party applications. You can use these keys to provide information, for example to trigger automations or custom messages to relay to your desired device.",
|
||||
"message-key": "Message Key",
|
||||
"parse": "Parse",
|
||||
"ingredients-not-parsed-description": "It looks like your ingredients aren't parsed yet. Click the \"{parse}\" button below to parse your ingredients into structured foods.",
|
||||
"attach-images-hint": "Attach images by dragging & dropping them into the editor",
|
||||
"drop-image": "Drop image",
|
||||
"enable-ingredient-amounts-to-use-this-feature": "Enable ingredient amounts to use this feature",
|
||||
|
|
|
@ -587,6 +587,7 @@
|
|||
"api-extras-description": "Recipes extras are a key feature of the Mealie API. They allow you to create custom JSON key/value pairs within a recipe, to reference from 3rd party applications. You can use these keys to provide information, for example to trigger automations or custom messages to relay to your desired device.",
|
||||
"message-key": "Message Key",
|
||||
"parse": "Parse",
|
||||
"ingredients-not-parsed-description": "It looks like your ingredients aren't parsed yet. Click the \"{parse}\" button below to parse your ingredients into structured foods.",
|
||||
"attach-images-hint": "Attach images by dragging & dropping them into the editor",
|
||||
"drop-image": "Drop image",
|
||||
"enable-ingredient-amounts-to-use-this-feature": "Enable ingredient amounts to use this feature",
|
||||
|
|
|
@ -587,6 +587,7 @@
|
|||
"api-extras-description": "Los extras de las recetas son una característica clave de la API de Mealie. Permiten crear pares json clave/valor personalizados dentro de una receta para acceder desde aplicaciones de terceros. Puede utilizar estas claves para almacenar información, para activar la automatización o mensajes personalizados para transmitir al dispositivo deseado.",
|
||||
"message-key": "Clave de mensaje",
|
||||
"parse": "Analizar",
|
||||
"ingredients-not-parsed-description": "It looks like your ingredients aren't parsed yet. Click the \"{parse}\" button below to parse your ingredients into structured foods.",
|
||||
"attach-images-hint": "Adjuntar imágenes arrastrando y soltando en el editor",
|
||||
"drop-image": "Soltar imagen",
|
||||
"enable-ingredient-amounts-to-use-this-feature": "Habilitar la cantidad de ingredientes para usar esta característica",
|
||||
|
|
|
@ -587,6 +587,7 @@
|
|||
"api-extras-description": "Retsepti väljavõtted on Meali API oluline funktsioon. Neid saab kasutada kohandatud JSON-võtme/väärtuse paaride loomiseks retseptis, et viidata kolmandate osapoolte rakendustele. Neid klahve saab kasutada teabe edastamiseks, näiteks automaatse toimingu või kohandatud sõnumi käivitamiseks teie valitud seadmele.",
|
||||
"message-key": "Sõnumi võti",
|
||||
"parse": "Analüüsi",
|
||||
"ingredients-not-parsed-description": "It looks like your ingredients aren't parsed yet. Click the \"{parse}\" button below to parse your ingredients into structured foods.",
|
||||
"attach-images-hint": "Lisa pildid manustesse neid lohistades ja vabastades need redaktorisse",
|
||||
"drop-image": "Vabasta pilt",
|
||||
"enable-ingredient-amounts-to-use-this-feature": "Luba koostisosa kogused, et kasutada seda omadust",
|
||||
|
|
|
@ -587,6 +587,7 @@
|
|||
"api-extras-description": "Reseptiekstrat ovat Mealien API:n tärkeä ominaisuus. Niiden avulla voidaan luoda mukautettuja JSON-avain/arvo-pareja reseptin sisällä viitaten kolmannen osapuolen sovelluksiin. Näitä avaimia voi käyttää tiedon antamiseksi, esimerkiksi automaattisen toiminnon tai mukautetun viestin käynnistämiseksi haluamaasi laitteeseen.",
|
||||
"message-key": "Viestiavain",
|
||||
"parse": "Jäsennä",
|
||||
"ingredients-not-parsed-description": "It looks like your ingredients aren't parsed yet. Click the \"{parse}\" button below to parse your ingredients into structured foods.",
|
||||
"attach-images-hint": "Liitä kuvia vetämällä ja pudottamalla ne editoriin",
|
||||
"drop-image": "Tuo kuva",
|
||||
"enable-ingredient-amounts-to-use-this-feature": "Käytä ainesosan määriä käyttääksesi tätä ominaisuutta",
|
||||
|
|
|
@ -587,6 +587,7 @@
|
|||
"api-extras-description": "Les suppléments des recettes sont une fonctionnalité clé de l’API Mealie. Ils permettent de créer des paires JSON clé/valeur personnalisées dans une recette, qui peuvent être référencées depuis des applications tierces. Ces clés peuvent être utilisées par exemple pour déclencher des tâches automatisées ou des messages personnalisés à transmettre à l’appareil souhaité.",
|
||||
"message-key": "Clé de message",
|
||||
"parse": "Analyser",
|
||||
"ingredients-not-parsed-description": "It looks like your ingredients aren't parsed yet. Click the \"{parse}\" button below to parse your ingredients into structured foods.",
|
||||
"attach-images-hint": "Ajouter des images en les glissant-déposant dans l'éditeur",
|
||||
"drop-image": "Déposer l'image",
|
||||
"enable-ingredient-amounts-to-use-this-feature": "Activez les quantités d'ingrédients pour utiliser cette fonctionnalité",
|
||||
|
|
|
@ -587,6 +587,7 @@
|
|||
"api-extras-description": "Les suppléments des recettes sont une fonctionnalité clé de l’API Mealie. Ils permettent de créer des paires JSON clé/valeur personnalisées dans une recette, qui peuvent être référencées depuis des applications tierces. Ces clés peuvent être utilisées par exemple pour déclencher des tâches automatisées ou des messages personnalisés à transmettre à l’appareil souhaité.",
|
||||
"message-key": "Clé de message",
|
||||
"parse": "Analyser",
|
||||
"ingredients-not-parsed-description": "It looks like your ingredients aren't parsed yet. Click the \"{parse}\" button below to parse your ingredients into structured foods.",
|
||||
"attach-images-hint": "Ajouter des images en les glissant-déposant dans l'éditeur",
|
||||
"drop-image": "Déposer l'image",
|
||||
"enable-ingredient-amounts-to-use-this-feature": "Activez les quantités d'ingrédients pour utiliser cette fonctionnalité",
|
||||
|
|
|
@ -587,6 +587,7 @@
|
|||
"api-extras-description": "Les suppléments des recettes sont une fonctionnalité clé de l’API Mealie. Ils permettent de créer des paires JSON clé/valeur personnalisées dans une recette, qui peuvent être référencées depuis des applications tierces. Ces clés peuvent être utilisées par exemple pour déclencher des tâches automatisées ou des messages personnalisés à transmettre à l’appareil souhaité.",
|
||||
"message-key": "Clé de message",
|
||||
"parse": "Analyser",
|
||||
"ingredients-not-parsed-description": "It looks like your ingredients aren't parsed yet. Click the \"{parse}\" button below to parse your ingredients into structured foods.",
|
||||
"attach-images-hint": "Ajouter des images en les glissant-déposant dans l'éditeur",
|
||||
"drop-image": "Déposer l'image",
|
||||
"enable-ingredient-amounts-to-use-this-feature": "Activez les quantités d'ingrédients pour utiliser cette fonctionnalité",
|
||||
|
|
|
@ -587,6 +587,7 @@
|
|||
"api-extras-description": "Os extras de receitas son unha característica clave da API de Mealie. Permítenche crear pares de clave/valor JSON personalizados dentro dunha receita, para facer referencia desde aplicacións de terceiros. Podes usar estas teclas para proporcionar información, por exemplo, para activar automatizacións ou mensaxes personalizadas para transmitir ao dispositivo que desexes.",
|
||||
"message-key": "Chave de Mensaxen",
|
||||
"parse": "Interpretar",
|
||||
"ingredients-not-parsed-description": "It looks like your ingredients aren't parsed yet. Click the \"{parse}\" button below to parse your ingredients into structured foods.",
|
||||
"attach-images-hint": "Anexe imaxens arrastrando e soltandoas no editor",
|
||||
"drop-image": "Arrastrar imaxen",
|
||||
"enable-ingredient-amounts-to-use-this-feature": "Ative cantidades de ingredientes para usar esta funcionalidade",
|
||||
|
|
|
@ -587,6 +587,7 @@
|
|||
"api-extras-description": "מתכונים נוספים הם יכולת מפתח של Mealie API. הם מאפשרים ליצור צמדי key/value בצורת JSON על מנת לקרוא אותם בתוכנת צד שלישית. תוכלו להשתמש בצמדים האלה כדי לספק מידע, לדוגמא להפעיל אוטומציות או הודעות מותאמות אישית למכשירים מסויימים.",
|
||||
"message-key": "מפתח הודעה",
|
||||
"parse": "ניתוח",
|
||||
"ingredients-not-parsed-description": "It looks like your ingredients aren't parsed yet. Click the \"{parse}\" button below to parse your ingredients into structured foods.",
|
||||
"attach-images-hint": "הוסף תמונות ע\"י גרירה ושחרור אל תוך העורך",
|
||||
"drop-image": "גרור תמונה",
|
||||
"enable-ingredient-amounts-to-use-this-feature": "אפשר לכמות המרכיבים להשתמש בפונקציה",
|
||||
|
|
|
@ -587,6 +587,7 @@
|
|||
"api-extras-description": "Recipes extras are a key feature of the Mealie API. They allow you to create custom JSON key/value pairs within a recipe, to reference from 3rd party applications. You can use these keys to provide information, for example to trigger automations or custom messages to relay to your desired device.",
|
||||
"message-key": "Ključ poruke",
|
||||
"parse": "Razluči (parsiraj)",
|
||||
"ingredients-not-parsed-description": "It looks like your ingredients aren't parsed yet. Click the \"{parse}\" button below to parse your ingredients into structured foods.",
|
||||
"attach-images-hint": "Priložite slike povlačenjem i ispuštanjem u uređivaču",
|
||||
"drop-image": "Drop image",
|
||||
"enable-ingredient-amounts-to-use-this-feature": "Omogući korištenje količina sastojaka za ovu značajku",
|
||||
|
|
|
@ -581,12 +581,13 @@
|
|||
"how-did-it-turn-out": "Hogyan sikerült?",
|
||||
"user-made-this": "ezt {user} készítette el",
|
||||
"added-to-timeline": "Idővonalhoz hozzáadva",
|
||||
"failed-to-add-to-timeline": "Failed to add to timeline",
|
||||
"failed-to-add-to-timeline": "Nem sikerült az idővonalhoz hozzáadni",
|
||||
"failed-to-update-recipe": "Nem sikerült frissíteni a receptet",
|
||||
"added-to-timeline-but-failed-to-add-image": "Idővonalhoz hozzáadva, azonban a kép hozzáadása sikertelen",
|
||||
"api-extras-description": "A receptek extrái a Mealie API egyik legfontosabb szolgáltatása. Lehetővé teszik, hogy egyéni JSON kulcs/érték párokat hozzon létre egy receptben, amelyekre harmadik féltől származó alkalmazásokból hivatkozhat. Ezeket a kulcsokat információszolgáltatásra használhatja, például automatizmusok vagy egyéni üzenetek indítására, amelyeket a kívánt eszközre küldhet.",
|
||||
"message-key": "Üzenetkulcs",
|
||||
"parse": "Előkészítés",
|
||||
"ingredients-not-parsed-description": "Úgy tűnik, hogy az összetevőket még nem elemezték. Kattintson az alábbi „{parse}” gombra, hogy az összetevőket strukturált élelmiszerekké alakítsa.",
|
||||
"attach-images-hint": "Képek csatolása a szerkesztőbe történő húzásával és ejtésével",
|
||||
"drop-image": "Dobd ide a képet",
|
||||
"enable-ingredient-amounts-to-use-this-feature": "Engedélyezze az összetevők mennyiségét a funkció használatához",
|
||||
|
|
|
@ -587,6 +587,7 @@
|
|||
"api-extras-description": "Recipes extras are a key feature of the Mealie API. They allow you to create custom JSON key/value pairs within a recipe, to reference from 3rd party applications. You can use these keys to provide information, for example to trigger automations or custom messages to relay to your desired device.",
|
||||
"message-key": "Message Key",
|
||||
"parse": "Parse",
|
||||
"ingredients-not-parsed-description": "It looks like your ingredients aren't parsed yet. Click the \"{parse}\" button below to parse your ingredients into structured foods.",
|
||||
"attach-images-hint": "Attach images by dragging & dropping them into the editor",
|
||||
"drop-image": "Drop image",
|
||||
"enable-ingredient-amounts-to-use-this-feature": "Enable ingredient amounts to use this feature",
|
||||
|
|
|
@ -587,6 +587,7 @@
|
|||
"api-extras-description": "Le opzioni extra delle ricette sono una caratteristica fondamentale dell'API Mealie. Consentono di creare json personalizzati con coppie di chiavi/valore all'interno di una ricetta a cui fare riferimento tramite applicazioni terze. È possibile utilizzare queste chiavi per inserire informazioni, per esempio per attivare automazioni oppure per inoltrare messaggi personalizzati al dispositivo desiderato.",
|
||||
"message-key": "Chiave Messaggio",
|
||||
"parse": "Analizza",
|
||||
"ingredients-not-parsed-description": "Sembra che gli ingredienti non siano ancora analizzati. Fare clic il pulsante \"{parse}\" qui sotto per analizzare gli ingredienti in alimenti strutturati.",
|
||||
"attach-images-hint": "Allega immagini trascinandole nell'editor",
|
||||
"drop-image": "Trascina l'immagine",
|
||||
"enable-ingredient-amounts-to-use-this-feature": "Abilita le quantità degli ingredienti per utilizzare questa funzione",
|
||||
|
|
|
@ -587,6 +587,7 @@
|
|||
"api-extras-description": "レシピの追加機能はMealie APIの主な機能です。 サードパーティアプリから参照するために、レシピ内にカスタムJSONキー/値のペアを作成することができます。 これらのキーを使用して情報を提供することができます。例えば、自動化をトリガーしたり、カスタムメッセージをお使いのデバイスにリレーするなどです。",
|
||||
"message-key": "メッセージキー",
|
||||
"parse": "解析",
|
||||
"ingredients-not-parsed-description": "It looks like your ingredients aren't parsed yet. Click the \"{parse}\" button below to parse your ingredients into structured foods.",
|
||||
"attach-images-hint": "エディタにドラッグ&ドロップして画像を添付する",
|
||||
"drop-image": "画像をドロップ",
|
||||
"enable-ingredient-amounts-to-use-this-feature": "この機能を使用するには、材料の量を有効にする",
|
||||
|
|
|
@ -587,6 +587,7 @@
|
|||
"api-extras-description": "Recipes extras are a key feature of the Mealie API. They allow you to create custom JSON key/value pairs within a recipe, to reference from 3rd party applications. You can use these keys to provide information, for example to trigger automations or custom messages to relay to your desired device.",
|
||||
"message-key": "Message Key",
|
||||
"parse": "Parse",
|
||||
"ingredients-not-parsed-description": "It looks like your ingredients aren't parsed yet. Click the \"{parse}\" button below to parse your ingredients into structured foods.",
|
||||
"attach-images-hint": "Attach images by dragging & dropping them into the editor",
|
||||
"drop-image": "Drop image",
|
||||
"enable-ingredient-amounts-to-use-this-feature": "Enable ingredient amounts to use this feature",
|
||||
|
|
|
@ -587,6 +587,7 @@
|
|||
"api-extras-description": "Recipes extras are a key feature of the Mealie API. They allow you to create custom JSON key/value pairs within a recipe, to reference from 3rd party applications. You can use these keys to provide information, for example to trigger automations or custom messages to relay to your desired device.",
|
||||
"message-key": "Žinutės raktas",
|
||||
"parse": "Nuskaityti",
|
||||
"ingredients-not-parsed-description": "It looks like your ingredients aren't parsed yet. Click the \"{parse}\" button below to parse your ingredients into structured foods.",
|
||||
"attach-images-hint": "Pridėkite vaizdus vilkdami ir numesdami juos į redaktorių",
|
||||
"drop-image": "Drop image",
|
||||
"enable-ingredient-amounts-to-use-this-feature": "Įjunkite ingredientų kiekius, kad galėtumėte naudoti šią funkciją",
|
||||
|
|
|
@ -587,6 +587,7 @@
|
|||
"api-extras-description": "Recepšu ekstras ir galvenā Mealie API iezīme. Tie ļauj jums izveidot pielāgotus JSON atslēgu/vērtību pārus receptē, lai atsaucotos no trešo pušu lietojumprogrammām. Varat izmantot šos taustiņus, lai sniegtu informāciju, piemēram, aktivizētu automatizāciju vai pielāgotus ziņojumus, lai tos pārsūtītu uz vēlamo ierīci.",
|
||||
"message-key": "Ziņojuma atslēga",
|
||||
"parse": "Parsēšana",
|
||||
"ingredients-not-parsed-description": "It looks like your ingredients aren't parsed yet. Click the \"{parse}\" button below to parse your ingredients into structured foods.",
|
||||
"attach-images-hint": "Pievienojiet attēlus, velkot un nometot tos redaktorā",
|
||||
"drop-image": "Nometiet attēlu",
|
||||
"enable-ingredient-amounts-to-use-this-feature": "Iespējojiet sastāvdaļu daudzumu, lai izmantotu šo funkciju",
|
||||
|
|
|
@ -587,6 +587,7 @@
|
|||
"api-extras-description": "Extra's bij recepten zijn een belangrijke functie van de Mealie API. Hiermee kun je aangepaste JSON key/value paren maken bij een recept om naar te verwijzen vanuit applicaties van derden. Je kunt deze sleutels gebruiken om extra informatie te bieden, bijvoorbeeld om automatisering aan te sturen of aangepaste berichten naar je gewenste apparaat te laten versturen.",
|
||||
"message-key": "Berichtsleutel",
|
||||
"parse": "Ontleed",
|
||||
"ingredients-not-parsed-description": "Mealie heeft je ingrediënten nog niet verwerkt. Klik op de '{parse}' knop om je ingrediënten te verwerken als gestructureerde levensmiddelen.",
|
||||
"attach-images-hint": "Voeg afbeeldingen toe door ze te slepen en in de editor te plaatsen",
|
||||
"drop-image": "Afbeelding toevoegen",
|
||||
"enable-ingredient-amounts-to-use-this-feature": "Schakel ingrediënthoeveelheden in om deze functie te gebruiken",
|
||||
|
|
|
@ -587,6 +587,7 @@
|
|||
"api-extras-description": "Ekstramaterialer til oppskrifter er en viktig funksjon i Mealie API-en. De lar deg opprette egendefinerte JSON-nøkkel/verdi-par innenfor en oppskrift for å referere fra tredjepartsapplikasjoner. Du kan bruke disse nøklene til å gi informasjon for eksempel for å utløse automatiseringer eller egendefinerte meldinger som skal videreformidles til ønsket enhet.",
|
||||
"message-key": "Meldingsnøkkel",
|
||||
"parse": "Analyser",
|
||||
"ingredients-not-parsed-description": "It looks like your ingredients aren't parsed yet. Click the \"{parse}\" button below to parse your ingredients into structured foods.",
|
||||
"attach-images-hint": "Fest bilder ved å dra og slippe dem inn i redigereringsverktøyet",
|
||||
"drop-image": "Slipp bilde",
|
||||
"enable-ingredient-amounts-to-use-this-feature": "Aktiver ingrediensmengder for å bruke denne funksjonen",
|
||||
|
|
|
@ -587,6 +587,7 @@
|
|||
"api-extras-description": "Dodatki w przepisach są kluczową cechą API Mealie. Pozwalają na tworzenie niestandardowych par kluczy/wartości JSON w przepisie do odwoływania się przez zewnętrzne aplikacje. Możesz użyć tych kluczy do wyzwalania automatyzacji lub przekazywania niestandardowych wiadomości do twoich wybranych urządzeń.",
|
||||
"message-key": "Klucz Wiadomości",
|
||||
"parse": "Analizuj",
|
||||
"ingredients-not-parsed-description": "It looks like your ingredients aren't parsed yet. Click the \"{parse}\" button below to parse your ingredients into structured foods.",
|
||||
"attach-images-hint": "Dołącz obrazy przeciągając i upuszczając je do edytora",
|
||||
"drop-image": "Upuść zdjęcie",
|
||||
"enable-ingredient-amounts-to-use-this-feature": "Włącz ilości składników, aby użyć tej funkcji",
|
||||
|
|
|
@ -587,6 +587,7 @@
|
|||
"api-extras-description": "Extras de receitas são atributos-chave da API do Mealie. Assim, você pode criar pares chave/valor JSON personalizados dentro de uma receita, referenciando aplicações de terceiros. Você pode usar as chaves para fornecer informações, como por ex. ativar automações ou mensagens que serão enviadas a seus dispositivos.",
|
||||
"message-key": "Chave de mensagem",
|
||||
"parse": "Analisar",
|
||||
"ingredients-not-parsed-description": "It looks like your ingredients aren't parsed yet. Click the \"{parse}\" button below to parse your ingredients into structured foods.",
|
||||
"attach-images-hint": "Anexe imagens arrastando e soltando-as no editor",
|
||||
"drop-image": "Arrastar imagem",
|
||||
"enable-ingredient-amounts-to-use-this-feature": "Ative quantidades de ingredientes para usar esta funcionalidade",
|
||||
|
|
|
@ -472,7 +472,7 @@
|
|||
"comment": "Comentário",
|
||||
"comments": "Comentários",
|
||||
"delete-confirmation": "Tem a certeza de que deseja eliminar esta receita?",
|
||||
"admin-delete-confirmation": "You're about to delete a recipe that isn't yours using admin permissions. Are you sure?",
|
||||
"admin-delete-confirmation": "Está prestes a excluir uma receita que não é sua com permissões de administrador. Tem a certeza?",
|
||||
"delete-recipe": "Eliminar Receita",
|
||||
"description": "Descrição",
|
||||
"disable-amount": "Desativar Quantidades dos Ingredientes",
|
||||
|
@ -580,13 +580,14 @@
|
|||
"made-this": "Eu fiz isto",
|
||||
"how-did-it-turn-out": "Que tal ficou?",
|
||||
"user-made-this": "{user} fez isto",
|
||||
"added-to-timeline": "Added to timeline",
|
||||
"failed-to-add-to-timeline": "Failed to add to timeline",
|
||||
"failed-to-update-recipe": "Failed to update recipe",
|
||||
"added-to-timeline-but-failed-to-add-image": "Added to timeline, but failed to add image",
|
||||
"added-to-timeline": "Adicionado à linha do tempo",
|
||||
"failed-to-add-to-timeline": "Falha ao adicionar à linha do tempo",
|
||||
"failed-to-update-recipe": "Falha ao atualizar a receita",
|
||||
"added-to-timeline-but-failed-to-add-image": "Adicionado à linha do tempo, mas não foi possível adicionar a imagem",
|
||||
"api-extras-description": "Extras para receitas são funcionalidades chave da API Mealie. Estas permitem criar, dentro de uma receita, pares personalizados de chave/valor em JSON, para referência a partir de aplicações de terceiros. Pode usar essas chaves para fornecer informações, por exemplo, para acionar automações ou mensagens personalizadas para transmitir a um determinado dispositivo.",
|
||||
"message-key": "Chave de Mensagem",
|
||||
"parse": "Interpretar",
|
||||
"ingredients-not-parsed-description": "Parece que os seus ingredientes ainda não foram processados. Clique no botão \"{parse}\" abaixo para os converter em alimentos estruturados.",
|
||||
"attach-images-hint": "Anexe imagens arrastando e soltando-as no editor",
|
||||
"drop-image": "Remover imagem",
|
||||
"enable-ingredient-amounts-to-use-this-feature": "Ativar para usar esta funcionalidade nas quantidades de ingredientes",
|
||||
|
@ -604,10 +605,10 @@
|
|||
"create-recipe-from-an-image": "Criar receita a partir de uma imagem",
|
||||
"create-recipe-from-an-image-description": "Crie uma receita carregando uma imagem da mesma. O Mealie tentará extrair o texto da imagem utilizando IA e criará uma receita a partir da mesma.",
|
||||
"crop-and-rotate-the-image": "Recorte e rode a imagem de modo a que apenas o texto seja visível e esteja na orientação correta.",
|
||||
"create-from-images": "Create from Images",
|
||||
"create-from-images": "Criar a partir de Imagens",
|
||||
"should-translate-description": "Traduzir a receita para a minha língua",
|
||||
"please-wait-image-procesing": "Aguarde, a imagem está a ser processada. Isto pode demorar algum tempo.",
|
||||
"please-wait-images-processing": "Please wait, the images are processing. This may take some time.",
|
||||
"please-wait-images-processing": "A processar imagens… Isto pode demorar um pouco.",
|
||||
"bulk-url-import": "Importação de URL em bloco",
|
||||
"debug-scraper": "Depurar Scraper",
|
||||
"create-a-recipe-by-providing-the-name-all-recipes-must-have-unique-names": "Crie uma receita fornecendo o nome. Todas as receitas devem ter nomes únicos.",
|
||||
|
@ -663,15 +664,15 @@
|
|||
"no-unit": "Nenhuma unidade",
|
||||
"missing-unit": "Criar unidade em falta: {unit}",
|
||||
"missing-food": "Criar ingrediente em falta: {food}",
|
||||
"this-unit-could-not-be-parsed-automatically": "This unit could not be parsed automatically",
|
||||
"this-food-could-not-be-parsed-automatically": "This food could not be parsed automatically",
|
||||
"this-unit-could-not-be-parsed-automatically": "Não foi possível processar automaticamente esta unidade",
|
||||
"this-food-could-not-be-parsed-automatically": "Não foi possível processar automaticamente este alimento",
|
||||
"no-food": "Nenhum Ingrediente"
|
||||
},
|
||||
"reset-servings-count": "Reiniciar Contador de Doses",
|
||||
"not-linked-ingredients": "Ingredientes Adicionais",
|
||||
"upload-another-image": "Upload another image",
|
||||
"upload-images": "Upload images",
|
||||
"upload-more-images": "Upload more images"
|
||||
"upload-another-image": "Carregar outra imagem",
|
||||
"upload-images": "Carregar imagens",
|
||||
"upload-more-images": "Carregar mais imagens"
|
||||
},
|
||||
"recipe-finder": {
|
||||
"recipe-finder": "Localizador de Receitas",
|
||||
|
@ -731,7 +732,7 @@
|
|||
"backup-restore": "Restaurar backup",
|
||||
"back-restore-description": "Restaurar este backup irá apagar todos os dados atuais da sua base de dados e da pasta de dados e substituí-los pelo conteúdo deste backup. {cannot-be-undone} Se o restauro for bem-sucedido, a sua sessão será encerrada.",
|
||||
"cannot-be-undone": "Esta acção não pode ser desfeita - use com prudência.",
|
||||
"postgresql-note": "If you are using PostgreSQL, please review the {backup-restore-process} prior to restoring.",
|
||||
"postgresql-note": "Se estiver a usar PostgreSQL, por favor reveja o {backup-restore-process} antes de restaurar.",
|
||||
"backup-restore-process-in-the-documentation": "processo de backup/restauro na documentação",
|
||||
"irreversible-acknowledgment": "Eu entendo que esta ação é irreversível, destrutiva e pode causar perda de dados",
|
||||
"restore-backup": "Restaurar Backup"
|
||||
|
|
|
@ -587,6 +587,7 @@
|
|||
"api-extras-description": "Дополнения к рецептам являются ключевым элементом Mealie API. Они позволяют создавать пользовательские пары json ключ/значение в рецепте для ссылания на другие приложения. Вы можете использовать эти ключи, чтобы сохранить нужную информацию, например, для автоматизаций или уведомлений на ваши устройства.",
|
||||
"message-key": "Ключ сообщения",
|
||||
"parse": "Обработать",
|
||||
"ingredients-not-parsed-description": "It looks like your ingredients aren't parsed yet. Click the \"{parse}\" button below to parse your ingredients into structured foods.",
|
||||
"attach-images-hint": "Прикрепляйте изображения, перетаскивая их в редактор",
|
||||
"drop-image": "Перетащите изображение",
|
||||
"enable-ingredient-amounts-to-use-this-feature": "Включите количество ингредиентов для использования этой функции",
|
||||
|
|
|
@ -587,6 +587,7 @@
|
|||
"api-extras-description": "API dolnky receptov sú kľúčovou funkcionalitou Mealie API. Umožňujú používateľom vytvárať vlastné JSON páry kľúč/hodnota v rámci receptu, a využiť v aplikáciách tretích strán. Údaje uložené pod jednotlivými kľúčmi je možné využiť napríklad ako spúšťač automatizovaných procesov, či pri zasielaní vlastných správ do vami zvolených zariadení.",
|
||||
"message-key": "Kľúč správy",
|
||||
"parse": "Analyzovať",
|
||||
"ingredients-not-parsed-description": "It looks like your ingredients aren't parsed yet. Click the \"{parse}\" button below to parse your ingredients into structured foods.",
|
||||
"attach-images-hint": "Pridaj obrázky ich potiahnutím a pustením na editor",
|
||||
"drop-image": "Odstrániť obrázok",
|
||||
"enable-ingredient-amounts-to-use-this-feature": "Povoľ množstvám prísad využívať túto vlastnosť",
|
||||
|
|
|
@ -587,6 +587,7 @@
|
|||
"api-extras-description": "Dodatni podatki za recepte so ključna funkcionalnost Mealie APIja. Omogočajo ustvarjanje lastnih JSON ključ / vrednost parov v okviru recepta, da lahko do njih dostopajo zunanje aplikacije. Te ključe lahko uporabiš za posredovanje informacij, na primer za sprožanje avtomatike ali sporočanje prilagojenih sporočil na poljubno napravo.",
|
||||
"message-key": "Ključ sporočila",
|
||||
"parse": "Razloči",
|
||||
"ingredients-not-parsed-description": "It looks like your ingredients aren't parsed yet. Click the \"{parse}\" button below to parse your ingredients into structured foods.",
|
||||
"attach-images-hint": "Slike pripneš z odlaganjem v urejevalnik",
|
||||
"drop-image": "Odloži sliko",
|
||||
"enable-ingredient-amounts-to-use-this-feature": "Vključi količine sestavin, da uporabiš to funkcijo",
|
||||
|
|
|
@ -587,6 +587,7 @@
|
|||
"api-extras-description": "Recipes extras are a key feature of the Mealie API. They allow you to create custom JSON key/value pairs within a recipe, to reference from 3rd party applications. You can use these keys to provide information, for example to trigger automations or custom messages to relay to your desired device.",
|
||||
"message-key": "Message Key",
|
||||
"parse": "Parse",
|
||||
"ingredients-not-parsed-description": "It looks like your ingredients aren't parsed yet. Click the \"{parse}\" button below to parse your ingredients into structured foods.",
|
||||
"attach-images-hint": "Attach images by dragging & dropping them into the editor",
|
||||
"drop-image": "Drop image",
|
||||
"enable-ingredient-amounts-to-use-this-feature": "Enable ingredient amounts to use this feature",
|
||||
|
|
|
@ -587,6 +587,7 @@
|
|||
"api-extras-description": "Recept API-tillägg är en viktig funktion i Mealie's API. Med hjälp av dem kan du skapa anpassade JSON-nyckel/värdepar i ett recept, som du kan referera till från tredjepartsapplikationer. Du kan använda dessa nycklar för att tillhandahålla information, till exempel för att trigga automatiseringar eller anpassade meddelanden som ska vidarebefordras till önskad enhet.",
|
||||
"message-key": "Meddelandenyckel",
|
||||
"parse": "Läs in",
|
||||
"ingredients-not-parsed-description": "It looks like your ingredients aren't parsed yet. Click the \"{parse}\" button below to parse your ingredients into structured foods.",
|
||||
"attach-images-hint": "Bifoga bilder genom att dra och släppa dem i redigeraren",
|
||||
"drop-image": "Släpp bild",
|
||||
"enable-ingredient-amounts-to-use-this-feature": "Aktivera ingrediensmängd för att använda denna funktion",
|
||||
|
@ -663,8 +664,8 @@
|
|||
"no-unit": "Ingen enhet",
|
||||
"missing-unit": "Skapa saknad enhet: {unit}",
|
||||
"missing-food": "Skapa saknad ingrediens: {food}",
|
||||
"this-unit-could-not-be-parsed-automatically": "This unit could not be parsed automatically",
|
||||
"this-food-could-not-be-parsed-automatically": "This food could not be parsed automatically",
|
||||
"this-unit-could-not-be-parsed-automatically": "Enheten kunde inte översättas automatiskt",
|
||||
"this-food-could-not-be-parsed-automatically": "Maten kunde inte översättas automatiskt",
|
||||
"no-food": "Ingen mat"
|
||||
},
|
||||
"reset-servings-count": "Nollställ antal portioner",
|
||||
|
|
|
@ -587,6 +587,7 @@
|
|||
"api-extras-description": "Tarif ekstraları Mealie API'nin önemli bir özelliğidir. Üçüncü taraf uygulamalardan referans almak üzere bir tarif içinde özel JSON anahtar/değer çiftleri oluşturmanıza olanak tanır. Bu tuşları, örneğin otomasyonları tetiklemek veya istediğiniz cihaza iletilecek özel mesajları bilgi sağlamak için kullanabilirsiniz.",
|
||||
"message-key": "İleti Anahtarı",
|
||||
"parse": "Ayrıştırma",
|
||||
"ingredients-not-parsed-description": "It looks like your ingredients aren't parsed yet. Click the \"{parse}\" button below to parse your ingredients into structured foods.",
|
||||
"attach-images-hint": "Düzenleyiciye sürükleyip bırakarak görselleri ekleyin",
|
||||
"drop-image": "Yüklenecek resimi sürükleyip bırakın",
|
||||
"enable-ingredient-amounts-to-use-this-feature": "Bu özelliği kullanabilmek için malzeme miktarlarını etkinleştirin",
|
||||
|
|
|
@ -587,6 +587,7 @@
|
|||
"api-extras-description": "Додатки в рецептах - ключова функція API Mealie. Вони дозволяють створювати користувацьку пару JSON ключів та значень в рецепті для сторонніх додатків. Це можна використовувати для автоматизації або для створення користувацьких повідомлень для сторонніх сервісів.",
|
||||
"message-key": "Ключ повідомлення",
|
||||
"parse": "Проаналізувати",
|
||||
"ingredients-not-parsed-description": "It looks like your ingredients aren't parsed yet. Click the \"{parse}\" button below to parse your ingredients into structured foods.",
|
||||
"attach-images-hint": "Прикріпіть зображення, перетягнувши їх у редактор",
|
||||
"drop-image": "Перетягніть зображення",
|
||||
"enable-ingredient-amounts-to-use-this-feature": "Увімкніть кількість інгредієнтів, щоб використовувати цю функцію",
|
||||
|
|
|
@ -587,6 +587,7 @@
|
|||
"api-extras-description": "Recipes extras are a key feature of the Mealie API. They allow you to create custom JSON key/value pairs within a recipe, to reference from 3rd party applications. You can use these keys to provide information, for example to trigger automations or custom messages to relay to your desired device.",
|
||||
"message-key": "Message Key",
|
||||
"parse": "Parse",
|
||||
"ingredients-not-parsed-description": "It looks like your ingredients aren't parsed yet. Click the \"{parse}\" button below to parse your ingredients into structured foods.",
|
||||
"attach-images-hint": "Attach images by dragging & dropping them into the editor",
|
||||
"drop-image": "Drop image",
|
||||
"enable-ingredient-amounts-to-use-this-feature": "Enable ingredient amounts to use this feature",
|
||||
|
|
|
@ -587,6 +587,7 @@
|
|||
"api-extras-description": "食谱扩展是Mealie API的关键功能之一。它允许你在食谱中添加自定义JSON键值对,以供第三方程序使用。你可以利用这些键提供信息,实现更多功能,例如触发自动化,或转发自定义信息到指定的设备上。",
|
||||
"message-key": "键名",
|
||||
"parse": "自动解析",
|
||||
"ingredients-not-parsed-description": "It looks like your ingredients aren't parsed yet. Click the \"{parse}\" button below to parse your ingredients into structured foods.",
|
||||
"attach-images-hint": "如需添加图片,可将其拖拽到编辑器",
|
||||
"drop-image": "拖放图片",
|
||||
"enable-ingredient-amounts-to-use-this-feature": "使用此项功能需启用食材用量",
|
||||
|
|
|
@ -587,6 +587,7 @@
|
|||
"api-extras-description": "Recipes extras are a key feature of the Mealie API. They allow you to create custom JSON key/value pairs within a recipe, to reference from 3rd party applications. You can use these keys to provide information, for example to trigger automations or custom messages to relay to your desired device.",
|
||||
"message-key": "Message Key",
|
||||
"parse": "Parse",
|
||||
"ingredients-not-parsed-description": "It looks like your ingredients aren't parsed yet. Click the \"{parse}\" button below to parse your ingredients into structured foods.",
|
||||
"attach-images-hint": "Attach images by dragging & dropping them into the editor",
|
||||
"drop-image": "Drop image",
|
||||
"enable-ingredient-amounts-to-use-this-feature": "Enable ingredient amounts to use this feature",
|
||||
|
|
|
@ -22,7 +22,6 @@ export interface CreateHouseholdPreferences {
|
|||
recipeShowAssets?: boolean;
|
||||
recipeLandscapeView?: boolean;
|
||||
recipeDisableComments?: boolean;
|
||||
recipeDisableAmount?: boolean;
|
||||
}
|
||||
export interface CreateInviteToken {
|
||||
uses: number;
|
||||
|
@ -191,7 +190,6 @@ export interface ReadHouseholdPreferences {
|
|||
recipeShowAssets?: boolean;
|
||||
recipeLandscapeView?: boolean;
|
||||
recipeDisableComments?: boolean;
|
||||
recipeDisableAmount?: boolean;
|
||||
id: string;
|
||||
}
|
||||
export interface HouseholdUserSummary {
|
||||
|
@ -269,7 +267,6 @@ export interface SaveHouseholdPreferences {
|
|||
recipeShowAssets?: boolean;
|
||||
recipeLandscapeView?: boolean;
|
||||
recipeDisableComments?: boolean;
|
||||
recipeDisableAmount?: boolean;
|
||||
householdId: string;
|
||||
}
|
||||
export interface SaveInviteToken {
|
||||
|
@ -303,8 +300,6 @@ export interface RecipeIngredient {
|
|||
unit?: IngredientUnit | CreateIngredientUnit | null;
|
||||
food?: IngredientFood | CreateIngredientFood | null;
|
||||
note?: string | null;
|
||||
isFood?: boolean | null;
|
||||
disableAmount?: boolean;
|
||||
display?: string;
|
||||
title?: string | null;
|
||||
originalText?: string | null;
|
||||
|
@ -409,8 +404,6 @@ export interface ShoppingListItemBase {
|
|||
unit?: IngredientUnit | CreateIngredientUnit | null;
|
||||
food?: IngredientFood | CreateIngredientFood | null;
|
||||
note?: string | null;
|
||||
isFood?: boolean;
|
||||
disableAmount?: boolean | null;
|
||||
display?: string;
|
||||
shoppingListId: string;
|
||||
checked?: boolean;
|
||||
|
@ -427,8 +420,6 @@ export interface ShoppingListItemCreate {
|
|||
unit?: IngredientUnit | CreateIngredientUnit | null;
|
||||
food?: IngredientFood | CreateIngredientFood | null;
|
||||
note?: string | null;
|
||||
isFood?: boolean;
|
||||
disableAmount?: boolean | null;
|
||||
display?: string;
|
||||
shoppingListId: string;
|
||||
checked?: boolean;
|
||||
|
@ -453,8 +444,6 @@ export interface ShoppingListItemOut {
|
|||
unit?: IngredientUnit | null;
|
||||
food?: IngredientFood | null;
|
||||
note?: string | null;
|
||||
isFood?: boolean;
|
||||
disableAmount?: boolean | null;
|
||||
display?: string;
|
||||
shoppingListId: string;
|
||||
checked?: boolean;
|
||||
|
@ -494,8 +483,6 @@ export interface ShoppingListItemUpdate {
|
|||
unit?: IngredientUnit | CreateIngredientUnit | null;
|
||||
food?: IngredientFood | CreateIngredientFood | null;
|
||||
note?: string | null;
|
||||
isFood?: boolean;
|
||||
disableAmount?: boolean | null;
|
||||
display?: string;
|
||||
shoppingListId: string;
|
||||
checked?: boolean;
|
||||
|
@ -513,8 +500,6 @@ export interface ShoppingListItemUpdateBulk {
|
|||
unit?: IngredientUnit | CreateIngredientUnit | null;
|
||||
food?: IngredientFood | CreateIngredientFood | null;
|
||||
note?: string | null;
|
||||
isFood?: boolean;
|
||||
disableAmount?: boolean | null;
|
||||
display?: string;
|
||||
shoppingListId: string;
|
||||
checked?: boolean;
|
||||
|
@ -679,14 +664,11 @@ export interface UpdateHouseholdPreferences {
|
|||
recipeShowAssets?: boolean;
|
||||
recipeLandscapeView?: boolean;
|
||||
recipeDisableComments?: boolean;
|
||||
recipeDisableAmount?: boolean;
|
||||
}
|
||||
export interface RecipeIngredientBase {
|
||||
quantity?: number | null;
|
||||
unit?: IngredientUnit | CreateIngredientUnit | null;
|
||||
food?: IngredientFood | CreateIngredientFood | null;
|
||||
note?: string | null;
|
||||
isFood?: boolean | null;
|
||||
disableAmount?: boolean | null;
|
||||
display?: string;
|
||||
}
|
||||
|
|
|
@ -31,7 +31,6 @@ export interface RecipeSettings {
|
|||
showAssets?: boolean;
|
||||
landscapeView?: boolean;
|
||||
disableComments?: boolean;
|
||||
disableAmount?: boolean;
|
||||
locked?: boolean;
|
||||
}
|
||||
export interface AssignTags {
|
||||
|
@ -212,8 +211,6 @@ export interface RecipeIngredient {
|
|||
unit?: IngredientUnit | CreateIngredientUnit | null;
|
||||
food?: IngredientFood | CreateIngredientFood | null;
|
||||
note?: string | null;
|
||||
isFood?: boolean | null;
|
||||
disableAmount?: boolean;
|
||||
display?: string;
|
||||
title?: string | null;
|
||||
originalText?: string | null;
|
||||
|
@ -347,8 +344,6 @@ export interface RecipeIngredientBase {
|
|||
unit?: IngredientUnit | CreateIngredientUnit | null;
|
||||
food?: IngredientFood | CreateIngredientFood | null;
|
||||
note?: string | null;
|
||||
isFood?: boolean | null;
|
||||
disableAmount?: boolean | null;
|
||||
display?: string;
|
||||
}
|
||||
export interface RecipeLastMade {
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
color="gray"
|
||||
secondary
|
||||
target="_blank"
|
||||
href="https://github.com/hay-kot/mealie/issues/new/choose"
|
||||
href="https://github.com/mealie-recipes/mealie/issues/new/choose"
|
||||
>
|
||||
<template #icon>
|
||||
{{ $globals.icons.github }}
|
||||
|
|
|
@ -364,7 +364,6 @@ export default defineNuxtComponent({
|
|||
confidence: {},
|
||||
ingredient: {
|
||||
quantity: 1.0,
|
||||
disableAmount: false,
|
||||
referenceId: uuid4(),
|
||||
},
|
||||
} as ParsedIngredient;
|
||||
|
@ -409,10 +408,6 @@ export default defineNuxtComponent({
|
|||
}
|
||||
|
||||
recipe.value.recipeIngredient = ingredients;
|
||||
if (recipe.value.settings) {
|
||||
recipe.value.settings.disableAmount = false;
|
||||
}
|
||||
|
||||
const { response } = await api.recipes.updateOne(recipe.value.slug, recipe.value);
|
||||
|
||||
if (response?.status === 200) {
|
||||
|
|
|
@ -88,7 +88,7 @@
|
|||
{{ $t("new-recipe.google-ld-json-info") }}
|
||||
</a>
|
||||
<a
|
||||
href="https://github.com/hay-kot/mealie/issues"
|
||||
href="https://github.com/mealie-recipes/mealie/issues"
|
||||
target="_blank"
|
||||
rel="noreferrer nofollow"
|
||||
>
|
||||
|
|
|
@ -415,7 +415,6 @@ export default defineNuxtComponent({
|
|||
showAssets: false,
|
||||
landscapeView: false,
|
||||
disableComments: false,
|
||||
disableAmount: false,
|
||||
locked: false,
|
||||
});
|
||||
|
||||
|
|
|
@ -95,12 +95,6 @@ export default defineNuxtComponent({
|
|||
label: i18n.t("group.disable-users-from-commenting-on-recipes"),
|
||||
description: i18n.t("group.disable-users-from-commenting-on-recipes-description"),
|
||||
} as Preference,
|
||||
{
|
||||
key: "recipeDisableAmount",
|
||||
value: household.value.preferences.recipeDisableAmount || false,
|
||||
label: i18n.t("group.disable-organizing-recipe-ingredients-by-units-and-food"),
|
||||
description: i18n.t("group.disable-organizing-recipe-ingredients-by-units-and-food-description"),
|
||||
} as Preference,
|
||||
];
|
||||
});
|
||||
|
||||
|
|
|
@ -191,7 +191,7 @@
|
|||
{
|
||||
text: $t('about.github'),
|
||||
icon: $globals.icons.github,
|
||||
href: 'https://github.com/hay-kot/mealie',
|
||||
href: 'https://github.com/mealie-recipes/mealie',
|
||||
},
|
||||
{
|
||||
text: $t('about.docs'),
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
"""empty migration to fix food flag data
|
||||
|
||||
Revision ID: d7b3ce6fa31a
|
||||
Revises: 7cf3054cbbcc
|
||||
Create Date: 2025-07-11 20:17:10.543280
|
||||
|
||||
"""
|
||||
|
||||
from textwrap import dedent
|
||||
|
||||
from alembic import op
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = "d7b3ce6fa31a"
|
||||
down_revision: str | None = "7cf3054cbbcc"
|
||||
branch_labels: str | tuple[str, ...] | None = None
|
||||
depends_on: str | tuple[str, ...] | None = None
|
||||
|
||||
|
||||
def is_postgres():
|
||||
return op.get_context().dialect.name == "postgresql"
|
||||
|
||||
|
||||
def upgrade():
|
||||
# Update recipes with disable_amount=True: set ingredient quantities of 1 to 0
|
||||
op.execute(
|
||||
dedent(
|
||||
f"""
|
||||
UPDATE recipes_ingredients
|
||||
SET quantity = 0
|
||||
WHERE quantity = 1
|
||||
AND recipe_id IN (
|
||||
SELECT r.id
|
||||
FROM recipes r
|
||||
JOIN recipe_settings rs ON r.id = rs.recipe_id
|
||||
WHERE rs.disable_amount = {"true" if is_postgres() else "1"}
|
||||
)
|
||||
"""
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def downgrade():
|
||||
pass
|
|
@ -15,7 +15,7 @@ def get_latest_github_release() -> str:
|
|||
str: The latest release from GitHub.
|
||||
"""
|
||||
|
||||
url = "https://api.github.com/repos/hay-kot/mealie/releases/latest"
|
||||
url = "https://api.github.com/repos/mealie-recipes/mealie/releases/latest"
|
||||
response = requests.get(url)
|
||||
response.raise_for_status()
|
||||
return response.json()["tag_name"]
|
||||
|
|
|
@ -31,6 +31,8 @@ class HouseholdPreferencesModel(SqlAlchemyBase, BaseMixins):
|
|||
recipe_show_assets: Mapped[bool | None] = mapped_column(sa.Boolean, default=False)
|
||||
recipe_landscape_view: Mapped[bool | None] = mapped_column(sa.Boolean, default=False)
|
||||
recipe_disable_comments: Mapped[bool | None] = mapped_column(sa.Boolean, default=False)
|
||||
|
||||
# Deprecated
|
||||
recipe_disable_amount: Mapped[bool | None] = mapped_column(sa.Boolean, default=True)
|
||||
|
||||
@auto_init()
|
||||
|
|
|
@ -65,7 +65,6 @@ class ShoppingListItem(SqlAlchemyBase, BaseMixins):
|
|||
quantity: Mapped[float | None] = mapped_column(Float, default=1)
|
||||
note: Mapped[str | None] = mapped_column(String)
|
||||
|
||||
is_food: Mapped[bool | None] = mapped_column(Boolean, default=False)
|
||||
extras: Mapped[list[ShoppingListItemExtras]] = orm.relationship(
|
||||
"ShoppingListItemExtras", cascade="all, delete-orphan"
|
||||
)
|
||||
|
@ -88,6 +87,9 @@ class ShoppingListItem(SqlAlchemyBase, BaseMixins):
|
|||
)
|
||||
model_config = ConfigDict(exclude={"label", "food", "unit"})
|
||||
|
||||
# Deprecated
|
||||
is_food: Mapped[bool | None] = mapped_column(Boolean, default=False)
|
||||
|
||||
@api_extras
|
||||
@auto_init()
|
||||
def __init__(self, **_) -> None:
|
||||
|
|
|
@ -13,10 +13,12 @@ class RecipeSettings(SqlAlchemyBase):
|
|||
show_nutrition: Mapped[bool | None] = mapped_column(sa.Boolean)
|
||||
show_assets: Mapped[bool | None] = mapped_column(sa.Boolean)
|
||||
landscape_view: Mapped[bool | None] = mapped_column(sa.Boolean)
|
||||
disable_amount: Mapped[bool | None] = mapped_column(sa.Boolean, default=True)
|
||||
disable_comments: Mapped[bool | None] = mapped_column(sa.Boolean, default=False)
|
||||
locked: Mapped[bool | None] = mapped_column(sa.Boolean, default=False)
|
||||
|
||||
# Deprecated
|
||||
disable_amount: Mapped[bool | None] = mapped_column(sa.Boolean, default=True)
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
public=True,
|
||||
|
|
|
@ -440,7 +440,6 @@ class RepositoryRecipes(HouseholdRepositoryGeneric[Recipe, RecipeModel]):
|
|||
)
|
||||
q = (
|
||||
q.join(settings_alias, self.model.settings)
|
||||
.filter(settings_alias.disable_amount == False) # noqa: E712 - required for SQLAlchemy comparison
|
||||
.outerjoin(unmatched_foods_query, self.model.id == unmatched_foods_query.c.recipe_id)
|
||||
.outerjoin(total_user_foods_query, self.model.id == total_user_foods_query.c.recipe_id)
|
||||
.filter(
|
||||
|
|
|
@ -7184,8 +7184,8 @@
|
|||
"thai red curry paste": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "thai red curry paste",
|
||||
"plural_name": "thai red curry pastes"
|
||||
"name": "Rote Thai-Currypaste",
|
||||
"plural_name": "Rote Thai-Currypasten"
|
||||
},
|
||||
"mixed herb": {
|
||||
"aliases": [],
|
||||
|
@ -7304,8 +7304,8 @@
|
|||
"teriyaki marinade": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "teriyaki marinade",
|
||||
"plural_name": "teriyaki marinades"
|
||||
"name": "Teriyaki Marinade",
|
||||
"plural_name": "Teriyaki Marinaden"
|
||||
},
|
||||
"adobo seasoning": {
|
||||
"aliases": [],
|
||||
|
@ -7622,8 +7622,8 @@
|
|||
"tom yum paste": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "tom yum paste",
|
||||
"plural_name": "tom yum pastes"
|
||||
"name": "Tom Yum Paste",
|
||||
"plural_name": "Tom Yum Pasten"
|
||||
},
|
||||
"fish masala": {
|
||||
"aliases": [],
|
||||
|
@ -7671,8 +7671,8 @@
|
|||
"baking soda": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "baking soda",
|
||||
"plural_name": "baking sodas"
|
||||
"name": "Backpulver",
|
||||
"plural_name": "Backpulver"
|
||||
},
|
||||
"cornstarch": {
|
||||
"aliases": [],
|
||||
|
@ -9464,8 +9464,8 @@
|
|||
"hyacinth bean": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "hyacinth bean",
|
||||
"plural_name": "hyacinth beans"
|
||||
"name": "Helmbohne",
|
||||
"plural_name": "Helmbohnen"
|
||||
},
|
||||
"petai": {
|
||||
"aliases": [],
|
||||
|
@ -9476,14 +9476,14 @@
|
|||
"scarlet runner bean": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "scarlet runner bean",
|
||||
"plural_name": "scarlet runner beans"
|
||||
"name": "Feuerbohne",
|
||||
"plural_name": "Feuerbohnen"
|
||||
},
|
||||
"soy flake": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "soy flake",
|
||||
"plural_name": "soy flakes"
|
||||
"name": "Sojaflocke",
|
||||
"plural_name": "Sojaflocken"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -9492,8 +9492,8 @@
|
|||
"short-cut pasta": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "short-cut pasta",
|
||||
"plural_name": "short-cut pastas"
|
||||
"name": "kurze Nudel",
|
||||
"plural_name": "kurze Nudeln"
|
||||
},
|
||||
"spaghetti": {
|
||||
"aliases": [],
|
||||
|
@ -9516,8 +9516,8 @@
|
|||
"spiral pasta": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "spiral pasta",
|
||||
"plural_name": "spiral pastas"
|
||||
"name": "Spiralnudel",
|
||||
"plural_name": "Spiralnudeln"
|
||||
},
|
||||
"lasagna noodle": {
|
||||
"aliases": [
|
||||
|
@ -9548,14 +9548,14 @@
|
|||
"pasta shell": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "pasta shell",
|
||||
"plural_name": "pasta shells"
|
||||
"name": "Muschelnudel",
|
||||
"plural_name": "Muschelnudeln"
|
||||
},
|
||||
"bow-tie pasta": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "bow-tie pasta",
|
||||
"plural_name": "bow-tie pastas"
|
||||
"name": "Farfalle",
|
||||
"plural_name": "Farfalle"
|
||||
},
|
||||
"noodle": {
|
||||
"aliases": [],
|
||||
|
@ -9572,8 +9572,8 @@
|
|||
"cheese tortellini": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "cheese tortellini",
|
||||
"plural_name": "cheese tortellinis"
|
||||
"name": "Käse-Tortellini",
|
||||
"plural_name": "Käse-Tortellini"
|
||||
},
|
||||
"rice noodle": {
|
||||
"aliases": [],
|
||||
|
@ -9596,8 +9596,8 @@
|
|||
"angel hair pasta": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "angel hair pasta",
|
||||
"plural_name": "angel hair pastas"
|
||||
"name": "Capelli d’angelo",
|
||||
"plural_name": "Capelli d’angelo"
|
||||
},
|
||||
"ramen noodle": {
|
||||
"aliases": [],
|
||||
|
@ -9608,8 +9608,8 @@
|
|||
"vermicelli": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "vermicelli",
|
||||
"plural_name": "vermicellis"
|
||||
"name": "Vermicelli",
|
||||
"plural_name": "Vermicelli"
|
||||
},
|
||||
"tagliatelle": {
|
||||
"aliases": [],
|
||||
|
@ -9632,8 +9632,8 @@
|
|||
"ziti": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "ziti",
|
||||
"plural_name": "zitis"
|
||||
"name": "Ziti",
|
||||
"plural_name": "Ziti"
|
||||
},
|
||||
"orecchiette": {
|
||||
"aliases": [],
|
||||
|
@ -9644,8 +9644,8 @@
|
|||
"israeli couscou": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "israeli couscou",
|
||||
"plural_name": "israeli couscous"
|
||||
"name": "Perlcouscous",
|
||||
"plural_name": "Perlcouscous"
|
||||
},
|
||||
"zoodle": {
|
||||
"aliases": [],
|
||||
|
@ -9662,20 +9662,20 @@
|
|||
"ditalini": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "ditalini",
|
||||
"plural_name": "ditalinis"
|
||||
"name": "Ditalini",
|
||||
"plural_name": "Ditalini"
|
||||
},
|
||||
"rice vermicelli": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "rice vermicelli",
|
||||
"plural_name": "rice vermicellis"
|
||||
"name": "Reis-Vermicelli",
|
||||
"plural_name": "Reis-Vermicelli"
|
||||
},
|
||||
"pappardelle": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "pappardelle",
|
||||
"plural_name": "pappardelles"
|
||||
"name": "Pappardella",
|
||||
"plural_name": "Pappardelle"
|
||||
},
|
||||
"glass noodle": {
|
||||
"aliases": [],
|
||||
|
@ -9692,26 +9692,26 @@
|
|||
"mac 'n cheese": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "mac 'n cheese",
|
||||
"plural_name": "mac 'n cheeses"
|
||||
"name": "Mac 'n Cheese",
|
||||
"plural_name": "Mac 'n Cheese"
|
||||
},
|
||||
"penne rigate": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "penne rigate",
|
||||
"plural_name": "penne rigates"
|
||||
"name": "Penne rigate",
|
||||
"plural_name": "Penne rigate"
|
||||
},
|
||||
"manicotti": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "manicotti",
|
||||
"plural_name": "manicottis"
|
||||
"name": "Manicotto",
|
||||
"plural_name": "Manicotti"
|
||||
},
|
||||
"bucatini": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "bucatini",
|
||||
"plural_name": "bucatinis"
|
||||
"name": "Bucatini",
|
||||
"plural_name": "Bucatini"
|
||||
},
|
||||
"cannelloni": {
|
||||
"aliases": [],
|
||||
|
@ -9734,8 +9734,8 @@
|
|||
"rotelle": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "rotelle",
|
||||
"plural_name": "rotelles"
|
||||
"name": "Rotelle",
|
||||
"plural_name": "Rotelle"
|
||||
},
|
||||
"shirataki noodle": {
|
||||
"aliases": [],
|
||||
|
@ -9770,14 +9770,14 @@
|
|||
"acini di pepe": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "acini di pepe",
|
||||
"plural_name": "acini di pepes"
|
||||
"name": "Acini di pepe",
|
||||
"plural_name": "Acini di pepe"
|
||||
},
|
||||
"cavatelli": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "cavatelli",
|
||||
"plural_name": "cavatellis"
|
||||
"name": "Cavatelli",
|
||||
"plural_name": "Cavatelli"
|
||||
},
|
||||
"instant noodle": {
|
||||
"aliases": [],
|
||||
|
@ -13006,8 +13006,8 @@
|
|||
"curry sauce": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "curry sauce",
|
||||
"plural_name": "curry sauces"
|
||||
"name": "Currysauce",
|
||||
"plural_name": "Currysaucen"
|
||||
},
|
||||
"liver spread": {
|
||||
"aliases": [],
|
||||
|
@ -13066,7 +13066,7 @@
|
|||
"japanese curry": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "japanese curry",
|
||||
"name": "Japanisches Curry",
|
||||
"plural_name": "japanese curries"
|
||||
},
|
||||
"mango salsa": {
|
||||
|
|
|
@ -2081,8 +2081,8 @@
|
|||
"swiss cheese": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "swiss cheese",
|
||||
"plural_name": "swiss cheeses"
|
||||
"name": "zwitserse kaas",
|
||||
"plural_name": "zwitserse kazen"
|
||||
},
|
||||
"pecorino": {
|
||||
"aliases": [],
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "alho",
|
||||
"plural_name": "garlics"
|
||||
"plural_name": "alhos"
|
||||
},
|
||||
"onion": {
|
||||
"aliases": [],
|
||||
|
@ -28,94 +28,94 @@
|
|||
"scallion": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "scallion",
|
||||
"plural_name": "scallions"
|
||||
"name": "cebolinho",
|
||||
"plural_name": "cebolinhos"
|
||||
},
|
||||
"zucchini": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "zucchini",
|
||||
"plural_name": "zucchinis"
|
||||
"name": "courgette",
|
||||
"plural_name": "courgettes"
|
||||
},
|
||||
"potato": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "potato",
|
||||
"name": "batata",
|
||||
"plural_name": "batatas"
|
||||
},
|
||||
"red onion": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "red onion",
|
||||
"plural_name": "red onions"
|
||||
"name": "cebola roxa",
|
||||
"plural_name": "cebolas roxas"
|
||||
},
|
||||
"yellow onion": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "yellow onion",
|
||||
"plural_name": "yellow onions"
|
||||
"name": "cebola",
|
||||
"plural_name": "cebolas"
|
||||
},
|
||||
"celery": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "celery",
|
||||
"plural_name": "celeries"
|
||||
"name": "aipo",
|
||||
"plural_name": "aipos"
|
||||
},
|
||||
"jalapeno": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "jalapeno",
|
||||
"plural_name": "jalapenoes"
|
||||
"name": "jalapeño",
|
||||
"plural_name": "jalapeños"
|
||||
},
|
||||
"avocado": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "avocado",
|
||||
"plural_name": "avocados"
|
||||
"name": "abacate",
|
||||
"plural_name": "abacates"
|
||||
},
|
||||
"shallot": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "shallot",
|
||||
"plural_name": "shallots"
|
||||
"name": "chalota",
|
||||
"plural_name": "chalotas"
|
||||
},
|
||||
"cherry tomato": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "cherry tomato",
|
||||
"plural_name": "cherry tomatoes"
|
||||
"name": "tomate cherry",
|
||||
"plural_name": "tomates cherry"
|
||||
},
|
||||
"cucumber": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "cucumber",
|
||||
"plural_name": "cucumbers"
|
||||
"name": "pepino",
|
||||
"plural_name": "pepinos"
|
||||
},
|
||||
"spinach": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "spinach",
|
||||
"plural_name": "spinaches"
|
||||
"name": "espinafre",
|
||||
"plural_name": "espinafres"
|
||||
},
|
||||
"sweet corn": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "sweet corn",
|
||||
"plural_name": "sweet corns"
|
||||
"name": "milho doce",
|
||||
"plural_name": "milhos doces"
|
||||
},
|
||||
"chile pepper": {
|
||||
"aliases": [
|
||||
"capsicum"
|
||||
"pimento"
|
||||
],
|
||||
"description": "",
|
||||
"name": "chile pepper",
|
||||
"plural_name": "chile peppers"
|
||||
"name": "malagueta",
|
||||
"plural_name": "malaguetas"
|
||||
},
|
||||
"sweet potato": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "sweet potato",
|
||||
"plural_name": "sweet potatoes"
|
||||
"name": "batata doce",
|
||||
"plural_name": "batatas doces"
|
||||
},
|
||||
"broccoli": {
|
||||
"aliases": [],
|
||||
|
|
|
@ -11659,7 +11659,7 @@
|
|||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "gochujang",
|
||||
"plural_name": "gochujangs"
|
||||
"plural_name": "gochujang"
|
||||
},
|
||||
"wasabi": {
|
||||
"aliases": [],
|
||||
|
@ -11742,8 +11742,8 @@
|
|||
"tartar sauce": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "tartar sauce",
|
||||
"plural_name": "tartar sauces"
|
||||
"name": "tartarsås",
|
||||
"plural_name": "tartarsåser"
|
||||
},
|
||||
"hot pepper jelly": {
|
||||
"aliases": [],
|
||||
|
@ -12060,8 +12060,8 @@
|
|||
"banana ketchup": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "banana ketchup",
|
||||
"plural_name": "banana ketchups"
|
||||
"name": "bananketchup",
|
||||
"plural_name": "bananketchuper"
|
||||
},
|
||||
"chili puree": {
|
||||
"aliases": [],
|
||||
|
@ -12723,7 +12723,7 @@
|
|||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "salsa",
|
||||
"plural_name": "salsas"
|
||||
"plural_name": "salsa"
|
||||
},
|
||||
"tahini": {
|
||||
"aliases": [],
|
||||
|
@ -12797,7 +12797,7 @@
|
|||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "salsa verde",
|
||||
"plural_name": "salsa verdes"
|
||||
"plural_name": "salsa verde"
|
||||
},
|
||||
"alfredo sauce": {
|
||||
"aliases": [],
|
||||
|
|
|
@ -101,22 +101,18 @@ def content_with_meta(group_slug: str, recipe: Recipe) -> str:
|
|||
image_url = "https://raw.githubusercontent.com/mealie-recipes/mealie/9571816ac4eed5beacfc0abf6c03eff1427fd0eb/frontend/static/icons/android-chrome-512x512.png"
|
||||
|
||||
ingredients: list[str] = []
|
||||
if recipe.settings.disable_amount: # type: ignore
|
||||
ingredients = [escape(i.note) for i in recipe.recipe_ingredient if i.note]
|
||||
for ing in recipe.recipe_ingredient:
|
||||
s = ""
|
||||
if ing.quantity:
|
||||
s += f"{ing.quantity} "
|
||||
if ing.unit:
|
||||
s += f"{ing.unit.name} "
|
||||
if ing.food:
|
||||
s += f"{ing.food.name} "
|
||||
if ing.note:
|
||||
s += f"{ing.note}"
|
||||
|
||||
else:
|
||||
for ing in recipe.recipe_ingredient:
|
||||
s = ""
|
||||
if ing.quantity:
|
||||
s += f"{ing.quantity} "
|
||||
if ing.unit:
|
||||
s += f"{ing.unit.name} "
|
||||
if ing.food:
|
||||
s += f"{ing.food.name} "
|
||||
if ing.note:
|
||||
s += f"{ing.note}"
|
||||
|
||||
ingredients.append(escape(s))
|
||||
ingredients.append(escape(s))
|
||||
|
||||
nutrition: dict[str, str | None] = recipe.nutrition.model_dump(by_alias=True) if recipe.nutrition else {}
|
||||
for k, v in nutrition.items():
|
||||
|
|
|
@ -66,7 +66,6 @@ class ShoppingListItemBase(RecipeIngredientBase):
|
|||
label_id: UUID4 | None = None
|
||||
unit_id: UUID4 | None = None
|
||||
|
||||
is_food: bool = False
|
||||
extras: dict | None = {}
|
||||
|
||||
@field_validator("extras", mode="before")
|
||||
|
|
|
@ -18,7 +18,6 @@ class UpdateHouseholdPreferences(MealieModel):
|
|||
recipe_show_assets: bool = False
|
||||
recipe_landscape_view: bool = False
|
||||
recipe_disable_comments: bool = False
|
||||
recipe_disable_amount: bool = True
|
||||
|
||||
|
||||
class CreateHouseholdPreferences(UpdateHouseholdPreferences): ...
|
||||
|
|
|
@ -6,7 +6,7 @@ from pathlib import Path
|
|||
from typing import Annotated, Any, ClassVar
|
||||
from uuid import uuid4
|
||||
|
||||
from pydantic import UUID4, BaseModel, ConfigDict, Field, field_validator, model_validator
|
||||
from pydantic import UUID4, BaseModel, ConfigDict, Field, field_validator
|
||||
from pydantic_core.core_schema import ValidationInfo
|
||||
from slugify import slugify
|
||||
from sqlalchemy import Select, desc, func, or_, select, text
|
||||
|
@ -228,18 +228,6 @@ class Recipe(RecipeSummary):
|
|||
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
|
||||
@model_validator(mode="after")
|
||||
def calculate_missing_food_flags_and_format_display(self):
|
||||
disable_amount = self.settings.disable_amount if self.settings else True
|
||||
for ingredient in self.recipe_ingredient:
|
||||
ingredient.disable_amount = disable_amount
|
||||
ingredient.is_food = not ingredient.disable_amount
|
||||
|
||||
# recalculate the display property, since it depends on the disable_amount flag
|
||||
ingredient.display = ingredient._format_display()
|
||||
|
||||
return self
|
||||
|
||||
@field_validator("slug", mode="before")
|
||||
def validate_slug(slug: str, info: ValidationInfo):
|
||||
if not info.data.get("name"):
|
||||
|
|
|
@ -152,13 +152,11 @@ class IngredientUnit(CreateIngredientUnit):
|
|||
|
||||
|
||||
class RecipeIngredientBase(MealieModel):
|
||||
quantity: NoneFloat = 1
|
||||
quantity: NoneFloat = 0
|
||||
unit: IngredientUnit | CreateIngredientUnit | None = None
|
||||
food: IngredientFood | CreateIngredientFood | None = None
|
||||
note: str | None = ""
|
||||
|
||||
is_food: bool | None = None
|
||||
disable_amount: bool | None = None
|
||||
display: str = ""
|
||||
"""
|
||||
How the ingredient should be displayed
|
||||
|
@ -166,20 +164,6 @@ class RecipeIngredientBase(MealieModel):
|
|||
Automatically calculated after the object is created, unless overwritten
|
||||
"""
|
||||
|
||||
@model_validator(mode="after")
|
||||
def calculate_missing_food_flags(self):
|
||||
# calculate missing is_food and disable_amount values
|
||||
# we can't do this in a validator since they depend on each other
|
||||
if self.is_food is None and self.disable_amount is not None:
|
||||
self.is_food = not self.disable_amount
|
||||
elif self.disable_amount is None and self.is_food is not None:
|
||||
self.disable_amount = not self.is_food
|
||||
elif self.is_food is None and self.disable_amount is None:
|
||||
self.is_food = bool(self.food)
|
||||
self.disable_amount = not self.is_food
|
||||
|
||||
return self
|
||||
|
||||
@model_validator(mode="after")
|
||||
def format_display(self):
|
||||
if not self.display:
|
||||
|
@ -266,28 +250,17 @@ class RecipeIngredientBase(MealieModel):
|
|||
def _format_display(self) -> str:
|
||||
components = []
|
||||
|
||||
use_food = True
|
||||
if self.is_food is False:
|
||||
use_food = False
|
||||
elif self.disable_amount is True:
|
||||
use_food = False
|
||||
|
||||
# ingredients with no food come across with a qty of 1, which looks weird
|
||||
# e.g. "1 2 tbsp of olive oil"
|
||||
if self.quantity and (use_food or self.quantity != 1):
|
||||
if self.quantity:
|
||||
components.append(self._format_quantity_for_display())
|
||||
|
||||
if not use_food:
|
||||
components.append(self.note or "")
|
||||
else:
|
||||
if self.quantity and self.unit:
|
||||
components.append(self._format_unit_for_display())
|
||||
if self.quantity and self.unit:
|
||||
components.append(self._format_unit_for_display())
|
||||
|
||||
if self.food:
|
||||
components.append(self._format_food_for_display())
|
||||
if self.food:
|
||||
components.append(self._format_food_for_display())
|
||||
|
||||
if self.note:
|
||||
components.append(self.note)
|
||||
if self.note:
|
||||
components.append(self.note)
|
||||
|
||||
return " ".join(components).strip()
|
||||
|
||||
|
@ -299,7 +272,6 @@ class IngredientUnitPagination(PaginationBase):
|
|||
class RecipeIngredient(RecipeIngredientBase):
|
||||
title: str | None = None
|
||||
original_text: str | None = None
|
||||
disable_amount: bool = True
|
||||
|
||||
# Ref is used as a way to distinguish between an individual ingredient on the frontend
|
||||
# It is required for the reorder and section titles to function properly because of how
|
||||
|
|
|
@ -9,6 +9,5 @@ class RecipeSettings(MealieModel):
|
|||
show_assets: bool = False
|
||||
landscape_view: bool = False
|
||||
disable_comments: bool = True
|
||||
disable_amount: bool = True
|
||||
locked: bool = False
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
|
|
|
@ -461,7 +461,7 @@
|
|||
|
||||
<a
|
||||
class="mj-link"
|
||||
href="https://github.com/hay-kot/mealie"
|
||||
href="https://github.com/mealie-recipes/mealie"
|
||||
target="_blank"
|
||||
style="
|
||||
display: inline-block;
|
||||
|
@ -505,7 +505,7 @@
|
|||
|
||||
<a
|
||||
class="mj-link"
|
||||
href="https://hay-kot.github.io/mealie/"
|
||||
href="https://docs.mealie.io/"
|
||||
target="_blank"
|
||||
style="
|
||||
display: inline-block;
|
||||
|
|
|
@ -312,12 +312,10 @@ class ShoppingListService:
|
|||
list_items: list[ShoppingListItemCreate] = []
|
||||
for ingredient in recipe_ingredients:
|
||||
if isinstance(ingredient.food, IngredientFood):
|
||||
is_food = True
|
||||
food_id = ingredient.food.id
|
||||
label_id = ingredient.food.label_id
|
||||
|
||||
else:
|
||||
is_food = False
|
||||
food_id = None
|
||||
label_id = None
|
||||
|
||||
|
@ -329,7 +327,6 @@ class ShoppingListService:
|
|||
|
||||
new_item = ShoppingListItemCreate(
|
||||
shopping_list_id=list_id,
|
||||
is_food=is_food,
|
||||
note=ingredient.note,
|
||||
quantity=ingredient.quantity * scale if ingredient.quantity else 0,
|
||||
food_id=food_id,
|
||||
|
|
|
@ -177,7 +177,6 @@ class BaseMigrator(BaseService):
|
|||
show_assets=self.household.preferences.recipe_show_assets,
|
||||
landscape_view=self.household.preferences.recipe_landscape_view,
|
||||
disable_comments=self.household.preferences.recipe_disable_comments,
|
||||
disable_amount=self.household.preferences.recipe_disable_amount,
|
||||
)
|
||||
|
||||
for recipe in validated_recipes:
|
||||
|
|
|
@ -36,7 +36,6 @@ class BruteForceParser(ABCIngredientParser):
|
|||
ingredient=RecipeIngredient(
|
||||
unit=CreateIngredientUnit(name=bfi.unit),
|
||||
food=CreateIngredientFood(name=bfi.food),
|
||||
disable_amount=False,
|
||||
quantity=bfi.amount,
|
||||
note=bfi.note,
|
||||
),
|
||||
|
@ -151,7 +150,6 @@ class NLPParser(ABCIngredientParser):
|
|||
quantity=qty,
|
||||
unit=CreateIngredientUnit(name=unit) if unit else None,
|
||||
food=CreateIngredientFood(name=food) if food else None,
|
||||
disable_amount=False,
|
||||
note=note,
|
||||
),
|
||||
)
|
||||
|
|
|
@ -173,7 +173,6 @@ class RecipeService(RecipeServiceBase):
|
|||
show_assets=self.household.preferences.recipe_show_assets,
|
||||
landscape_view=self.household.preferences.recipe_landscape_view,
|
||||
disable_comments=self.household.preferences.recipe_disable_comments,
|
||||
disable_amount=self.household.preferences.recipe_disable_amount,
|
||||
)
|
||||
else:
|
||||
data.settings = RecipeSettings()
|
||||
|
|
|
@ -74,7 +74,6 @@ class RegistrationService:
|
|||
recipe_show_assets=self.registration.advanced,
|
||||
recipe_landscape_view=False,
|
||||
recipe_disable_comments=self.registration.advanced,
|
||||
recipe_disable_amount=self.registration.advanced,
|
||||
)
|
||||
return HouseholdService.create_household(group_repos, household_data, household_preferences)
|
||||
|
||||
|
|
12
tests/fixtures/fixture_recipe.py
vendored
12
tests/fixtures/fixture_recipe.py
vendored
|
@ -37,12 +37,12 @@ def recipe_ingredient_only(unique_user: TestUser):
|
|||
group_id=unique_user.group_id,
|
||||
name=random_string(10),
|
||||
recipe_ingredient=[
|
||||
RecipeIngredient(note="Ingredient 1"),
|
||||
RecipeIngredient(note="Ingredient 2"),
|
||||
RecipeIngredient(note="Ingredient 3"),
|
||||
RecipeIngredient(note="Ingredient 4"),
|
||||
RecipeIngredient(note="Ingredient 5"),
|
||||
RecipeIngredient(note="Ingredient 6"),
|
||||
RecipeIngredient(quantity=1, note="Ingredient 1"),
|
||||
RecipeIngredient(quantity=1, note="Ingredient 2"),
|
||||
RecipeIngredient(quantity=1, note="Ingredient 3"),
|
||||
RecipeIngredient(quantity=1, note="Ingredient 4"),
|
||||
RecipeIngredient(quantity=1, note="Ingredient 5"),
|
||||
RecipeIngredient(quantity=1, note="Ingredient 6"),
|
||||
],
|
||||
)
|
||||
|
||||
|
|
1
tests/fixtures/fixture_shopping_lists.py
vendored
1
tests/fixtures/fixture_shopping_lists.py
vendored
|
@ -12,7 +12,6 @@ def create_item(list_id: UUID4) -> dict:
|
|||
"shopping_list_id": str(list_id),
|
||||
"checked": False,
|
||||
"position": 0,
|
||||
"is_food": False,
|
||||
"note": random_string(10),
|
||||
"quantity": 1,
|
||||
"unit_id": None,
|
||||
|
|
|
@ -49,7 +49,6 @@ def test_admin_update_household(api_client: TestClient, admin_user: TestUser, un
|
|||
"recipeShowAssets": random_bool(),
|
||||
"recipeLandscapeView": random_bool(),
|
||||
"recipeDisableComments": random_bool(),
|
||||
"recipeDisableAmount": random_bool(),
|
||||
},
|
||||
}
|
||||
|
||||
|
|
|
@ -377,7 +377,6 @@ def test_get_suggested_recipes(
|
|||
SaveIngredientFood(id=uuid4(), name=random_string(), group_id=unique_user.group_id)
|
||||
)
|
||||
random_recipe.recipe_ingredient = [RecipeIngredient(food_id=known_food.id, food=known_food)]
|
||||
random_recipe.settings.disable_amount = False
|
||||
database.recipes.update(random_recipe.slug, random_recipe)
|
||||
|
||||
## Try to find suggested recipes
|
||||
|
|
|
@ -45,10 +45,10 @@ def test_recipe_assets_create(api_client: TestClient, unique_user: TestUser, rec
|
|||
def test_recipe_asset_exploit(api_client: TestClient, unique_user: TestUser, recipe_ingredient_only: Recipe):
|
||||
"""
|
||||
Test to ensure that users are unable to circumvent the destination directory when uploading a file
|
||||
as an asset to the recipe. This was reported via huntr and was confirmed to be a sevre security issue.
|
||||
as an asset to the recipe. This was reported via huntr and was confirmed to be a severe security issue.
|
||||
|
||||
mitigration is implemented by ensuring that the destination file is checked to ensure that the parent directory
|
||||
is the recipe's asset directory. otherwise an exception is raised and a 400 error is returned.
|
||||
A mitigation is implemented by ensuring that the destination file is checked to ensure that the parent directory
|
||||
is the recipe's asset directory. Otherwise, an exception is raised and a 400 error is returned.
|
||||
|
||||
Report Details:
|
||||
-------------------
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue