diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index a37cfd007..fe02ce452 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -49,7 +49,9 @@ "onCreateCommand": "sudo chown -R vscode:vscode /workspaces/mealie/frontend/node_modules && task setup", // Comment out to connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root. "remoteUser": "vscode", - // "features": { - // "git": "latest" - // } + "features": { + "ghcr.io/devcontainers/features/docker-in-docker:2": { + "dockerDashComposeVersion": "v2" + } + } } diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 78162ddcf..8417fff33 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -49,6 +49,9 @@ jobs: needs: - build-release runs-on: ubuntu-latest + permissions: + contents: write + pull-requests: write steps: - name: Checkout 🛎 uses: actions/checkout@v4 @@ -58,11 +61,12 @@ jobs: sed -i 's/:v[0-9]*.[0-9]*.[0-9]*/:${{ github.event.release.tag_name }}/' docs/docs/documentation/getting-started/installation/sqlite.md sed -i 's/:v[0-9]*.[0-9]*.[0-9]*/:${{ github.event.release.tag_name }}/' docs/docs/documentation/getting-started/installation/postgres.md - - name: Commit updates - uses: test-room-7/action-update-file@v1 + - name: Create Pull Request + uses: peter-evans/create-pull-request@v6 with: - file-path: | - docs/docs/documentation/getting-started/installation/sqlite.md - docs/docs/documentation/getting-started/installation/postgres.md - commit-msg: "Change image tag, for release ${{ github.event.release.tag_name }}" - github-token: ${{ secrets.GITHUB_TOKEN }} + commit-message: "Update image tag, for release ${{ github.event.release.tag_name }}" + branch: "docs/newrelease-update-version-${{ github.event.release.tag_name }}" + delete-branch: true + base: mealie-next + title: "docs(auto): Update image tag, for release ${{ github.event.release.tag_name }}" + body: "Auto-generated by `.github/workflows/release.yml`, on publish of release ${{ github.event.release.tag_name }}" diff --git a/Taskfile.yml b/Taskfile.yml index ed3f47d01..085d9cf8c 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -14,7 +14,9 @@ env: SMTP_HOST: localhost SMTP_PORT: 1025 SMTP_FROM_NAME: MealieDev + SMTP_FROM_EMAIL: mealie@example.com SMTP_AUTH_STRATEGY: NONE + BASE_URL: http://localhost:3000 LANG: en-US # loads .env file if it exists diff --git a/docs/docs/documentation/getting-started/installation/backend-config.md b/docs/docs/documentation/getting-started/installation/backend-config.md index dce06309b..80f678b48 100644 --- a/docs/docs/documentation/getting-started/installation/backend-config.md +++ b/docs/docs/documentation/getting-started/installation/backend-config.md @@ -54,8 +54,8 @@ Changing the webworker settings may cause unforeseen memory leak issues with Mea | ---------------- | :-----: | --------------------------------------------------------------------------------------------------------------------------------- | | WEB_GUNICORN | false | Enables Gunicorn to manage Uvicorn web for multiple works | | WORKERS_PER_CORE | 1 | Set the number of workers to the number of CPU cores multiplied by this value (Value \* CPUs). More info [here][workers_per_core] | -| MAX_WORKERS | 1 | Set the maximum number of workers to use. Default is not set meaning unlimited. More info [here][max_workers] | -| WEB_CONCURRENCY | 1 | Override the automatic definition of number of workers. More info [here][web_concurrency] | +| MAX_WORKERS | None | Set the maximum number of workers to use. Default is not set meaning unlimited. More info [here][max_workers] | +| WEB_CONCURRENCY | 2 | Override the automatic definition of number of workers. More info [here][web_concurrency] | ### LDAP @@ -95,3 +95,8 @@ Setting the following environmental variables will change the theme of the front | THEME_DARK_INFO | #1976D2 | Dark Theme Config Variable | | THEME_DARK_WARNING | #FF6D00 | Dark Theme Config Variable | | THEME_DARK_ERROR | #EF5350 | Dark Theme Config Variable | + + +[workers_per_core]: https://github.com/tiangolo/uvicorn-gunicorn-docker/blob/2daa3e3873c837d5781feb4ff6a40a89f791f81b/README.md#workers_per_core +[max_workers]: https://github.com/tiangolo/uvicorn-gunicorn-docker/blob/2daa3e3873c837d5781feb4ff6a40a89f791f81b/README.md#max_workers +[web_concurrency]: https://github.com/tiangolo/uvicorn-gunicorn-docker/blob/2daa3e3873c837d5781feb4ff6a40a89f791f81b/README.md#web_concurrency diff --git a/docs/docs/overrides/api.html b/docs/docs/overrides/api.html index 28fdc391d..4e7f1d6d2 100644 --- a/docs/docs/overrides/api.html +++ b/docs/docs/overrides/api.html @@ -14,7 +14,7 @@
diff --git a/frontend/components/Domain/Recipe/RecipeNutrition.vue b/frontend/components/Domain/Recipe/RecipeNutrition.vue index 9b90fe990..f53ea29bd 100644 --- a/frontend/components/Domain/Recipe/RecipeNutrition.vue +++ b/frontend/components/Domain/Recipe/RecipeNutrition.vue @@ -19,11 +19,11 @@ - +
{{ item.label }}
-
{{ value[key] }}
+
{{ item.value }}
{{ item.suffix }}
@@ -37,6 +37,14 @@ import { computed, defineComponent, useContext } from "@nuxtjs/composition-api"; import { Nutrition } from "~/lib/api/types/recipe"; +type NutritionLabelType = { + [key: string]: { + label: string; + suffix: string; + value?: string; + }; +}; + export default defineComponent({ props: { value: { @@ -50,34 +58,34 @@ export default defineComponent({ }, setup(props, context) { const { i18n } = useContext(); - const labels = { + const labels = { calories: { - label: i18n.t("recipe.calories"), - suffix: i18n.t("recipe.calories-suffix"), + label: i18n.tc("recipe.calories"), + suffix: i18n.tc("recipe.calories-suffix"), }, fatContent: { - label: i18n.t("recipe.fat-content"), - suffix: i18n.t("recipe.grams"), + label: i18n.tc("recipe.fat-content"), + suffix: i18n.tc("recipe.grams"), }, fiberContent: { - label: i18n.t("recipe.fiber-content"), - suffix: i18n.t("recipe.grams"), + label: i18n.tc("recipe.fiber-content"), + suffix: i18n.tc("recipe.grams"), }, proteinContent: { - label: i18n.t("recipe.protein-content"), - suffix: i18n.t("recipe.grams"), + label: i18n.tc("recipe.protein-content"), + suffix: i18n.tc("recipe.grams"), }, sodiumContent: { - label: i18n.t("recipe.sodium-content"), - suffix: i18n.t("recipe.milligrams"), + label: i18n.tc("recipe.sodium-content"), + suffix: i18n.tc("recipe.milligrams"), }, sugarContent: { - label: i18n.t("recipe.sugar-content"), - suffix: i18n.t("recipe.grams"), + label: i18n.tc("recipe.sugar-content"), + suffix: i18n.tc("recipe.grams"), }, carbohydrateContent: { - label: i18n.t("recipe.carbohydrate-content"), - suffix: i18n.t("recipe.grams"), + label: i18n.tc("recipe.carbohydrate-content"), + suffix: i18n.tc("recipe.grams"), }, }; const valueNotNull = computed(() => { @@ -96,11 +104,25 @@ export default defineComponent({ context.emit("input", { ...props.value, [key]: event }); } + // Build a new list that only contains nutritional information that has a value + const renderedList = computed(() => { + return Object.entries(labels).reduce((item: NutritionLabelType, [key, label]) => { + if (props.value[key]?.trim()) { + item[key] = { + ...label, + value: props.value[key], + }; + } + return item; + }, {}); + }); + return { labels, valueNotNull, showViewer, updateValue, + renderedList, }; }, }); diff --git a/frontend/lang/messages/bg-BG.json b/frontend/lang/messages/bg-BG.json index 0c7a74e3e..35e0b0872 100644 --- a/frontend/lang/messages/bg-BG.json +++ b/frontend/lang/messages/bg-BG.json @@ -200,7 +200,7 @@ "created-on-date": "Създадено на {0}", "unsaved-changes": "Имате незапазени промени. Желаете ли да ги запазите преди да излезете? Натиснете Ок за запазване и Отказ за отхвърляне на промените.", "clipboard-copy-failure": "Линкът към рецептата е копиран в клипборда.", - "confirm-delete-generic-items": "Are you sure you want to delete the following items?" + "confirm-delete-generic-items": "Сигурни ли сте, че желаете да изтриете следните елементи?" }, "group": { "are-you-sure-you-want-to-delete-the-group": "Сигурни ли сте, че искате да изтриете {groupName}?", @@ -259,7 +259,7 @@ }, "meal-plan": { "create-a-new-meal-plan": "Създаване на нов хранителен план", - "update-this-meal-plan": "Update this Meal Plan", + "update-this-meal-plan": "Обнови този План за хранене", "dinner-this-week": "Вечеря тази седмица", "dinner-today": "Вечеря Днес", "dinner-tonight": "Вечеря ТАЗИ ВЕЧЕР", @@ -474,11 +474,11 @@ "add-to-timeline": "Добави към времевата линия", "recipe-added-to-list": "Рецептата е добавена към списъка", "recipes-added-to-list": "Рецептите са добавени към списъка", - "successfully-added-to-list": "Successfully added to list", + "successfully-added-to-list": "Успешно добавено в списъка", "recipe-added-to-mealplan": "Рецептата е добавена към хранителния план", "failed-to-add-recipes-to-list": "Неуспешно добавяне на рецепта към списъка", "failed-to-add-recipe-to-mealplan": "Рецептата не беше добавена към хранителния план", - "failed-to-add-to-list": "Failed to add to list", + "failed-to-add-to-list": "Неуспешно добавяне към списъка", "yield": "Добив", "quantity": "Количество", "choose-unit": "Избери единица", @@ -537,8 +537,8 @@ "new-recipe-names-must-be-unique": "Името на рецептата трябва да бъде уникално", "scrape-recipe": "Обхождане на рецепта", "scrape-recipe-description": "Обходи рецепта по линк. Предоставете линк за сайт, който искате да бъде обходен. Mealie ще опита да обходи рецептата от този сайт и да я добави във Вашата колекция.", - "scrape-recipe-have-a-lot-of-recipes": "Have a lot of recipes you want to scrape at once?", - "scrape-recipe-suggest-bulk-importer": "Try out the bulk importer", + "scrape-recipe-have-a-lot-of-recipes": "Имате много рецепти, които искате да обходите наведнъж?", + "scrape-recipe-suggest-bulk-importer": "Пробвайте масовото импорторане", "import-original-keywords-as-tags": "Импортирай оригиналните ключови думи като тагове", "stay-in-edit-mode": "Остани в режим на редакция", "import-from-zip": "Импортирай от Zip", @@ -562,7 +562,7 @@ "upload-image": "Качване на изображение", "screen-awake": "Запази екрана активен", "remove-image": "Премахване на изображение", - "nextStep": "Next step" + "nextStep": "Следваща стъпка" }, "search": { "advanced-search": "Разширено търсене", @@ -1187,7 +1187,7 @@ "require-all-tools": "Изискване на всички инструменти", "cookbook-name": "Име на книгата с рецепти", "cookbook-with-name": "Книга с рецепти {0}", - "create-a-cookbook": "Create a Cookbook", - "cookbook": "Cookbook" + "create-a-cookbook": "Създай Готварска книга", + "cookbook": "Готварска книга" } } diff --git a/frontend/lang/messages/he-IL.json b/frontend/lang/messages/he-IL.json index 05c04b935..b4a604930 100644 --- a/frontend/lang/messages/he-IL.json +++ b/frontend/lang/messages/he-IL.json @@ -200,7 +200,7 @@ "created-on-date": "נוצר ב-{0}", "unsaved-changes": "יש שינויים שלא נשמרו. לצאת לפני שמירה? אשר לשמירה, בטל למחיקת שינויים.", "clipboard-copy-failure": "כשלון בהעתקה ללוח ההדבקה.", - "confirm-delete-generic-items": "Are you sure you want to delete the following items?" + "confirm-delete-generic-items": "האם אתה בטוח שברצונך למחוק את הפריטים הנבחרים?" }, "group": { "are-you-sure-you-want-to-delete-the-group": "האם את/ה בטוח/ה שברצונך למחוק את {groupName}?", @@ -259,7 +259,7 @@ }, "meal-plan": { "create-a-new-meal-plan": "יצירת תכנית ארוחות חדשה", - "update-this-meal-plan": "Update this Meal Plan", + "update-this-meal-plan": "עדכן את תכנון הארוחות", "dinner-this-week": "ארוחות ערב השבוע", "dinner-today": "ארוחת ערב היום", "dinner-tonight": "ארוחת ערב היום", @@ -474,11 +474,11 @@ "add-to-timeline": "הוסף לציר הזמן", "recipe-added-to-list": "מתכון נוסף לרשימה", "recipes-added-to-list": "מתכונים הוספו לרשימה", - "successfully-added-to-list": "Successfully added to list", + "successfully-added-to-list": "נוסף לרשימה בהצלחה", "recipe-added-to-mealplan": "מתכון נוסף לתכנון ארוחות", "failed-to-add-recipes-to-list": "כשלון בהוספת מתכון לרשימה", "failed-to-add-recipe-to-mealplan": "הוספת מתכון לתכנון ארוחות נכשלה", - "failed-to-add-to-list": "Failed to add to list", + "failed-to-add-to-list": "כשלון בהוספה לרשימה", "yield": "תשואה", "quantity": "כמות", "choose-unit": "בחירת יחידת מידה", @@ -515,7 +515,7 @@ "how-did-it-turn-out": "איך יצא?", "user-made-this": "{user} הכין את זה", "last-made-date": "נעשה לאחרונה ב{date}", - "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.", + "api-extras-description": "מתכונים נוספים הם יכולת מפתח של Mealie API. הם מאפשרים ליצור צמדי key/value בצורת JSON על מנת לקרוא אותם בתוכנת צד שלישית. תוכלו להשתמש בצמדים האלה כדי לספק מידע, לדוגמא להפעיל אוטומציות או הודעות מותאמות אישית למכשירים מסויימים.", "message-key": "מפתח הודעה", "parse": "ניתוח", "attach-images-hint": "הוסף תמונות ע\"י גרירה ושחרור אל תוך העורך", @@ -537,8 +537,8 @@ "new-recipe-names-must-be-unique": "שם מתכון חדש חייב להיות ייחודי", "scrape-recipe": "קריאת מתכון", "scrape-recipe-description": "קריאת מתכון בעזרת לינק. ספק את הלינק של האתר שברצונך לקרוא, ומילי תנסה לקרוא את המתכון מהאתר ולהוסיף אותו לאוסף.", - "scrape-recipe-have-a-lot-of-recipes": "Have a lot of recipes you want to scrape at once?", - "scrape-recipe-suggest-bulk-importer": "Try out the bulk importer", + "scrape-recipe-have-a-lot-of-recipes": "יש לך הרבה מתכונים שאתה רוצה לקרוא בבת אחת?", + "scrape-recipe-suggest-bulk-importer": "נסה את יכולת קריאת רשימה", "import-original-keywords-as-tags": "ייבא שמות מפתח מקוריות כתגיות", "stay-in-edit-mode": "השאר במצב עריכה", "import-from-zip": "ייבא מקובץ", @@ -562,7 +562,7 @@ "upload-image": "העלה תמונה", "screen-awake": "השאר את המסך פעיל", "remove-image": "האם למחוק את התמונה?", - "nextStep": "Next step" + "nextStep": "השלב הבא" }, "search": { "advanced-search": "חיפוש מתקדם", @@ -797,7 +797,7 @@ "untagged-count": "לא מתוייג {count}", "create-a-tag": "צור תגית", "tag-name": "שם תגית", - "tag": "Tag" + "tag": "תגית" }, "tool": { "tools": "כלים", @@ -807,7 +807,7 @@ "create-new-tool": "יצירת כלי חדש", "on-hand-checkbox-label": "הראה מה יש לי במטבח", "required-tools": "צריך כלים", - "tool": "Tool" + "tool": "כלי" }, "user": { "admin": "אדמין", @@ -898,10 +898,10 @@ "user-can-organize-group-data": "משתמש יכול לשנות מידע של קבוצה", "enable-advanced-features": "אפשר אפשרויות מתקדמות", "it-looks-like-this-is-your-first-time-logging-in": "נראה שזו ההתחברות הראשונה שלך.", - "dont-want-to-see-this-anymore-be-sure-to-change-your-email": "Don't want to see this anymore? Be sure to change your email in your user settings!", + "dont-want-to-see-this-anymore-be-sure-to-change-your-email": "לא רוצה לראות את זה יותר? דאג לשנות את המייל של בהגדרות המשתמש!", "forgot-password": "שכחתי סיסמא", - "forgot-password-text": "Please enter your email address and we will send you a link to reset your password.", - "changes-reflected-immediately": "Changes to this user will be reflected immediately." + "forgot-password-text": "נא לספק כתובת דוא\"ל. אנו נשלח לך הודעת דוא\"ל לצורך איפוס הסיסמה שלך.", + "changes-reflected-immediately": "השינויים למשתמש זה יבוצעו מיידית." }, "language-dialog": { "translated": "תורגם", @@ -923,8 +923,8 @@ "food-label": "תוית אוכל", "edit-food": "עריכת מזון", "food-data": "נתוני אוכל", - "example-food-singular": "ex: Onion", - "example-food-plural": "ex: Onions" + "example-food-singular": "דוגמא: בצל", + "example-food-plural": "דוגמא: בצלים" }, "units": { "seed-dialog-text": "אכלס את מסד הנתונים עם יחידות מדידה בהתאם לשפה המקומית שלך.", @@ -935,7 +935,7 @@ "merging-unit-into-unit": "ממזג את {0} לתוך {1}", "create-unit": "יצירת יחידה", "abbreviation": "קיצור", - "plural-abbreviation": "Plural Abbreviation", + "plural-abbreviation": "צורת הרבית", "description": "תיאור", "display-as-fraction": "הצגה כשבר", "use-abbreviation": "השתמש בקיצור", @@ -943,10 +943,10 @@ "unit-data": "נתוני יחידה", "use-abbv": "השתמש בקיצור", "fraction": "שבר", - "example-unit-singular": "ex: Tablespoon", - "example-unit-plural": "ex: Tablespoons", - "example-unit-abbreviation-singular": "ex: Tbsp", - "example-unit-abbreviation-plural": "ex: Tbsps" + "example-unit-singular": "דוגמא: כפית", + "example-unit-plural": "דוגמא: כפיות", + "example-unit-abbreviation-singular": "דוגמא: כף", + "example-unit-abbreviation-plural": "דוגמא: כפות" }, "labels": { "seed-dialog-text": "אכלס את מסד הנתונים בתגיות נפוצות בהתאם לשפה המקומית שלך.", @@ -1187,7 +1187,7 @@ "require-all-tools": "זקוק לכל הכלים", "cookbook-name": "שם ספר בישול", "cookbook-with-name": "ספר בישול {0}", - "create-a-cookbook": "Create a Cookbook", - "cookbook": "Cookbook" + "create-a-cookbook": "צור ספר בישול חדש", + "cookbook": "ספר בישול" } } diff --git a/frontend/lang/messages/nl-NL.json b/frontend/lang/messages/nl-NL.json index d76d2fc2c..a0dfdd8c8 100644 --- a/frontend/lang/messages/nl-NL.json +++ b/frontend/lang/messages/nl-NL.json @@ -200,7 +200,7 @@ "created-on-date": "Gemaakt op {0}", "unsaved-changes": "Er zijn niet-opgeslagen wijzigingen. Wil je eerst opslaan voordat je vertrekt? Okay om op te slaan, Annuleren om wijzigingen ongedaan te maken.", "clipboard-copy-failure": "Kopiëren naar klembord mislukt.", - "confirm-delete-generic-items": "Are you sure you want to delete the following items?" + "confirm-delete-generic-items": "Weet u zeker dat u de volgende items wilt verwijderen?" }, "group": { "are-you-sure-you-want-to-delete-the-group": "Weet je zeker dat je {groupName} wil verwijderen?", diff --git a/frontend/lang/messages/ru-RU.json b/frontend/lang/messages/ru-RU.json index e395d82d1..409702108 100644 --- a/frontend/lang/messages/ru-RU.json +++ b/frontend/lang/messages/ru-RU.json @@ -707,7 +707,7 @@ "email-configured": "Email настроен", "email-test-results": "Результаты теста Email", "ready": "Готово", - "not-ready": "Не готово - Проверьте переменные окружающей среды", + "not-ready": "Не готово - Проверьте переменные окружения", "succeeded": "Выполнено успешно", "failed": "Ошибка", "general-about": "Общая информация", diff --git a/frontend/pages/admin/manage/users/_id.vue b/frontend/pages/admin/manage/users/_id.vue index 182378eda..31ad6fc8e 100644 --- a/frontend/pages/admin/manage/users/_id.vue +++ b/frontend/pages/admin/manage/users/_id.vue @@ -31,7 +31,24 @@ {{ $t("user.generate-password-reset-link") }} - + +
+ +

+ {{ resetUrl }} +

+
+ + {{ $t("general.close") }} + + + + {{ $t("user.email") }} + + +
@@ -46,7 +63,7 @@