Compare commits

...

75 Commits

Author SHA1 Message Date
mealie-commit-bot[bot]
c880c0865b chore: bump version to v3.17.0 2026-05-06 18:40:44 +00:00
Michael Genson
294238f183 fix: Adjust ingredient section spacing (#7580) 2026-05-06 11:57:27 -05:00
renovate[bot]
985b656d3f chore(deps): update dependency axios to v1.15.2 [security] (#7579)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-06 15:31:14 +00:00
miah
09c2a0b2ad feat: Shopping list / Swipe to check off (#7118)
Co-authored-by: Michael Genson <genson.michael@gmail.com>
Co-authored-by: Copilot <copilot@github.com>
Co-authored-by: Michael Genson <71845777+michael-genson@users.noreply.github.com>
2026-05-06 10:31:33 -05:00
renovate[bot]
f2b087730e fix(deps): update dependency pydantic-settings to v2.14.0 (#7534)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-06 14:56:01 +00:00
miah
e71b31e9cc feat: Improve add shopping list item form (#7091)
Co-authored-by: Michael Genson <71845777+michael-genson@users.noreply.github.com>
Co-authored-by: Michael Genson <genson.michael@gmail.com>
2026-05-04 11:15:01 -05:00
Hayden
41a9a1e018 chore(l10n): New Crowdin updates (#7558)
Co-authored-by: Michael Genson <71845777+michael-genson@users.noreply.github.com>
2026-05-03 17:54:02 +00:00
renovate[bot]
7b2372edfc fix(deps): update dependency openai to v2.33.0 (#7570)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-03 14:23:17 +00:00
mealie-actions[bot]
65f109dee4 chore(l10n): Crowdin locale sync (#7569)
Co-authored-by: GitHub Action <action@github.com>
2026-05-03 03:10:04 +00:00
renovate[bot]
8dc85640e1 fix(deps): update dependency python-multipart to v0.0.27 (#7567)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-02 12:48:26 +00:00
renovate[bot]
6c5f1c2413 fix(deps): update dependency apprise to v1.10.0 (#7566)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-01 16:55:00 +00:00
Zdenek Stursa
bc3ae3c6c0 fix: restore create-item button in recipe dropdowns (categories, tags, tools) (#7564)
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-30 15:16:27 +00:00
garlic-hub
5b37eb012c fix: Don't hit authenticated endpoints when logged out (#7563) 2026-04-30 04:21:48 +00:00
renovate[bot]
f354f12853 fix(deps): update dependency tzdata to v2026.2 (#7560)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-29 20:00:29 +00:00
renovate[bot]
062484dec9 chore(deps): update dependency ruff to v0.15.12 (#7559)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-29 19:59:26 +00:00
renovate[bot]
b5d991c516 fix(deps): update dependency fastapi to v0.136.1 (#7556)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-28 19:14:55 +00:00
renovate[bot]
b60aeed8dc fix(deps): update dependency uvicorn to v0.46.0 (#7553)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-28 11:47:35 +00:00
renovate[bot]
1f42ba4934 chore(deps): update dependency pre-commit to v4.6.0 (#7547)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-26 21:12:20 +00:00
Hayden
32e0404564 chore(l10n): New Crowdin updates (#7546) 2026-04-26 20:47:51 +00:00
renovate[bot]
a1a26b23c4 chore(deps): update dependency mypy to v1.20.2 (#7544)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-26 18:15:38 +00:00
renovate[bot]
e66c0dea58 fix(deps): update dependency uvicorn to v0.45.0 (#7543)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-26 14:51:00 +00:00
mealie-actions[bot]
fb5b028b92 chore(l10n): Crowdin locale sync (#7541)
Co-authored-by: GitHub Action <action@github.com>
2026-04-26 03:08:57 +00:00
renovate[bot]
2854449213 fix(deps): update dependency psycopg2-binary to v2.9.12 (#7539)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-26 01:15:14 +00:00
Hayden
1bd423d741 chore(l10n): New Crowdin updates (#7536) 2026-04-25 20:16:11 +00:00
renovate[bot]
a754693787 fix(deps): update dependency pydantic to v2.13.3 (#7533)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-25 15:09:02 +00:00
Hayden
176587079f chore(l10n): New Crowdin updates (#7526) 2026-04-24 00:35:23 +00:00
renovate[bot]
718d232517 fix(deps): update dependency authlib to v1.7.0 (#7525)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-23 13:34:34 +00:00
Hayden
072f93d02d chore(l10n): New Crowdin updates (#7523) 2026-04-22 22:39:22 +00:00
renovate[bot]
70749b740a chore(deps): update node.js to e989123 (#7520)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-22 18:45:07 +00:00
renovate[bot]
60daa3b4e2 chore(deps): update node.js to 91447bc (#7519)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-22 12:11:41 +00:00
renovate[bot]
2da78b4fb5 fix(deps): update dependency pydantic to v2.13.2 (#7517)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-22 11:49:47 +00:00
renovate[bot]
a5daaaab9e chore(deps): update node.js to 807109d (#7516)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-22 11:48:43 +00:00
Hayden
ad77b9851f chore(l10n): New Crowdin updates (#7515) 2026-04-22 10:42:56 +00:00
renovate[bot]
3db94d876c fix(deps): update dependency lxml to v6.1.0 [security] (#7513)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-22 00:08:20 +00:00
renovate[bot]
39529ed606 chore(deps): update dependency ruff to v0.15.11 (#7514)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-21 23:45:55 +00:00
Zdenek Stursa
b3fd2ccb33 fix: add missing search bar to Recipe Data management page (#7504)
Co-authored-by: Zdenek <tvuj-email@example.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Michael Genson <71845777+michael-genson@users.noreply.github.com>
2026-04-21 17:20:08 +00:00
Zdenek Stursa
fce0538671 fix: pressing Enter in dialogs now confirms instead of silently closing (#7503)
Co-authored-by: Zdenek <tvuj-email@example.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Michael Genson <genson.michael@gmail.com>
Co-authored-by: Michael Genson <71845777+michael-genson@users.noreply.github.com>
2026-04-21 10:03:31 -05:00
Ben Harper
b3ce0faf26 docs: document necessity of forwarded-allow-ips with OIDC behind reverse-proxy https in oidc-v2.md (#7424)
Co-authored-by: Michael Genson <71845777+michael-genson@users.noreply.github.com>
2026-04-21 14:30:04 +00:00
BadCo-NZ
870b793d5f docs: Enhance BASE_URL description in backend config (#7449)
Co-authored-by: Michael Genson <genson.michael@gmail.com>
Co-authored-by: Michael Genson <71845777+michael-genson@users.noreply.github.com>
2026-04-21 09:14:34 -05:00
renovate[bot]
26dfeac956 fix(deps): update dependency fastapi to v0.136.0 (#7511)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-21 12:52:00 +00:00
Hayden
cfb60228f7 chore(l10n): New Crowdin updates (#7509) 2026-04-21 10:24:51 +00:00
Xavier L.
c9a0cac055 fix: Allow user-configurable OIDC timeout (#7496) 2026-04-21 03:22:36 +00:00
renovate[bot]
83bc2f3889 fix(deps): update dependency openai to v2.32.0 (#7507)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-20 22:49:17 +00:00
Hayden
0ffc1e7bf7 chore(l10n): New Crowdin updates (#7506) 2026-04-20 22:25:35 +00:00
renovate[bot]
e166baa33c fix(deps): update dependency pydantic to v2.13.1 (#7505)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-20 17:23:35 +00:00
Hayden
3e25005ea6 chore(l10n): New Crowdin updates (#7502) 2026-04-20 10:16:42 +00:00
Hayden
c92ebf2099 chore(l10n): New Crowdin updates (#7500) 2026-04-19 21:27:03 +00:00
Zdenek Stursa
8e429834af fix: use correct title and icon on Recipe Actions data page (#7498)
Co-authored-by: Zdenek <tvuj-email@example.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-19 16:04:38 +00:00
mealie-actions[bot]
2ca5694391 chore(l10n): Crowdin locale sync (#7497)
Co-authored-by: GitHub Action <action@github.com>
2026-04-19 03:08:18 +00:00
Michael Genson
8d8987ab05 docs: Update recipe creation docs (#7494) 2026-04-18 17:50:26 -05:00
Zdenek Stursa
372474ea2b fix: prevent delete-image dialog from reopening in a loop inside v-menu (#7469)
Co-authored-by: Zdenek <tvuj-email@example.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-18 20:39:43 +00:00
renovate[bot]
5b93129368 fix(deps): update dependency pydantic to v2.13.0 (#7492)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-18 14:27:40 +00:00
renovate[bot]
ffeb4dceaf chore(deps): update dependency mypy to v1.20.1 (#7490)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-18 05:55:14 +00:00
mealie-commit-bot[bot]
5fc4851ef5 chore: bump version to v3.16.0 2026-04-17 20:59:57 +00:00
Michael Genson
d9e933d5ae fix: Misc frontend layout fixes (#7487) 2026-04-17 12:28:13 -05:00
renovate[bot]
0a07835338 fix(deps): update dependency lxml to v6.0.4 (#7485)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-17 16:46:53 +00:00
Michael Genson
7a85ea6ae9 chore: Update yarn deps (#7486) 2026-04-17 11:58:19 -05:00
renovate[bot]
c4c60f1645 fix(deps): update dependency authlib to v1.6.11 [security] (#7481)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-17 16:46:22 +00:00
Zdenek Stursa
9f7ba8dc08 fix: preserve ingredient section titles when parsing recipe ingredients (#7483)
Co-authored-by: Zdenek <tvuj-email@example.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-17 16:44:45 +00:00
Michael Genson
c4799ceb9e dev: Enable lockfile maintenance and update deps (#7484) 2026-04-17 11:33:50 -05:00
Michael Genson
828be095a2 fix: Blank query filter builder fields (#7480) 2026-04-16 19:11:05 -05:00
renovate[bot]
18718fb647 chore(deps): update node.js to 33cf7f0 (#7478)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-16 15:57:22 +00:00
Brian Choromanski
fb545962dd feat: Migrate PWA manifest to backend (#7331)
Co-authored-by: Michael Genson <genson.michael@gmail.com>
Co-authored-by: Michael Genson <71845777+michael-genson@users.noreply.github.com>
2026-04-16 10:59:21 -05:00
Brian Choromanski
781a08ef54 docs: Added copy button to codeblocks (#7343) 2026-04-16 15:34:28 +00:00
mealie-commit-bot[bot]
a7a08b6b11 chore: bump version to v3.15.2 2026-04-16 03:43:59 +00:00
Hayden
bd296c3eaf fix: path traversal vulnerabilities in migration image imports and media routes (#7474) 2026-04-16 03:24:50 +00:00
renovate[bot]
8aa016e57b fix(deps): update dependency python-multipart to v0.0.26 [security] (#7473)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-16 01:39:09 +00:00
renovate[bot]
480574eb3d fix(deps): update dependency python-multipart to v0.0.25 (#7470)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-15 13:30:07 +00:00
mealie-commit-bot[bot]
0573d6fc9c chore: bump version to v3.15.1 2026-04-14 17:37:56 +00:00
Xenov
f8d08c6785 fix: seed labels before foods in setup wizard to prevent race condition (#7429)
Co-authored-by: xenov <redacted>
Co-authored-by: Michael Genson <71845777+michael-genson@users.noreply.github.com>
2026-04-14 16:24:32 +00:00
renovate[bot]
e6368174f0 chore(deps): update dependency ruff to v0.15.10 (#7464)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-14 16:22:02 +00:00
renovate[bot]
2252875050 fix(deps): update dependency lxml to v6.0.3 (#7465)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-14 16:21:30 +00:00
DeepReef11
54c62ec491 fix: eliminate white flash on page load for dark theme users (#7358)
Co-authored-by: Docker User <user@example.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Kuchenpirat <24235032+Kuchenpirat@users.noreply.github.com>
Co-authored-by: Michael Genson <71845777+michael-genson@users.noreply.github.com>
2026-04-14 16:18:00 +00:00
Brian Choromanski
af79a751fb fix: Admin settings checkboxes not updating (#7462) 2026-04-14 15:58:07 +00:00
renovate[bot]
6e2c849412 fix(deps): update dependency openai to v2.31.0 (#7460)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-13 22:53:42 +00:00
140 changed files with 5901 additions and 5513 deletions

View File

@@ -1,7 +1,7 @@
###############################################
# Frontend Build
###############################################
FROM node:24@sha256:80fc934952c8f1b2b4d39907af7211f8a9fff1a4c2cf673fb49099292c251cec \
FROM node:24@sha256:e9891237dfbb1de60ce19e9ff9fac5d73ad9c37da303ad72ff2a425ad1057e71 \
AS frontend-builder
WORKDIR /frontend

View File

@@ -42,6 +42,10 @@ Before you can start using OIDC Authentication, you must first configure a new c
http://localhost:9091/login
https://mealie.example.com/login
If you are hosting Mealie behind a reverse proxy (nginx, Caddy, ...) to terminate TLS, make sure to start Mealie's Gunicorn server
with `--forwarded-allow-ips=<ip-of-proxy>`, otherwise the `X-Forwarded-*` headers will be ignored and the generated OIDC redirect
URI will use the wrong scheme (http instead of https). This will lead to authentication errors with strict OIDC providers.
3. Configure allowed scopes
The scopes required are `openid profile email`

View File

@@ -6,10 +6,16 @@
### Creating Recipes
Mealie offers several ways to create recipes:
- **Recipe Scraper:** Create recipes from hundreds of websites by simply providing a URL.
- **Image Import:** Upload an image of a written or typed recipe and Mealie will use OCR to import it.
- **Video URL Import:** Provide a video URL (e.g., YouTube) and Mealie will transcribe the audio and parse the recipe.
- **Recipe HTML or JSON:** Copy/paste structured HTML or JSON and Mealie can import it.
- **Manual Editor:** Create recipes from scratch using the integrated editor.
Mealie's [AI integration](./installation/open-ai.md) greatly expands the ways you can create recipes:
- **Image Import:** Upload an image of a written or typed recipe and Mealie will use OCR and AI to import it.
- **Video URL Import:** Provide a video URL (e.g., YouTube) and Mealie will transcribe the audio and turn it into a recipe.
[Creation Demo](https://demo.mealie.io/g/home/r/create/url){ .md-button .md-button--primary .align-right }
### Importing Recipes

View File

@@ -10,7 +10,7 @@
| PGID | 911 | GroupID permissions between host OS and container |
| DEFAULT_GROUP | Home | The default group for users |
| DEFAULT_HOUSEHOLD | Family | The default household for users in each group |
| BASE_URL | http://localhost:8080 | Used for Notifications |
| BASE_URL | http://localhost:8080 | Used for notifications and the OIDC callback url |
| TOKEN_TIME | 48 | The time in hours that a login/auth token is valid. Must be <= 9600 (400 days, in hours). |
| API_PORT | 9000 | The port exposed by backend API. **Do not change this if you're running in Docker** |
| API_DOCS | True | Turns on/off access to the API documentation locally |
@@ -114,6 +114,7 @@ For usage, see [Usage - OpenID Connect](../authentication/oidc-v2.md)
| OIDC_GROUPS_CLAIM | groups | Optional if not using `OIDC_USER_GROUP` or `OIDC_ADMIN_GROUP`. This is the claim Mealie will request from your IdP and will use to compare to `OIDC_USER_GROUP` or `OIDC_ADMIN_GROUP` to allow the user to log in to Mealie or is set as an admin. **Your IdP must be configured to grant this claim** |
| OIDC_SCOPES_OVERRIDE | None | Advanced configuration used to override the scopes requested from the IdP. **Most users won't need to change this**. At a minimum, 'openid profile email' are required. |
| OIDC_TLS_CACERTFILE | None | File path to Certificate Authority used to verify server certificate (e.g. `/path/to/ca.crt`) |
| OIDC_CLIENT_TIMEOUT | default | Configures the timeout value of the httpx client used for OIDC communications. If set to the string `default`, does not configure the value (uses the library's default of 5.0s). If set to the string `None`, disables the timeout entirely. If set to a numeric value, uses that as the timeout. |
### OpenAI

View File

@@ -31,7 +31,7 @@ To deploy mealie on your local network, it is highly recommended to use Docker t
We've gone through a few versions of Mealie v1 deployment targets. We have settled on a single container deployment, and we've begun publishing the nightly container on github containers. If you're looking to move from the old nightly (split containers _or_ the omni image) to the new nightly, there are a few things you need to do:
1. Take a backup just in case!
2. Replace the image for the API container with `ghcr.io/mealie-recipes/mealie:v3.15.0`
2. Replace the image for the API container with `ghcr.io/mealie-recipes/mealie:v3.17.0`
3. Take the external port from the frontend container and set that as the port mapped to port `9000` on the new container. The frontend is now served on port 9000 from the new container, so it will need to be mapped for you to have access.
4. Restart the container

View File

@@ -10,7 +10,7 @@ PostgreSQL might be considered if you need to support many concurrent users. In
```yaml
services:
mealie:
image: ghcr.io/mealie-recipes/mealie:v3.15.0 # (3)
image: ghcr.io/mealie-recipes/mealie:v3.17.0 # (3)
container_name: mealie
restart: always
ports:

View File

@@ -11,7 +11,7 @@ SQLite is a popular, open source, self-contained, zero-configuration database th
```yaml
services:
mealie:
image: ghcr.io/mealie-recipes/mealie:v3.15.0 # (3)
image: ghcr.io/mealie-recipes/mealie:v3.17.0 # (3)
container_name: mealie
restart: always
ports:

View File

@@ -19,6 +19,7 @@ theme:
custom_dir: docs/overrides
features:
- content.code.annotate
- content.code.copy
- navigation.top
- navigation.instant
- navigation.expand

View File

@@ -20,16 +20,12 @@
max-width: 1100px !important;
}
.theme--dark.v-application {
background-color: rgb(var(--v-theme-background, 30, 30, 30)) !important;
.v-theme--dark.v-application {
background-color: rgb(var(--v-theme-background)) !important;
}
.theme--dark.v-navigation-drawer {
background-color: rgb(var(--v-theme-background, 30, 30, 30)) !important;
}
.theme--dark.v-card {
background-color: #1e1e1e !important;
.v-theme--dark .v-navigation-drawer {
background-color: rgb(var(--v-theme-background)) !important;
}
.left-border {

View File

@@ -3,7 +3,7 @@
<BaseCardSectionTitle :title="$t('group.group-preferences')" />
<div class="mb-6">
<v-checkbox
v-model="preferences.privateGroup"
v-model="local.privateGroup"
hide-details
density="compact"
color="primary"
@@ -21,7 +21,7 @@
</div>
<div class="mb-6">
<v-checkbox
v-model="preferences.showAnnouncements"
v-model="local.showAnnouncements"
hide-details
density="compact"
color="primary"
@@ -40,4 +40,6 @@
import type { ReadGroupPreferences } from "~/lib/api/types/user";
const preferences = defineModel<ReadGroupPreferences>({ required: true });
const local = reactive({ ...preferences.value });
watch(local, (newVal) => { preferences.value = { ...newVal }; });
</script>

View File

@@ -2,7 +2,7 @@
<div v-if="preferences">
<BaseCardSectionTitle :title="$t('household.household-preferences')" />
<div class="mb-6">
<v-checkbox v-model="preferences.privateHousehold" hide-details density="compact" :label="$t('household.private-household')" color="primary" />
<v-checkbox v-model="local.privateHousehold" hide-details density="compact" :label="$t('household.private-household')" color="primary" />
<div class="ml-8">
<p class="text-subtitle-2 my-0 py-0">
{{ $t("household.private-household-description") }}
@@ -11,7 +11,7 @@
</div>
</div>
<div class="mb-6">
<v-checkbox v-model="preferences.lockRecipeEditsFromOtherHouseholds" hide-details density="compact" :label="$t('household.lock-recipe-edits-from-other-households')" color="primary" />
<v-checkbox v-model="local.lockRecipeEditsFromOtherHouseholds" hide-details density="compact" :label="$t('household.lock-recipe-edits-from-other-households')" color="primary" />
<div class="ml-8">
<p class="text-subtitle-2 my-0 py-0">
{{ $t("household.lock-recipe-edits-from-other-households-description") }}
@@ -20,7 +20,7 @@
</div>
<div class="mb-6">
<v-checkbox
v-model="preferences.showAnnouncements"
v-model="local.showAnnouncements"
hide-details
density="compact"
color="primary"
@@ -33,7 +33,7 @@
</div>
</div>
<v-select
v-model="preferences.firstDayOfWeek"
v-model="local.firstDayOfWeek"
:prepend-icon="$globals.icons.calendarWeekBegin"
:items="allDays"
item-title="name"
@@ -48,7 +48,7 @@
</BaseCardSectionTitle>
<div class="preference-container">
<div v-for="p in recipePreferences" :key="p.key">
<v-checkbox v-model="preferences[p.key]" hide-details density="compact" :label="p.label" color="primary" />
<v-checkbox v-model="local[p.key]" hide-details density="compact" :label="p.label" color="primary" />
<p class="ml-8 text-subtitle-2 my-0 py-0">
{{ p.description }}
</p>
@@ -61,6 +61,9 @@
import type { ReadHouseholdPreferences } from "~/lib/api/types/household";
const preferences = defineModel<ReadHouseholdPreferences>({ required: true });
const local = reactive({ ...preferences.value });
watch(local, (newVal) => { preferences.value = { ...newVal }; });
const i18n = useI18n();
type Preference = {

View File

@@ -41,19 +41,14 @@
>
<v-select
v-if="index"
:model-value="field.logicalOperator"
:model-value="field.logicalOperator?.value"
:items="[logOps.AND, logOps.OR]"
item-title="label"
item-value="value"
variant="underlined"
class="text-center"
@update:model-value="setLogicalOperatorValue(field, index, $event as unknown as LogicalOperator)"
>
<template #chip="{ item }">
<span :class="config.select.textClass" style="width: 100%;">
{{ item.raw.label }}
</span>
</template>
</v-select>
/>
</v-col>
<!-- left parenthesis -->
@@ -67,14 +62,9 @@
:model-value="field.leftParenthesis"
:items="['', '(', '((', '(((']"
variant="underlined"
class="text-center"
@update:model-value="setLeftParenthesisValue(field, index, $event)"
>
<template #chip="{ item }">
<span :class="config.select.textClass" style="width: 100%;">
{{ item.raw }}
</span>
</template>
</v-select>
/>
</v-col>
<!-- field name -->
@@ -84,19 +74,14 @@
:class="config.col.class"
>
<v-select
chips
:model-value="field.label"
:items="fieldDefs"
variant="underlined"
item-title="label"
item-value="label"
class="text-center"
@update:model-value="setField(index, $event)"
>
<template #chip="{ item }">
<span :class="config.select.textClass" style="width: 100%;">
{{ item.raw.label }}
</span>
</template>
</v-select>
/>
</v-col>
<!-- relational operator -->
@@ -107,19 +92,14 @@
>
<v-select
v-if="field.type !== 'boolean'"
:model-value="field.relationalOperatorValue"
:model-value="field.relationalOperatorValue?.value"
:items="field.relationalOperatorChoices"
item-title="label"
item-value="value"
variant="underlined"
class="text-center"
@update:model-value="setRelationalOperatorValue(field, index, $event as unknown as RelationalKeyword | RelationalOperator)"
>
<template #chip="{ item }">
<span :class="config.select.textClass" style="width: 100%;">
{{ item.raw.label }}
</span>
</template>
</v-select>
/>
</v-col>
<!-- field value -->
@@ -275,23 +255,14 @@
:model-value="field.rightParenthesis"
:items="['', ')', '))', ')))']"
variant="underlined"
class="text-center"
@update:model-value="setRightParenthesisValue(field, index, $event)"
>
<template #chip="{ item }">
<span :class="config.select.textClass" style="width: 100%;">
{{ item.raw }}
</span>
</template>
</v-select>
</v-col>
<!-- field actions -->
<v-col
/>
v-if="!$vuetify.display.smAndDown || index === fields.length - 1"
:cols="config.items.fieldActions.cols(index)"
:sm="config.items.fieldActions.sm(index)"
:class="config.col.class"
>
>
<BaseButtonGroup
:buttons="[
{
@@ -723,9 +694,6 @@ const config = computed(() => {
col: {
class: "d-flex justify-center align-end py-0",
},
select: {
textClass: "d-flex justify-center text-center",
},
items: {
icon: {
cols: (_index: number) => 2,

View File

@@ -32,7 +32,6 @@
density="compact"
:label="$t('recipe.recipe-name')"
autofocus
@keyup.enter="duplicateRecipe()"
/>
</v-card-text>
</BaseDialog>

View File

@@ -9,6 +9,7 @@
:items-per-page="15"
class="elevation-0"
:loading="loading"
:search="search"
return-object
>
<template #[`item.name`]="{ item }">
@@ -86,6 +87,7 @@ interface Props {
loading?: boolean;
recipes?: Recipe[];
showHeaders?: ShowHeaders;
search?: string;
}
const props = withDefaults(defineProps<Props>(), {
loading: false,

View File

@@ -1,5 +1,17 @@
<template>
<div class="text-center">
<BaseDialog
v-model="dialogDeleteImage"
:title="$t('recipe.delete-image')"
:icon="$globals.icons.alertCircle"
color="error"
can-delete
@delete="deleteImage"
>
<v-card-text>
{{ $t("recipe.delete-image-confirmation") }}
</v-card-text>
</BaseDialog>
<v-menu
v-model="menu"
offset-y
@@ -37,18 +49,6 @@
delete
@click="dialogDeleteImage = true"
/>
<BaseDialog
v-model="dialogDeleteImage"
:title="$t('recipe.delete-image')"
:icon="$globals.icons.alertCircle"
color="error"
can-delete
@delete="deleteImage"
>
<v-card-text>
{{ $t("recipe.delete-image-confirmation") }}
</v-card-text>
</BaseDialog>
</div>
</v-card-title>
<v-card-text class="mt-n5">

View File

@@ -88,7 +88,7 @@
</div>
</template>
<template #append-item>
<div class="px-2">
<div v-if="showCreateUnit" class="px-2">
<BaseButton
block
size="small"
@@ -147,7 +147,7 @@
</div>
</template>
<template #append-item>
<div class="px-2">
<div v-if="showCreateFood" class="px-2">
<BaseButton
block
size="small"
@@ -344,6 +344,11 @@ const foodData = useFoodData();
const foodAutocomplete = ref<HTMLInputElement>();
const { search: foodSearch, filtered: filteredFoods } = useSearch(foodStore.store);
const showCreateFood = computed(() =>
!!foodSearch.value
&& !filteredFoods.value.some((f: any) => (f.name ?? "").toLowerCase() === foodSearch.value.toLowerCase()),
);
async function createAssignFood() {
foodData.data.name = foodSearch.value;
model.value.food = await foodStore.actions.createOne(foodData.data) || undefined;
@@ -376,6 +381,11 @@ const unitsData = useUnitData();
const unitAutocomplete = ref<HTMLInputElement>();
const { search: unitSearch, filtered: filteredUnits } = useSearch(unitStore.store);
const showCreateUnit = computed(() =>
!!unitSearch.value
&& !filteredUnits.value.some((u: any) => (u.name ?? "").toLowerCase() === unitSearch.value.toLowerCase()),
);
async function createAssignUnit() {
unitsData.data.name = unitSearch.value;
model.value.unit = await unitStore.actions.createOne(unitsData.data) || undefined;

View File

@@ -19,11 +19,11 @@
>
<h3
v-if="showTitleEditor[index]"
class="mt-2"
class="mt-4 mb-0"
>
{{ ingredient.title }}
</h3>
<v-divider v-if="showTitleEditor[index]" />
<v-divider v-if="showTitleEditor[index]" class="my-2" />
<v-list-item
density="compact"
class="pa-0"

View File

@@ -19,6 +19,7 @@
class="pa-0 ma-0"
@update:model-value="resetSearchInput"
@click:append="dialog = true"
@keyup.enter="handleEnter"
>
<template #chip="{ item, index }">
<v-chip
@@ -32,6 +33,26 @@
@click:close="removeByIndex(index)"
/>
</template>
<template
v-if="showAdd"
#no-data
>
<div class="caption text-center pb-2">
{{ $t("recipe.press-enter-to-create") }}
</div>
</template>
<template
v-if="showAdd && searchInput"
#append-item
>
<div class="px-2">
<BaseButton
block
size="small"
@click="createItem()"
/>
</div>
</template>
<template
v-if="showAdd"
#append
@@ -180,6 +201,32 @@ function appendCreated(item: any) {
selected.value = [...selected.value, item];
}
function handleEnter() {
if (!searchInput.value) {
return;
}
const exactMatch = items.value.some(
(item: any) => (item.name ?? "").toLowerCase() === searchInput.value.toLowerCase(),
);
if (!exactMatch) {
createItem();
}
}
async function createItem() {
if (!searchInput.value) {
return;
}
const actions = storeMap[props.selectorType].actions;
// @ts-expect-error different organizer types have different required fields
const newItem = await actions.createOne({ name: searchInput.value });
if (newItem) {
appendCreated(newItem);
}
searchInput.value = "";
}
const dialog = ref(false);
const searchInput = ref("");

View File

@@ -371,14 +371,18 @@ async function parseIngredients() {
}
state.loading.parser = true;
try {
const ingsAsString = props.ingredients
.filter(ing => !ing.referencedRecipe)
.map(ing => ingredientToParserString(ing));
const filteredIngredients = props.ingredients.filter(ing => !ing.referencedRecipe);
const ingsAsString = filteredIngredients.map(ing => ingredientToParserString(ing));
const { data, error } = await api.recipes.parseIngredients(parser.value, ingsAsString);
if (error || !data) {
throw new Error("Failed to parse ingredients");
}
parsedIngs.value = data;
// Restore section titles from original ingredients — the parser doesn't return them
data.forEach((parsed, index) => {
parsed.ingredient.title = filteredIngredients[index]?.title || "";
});
const parsed = data ?? [];
const recipeRefs = props.ingredients.filter(ing => ing.referencedRecipe).map(ing => ({
input: ing.note || "",

View File

@@ -1,6 +1,6 @@
<template>
<div style="height: 100%;">
<v-row class="my-0 mx-7">
<v-row class="mb-0 mt-3 mx-7">
<v-spacer />
<v-col class="text-right">
<!-- Filters -->
@@ -44,6 +44,7 @@
:model-value="option.checked"
color="primary"
readonly
hide-details
@click="toggleEventTypeOption(option.value)"
>
<template #label>

View File

@@ -28,7 +28,6 @@
<v-col v-else cols="9" style="margin: auto; text-align: center">
{{ event.subject }}
</v-col>
<v-spacer />
<v-col :cols="useMobileFormat ? 'auto' : '1'" class="px-0 pt-0">
<RecipeTimelineContextMenu
v-if="currentUser && currentUser.id == event.userId && event.eventType != 'system'"

View File

@@ -0,0 +1,105 @@
<template>
<v-navigation-drawer
permanent
rounded="t-xl"
location="bottom"
class="pa-4 pt-2 mb-0"
width="300"
rail-width="85"
:rail="rail"
elevation="4"
>
<div class="d-flex flex-column ga-3">
<v-card-actions class="pa-0">
<InputLabelType
v-model="listItem.food"
v-model:item-id="listItem.foodId!"
:items="foods"
:label="rail ? $t('shopping-list.add-item') : $t('shopping-list.food')"
:icon="$globals.icons.foods"
:style="rail ? 'margin-inline: 3px;' : undefined"
:search="rail"
create
@create="createAssignFood"
@focus="rail = false"
/>
<BaseButtonGroup
v-if="!rail"
:buttons="[
{
icon: $globals.icons.close,
text: $t('general.cancel'),
event: 'cancel',
},
{
icon: $globals.icons.save,
text: $t('general.save'),
event: 'save',
},
]"
@save="$emit('save')"
@cancel="rail = true; $emit('cancel')"
/>
</v-card-actions>
<ShoppingListItemDetails
v-if="!rail"
v-model="listItem"
:labels="labels"
:units="units"
@save="$emit('save')"
/>
</div>
</v-navigation-drawer>
</template>
<script setup lang="ts">
import { useShoppingListItemEditor } from "~/composables/shopping-list-page/use-shopping-list-item-editor";
import type { ShoppingListItemCreate, ShoppingListItemOut } from "~/lib/api/types/household";
import type { MultiPurposeLabelOut } from "~/lib/api/types/labels";
import type { IngredientFood, IngredientUnit } from "~/lib/api/types/recipe";
import ShoppingListItemDetails from "./ShoppingListItemDetails.vue";
// modelValue as reactive v-model
const listItem = defineModel<ShoppingListItemCreate | ShoppingListItemOut>({ required: true });
defineProps({
labels: {
type: Array as () => MultiPurposeLabelOut[],
required: true,
},
units: {
type: Array as () => IngredientUnit[],
required: true,
},
foods: {
type: Array as () => IngredientFood[],
required: true,
},
});
defineEmits<{
(e: "save" | "cancel" | "delete"): void;
}>();
const { createAssignFood } = useShoppingListItemEditor(listItem);
watch(
() => listItem.value.quantity,
(newQty) => {
if (!newQty) {
listItem.value.quantity = 0;
}
},
);
watch(
() => listItem.value.food,
(newFood) => {
listItem.value.label = newFood?.label || null;
listItem.value.labelId = listItem.value.label?.id || null;
},
);
const rail = ref(true);
</script>

View File

@@ -1,154 +1,178 @@
<template>
<v-container
v-if="!edit"
class="pa-0"
>
<v-row
no-gutters
class="flex-nowrap align-center"
<div style="overflow-x: hidden;">
<v-container
v-if="!edit"
class="pa-0"
:style="{
transform: `translateX(${isRtl ? -swiping : swiping}px)`,
transition: swiping === 0 ? 'transform 0.2s ease' : 'none',
opacity: swiping >= SWIPE_THRESHOLD ? 0.5 : 1,
}"
>
<v-col :cols="itemLabelCols">
<div class="d-flex align-center flex-nowrap">
<v-checkbox
:model-value="listItem.checked"
hide-details
density="compact"
class="mt-0 flex-shrink-0"
color="null"
@click="toggleChecked"
/>
<div
class="ml-2 text-truncate"
:class="listItem.checked ? 'strike-through' : ''"
style="min-width: 0;"
>
<RecipeIngredientListItem :ingredient="listItem" />
<v-row
v-touch="{
move: ({ originalEvent: { touches: [{ screenX }] } }) => {
swipeInfo.touchendX = screenX;
},
start: ({ originalEvent: { touches: [{ screenX }] } }) => {
swipeInfo.touchstartX = screenX;
},
end: () => {
if (swiping < SWIPE_THRESHOLD) {
swipeInfo = {};
return;
}
swipeInfo = {};
toggleChecked();
},
}"
no-gutters
class="flex-nowrap align-center"
>
<v-col :cols="itemLabelCols">
<div class="d-flex align-center flex-nowrap">
<v-checkbox
:model-value="listItem.checked"
hide-details
density="compact"
class="mt-0 flex-shrink-0"
color="null"
@click="toggleChecked"
/>
<div
class="ml-2 text-truncate"
:class="listItem.checked ? 'strike-through' : ''"
style="min-width: 0;"
>
<RecipeIngredientListItem :ingredient="listItem" />
</div>
</div>
</div>
</v-col>
<v-spacer />
<v-col
cols="auto"
class="text-right"
>
<div
v-if="!listItem.checked"
style="min-width: 72px"
</v-col>
<v-spacer />
<v-col
cols="auto"
class="text-right"
>
<v-menu
offset-x
start
min-width="125px"
<div
v-if="!listItem.checked"
style="min-width: 72px"
>
<template #activator="{ props: hoverProps }">
<v-tooltip
v-if="recipeList && recipeList.length"
open-delay="200"
transition="slide-x-reverse-transition"
density="compact"
location="end"
content-class="text-caption"
>
<template #activator="{ props: tooltipProps }">
<v-btn
size="small"
variant="text"
class="ml-2"
icon
v-bind="tooltipProps"
@click="displayRecipeRefs = !displayRecipeRefs"
>
<v-icon>
{{ $globals.icons.potSteam }}
</v-icon>
</v-btn>
</template>
<span>Toggle Recipes</span>
</v-tooltip>
<v-btn
size="small"
variant="text"
class="ml-2"
icon
@click="toggleEdit(true)"
>
<v-icon>
{{ $globals.icons.edit }}
</v-icon>
</v-btn>
<v-btn
size="small"
variant="text"
class="handle"
icon
v-bind="hoverProps"
>
<v-icon>
{{ $globals.icons.arrowUpDown }}
</v-icon>
</v-btn>
</template>
<v-list density="compact">
<v-list-item
v-for="action in contextMenu"
:key="action.event"
density="compact"
@click="contextHandler(action.event)"
>
<v-list-item-title>
{{ action.text }}
</v-list-item-title>
</v-list-item>
</v-list>
</v-menu>
</div>
</v-col>
</v-row>
<v-row
v-if="!listItem.checked && recipeList && recipeList.length && displayRecipeRefs"
no-gutters
class="mb-2"
>
<v-col
cols="auto"
style="width: 100%;"
<v-menu
offset-x
start
min-width="125px"
>
<template #activator="{ props: hoverProps }">
<v-tooltip
v-if="recipeList && recipeList.length"
open-delay="200"
transition="slide-x-reverse-transition"
density="compact"
location="end"
content-class="text-caption"
>
<template #activator="{ props: tooltipProps }">
<v-btn
size="small"
variant="text"
class="ml-2"
icon
v-bind="tooltipProps"
@click="displayRecipeRefs = !displayRecipeRefs"
>
<v-icon>
{{ $globals.icons.potSteam }}
</v-icon>
</v-btn>
</template>
<span>Toggle Recipes</span>
</v-tooltip>
<v-btn
size="small"
variant="text"
class="ml-2"
icon
@click="toggleEdit(true)"
>
<v-icon>
{{ $globals.icons.edit }}
</v-icon>
</v-btn>
<v-btn
size="small"
variant="text"
class="handle"
icon
v-bind="hoverProps"
>
<v-icon>
{{ $globals.icons.arrowUpDown }}
</v-icon>
</v-btn>
</template>
<v-list density="compact">
<v-list-item
v-for="action in contextMenu"
:key="action.event"
density="compact"
@click="contextHandler(action.event)"
>
<v-list-item-title>
{{ action.text }}
</v-list-item-title>
</v-list-item>
</v-list>
</v-menu>
</div>
</v-col>
</v-row>
<v-row
v-if="!listItem.checked && recipeList && recipeList.length && displayRecipeRefs"
no-gutters
class="mb-2"
>
<RecipeList
:recipes="recipeList"
:list-item="listItem"
:disabled="isOffline"
size="small"
tile
/>
</v-col>
</v-row>
<v-row
v-if="listItem.checked"
no-gutters
class="mb-2"
<v-col
cols="auto"
style="width: 100%;"
>
<RecipeList
:recipes="recipeList"
:list-item="listItem"
:disabled="isOffline"
size="small"
tile
/>
</v-col>
</v-row>
<v-row
v-if="listItem.checked"
no-gutters
class="mb-2"
>
<v-col cols="auto">
<div class="text-caption font-weight-light font-italic">
{{ $t("shopping-list.completed-on", {
date: listItem.updatedAt ? $d(new Date(listItem.updatedAt)) : '',
}) }}
</div>
</v-col>
</v-row>
</v-container>
<div
v-else
class="mb-1 mt-6"
>
<v-col cols="auto">
<div class="text-caption font-weight-light font-italic">
{{ $t("shopping-list.completed-on", {
date: listItem.updatedAt ? $d(new Date(listItem.updatedAt)) : '',
}) }}
</div>
</v-col>
</v-row>
</v-container>
<div
v-else
class="mb-1 mt-6"
>
<ShoppingListItemEditor
v-model="localListItem"
:labels="labels"
:units="units"
:foods="foods"
@save="save"
@cancel="toggleEdit(false)"
@delete="$emit('delete')"
/>
<ShoppingListItemEditor
v-model="localListItem"
:labels="labels"
:units="units"
:foods="foods"
class="ma-2"
@save="save"
@cancel="toggleEdit(false)"
@delete="$emit('delete')"
/>
</div>
</div>
</template>
@@ -156,10 +180,10 @@
import { useOnline } from "@vueuse/core";
import RecipeIngredientListItem from "../Recipe/RecipeIngredientListItem.vue";
import ShoppingListItemEditor from "./ShoppingListItemEditor.vue";
import RecipeList from "~/components/Domain/Recipe/RecipeList.vue";
import type { ShoppingListItemOut } from "~/lib/api/types/household";
import type { MultiPurposeLabelOut } from "~/lib/api/types/labels";
import type { IngredientFood, IngredientUnit, RecipeSummary } from "~/lib/api/types/recipe";
import RecipeList from "~/components/Domain/Recipe/RecipeList.vue";
import type { IngredientUnit, IngredientFood, RecipeSummary } from "~/lib/api/types/recipe";
const model = defineModel<ShoppingListItemOut>({ type: Object as () => ShoppingListItemOut, required: true });
@@ -187,6 +211,9 @@ const emit = defineEmits<{
(e: "delete"): void;
}>();
const SWIPE_THRESHOLD = 50;
const { isRtl } = useRtl();
const i18n = useI18n();
const displayRecipeRefs = ref(false);
const itemLabelCols = computed<string>(() => (model.value?.checked ? "auto" : "6"));
@@ -237,6 +264,16 @@ function save() {
edit.value = false;
}
const swipeInfo: Ref<{ touchstartX?: number; touchendX?: number }> = ref({ touchstartX: undefined, touchendX: undefined });
const swiping = computed(() => {
const { touchstartX, touchendX } = swipeInfo.value ?? {};
if (touchstartX === undefined || touchendX === undefined) {
return 0;
}
const delta = isRtl.value ? touchstartX - touchendX : touchendX - touchstartX;
return Math.min(Math.max(0, delta), 100);
});
const recipeList = computed<RecipeSummary[]>(() => {
const ret: RecipeSummary[] = [];
if (!listItem.value.recipeReferences) return ret;

View File

@@ -0,0 +1,85 @@
<template>
<div class="d-flex ga-3">
<v-number-input
v-model="listItem.quantity"
hide-details
:label="$t('form.quantity-label-abbreviated')"
:min="0"
:precision="null"
control-variant="stacked"
style="flex: 1"
inset
/>
<InputLabelType
v-model="listItem.unit"
v-model:item-id="listItem.unitId!"
:items="units"
:label="$t('recipe.unit')"
:icon="$globals.icons.units"
style="flex: 3"
create
@create="createAssignUnit"
/>
</div>
<v-textarea
v-model="listItem.note"
hide-details
:label="$t('shopping-list.note')"
rows="1"
auto-grow
@keypress="handleNoteKeyPress"
/>
<div class="d-flex flex-wrap align-end ga-3">
<InputLabelType
v-model="listItem.label"
v-model:item-id="listItem.labelId!"
:items="labels"
:label="$t('shopping-list.label')"
style="flex: 1 0 200px"
/>
<BaseButton
v-if="listItem.labelId && listItem.food && listItem.labelId !== listItem.food.labelId"
small
color="info"
:icon="$globals.icons.tagArrowRight"
:text="$t('shopping-list.save-label')"
class="mt-2 align-items-flex-start"
style="flex-grow: 0"
@click="assignLabelToFood"
/>
<v-spacer />
</div>
</template>
<script setup lang="ts">
import { useShoppingListItemEditor } from "~/composables/shopping-list-page/use-shopping-list-item-editor";
import type { ShoppingListItemCreate, ShoppingListItemOut } from "~/lib/api/types/household";
import type { MultiPurposeLabelOut } from "~/lib/api/types/labels";
import type { IngredientUnit } from "~/lib/api/types/recipe";
// modelValue as reactive v-model
const listItem = defineModel<ShoppingListItemCreate | ShoppingListItemOut>({ required: true });
defineProps({
labels: {
type: Array as () => MultiPurposeLabelOut[],
required: true,
},
units: {
type: Array as () => IngredientUnit[],
required: true,
},
});
const emit = defineEmits<{ (e: "save"): void }>();
const { assignLabelToFood, createAssignUnit } = useShoppingListItemEditor(listItem);
function handleNoteKeyPress(event: KeyboardEvent) {
// Save on Enter
if (!event.shiftKey && event.key === "Enter") {
event.preventDefault();
emit("save");
}
}
</script>

View File

@@ -1,112 +1,60 @@
<template>
<div>
<v-card variant="outlined">
<v-card-text class="pb-3 pt-1">
<div class="d-md-flex align-center mb-2" style="gap: 20px">
<div>
<v-number-input
v-model="listItem.quantity"
hide-details
:label="$t('form.quantity-label-abbreviated')"
:min="0"
:precision="null"
control-variant="stacked"
inset
style="width: 100px;"
/>
</div>
<InputLabelType
v-model="listItem.unit"
v-model:item-id="listItem.unitId!"
:items="units"
:label="$t('recipe.unit')"
:icon="$globals.icons.units"
create
@create="createAssignUnit"
/>
<InputLabelType
v-model="listItem.food"
v-model:item-id="listItem.foodId!"
:items="foods"
:label="$t('shopping-list.food')"
:icon="$globals.icons.foods"
:autofocus="autoFocus === 'food'"
create
@create="createAssignFood"
/>
</div>
<div class="d-md-flex align-center" style="gap: 20px">
<v-textarea
v-model="listItem.note"
hide-details
:label="$t('shopping-list.note')"
rows="1"
auto-grow
:autofocus="autoFocus === 'note'"
@keypress="handleNoteKeyPress"
/>
</div>
<div class="d-flex flex-wrap align-end" style="gap: 20px">
<div class="d-flex align-end">
<div style="max-width: 300px" class="mt-3 mr-auto">
<InputLabelType
v-model="listItem.label"
v-model:item-id="listItem.labelId!"
:items="labels"
:label="$t('shopping-list.label')"
width="250"
/>
</div>
</div>
<BaseButton
v-if="listItem.labelId && listItem.food && listItem.labelId !== listItem.food.labelId"
small
color="info"
:icon="$globals.icons.tagArrowRight"
:text="$t('shopping-list.save-label')"
class="mt-2 align-items-flex-start"
@click="assignLabelToFood"
/>
<v-spacer />
</div>
</v-card-text>
<v-card-actions class="ma-0 pt-0 pb-1 justify-end">
<BaseButtonGroup
:buttons="[
...(allowDelete
? [
{
icon: $globals.icons.delete,
text: $t('general.delete'),
event: 'delete',
},
]
: []),
{
icon: $globals.icons.close,
text: $t('general.cancel'),
event: 'cancel',
},
{
icon: $globals.icons.save,
text: $t('general.save'),
event: 'save',
},
]"
@save="$emit('save')"
@cancel="$emit('cancel')"
@delete="$emit('delete')"
/>
</v-card-actions>
</v-card>
</div>
<v-card variant="elevated" class="pa-2" border="primary s-lg opacity-100">
<div class="d-flex flex-column ga-3">
<InputLabelType
v-model="listItem.food"
v-model:item-id="listItem.foodId!"
:items="foods"
:label="$t('shopping-list.food')"
:icon="$globals.icons.foods"
:autofocus="autoFocus === 'food'"
create
@create="createAssignFood"
/>
<ShoppingListItemDetails
v-model="listItem"
:labels="labels"
:units="units"
@save="$emit('save')"
/>
</div>
<v-card-actions class="justify-end pa-0">
<BaseButtonGroup
:buttons="[
...(allowDelete
? [
{
icon: $globals.icons.delete,
text: $t('general.delete'),
event: 'delete',
},
]
: []),
{
icon: $globals.icons.close,
text: $t('general.cancel'),
event: 'cancel',
},
{
icon: $globals.icons.save,
text: $t('general.save'),
event: 'save',
},
]"
@save="$emit('save')"
@cancel="$emit('cancel')"
@delete="$emit('delete')"
/>
</v-card-actions>
</v-card>
</template>
<script setup lang="ts">
import { useShoppingListItemEditor } from "~/composables/shopping-list-page/use-shopping-list-item-editor";
import type { ShoppingListItemCreate, ShoppingListItemOut } from "~/lib/api/types/household";
import type { MultiPurposeLabelOut } from "~/lib/api/types/labels";
import type { IngredientFood, IngredientUnit } from "~/lib/api/types/recipe";
import { useFoodStore, useFoodData, useUnitStore, useUnitData } from "~/composables/store";
import ShoppingListItemDetails from "./ShoppingListItemDetails.vue";
// modelValue as reactive v-model
const listItem = defineModel<ShoppingListItemCreate | ShoppingListItemOut>({ required: true });
@@ -132,16 +80,11 @@ defineProps({
});
// const emit = defineEmits<["save", "cancel", "delete"]>();
const emit = defineEmits<{
(e: "save", item: ShoppingListItemOut): void;
(e: "cancel" | "delete"): void;
defineEmits<{
(e: "save" | "cancel" | "delete"): void;
}>();
const foodStore = useFoodStore();
const foodData = useFoodData();
const unitStore = useUnitStore();
const unitData = useUnitData();
const { createAssignFood } = useShoppingListItemEditor(listItem);
watch(
() => listItem.value.quantity,
@@ -161,49 +104,4 @@ watch(
);
const autoFocus = computed(() => (!listItem.value.food && listItem.value.note ? "note" : "food"));
async function createAssignFood(val: string) {
// keep UI reactive
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
listItem.value.food ? (listItem.value.food.name = val) : (listItem.value.food = { name: val } as any);
foodData.data.name = val;
const newFood = await foodStore.actions.createOne(foodData.data);
if (newFood) {
listItem.value.food = newFood;
listItem.value.foodId = newFood.id;
}
foodData.reset();
}
async function createAssignUnit(val: string) {
// keep UI reactive
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
listItem.value.unit ? (listItem.value.unit.name = val) : (listItem.value.unit = { name: val } as any);
unitData.data.name = val;
const newUnit = await unitStore.actions.createOne(unitData.data);
if (newUnit) {
listItem.value.unit = newUnit;
listItem.value.unitId = newUnit.id;
}
unitData.reset();
}
async function assignLabelToFood() {
if (!(listItem.value.food && listItem.value.foodId && listItem.value.labelId)) {
return;
}
listItem.value.food.labelId = listItem.value.labelId;
await foodStore.actions.updateOne(listItem.value.food);
}
function handleNoteKeyPress(event: KeyboardEvent) {
const e = event as KeyboardEvent & { key: string; shiftKey: boolean };
if (!e.shiftKey && e.key === "Enter") {
e.preventDefault();
emit("save");
}
}
</script>

View File

@@ -110,7 +110,7 @@ const route = useRoute();
const groupSlug = computed(() => route.params.groupSlug as string || auth.user.value?.groupSlug || "");
const cookbookPreferences = useCookbookPreferences();
const ownCookbookStore = useCookbookStore(i18n);
const ownCookbookStore = computed(() => isOwnGroup.value ? useCookbookStore(i18n) : null);
const publicCookbookStoreCache = ref<Record<string, ReturnType<typeof usePublicCookbookStore>>>({});
function getPublicCookbookStore(slug: string) {
@@ -121,8 +121,8 @@ function getPublicCookbookStore(slug: string) {
}
const cookbooks = computed(() => {
if (isOwnGroup.value) {
return ownCookbookStore.store.value;
if (ownCookbookStore.value) {
return ownCookbookStore.value.store.value;
}
else if (groupSlug.value) {
const publicStore = getPublicCookbookStore(groupSlug.value);

View File

@@ -4,7 +4,7 @@
v-model="toastAlert.open"
location="top"
:color="toastAlert.color"
timeout="2000"
:timeout="toastAlert.timeout ?? 2000"
>
<v-icon
v-if="icon"
@@ -19,9 +19,12 @@
<template #actions>
<v-btn
variant="text"
@click="toastAlert.open = false"
@click="() => {
toastAlert.action?.onClick();
toastAlert.open = false
}"
>
{{ $t('general.close') }}
{{ toastAlert.action?.message ?? $t('general.close') }}
</v-btn>
</template>
</v-snackbar>

View File

@@ -192,6 +192,14 @@ function submitOnEnter() {
return;
}
if (props.canConfirm) {
if (!props.submitDisabled) {
emit("confirm");
dialog.value = false;
}
return;
}
submitEvent();
}

View File

@@ -7,12 +7,15 @@
item-title="name"
return-object
:items="filteredItems"
:prepend-icon="icon || $globals.icons.tags"
:prepend-inner-icon="icon || (search ? $globals.icons.search : $globals.icons.tags)"
:menu-icon="search ? '' : undefined"
:rounded="search ? true : '4px'"
:custom-filter="() => true"
:variant="search ? 'solo-filled' : undefined"
color="primary"
auto-select-first
clearable
color="primary"
hide-details
:custom-filter="() => true"
@keyup.enter="emitCreate"
>
<template
@@ -55,6 +58,10 @@ const props = defineProps({
type: Boolean,
default: false,
},
search: {
type: Boolean,
default: false,
},
});
const emit = defineEmits<{

View File

@@ -0,0 +1,54 @@
import type { ModelRef } from "vue";
import type { ShoppingListItemOut, ShoppingListItemCreate } from "~/lib/api/types/household";
import { useFoodData, useFoodStore, useUnitData, useUnitStore } from "../store";
export function useShoppingListItemEditor(listItem: ModelRef<ShoppingListItemOut | ShoppingListItemCreate, string, ShoppingListItemOut | ShoppingListItemCreate, ShoppingListItemOut | ShoppingListItemCreate>) {
const foodStore = useFoodStore();
const foodData = useFoodData();
const unitStore = useUnitStore();
const unitData = useUnitData();
async function createAssignFood(val: string) {
// keep UI reactive
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
listItem.value.food ? (listItem.value.food.name = val) : (listItem.value.food = { name: val } as any);
foodData.data.name = val;
const newFood = await foodStore.actions.createOne(foodData.data);
if (newFood) {
listItem.value.food = newFood;
listItem.value.foodId = newFood.id;
}
foodData.reset();
}
async function createAssignUnit(val: string) {
// keep UI reactive
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
listItem.value.unit ? (listItem.value.unit.name = val) : (listItem.value.unit = { name: val } as any);
unitData.data.name = val;
const newUnit = await unitStore.actions.createOne(unitData.data);
if (newUnit) {
listItem.value.unit = newUnit;
listItem.value.unitId = newUnit.id;
}
unitData.reset();
}
async function assignLabelToFood() {
if (!(listItem.value.food && listItem.value.foodId && listItem.value.labelId)) {
return;
}
listItem.value.food.labelId = listItem.value.labelId;
await foodStore.actions.updateOne(listItem.value.food);
}
return {
assignLabelToFood,
createAssignFood,
createAssignUnit,
};
}

View File

@@ -6,7 +6,12 @@ const loading = ref(false);
export const useGroupSelf = function () {
const api = useUserApi();
const auth = useMealieAuth();
async function refreshGroupSelf() {
if (!auth.user.value) {
groupSelfRef.value = null;
return;
}
loading.value = true;
const { data } = await api.groups.getCurrentUserGroup();
groupSelfRef.value = data;

View File

@@ -6,8 +6,13 @@ const loading = ref(false);
export const useHouseholdSelf = function () {
const api = useUserApi();
const auth = useMealieAuth();
async function refreshHouseholdSelf() {
if (!auth.user.value) {
householdSelfRef.value = null;
return;
}
loading.value = true;
const { data } = await api.households.getCurrentUserHousehold();
householdSelfRef.value = data;

View File

@@ -3,224 +3,224 @@ export const LOCALES = [
{
name: "繁體中文 (Chinese traditional)",
value: "zh-TW",
progress: 72,
progress: 98,
dir: "ltr",
pluralFoodHandling: "never",
},
{
name: "简体中文 (Chinese simplified)",
value: "zh-CN",
progress: 27,
progress: 55,
dir: "ltr",
pluralFoodHandling: "never",
},
{
name: "Tiếng Việt (Vietnamese)",
value: "vi-VN",
progress: 1,
progress: 2,
dir: "ltr",
pluralFoodHandling: "never",
},
{
name: "Українська (Ukrainian)",
value: "uk-UA",
progress: 60,
progress: 86,
dir: "ltr",
pluralFoodHandling: "always",
},
{
name: "Türkçe (Turkish)",
value: "tr-TR",
progress: 28,
progress: 54,
dir: "ltr",
pluralFoodHandling: "never",
},
{
name: "Svenska (Swedish)",
value: "sv-SE",
progress: 46,
progress: 74,
dir: "ltr",
pluralFoodHandling: "always",
},
{
name: "српски (Serbian)",
value: "sr-SP",
progress: 72,
progress: 99,
dir: "ltr",
pluralFoodHandling: "always",
},
{
name: "Slovenščina (Slovenian)",
value: "sl-SI",
progress: 30,
progress: 57,
dir: "ltr",
pluralFoodHandling: "always",
},
{
name: "Slovenčina (Slovak)",
value: "sk-SK",
progress: 34,
progress: 61,
dir: "ltr",
pluralFoodHandling: "always",
},
{
name: "Pусский (Russian)",
value: "ru-RU",
progress: 32,
progress: 59,
dir: "ltr",
pluralFoodHandling: "always",
},
{
name: "Română (Romanian)",
value: "ro-RO",
progress: 33,
progress: 60,
dir: "ltr",
pluralFoodHandling: "always",
},
{
name: "Português (Portuguese)",
value: "pt-PT",
progress: 30,
progress: 57,
dir: "ltr",
pluralFoodHandling: "always",
},
{
name: "Português do Brasil (Brazilian Portuguese)",
value: "pt-BR",
progress: 72,
progress: 99,
dir: "ltr",
pluralFoodHandling: "always",
},
{
name: "Polski (Polish)",
value: "pl-PL",
progress: 72,
progress: 99,
dir: "ltr",
pluralFoodHandling: "always",
},
{
name: "Norsk (Norwegian)",
value: "no-NO",
progress: 32,
progress: 59,
dir: "ltr",
pluralFoodHandling: "always",
},
{
name: "Nederlands (Dutch)",
value: "nl-NL",
progress: 70,
progress: 97,
dir: "ltr",
pluralFoodHandling: "always",
},
{
name: "Latviešu (Latvian)",
value: "lv-LV",
progress: 27,
progress: 53,
dir: "ltr",
pluralFoodHandling: "always",
},
{
name: "Lietuvių (Lithuanian)",
value: "lt-LT",
progress: 22,
progress: 42,
dir: "ltr",
pluralFoodHandling: "always",
},
{
name: "한국어 (Korean)",
value: "ko-KR",
progress: 28,
progress: 55,
dir: "ltr",
pluralFoodHandling: "never",
},
{
name: "日本語 (Japanese)",
value: "ja-JP",
progress: 26,
progress: 50,
dir: "ltr",
pluralFoodHandling: "never",
},
{
name: "Italiano (Italian)",
value: "it-IT",
progress: 45,
progress: 72,
dir: "ltr",
pluralFoodHandling: "always",
},
{
name: "Íslenska (Icelandic)",
value: "is-IS",
progress: 31,
progress: 57,
dir: "ltr",
pluralFoodHandling: "always",
},
{
name: "Magyar (Hungarian)",
value: "hu-HU",
progress: 34,
progress: 61,
dir: "ltr",
pluralFoodHandling: "always",
},
{
name: "Hrvatski (Croatian)",
value: "hr-HR",
progress: 21,
progress: 42,
dir: "ltr",
pluralFoodHandling: "always",
},
{
name: "עברית (Hebrew)",
value: "he-IL",
progress: 46,
progress: 73,
dir: "rtl",
pluralFoodHandling: "always",
},
{
name: "Galego (Galician)",
value: "gl-ES",
progress: 27,
progress: 52,
dir: "ltr",
pluralFoodHandling: "always",
},
{
name: "Français (French)",
value: "fr-FR",
progress: 55,
progress: 82,
dir: "ltr",
pluralFoodHandling: "always",
},
{
name: "Français canadien (Canadian French)",
value: "fr-CA",
progress: 60,
progress: 90,
dir: "ltr",
pluralFoodHandling: "always",
},
{
name: "Belge (Belgian)",
value: "fr-BE",
progress: 28,
progress: 72,
dir: "ltr",
pluralFoodHandling: "always",
},
{
name: "Suomi (Finnish)",
value: "fi-FI",
progress: 72,
progress: 99,
dir: "ltr",
pluralFoodHandling: "always",
},
{
name: "Eesti (Estonian)",
value: "et-EE",
progress: 32,
progress: 58,
dir: "ltr",
pluralFoodHandling: "always",
},
{
name: "Español (Spanish)",
value: "es-ES",
progress: 35,
progress: 62,
dir: "ltr",
pluralFoodHandling: "always",
},
@@ -234,63 +234,63 @@ export const LOCALES = [
{
name: "British English",
value: "en-GB",
progress: 32,
progress: 36,
dir: "ltr",
pluralFoodHandling: "without-unit",
},
{
name: "Ελληνικά (Greek)",
value: "el-GR",
progress: 33,
progress: 57,
dir: "ltr",
pluralFoodHandling: "always",
},
{
name: "Deutsch (German)",
value: "de-DE",
progress: 72,
progress: 99,
dir: "ltr",
pluralFoodHandling: "always",
},
{
name: "Dansk (Danish)",
value: "da-DK",
progress: 72,
progress: 100,
dir: "ltr",
pluralFoodHandling: "always",
},
{
name: "Čeština (Czech)",
value: "cs-CZ",
progress: 31,
progress: 59,
dir: "ltr",
pluralFoodHandling: "always",
},
{
name: "Català (Catalan)",
value: "ca-ES",
progress: 33,
progress: 60,
dir: "ltr",
pluralFoodHandling: "always",
},
{
name: "Български (Bulgarian)",
value: "bg-BG",
progress: 44,
progress: 71,
dir: "ltr",
pluralFoodHandling: "always",
},
{
name: "العربية (Arabic)",
value: "ar-SA",
progress: 71,
progress: 98,
dir: "rtl",
pluralFoodHandling: "always",
},
{
name: "Afrikaans (Afrikaans)",
value: "af-ZA",
progress: 18,
progress: 37,
dir: "ltr",
pluralFoodHandling: "always",
},

View File

@@ -73,11 +73,11 @@ function createRecipeExplorerSearchState(groupSlug: ComputedRef<string>): Recipe
});
// Store references
const categories = isOwnGroup ? useCategoryStore() : usePublicCategoryStore(groupSlug.value);
const foods = isOwnGroup ? useFoodStore() : usePublicFoodStore(groupSlug.value);
const households = isOwnGroup ? useHouseholdStore() : usePublicHouseholdStore(groupSlug.value);
const tags = isOwnGroup ? useTagStore() : usePublicTagStore(groupSlug.value);
const tools = isOwnGroup ? useToolStore() : usePublicToolStore(groupSlug.value);
const categories = isOwnGroup.value ? useCategoryStore() : usePublicCategoryStore(groupSlug.value);
const foods = isOwnGroup.value ? useFoodStore() : usePublicFoodStore(groupSlug.value);
const households = isOwnGroup.value ? useHouseholdStore() : usePublicHouseholdStore(groupSlug.value);
const tags = isOwnGroup.value ? useTagStore() : usePublicTagStore(groupSlug.value);
const tools = isOwnGroup.value ? useToolStore() : usePublicToolStore(groupSlug.value);
// Selected items
const selectedCategories = ref<NoUndefinedField<RecipeCategory>[]>([]);

View File

@@ -3,6 +3,11 @@ interface Toast {
text: string;
title: string | null;
color: string;
timeout?: number;
action?: {
onClick: VoidFunction;
message?: string;
};
}
export const toastAlert = reactive<Toast>({
@@ -19,11 +24,13 @@ export const toastLoading = reactive<Toast>({
color: "success",
});
function setToast(toast: Toast, text: string, title: string | null, color: string) {
function setToast(toast: Toast, text: string, title: string | null, color: string, options?: Partial<Toast>) {
toast.open = true;
toast.text = text;
toast.title = title;
toast.color = color;
toast.timeout = options?.timeout;
toast.action = options?.action;
}
export const loader = {
@@ -45,17 +52,17 @@ export const loader = {
};
export const alert = {
info(text: string, title: string | null = null) {
setToast(toastAlert, text, title, "info");
info(text: string, title: string | null = null, options?: Partial<Toast>) {
setToast(toastAlert, text, title, "info", options);
},
success(text: string, title: string | null = null) {
setToast(toastAlert, text, title, "success");
success(text: string, title: string | null = null, options?: Partial<Toast>) {
setToast(toastAlert, text, title, "success", options);
},
error(text: string, title: string | null = null) {
setToast(toastAlert, text, title, "error");
error(text: string, title: string | null = null, options?: Partial<Toast>) {
setToast(toastAlert, text, title, "error", options);
},
warning(text: string, title: string | null = null) {
setToast(toastAlert, text, title, "warning");
warning(text: string, title: string | null = null, options?: Partial<Toast>) {
setToast(toastAlert, text, title, "warning", options);
},
close() {
toastAlert.open = false;

View File

@@ -98,6 +98,7 @@
"dashboard": "Beheerpaneel",
"delete": "Verwyder",
"disabled": "Afkeskakel",
"done": "Done",
"download": "Laai af",
"duplicate": "Dupliseer",
"edit": "Wysig",
@@ -1472,5 +1473,12 @@
"no-whitespace": "No Whitespace Allowed",
"min-length": "Must Be At Least {min} Characters",
"max-length": "Must Be At Most {max} Character|Must Be At Most {max} Characters"
},
"announcements": {
"announcements": "Announcements",
"all-announcements": "All announcements",
"mark-all-as-read": "Mark All as Read",
"show-announcements-from-mealie": "Show announcements from Mealie",
"show-announcements-setting-description": "Whether or not you want to allow users to see announcements from Mealie. When enabled users can still opt-out from seeing them in their user settings"
}
}

View File

@@ -98,6 +98,7 @@
"dashboard": "لوحة المعلومات",
"delete": "حذف",
"disabled": "معطَّل",
"done": "Done",
"download": "تحميل",
"duplicate": "استنساخ",
"edit": "تعديل",
@@ -429,7 +430,7 @@
},
"myrecipebox": {
"title": "صندوق وصفاتي",
"description-long": ""
"description-long": "Mealie can import recipes from My Recipe Box. Export your recipes in CSV format, then upload the .csv file below."
},
"recipekeeper": {
"title": "مدير الوصفة",
@@ -573,11 +574,11 @@
"yield-text": "نص الإرجاع",
"quantity": "الكَمّيَّة",
"choose-unit": "اختر الوحدة",
"press-enter-to-create": "",
"press-enter-to-create": "Press Enter to Create",
"choose-food": "اختيار الطعام",
"choose-recipe": "اختر وصفة",
"notes": "ملاحظات",
"toggle-section": "",
"toggle-section": "Toggle Section",
"see-original-text": "عرض النص الأصلي",
"original-text-with-value": "النص الأصلي: {originalText}",
"ingredient-linker": "رابط المكون",
@@ -885,7 +886,7 @@
"application-version-error-text": "الإصدار الحالي الخاص بك ({0}) لا يتطابق مع الإصدار الأخير. انظر في التحديث إلى الإصدار الأحدث ({1}).",
"mealie-is-up-to-date": "Malie على آخر تحديث",
"secure-site": "موقع آمن",
"secure-site-error-text": "",
"secure-site-error-text": "Serve via localhost or secure with https. Clipboard and additional browser APIs may not work.",
"secure-site-success-text": "يتم الوصول إلى الموقع بواسطة localhost أو peps",
"server-side-base-url": "الرابط الأساسي للخادم",
"server-side-base-url-error-text": "'BASE_URL' لا يزال القيمة الافتراضية على خادم API. وهذا سيسبب مشاكل مع روابط الإشعارات التي تم إنشاؤها على الخادم لرسائل البريد الإلكتروني، إلخ.",
@@ -917,7 +918,7 @@
"shopping-lists": "قوائم التسوق",
"food": "الطعام",
"note": "ملاحظة",
"label": "",
"label": "Label",
"save-label": "حفظ التصنيف",
"linked-item-warning": "هذا العنصر مرتبط بوصفة واحدة أو أكثر. تعديل الوحدات أو الأطعمة سوف يسفر عن نتائج غير متوقعة عند إضافة أو إزالة الوصفة من هذه القائمة.",
"toggle-food": "تبديل الطعام",
@@ -1472,5 +1473,12 @@
"no-whitespace": "لا يسمح باستخدام المسافات",
"min-length": "يجب أن يكون على الأقل {min} أحرف",
"max-length": "يجب أن لا يتجاوز {max} حرف يجب أن يكون على الأكثر {max}أحرف "
},
"announcements": {
"announcements": "Announcements",
"all-announcements": "All announcements",
"mark-all-as-read": "Mark All as Read",
"show-announcements-from-mealie": "Show announcements from Mealie",
"show-announcements-setting-description": "Whether or not you want to allow users to see announcements from Mealie. When enabled users can still opt-out from seeing them in their user settings"
}
}

View File

@@ -98,6 +98,7 @@
"dashboard": "Табло",
"delete": "Изтриване",
"disabled": "Изключено",
"done": "Done",
"download": "Изтегли",
"duplicate": "Дублиране",
"edit": "Редактирай",
@@ -1472,5 +1473,12 @@
"no-whitespace": "Не са позволени интервали",
"min-length": "Трябва да съдържа поне {min} знака",
"max-length": "Трябва да бъде най-много {max} символа|Трябва да бъде най-много {max} символа"
},
"announcements": {
"announcements": "Announcements",
"all-announcements": "All announcements",
"mark-all-as-read": "Mark All as Read",
"show-announcements-from-mealie": "Show announcements from Mealie",
"show-announcements-setting-description": "Whether or not you want to allow users to see announcements from Mealie. When enabled users can still opt-out from seeing them in their user settings"
}
}

View File

@@ -98,6 +98,7 @@
"dashboard": "Tauler de control",
"delete": "Suprimeix",
"disabled": "Desactivat",
"done": "Done",
"download": "Descarregar",
"duplicate": "Duplica",
"edit": "Edita",
@@ -1472,5 +1473,12 @@
"no-whitespace": "No es permeten espais en blanc",
"min-length": "Ha de tenir almenys {min} caràcters",
"max-length": "Ha de tenir com a màxim {max} caràcter|Ha de tenir com a màxim {max} caràcters"
},
"announcements": {
"announcements": "Announcements",
"all-announcements": "All announcements",
"mark-all-as-read": "Mark All as Read",
"show-announcements-from-mealie": "Show announcements from Mealie",
"show-announcements-setting-description": "Whether or not you want to allow users to see announcements from Mealie. When enabled users can still opt-out from seeing them in their user settings"
}
}

View File

@@ -98,6 +98,7 @@
"dashboard": "Nástěnka",
"delete": "Smazat",
"disabled": "Deaktivováno",
"done": "Hotovo",
"download": "Stáhnout",
"duplicate": "Duplikovat",
"edit": "Upravit",
@@ -179,7 +180,7 @@
"units": "Jednotky",
"back": "Zpět",
"next": "Další",
"start": "Start",
"start": "Spustit",
"toggle-view": "Přepnout zobrazení",
"date": "Datum",
"id": "Id",
@@ -331,8 +332,8 @@
"any-household": "Jakákoliv domácnost",
"no-meal-plan-defined-yet": "Dosud nebyl definován žádný jídelníček",
"no-meal-planned-for-today": "Pro dnešek není naplánováno žádné jídlo",
"numberOfDaysPast-hint": "Number of days in the past on page load",
"numberOfDaysPast-label": "Default Days in the Past",
"numberOfDaysPast-hint": "Počet dní v minulosti při načtení stránky",
"numberOfDaysPast-label": "Výchozí dny v minulosti",
"numberOfDays-hint": "Počet dní při načtení stránky",
"numberOfDays-label": "Výchozí dny",
"only-recipes-with-these-categories-will-be-used-in-meal-plans": "Pouze recepty z těchto kategorií budou použity v jídelníčku",
@@ -442,7 +443,7 @@
"error-title": "Vypadá to, že se nám nic nepodařilo najít",
"from-url": "Přenést recept",
"github-issues": "Hlášení chyb na GitHubu",
"google-ld-json-info": "Google ld+json Info",
"google-ld-json-info": "Informace o Google ld+json",
"must-be-a-valid-url": "Musí být validní URL",
"paste-in-your-recipe-data-each-line-will-be-treated-as-an-item-in-a-list": "Vložte data receptu. Každý řádek bude považován za položku v seznamu",
"recipe-markup-specification": "Specifikace Markupu pro recept",
@@ -480,7 +481,7 @@
"recipe": {
"add-key": "Přidat klíč",
"add-to-favorites": "Přidat do oblíbených",
"api-extras": "API Extras",
"api-extras": "API doplňky",
"calories": "Kalorie",
"calories-suffix": "kalorie",
"carbohydrate-content": "Sacharidy",
@@ -638,8 +639,8 @@
"create-a-recipe-by-providing-the-name-all-recipes-must-have-unique-names": "Vytvořte recept zadáním názvu. Všechny recepty musí mít jedinečná jména.",
"new-recipe-names-must-be-unique": "Názvy receptů musí být jedinečné",
"scrape-recipe": "Zpracovat recept",
"scrape-recipe-description": "Scrape a recipe by url. Provide the url for the site you want to scrape, and Mealie will attempt to scrape the recipe from that site and add it to your collection.",
"scrape-recipe-description-transcription": "You can also provide the url to a video and Mealie will attempt to transcribe it into a recipe.",
"scrape-recipe-description": "Stáhněte recept z URL. Zadejte URL webu, ze kterého chcete recept stáhnout, a Mealie se pokusí recept stáhnout a přidat ho do vaší kolekce.",
"scrape-recipe-description-transcription": "Můžete také zadat URL videa a Mealie se pokusí přepsat ho do receptu.",
"scrape-recipe-have-a-lot-of-recipes": "Máte spoustu receptů, které chcete zpracovat najednou?",
"scrape-recipe-suggest-bulk-importer": "Vyzkoušejte hromadný import",
"scrape-recipe-have-raw-html-or-json-data": "Máte surová data HTML nebo JSON?",
@@ -655,7 +656,7 @@
"import-from-html-or-json": "Importovat z HTML nebo JSON",
"import-from-html-or-json-description": "Import jednoho receptu ze surového HTML nebo JSON. To je užitečné, pokud máte recept z webu, který Mealie nedokáže normálně seškrábat, nebo z jiného externího zdroje.",
"json-import-format-description-colon": "Chcete-li importovat přes JSON, musí mít platný formát:",
"json-editor": "JSON Editor",
"json-editor": "JSON editor",
"zip-files-must-have-been-exported-from-mealie": "Soubory .zip musí být exportovány z aplikace Mealie",
"create-a-recipe-by-uploading-a-scan": "Vytvořte recept nahráním skenu.",
"upload-a-png-image-from-a-recipe-book": "Nahrát png obrázek z knihy receptů",
@@ -835,7 +836,7 @@
},
"token": {
"active-tokens": "AKTIVNÍ TOKENY",
"api-token": "API Token",
"api-token": "API token",
"api-tokens": "API Tokeny",
"copy-this-token-for-use-with-an-external-application-this-token-will-not-be-viewable-again": "Zkopírujte tento token pro použití v externí aplikaci. Tento token nebude znovu zobrazen.",
"create-an-api-token": "Vytvořit nový API token",
@@ -865,7 +866,7 @@
},
"bug-report": "Chybové hlášení",
"bug-report-information": "Použijte tyto informace k nahlášení chyby. Poskytnutí podrobností vaší instance vývojářům je nejlepší způsob, jak rychle vyřešit vaše problémy.",
"tracker": "Tracker",
"tracker": "Sledovač",
"configuration": "Konfigurace",
"docker-volume": "Volume dockeru",
"docker-volume-help": "Mealie vyžaduje, aby kontejner prostředí a podpůrné vrstvy sdílely stejný úložný prostor dockeru. Tím se zajistí, že kontejner prostředí bude moci správně přistupovat k obrázkům a informacím uloženým na disku.",
@@ -891,17 +892,17 @@
"server-side-base-url-error-text": "`BASE_URL` je stále výchozí hodnotou na serveru API. To způsobí problémy s odkazy v oznámení generované na serveru pro e-maily atd.",
"server-side-base-url-success-text": "Adresa URL na straně serveru neodpovídá výchozímu nastavení",
"ldap-ready": "LDAP připraven",
"ldap-not-ready": "LDAP Not Ready",
"ldap-not-ready": "LDAP nepřipraveno",
"ldap-ready-error-text": "Nejsou nakonfigurovány všechny LDAP hodnoty. To můžete ignorovat, pokud nepoužíváte LDAP autentizaci.",
"ldap-ready-success-text": "Všechny požadované proměnné LDAP jsou nastaveny.",
"build": "Sestavení",
"recipe-scraper-version": "Verze scraperu receptů",
"oidc-ready": "OIDC připraveno",
"oidc-not-ready": "OIDC Not Ready",
"oidc-not-ready": "OIDC nepřipraveno",
"oidc-ready-error-text": "Nejsou nakonfigurovány všechny OIDC hodnoty. To můžete ignorovat, pokud nepoužíváte OIDC autentizaci.",
"oidc-ready-success-text": "Všechny požadované proměnné OIDC jsou nastaveny.",
"openai-ready": "OpenAI připraveno",
"openai-not-ready": "OpenAI Not Ready",
"openai-not-ready": "OpenAI nepřipraveno",
"openai-ready-error-text": "Nejsou nakonfigurovány všechny OpenAI hodnoty. To můžete ignorovat, pokud nepoužíváte OpenAI funkce.",
"openai-ready-success-text": "Všechny požadované proměnné OpenAI jsou nastaveny."
},
@@ -909,7 +910,7 @@
"all-lists": "Všechny seznamy",
"create-shopping-list": "Vytvořit nákupní seznam",
"from-recipe": "Z receptu",
"ingredient-of-recipe": "Ingredient of {recipe}",
"ingredient-of-recipe": "Ingredience receptu {recipe}",
"list-name": "Název seznamu",
"new-list": "Nový seznam",
"quantity": "Množství: {0}",
@@ -1010,7 +1011,7 @@
"current-password": "Současné heslo",
"e-mail-must-be-valid": "E-mail musí být platný",
"edit-user": "Upravit uživatele",
"email": "Email",
"email": "E-mail",
"error-cannot-delete-super-user": "Chyba! Nelze odstranit superuživatele",
"existing-password-does-not-match": "Hesla se neshodují",
"full-name": "Jméno a příjmení",
@@ -1142,18 +1143,18 @@
"example-unit-plural": "např.: Čajové lžičky",
"example-unit-abbreviation-singular": "např.: čl",
"example-unit-abbreviation-plural": "např.: čl",
"standardization": "Standardization",
"standardization-description": "How this unit can be represented as a standard unit. This enables unit conversion features such as merging compatible units in shopping lists.",
"standard-unit": "Standard Unit",
"standard-quantity": "Standard Quantity",
"unit-conversion": "Unit Conversion",
"standardization": "Standardizace",
"standardization-description": "Jak lze tuto jednotku reprezentovat jako standardní jednotku. Umožňuje funkce konverze jednotek, jako je slučování kompatibilních jednotek v nákupních seznamech.",
"standard-unit": "Standardní jednotka",
"standard-quantity": "Standardní množství",
"unit-conversion": "Konverze jednotek",
"standard-unit-labels": {
"fluid-ounce": "fluid ounce",
"cup": "cup",
"ounce": "ounce",
"pound": "pound",
"milliliter": "milliliter",
"liter": "liter",
"fluid-ounce": "tekutá unce",
"cup": "šálek",
"ounce": "unce",
"pound": "libra",
"milliliter": "mililitr",
"liter": "litr",
"gram": "gram",
"kilogram": "kilogram"
}
@@ -1192,13 +1193,13 @@
"edit-recipe-action": "Upravit akci receptu",
"action-type": "Typ akce",
"action-types": {
"link": "Link",
"link": "Odkaz",
"post": "Publikovat"
}
},
"create-alias": "Vytvořit alias",
"manage-aliases": "Spravovat aliasy",
"seed-data": "Seed Data",
"seed-data": "Výchozí data",
"seed": "Zdroj",
"data-management": "Správa dat",
"data-management-description": "Vyberte datovou sadu, ve které chcete provést změny.",
@@ -1472,5 +1473,12 @@
"no-whitespace": "Mezery nejsou povoleny",
"min-length": "Musí být alespoň {min} znaků",
"max-length": "Musí být maximálně {max} znak|Musí být na většině {max} znaků"
},
"announcements": {
"announcements": "Oznámení",
"all-announcements": "Všechna oznámení",
"mark-all-as-read": "Označit vše jako přečtené",
"show-announcements-from-mealie": "Zobrazit oznámení od Mealie",
"show-announcements-setting-description": "Pokud je povoleno, uživatelé uvidí oznámení od Mealie. Mohou to změnit ve svém uživatelském nastavení"
}
}

View File

@@ -98,6 +98,7 @@
"dashboard": "Overblik",
"delete": "Slet",
"disabled": "Deaktiveret",
"done": "Udført",
"download": "Hent",
"duplicate": "Kopier",
"edit": "Rediger",
@@ -182,7 +183,7 @@
"start": "Start",
"toggle-view": "Skift visning",
"date": "Dato",
"id": "Id",
"id": "ID",
"owner": "Ejer",
"change-owner": "Skift ejer",
"date-added": "Oprettelsesdato",
@@ -686,9 +687,9 @@
"explanation": "For at bruge ingrediensfortolkeren, skal du klikke på knappen 'Fortolk alt' for at starte behandlingen. Når relevante ingredienser er identificeret, kan du gennemgå dem og kontrollere, at de blev korrekt identificeret. Modellens konfidensscore vises til højre for ingrediensens titel. Denne score er et gennemsnit af alle de enkelte scorer og er måske ikke altid helt præcis.",
"alerts-explainer": "En advarsel vil blive vist, hvis en identificeret fødevare eller måleenhed ikke findes i databasen.",
"select-parser": "Vælg fortolker",
"natural-language-processor": "Natural Language Processor",
"brute-parser": "Brute Parser",
"openai-parser": "OpenAI Parser",
"natural-language-processor": "Naturlig sprogbehandler",
"brute-parser": "Rå parser",
"openai-parser": "OpenAI-parser",
"parse-all": "Fortolk alt",
"no-unit": "Ingen enhed",
"missing-unit": "Opret manglende måleenhed: {unit}",
@@ -835,8 +836,8 @@
},
"token": {
"active-tokens": "Aktive tokens",
"api-token": "API Token",
"api-tokens": "API Tokens",
"api-token": "API-token",
"api-tokens": "API-tokener",
"copy-this-token-for-use-with-an-external-application-this-token-will-not-be-viewable-again": "Kopier denne token ved brug i en anden applikation. Denne token kan ikke ses igen.",
"create-an-api-token": "Opret en API token",
"token-name": "Tokennavn",
@@ -855,9 +856,9 @@
"unorganized": "Uorganiseret"
},
"webhooks": {
"test-webhooks": "Test Webhooks",
"test-webhooks": "Test webhooks",
"the-urls-listed-below-will-recieve-webhooks-containing-the-recipe-data-for-the-meal-plan-on-its-scheduled-day-currently-webhooks-will-execute-at": "Webadresserne, der er anført nedenfor, modtager webhooks, der indeholder opskriftsdataene for måltidsplanen på den planlagte dag. \nWebhooks udføres i øjeblikket på ",
"webhook-url": "Webhook URL",
"webhook-url": "Webhook-URL",
"webhooks-caps": "WEBHOOKS",
"webhooks": "Webhooks",
"webhook-name": "Webhooknavn",
@@ -865,9 +866,9 @@
},
"bug-report": "Fejlrapport",
"bug-report-information": "Brug denne information til at rapportere en fejl. At give detaljer om din instans til udviklere er den bedste måde at få dine problemer løst hurtigt.",
"tracker": "Tracker",
"tracker": "Sporing",
"configuration": "Konfiguration",
"docker-volume": "Docker Volume",
"docker-volume": "Docker-volumen",
"docker-volume-help": "Mealie kræver, at frontend og backend containere deler den samme docker mappe. Dette sikrer, at frontend container har adgang til billeder og øvrige lagret på disken.",
"volumes-are-misconfigured": "Docker mapper er forkert konfigureret.",
"volumes-are-configured-correctly": "Docker mapper er korrekt konfigureret.",
@@ -953,7 +954,7 @@
"profile": "Profil",
"search": "Søg",
"site-settings": "Sideindstillinger",
"tags": "Tags",
"tags": "Etiketter",
"toolbox": "Værktøjskasse",
"language": "Sprog",
"maintenance": "Vedligeholdelse",
@@ -980,7 +981,7 @@
"tag-deletion-failed": "Sletning af tag fejlede",
"tag-update-failed": "Opdatering af tag fejlede",
"tag-updated": "Tag blev opdateret",
"tags": "Tags",
"tags": "Etiket",
"untagged-count": "Ikke-tagget: {count}",
"create-a-tag": "Opret tag",
"tag-name": "Tag navn",
@@ -1016,7 +1017,7 @@
"full-name": "Fulde navn",
"generate-password-reset-link": "Generér link til nulstilling af adgangskode",
"invite-only": "Kun inviterede",
"link-id": "Link ID",
"link-id": "Link-ID",
"link-name": "Linknavn",
"login": "Log på",
"login-oidc": "Log ind med",
@@ -1329,7 +1330,7 @@
"action-clean-images-description": "Fjerner alle de billeder, der ikke slutter med .webp",
"actions-description": "Vedligeholdelseshandlinger er {destructive_in_bold} og bør bruges med forsigtighed. Udførelse af alle disse handlinger er {irreversible_in_bold}.",
"actions-description-destructive": "destruktive",
"actions-description-irreversible": "irreversible",
"actions-description-irreversible": "uomgørlig",
"logs-action-refresh": "Opdater logfiler",
"logs-page-title": "Mealie logfiler",
"logs-tail-lines-label": "Følg log"
@@ -1341,7 +1342,7 @@
"ingredients-natural-language-processor-explanation": "Mealie bruger Conditional Random Fields felter (CRF'er) til berarbejdning af ingredienser. Den model, der anvendes til ingredienser er baseret ud fra et datasæt på over 100.000 ingredienser fra et datasæt udarbejdet af New York Times. Bemærk, at da modellen kun er trænet på engelsk, kan du have forskellige resultater, når du bruger modellen på andre sprog. På denne side kan du teste modellen.",
"ingredients-natural-language-processor-explanation-2": "Det er ikke perfekt, men giver generelt gode resultater og er et godt udgangspunkt for manuel redigering af ingredienser i individuelle felter. Alternativt kan du også bruge \"Brute\"-metoden, der bruger en mønstermatchende teknik til at identificere ingredienser.",
"nlp": "NLP",
"brute": "Brute",
"brute": "",
"openai": "OpenAI",
"show-individual-confidence": "Vis individual konfidensscore",
"ingredient-text": "Ingredienstekst",
@@ -1472,5 +1473,12 @@
"no-whitespace": "Mellemrum er ikke tilladt",
"min-length": "Der skal mindst være {min} tegn",
"max-length": "Må højst være {max} tegn|Må højst være {max} tegn"
},
"announcements": {
"announcements": "Meddelelser",
"all-announcements": "Alle meddelelser",
"mark-all-as-read": "Markér alle som læst",
"show-announcements-from-mealie": "Vis meddelelser fra Mealie",
"show-announcements-setting-description": "Hvorvidt det ønskes, at brugere skal kunne se meddelelser fra Mealie. Hvis dette er slået til, er det stadig muligt for brugere at fravælge det i deres brugerindstillinger."
}
}

View File

@@ -98,6 +98,7 @@
"dashboard": "Übersicht",
"delete": "Löschen",
"disabled": "Deaktiviert",
"done": "Done",
"download": "Herunterladen",
"duplicate": "Duplizieren",
"edit": "Bearbeiten",
@@ -1472,5 +1473,12 @@
"no-whitespace": "Kein Leerzeichen erlaubt",
"min-length": "Muss mindestens {min} Zeichen haben",
"max-length": "Muss maximal {max} Zeichen haben|Muss maximal {max} Zeichen haben"
},
"announcements": {
"announcements": "Announcements",
"all-announcements": "All announcements",
"mark-all-as-read": "Alle als gelesen markieren",
"show-announcements-from-mealie": "Show announcements from Mealie",
"show-announcements-setting-description": "Whether or not you want to allow users to see announcements from Mealie. When enabled users can still opt-out from seeing them in their user settings"
}
}

View File

@@ -98,6 +98,7 @@
"dashboard": "Ταμπλό",
"delete": "Διαγραφή",
"disabled": "Ανενεργό",
"done": "Ολοκληρώθηκε",
"download": "Λήψη",
"duplicate": "Δημιουργία διπλότυπου",
"edit": "Επεξεργασία",
@@ -1472,5 +1473,12 @@
"no-whitespace": "Δεν επιτρέπονται κενοί χαρακτήρες",
"min-length": "Πρέπει να αποτελείται από τουλάχιστον {min} χαρακτήρες",
"max-length": "Πρέπει να αποτελείται το πολύ από {max} χαρακτήρα|Πρέπει να αποτελείται το πολύ από {max} χαρακτήρες"
},
"announcements": {
"announcements": "Ανακοινώσεις",
"all-announcements": "Oλες οι ανακοινώσεις",
"mark-all-as-read": "Σήμανση όλων ως αναγνωσμένων",
"show-announcements-from-mealie": "Εμφάνιση ανακοινώσεων από το Mealie",
"show-announcements-setting-description": "Εάνε θέλετε ή όχι να επιτρέψετε στους χρήστες να βλέπουν ανακοινώσεις από την Mealie. Οταν είναι ενεργοποιημένο οι χρήστες μπορούν ακόμα να απεγγραφούν από αυτές από τις ρυθμίσεις χρήστη τους ώστε να μην τις βλέπουν"
}
}

View File

@@ -98,6 +98,7 @@
"dashboard": "Dashboard",
"delete": "Delete",
"disabled": "Disabled",
"done": "Done",
"download": "Download",
"duplicate": "Duplicate",
"edit": "Edit",
@@ -261,7 +262,7 @@
"enable-public-access": "Enable Public Access",
"enable-public-access-description": "Make group recipes public by default, and allow visitors to view recipes without logging-in",
"allow-users-outside-of-your-group-to-see-your-recipes": "Allow users outside your group to see your recipes",
"allow-users-outside-of-your-group-to-see-your-recipes-description": "When enabled you can use a public share link to share specific recipes without authorizing the user. When disabled, you can only share recipes with users who are in your group or with a pre-generated private link",
"allow-users-outside-of-your-group-to-see-your-recipes-description": "When enabled you can use a public share link to share specific recipes without authorising the user. When disabled, you can only share recipes with users who are in your group or with a pre-generated private link",
"show-nutrition-information": "Show nutrition information",
"show-nutrition-information-description": "When enabled the nutrition information will be shown on the recipe if available. If there is no nutrition information available the nutrition information will now be shown",
"show-recipe-assets": "Show recipe assets",
@@ -270,7 +271,7 @@
"default-to-landscape-view-description": "When enabled the recipe header section will be shown in landscape view",
"disable-users-from-commenting-on-recipes": "Disable users from commenting on recipes",
"disable-users-from-commenting-on-recipes-description": "Hides the comment section on the recipe page and disables commenting",
"disable-organizing-recipe-ingredients-by-units-and-food": "Disable organizing recipe ingredients by units and food",
"disable-organizing-recipe-ingredients-by-units-and-food": "Disable organising recipe ingredients by units and food",
"disable-organizing-recipe-ingredients-by-units-and-food-description": "Hides the Food, Unit, and Amount fields for ingredients and treats ingredients as plain text fields",
"general-preferences": "General Preferences",
"group-recipe-preferences": "Group Recipe Preferences",
@@ -1152,8 +1153,8 @@
"cup": "cup",
"ounce": "ounce",
"pound": "pound",
"milliliter": "milliliter",
"liter": "liter",
"milliliter": "millilitre",
"liter": "litre",
"gram": "gram",
"kilogram": "kilogram"
}
@@ -1472,5 +1473,12 @@
"no-whitespace": "No Whitespace Allowed",
"min-length": "Must Be At Least {min} Characters",
"max-length": "Must Be At Most {max} Character|Must Be At Most {max} Characters"
},
"announcements": {
"announcements": "Announcements",
"all-announcements": "All announcements",
"mark-all-as-read": "Mark All as Read",
"show-announcements-from-mealie": "Show announcements from Mealie",
"show-announcements-setting-description": "Whether or not you want to allow users to see announcements from Mealie. When enabled users can still opt-out from seeing them in their user settings"
}
}

View File

@@ -169,6 +169,7 @@
"token": "Token",
"tuesday": "Tuesday",
"type": "Type",
"undo": "Undo",
"update": "Update",
"updated": "Updated",
"upload": "Upload",
@@ -916,6 +917,7 @@
"quantity": "Quantity: {0}",
"shopping-list": "Shopping List",
"shopping-lists": "Shopping Lists",
"add-item": "Add item",
"food": "Food",
"note": "Note",
"label": "Label",
@@ -940,7 +942,8 @@
"are-you-sure-you-want-to-check-all-items": "Are you sure you want to check all items?",
"are-you-sure-you-want-to-uncheck-all-items": "Are you sure you want to uncheck all items?",
"are-you-sure-you-want-to-delete-checked-items": "Are you sure you want to delete all checked items?",
"no-shopping-lists-found": "No Shopping Lists Found"
"no-shopping-lists-found": "No Shopping Lists Found",
"item-checked-off": "{item} was checked off"
},
"sidebar": {
"all-recipes": "All Recipes",

View File

@@ -98,6 +98,7 @@
"dashboard": "Panel de control",
"delete": "Eliminar",
"disabled": "Deshabilitado",
"done": "Done",
"download": "Descargar",
"duplicate": "Duplicar",
"edit": "Editar",
@@ -1462,7 +1463,7 @@
"is-not-like": "no es como"
},
"dates": {
"days-ago": ""
"days-ago": "days ago|day ago|days ago"
}
},
"validators": {
@@ -1472,5 +1473,12 @@
"no-whitespace": "No se permiten espacios en blanco",
"min-length": "Debe tener como mínimo {min} caracteres",
"max-length": "Debe Ser Como Máximo {max} Carácter|Debe Ser Como Máximo {max} Caracteres"
},
"announcements": {
"announcements": "Announcements",
"all-announcements": "All announcements",
"mark-all-as-read": "Mark All as Read",
"show-announcements-from-mealie": "Show announcements from Mealie",
"show-announcements-setting-description": "Whether or not you want to allow users to see announcements from Mealie. When enabled users can still opt-out from seeing them in their user settings"
}
}

View File

@@ -98,6 +98,7 @@
"dashboard": "Töölaud",
"delete": "Kustuta",
"disabled": "Keelatud",
"done": "Done",
"download": "Lae alla",
"duplicate": "Duplitseeri",
"edit": "Muuda",
@@ -569,7 +570,7 @@
"failed-to-add-recipe-to-mealplan": "Retsepti lisamine toitumisplaani ebaõnnestus",
"failed-to-add-to-list": "Nimekirja lisamine ebaõnnestus",
"yield": "Saagikus",
"yields-amount-with-text": "",
"yields-amount-with-text": "Yields {amount} {text}",
"yield-text": "Saaduse tekst",
"quantity": "Kogus",
"choose-unit": "Vali ühik",
@@ -1472,5 +1473,12 @@
"no-whitespace": "No Whitespace Allowed",
"min-length": "Must Be At Least {min} Characters",
"max-length": "Must Be At Most {max} Character|Must Be At Most {max} Characters"
},
"announcements": {
"announcements": "Announcements",
"all-announcements": "All announcements",
"mark-all-as-read": "Mark All as Read",
"show-announcements-from-mealie": "Show announcements from Mealie",
"show-announcements-setting-description": "Whether or not you want to allow users to see announcements from Mealie. When enabled users can still opt-out from seeing them in their user settings"
}
}

View File

@@ -98,6 +98,7 @@
"dashboard": "Hallintanäkymä",
"delete": "Poista",
"disabled": "Poistettu käytöstä",
"done": "Done",
"download": "Lataa",
"duplicate": "Monista",
"edit": "Muokkaa",
@@ -700,7 +701,7 @@
"confidence-score": "Varmuuspisteet",
"ingredient-parser-description": "Ainesosat on haettu onnistuneesti. Ole hyvä ja tarkista ainesosat joista emme ole varmoja.",
"ingredient-parser-final-review-description": "Kun kaikki ainesosat on tarkistettu, sinulla on vielä yksi mahdollisuus tarkistaa kaikki ainesosat ennen kuin muokkaat reseptiäsi.",
"add-text-as-alias-for-item": "",
"add-text-as-alias-for-item": "Add \"{text}\" as alias for {item}",
"delete-item": "Poista kohde"
},
"reset-servings-count": "Palauta Annoksien Määrä",
@@ -1372,7 +1373,7 @@
"profile": {
"welcome-user": "👋 Tervetuloa, {0}!",
"description": "Hallitse profiiliasi, reseptejäsi ja ryhmäasetuksiasi.",
"invite-link": "",
"invite-link": "Invite Link",
"get-invite-link": "Hanki Kutsulinkki",
"get-public-link": "Julkinen linkki",
"account-summary": "Tilin Yhteenveto",
@@ -1472,5 +1473,12 @@
"no-whitespace": "Tekstissä ei saa olla välilyöntejä",
"min-length": "Vähimmäispituus on {min} merkkiä",
"max-length": "Saa olla enintään {max} merkki|Saa olla enintään {max} merkkiä"
},
"announcements": {
"announcements": "Announcements",
"all-announcements": "All announcements",
"mark-all-as-read": "Mark All as Read",
"show-announcements-from-mealie": "Show announcements from Mealie",
"show-announcements-setting-description": "Whether or not you want to allow users to see announcements from Mealie. When enabled users can still opt-out from seeing them in their user settings"
}
}

View File

@@ -98,6 +98,7 @@
"dashboard": "Tableau de bord",
"delete": "Supprimer",
"disabled": "Désactivé",
"done": "Terminé",
"download": "Télécharger",
"duplicate": "Dupliquer",
"edit": "Modifier",
@@ -331,8 +332,8 @@
"any-household": "Tout foyer",
"no-meal-plan-defined-yet": "Aucun menu planifié",
"no-meal-planned-for-today": "Aucun repas prévu pour aujourdhui",
"numberOfDaysPast-hint": "Number of days in the past on page load",
"numberOfDaysPast-label": "Default Days in the Past",
"numberOfDaysPast-hint": "Nombre de jours passé à charger",
"numberOfDaysPast-label": "Jours par défaut dans le pas",
"numberOfDays-hint": "Nombre de jours lors du chargement de la page",
"numberOfDays-label": "Jours par défaut",
"only-recipes-with-these-categories-will-be-used-in-meal-plans": "Seules les recettes appartenant à ces catégories seront utilisées dans les menus",
@@ -891,17 +892,17 @@
"server-side-base-url-error-text": "`BASE_URL` est encore la valeur par défaut sur le serveur API. Cela causera des problèmes avec les liens générés par les notifications sur le serveur pour les e-mails, etc.",
"server-side-base-url-success-text": "L'URL du côté du serveur ne correspond pas à celle par défaut",
"ldap-ready": "Prêt pour LDAP",
"ldap-not-ready": "LDAP Not Ready",
"ldap-not-ready": "LDAP n'est pas prêt",
"ldap-ready-error-text": "Toutes les valeurs LDAP ne sont pas configurées. Vous pouvez ignorer cet avertissement si vous n'utilisez pas l'authentification LDAP.",
"ldap-ready-success-text": "Les variables LDAP obligatoires sont toutes définies.",
"build": "Build",
"recipe-scraper-version": "Version du Scraper de recette",
"oidc-ready": "Prêt pour OIDC",
"oidc-not-ready": "OIDC Not Ready",
"oidc-not-ready": "OIDC n'est pas prêt",
"oidc-ready-error-text": "Toutes les valeurs OIDC ne sont pas configurées. Vous pouvez ignorer cet avertissement si vous nutilisez pas lauthentification OIDC.",
"oidc-ready-success-text": "Les variables OIDC obligatoires sont toutes définies.",
"openai-ready": "Prêt pour OpenAI",
"openai-not-ready": "OpenAI Not Ready",
"openai-not-ready": "OpenAI n'est pas prêt",
"openai-ready-error-text": "Toutes les valeurs OpenAI ne sont pas configurées. Vous pouvez ignorer cet avertissement si vous n'utilisez pas les fonctionnalités OpenAI.",
"openai-ready-success-text": "Les variables OpenAI obligatoires sont toutes définies."
},
@@ -916,7 +917,7 @@
"shopping-list": "Liste de courses",
"shopping-lists": "Listes de courses",
"food": "Aliment",
"note": "Note",
"note": "Remarque",
"label": "Étiquette",
"save-label": "Sauvegarder le libellé",
"linked-item-warning": "Cet article est lié à une ou plusieurs recettes. Ajuster les unités ou les aliments donnera des résultats inattendus lors de lajout ou de la suppression de la recette de cette liste.",
@@ -1347,7 +1348,7 @@
"ingredient-text": "Texte de l'ingrédient",
"average-confident": "Confiant à {0}",
"try-an-example": "Essayez avec un exemple",
"parser": "Parser",
"parser": "Analyseur syntaxique",
"background-tasks": "Tâches en arrière plan",
"background-tasks-description": "Ici vous pouvez voir toutes les tâches en arrière-plan en cours et leur statut",
"no-logs-found": "Pas de journaux trouvés",
@@ -1472,5 +1473,12 @@
"no-whitespace": "Aucun espace n'est autorisé",
"min-length": "Doit contenir au moins {min} caractères",
"max-length": "Doit comporter au maximum {max} caractère|Doit comporter au maximum {max} caractères"
},
"announcements": {
"announcements": "Annonces",
"all-announcements": "Toutes les annonces",
"mark-all-as-read": "Marquer tout comme lu",
"show-announcements-from-mealie": "Afficher les annonces de Mealie",
"show-announcements-setting-description": "Si vous voulez autoriser ou non les utilisateurs à voir les annonces de Mealie. Lorsque cette option est activée, les utilisateurs peuvent toujours refuser de les voir dans leurs paramètres utilisateur"
}
}

View File

@@ -19,7 +19,7 @@
"log-lines": "Lignes du journal",
"not-demo": "Non démo",
"portfolio": "Portfolio",
"production": "Production",
"production": "Réalisation",
"support": "Soutenir",
"version": "Version",
"unknown-version": "inconnu",
@@ -98,6 +98,7 @@
"dashboard": "Tableau de bord",
"delete": "Supprimer",
"disabled": "Désactivé",
"done": "Terminé",
"download": "Télécharger",
"duplicate": "Dupliquer",
"edit": "Modifier",
@@ -331,8 +332,8 @@
"any-household": "Tout foyer",
"no-meal-plan-defined-yet": "Aucun menu planifié",
"no-meal-planned-for-today": "Aucun repas prévu pour aujourd'hui",
"numberOfDaysPast-hint": "Number of days in the past on page load",
"numberOfDaysPast-label": "Default Days in the Past",
"numberOfDaysPast-hint": "Nombre de jours passé à charger",
"numberOfDaysPast-label": "Jours par défaut dans le pas",
"numberOfDays-hint": "Nombre de jours lors du chargement de la page",
"numberOfDays-label": "Jours par défaut",
"only-recipes-with-these-categories-will-be-used-in-meal-plans": "Seules les recettes appartenant à ces catégories seront utilisées dans les menus",
@@ -513,7 +514,7 @@
"milligrams": "milligrammes",
"new-key-name": "Nouveau nom de clé",
"no-white-space-allowed": "Aucun espace blanc autorisé",
"note": "Note",
"note": "Remarque",
"nutrition": "Valeurs nutritionnelles",
"object-key": "Clé d'objet",
"object-value": "Valeur d'objet",
@@ -891,17 +892,17 @@
"server-side-base-url-error-text": "`BASE_URL` est encore la valeur par défaut sur le serveur API. Cela causera des problèmes avec les liens générés par les notifications sur le serveur pour les e-mails, etc.",
"server-side-base-url-success-text": "L'URL du côté du serveur ne correspond pas à celle par défaut",
"ldap-ready": "Prêt pour LDAP",
"ldap-not-ready": "LDAP Not Ready",
"ldap-not-ready": "LDAP n'est pas prêt",
"ldap-ready-error-text": "Toutes les valeurs LDAP ne sont pas configurées. Vous pouvez ignorer cet avertissement si vous n'utilisez pas l'authentification LDAP.",
"ldap-ready-success-text": "Les variables LDAP obligatoires sont toutes définies.",
"build": "Build",
"recipe-scraper-version": "Version du Scraper de recette",
"oidc-ready": "Prêt pour OIDC",
"oidc-not-ready": "OIDC Not Ready",
"oidc-not-ready": "OIDC n'est pas prêt",
"oidc-ready-error-text": "Toutes les valeurs OIDC ne sont pas configurées. Vous pouvez ignorer cet avertissement si vous nutilisez pas lauthentification OIDC.",
"oidc-ready-success-text": "Les variables OIDC obligatoires sont toutes définies.",
"openai-ready": "Prêt pour OpenAI",
"openai-not-ready": "OpenAI Not Ready",
"openai-not-ready": "OpenAI n'est pas prêt",
"openai-ready-error-text": "Toutes les valeurs OpenAI ne sont pas configurées. Vous pouvez ignorer cet avertissement si vous n'utilisez pas les fonctionnalités OpenAI.",
"openai-ready-success-text": "Les variables OpenAI obligatoires sont toutes définies."
},
@@ -916,7 +917,7 @@
"shopping-list": "Liste d'épicerie",
"shopping-lists": "Listes d'épicerie",
"food": "Aliments",
"note": "Note",
"note": "Remarque",
"label": "Étiquette",
"save-label": "Sauvegarder le libellé",
"linked-item-warning": "Cet article est lié à une ou plusieurs recettes. Ajuster les unités ou les aliments donnera des résultats inattendus lors de lajout ou de la suppression de la recette de cette liste.",
@@ -1347,7 +1348,7 @@
"ingredient-text": "Texte de l'ingrédient",
"average-confident": "Confiant à {0}",
"try-an-example": "Essayez avec un exemple",
"parser": "Parser",
"parser": "Analyseur syntaxique",
"background-tasks": "Tâches en arrière plan",
"background-tasks-description": "Ici vous pouvez voir toutes les tâches en arrière-plan en cours et leur statut",
"no-logs-found": "Pas de journaux trouvés",
@@ -1470,7 +1471,14 @@
"invalid-email": "Le-mail doit être valide",
"invalid-url": "Doit être une URL valide",
"no-whitespace": "Aucun espace n'est autorisé",
"min-length": "",
"min-length": "Doit contenir au moins {min} caractères",
"max-length": "Doit comporter au maximum {max} caractère|Doit comporter au maximum {max} caractères"
},
"announcements": {
"announcements": "Annonces",
"all-announcements": "Toutes les annonces",
"mark-all-as-read": "Marquer tout comme lu",
"show-announcements-from-mealie": "Afficher les annonces de Mealie",
"show-announcements-setting-description": "Si vous voulez autoriser ou non les utilisateurs à voir les annonces de Mealie. Lorsque cette option est activée, les utilisateurs peuvent toujours refuser de les voir dans leurs paramètres utilisateur"
}
}

View File

@@ -19,7 +19,7 @@
"log-lines": "Lignes de log",
"not-demo": "Non",
"portfolio": "Portfolio",
"production": "Production",
"production": "Réalisation",
"support": "Soutenir",
"version": "Version",
"unknown-version": "inconnu",
@@ -98,6 +98,7 @@
"dashboard": "Tableau de bord",
"delete": "Supprimer",
"disabled": "Désactivé",
"done": "Terminé",
"download": "Télécharger",
"duplicate": "Dupliquer",
"edit": "Modifier",
@@ -916,7 +917,7 @@
"shopping-list": "Liste de courses",
"shopping-lists": "Listes de courses",
"food": "Aliment",
"note": "Note",
"note": "Remarque",
"label": "Étiquette",
"save-label": "Sauvegarder le libellé",
"linked-item-warning": "Cet article est lié à une ou plusieurs recettes. Ajuster les unités ou les aliments donnera des résultats inattendus lors de lajout ou de la suppression de la recette de cette liste.",
@@ -1347,7 +1348,7 @@
"ingredient-text": "Texte de l'ingrédient",
"average-confident": "Confiant à {0}",
"try-an-example": "Essayez avec un exemple",
"parser": "Parser",
"parser": "Analyseur syntaxique",
"background-tasks": "Tâches en arrière-plan",
"background-tasks-description": "Ici vous pouvez voir toutes les tâches en arrière-plan en cours et leur statut",
"no-logs-found": "Pas de journaux trouvés",
@@ -1472,5 +1473,12 @@
"no-whitespace": "Aucun espace n'est autorisé",
"min-length": "Doit contenir au moins {min} caractères",
"max-length": "Doit comporter au maximum {max} caractère|Doit comporter au maximum {max} caractères"
},
"announcements": {
"announcements": "Annonces",
"all-announcements": "Toutes les annonces",
"mark-all-as-read": "Marquer tout comme lu",
"show-announcements-from-mealie": "Afficher les annonces de Mealie",
"show-announcements-setting-description": "Si vous voulez autoriser ou non les utilisateurs à voir les annonces de Mealie. Lorsque cette option est activée, les utilisateurs peuvent toujours refuser de les voir dans leurs paramètres utilisateur"
}
}

View File

@@ -98,6 +98,7 @@
"dashboard": "Panel",
"delete": "Eliminar",
"disabled": "Desactivado",
"done": "Done",
"download": "Descargar",
"duplicate": "Duplicar",
"edit": "Editar",
@@ -1472,5 +1473,12 @@
"no-whitespace": "No Whitespace Allowed",
"min-length": "Must Be At Least {min} Characters",
"max-length": "Must Be At Most {max} Character|Must Be At Most {max} Characters"
},
"announcements": {
"announcements": "Announcements",
"all-announcements": "All announcements",
"mark-all-as-read": "Mark All as Read",
"show-announcements-from-mealie": "Show announcements from Mealie",
"show-announcements-setting-description": "Whether or not you want to allow users to see announcements from Mealie. When enabled users can still opt-out from seeing them in their user settings"
}
}

View File

@@ -98,6 +98,7 @@
"dashboard": "לוח הבקרה",
"delete": "מחיקה",
"disabled": "כבוי",
"done": "Done",
"download": "הורדה",
"duplicate": "שכפול",
"edit": "עריכה",
@@ -424,7 +425,7 @@
"paprika-text": "Mealie יכולה לייבא מתכונים מאפליקציית Paprika. יש לייצא את המתכונים מהאפליקציה, לשנות את סיומת הקובץ ל- zip ולהעלות אותו כאן.",
"mealie-text": "Mealie יכול לייבא מתכונים מגרסאות ישנות של Mealie מתחת ל- v1.0. ייצא את המתכונים מהסביבה הישנה והעלה את קובץ ה- zip למטה. ניתן לייבא רק מתכונים מתהליך הייצוא.",
"plantoeat": {
"title": "Plan to Eat",
"title": "בתכנון לאכול",
"description-long": "Mealie יכולה לייבא מתכונים מהאתר- Plan to Eat."
},
"myrecipebox": {
@@ -644,10 +645,10 @@
"scrape-recipe-suggest-bulk-importer": "נסה את יכולת קריאת רשימה",
"scrape-recipe-have-raw-html-or-json-data": "יש לך מידע גולמי ב-HTML או JSON?",
"scrape-recipe-you-can-import-from-raw-data-directly": "ניתן לייבא ישירות ממידע גולמי",
"scrape-recipe-website-being-blocked": "Website being blocked?",
"scrape-recipe-website-being-blocked": "האתר חסום?",
"scrape-recipe-try-importing-raw-html-instead": "Try importing the raw HTML instead.",
"import-original-keywords-as-tags": "ייבוא שמות מפתח מקוריות כתגיות",
"import-original-categories": "Import original categories",
"import-original-categories": "ייבא קטגוריות מקוריות",
"stay-in-edit-mode": "השאר במצב עריכה",
"parse-recipe-ingredients-after-import": "Parse recipe ingredients after import",
"import-from-zip": "ייבא מקובץ",
@@ -693,15 +694,15 @@
"no-unit": "ללא יחידות",
"missing-unit": "יצירת יחידה חסרה: {unit}",
"missing-food": "יצירת אוכל חסר: {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": "יחידת המידה הזאת לא יכלה להיות מחולצת אוטומטית",
"this-food-could-not-be-parsed-automatically": "המאכל הזה לא יכל להיות מחולץ אוטומטית",
"no-food": "אין אוכל",
"review-parsed-ingredients": "Review parsed ingredients",
"confidence-score": "Confidence Score",
"ingredient-parser-description": "Your ingredients have been successfully parsed. Please review the ingredients we're not sure about.",
"ingredient-parser-final-review-description": "Once all ingredients have been reviewed, you'll have one more chance to review all ingredients before applying the changes to your recipe.",
"add-text-as-alias-for-item": "Add \"{text}\" as alias for {item}",
"delete-item": "Delete Item"
"delete-item": "מחק פריט"
},
"reset-servings-count": "איפוס מספר המנות",
"not-linked-ingredients": "מרכיבים נוספים",
@@ -1094,7 +1095,7 @@
"forgot-password-text": "נא לספק כתובת דוא\"ל. אנו נשלח לך הודעת דוא\"ל לצורך איפוס הסיסמה שלך.",
"changes-reflected-immediately": "שינויים למשתמש זה ישתקפו מיידית.",
"default-activity": "Default Activity",
"default-activity-hint": "Select which page you'd like to navigate to upon logging in from this device"
"default-activity-hint": "בחר את עמוד ברירת המחדל בשביל המכשיר הזה"
},
"language-dialog": {
"translated": "תורגם",
@@ -1153,8 +1154,8 @@
"ounce": "ounce",
"pound": "pound",
"milliliter": "מיליליטר",
"liter": "liter",
"gram": "gram",
"liter": "ליטר",
"gram": "גרם",
"kilogram": "kilogram"
}
},
@@ -1192,7 +1193,7 @@
"edit-recipe-action": "עריכת פעולת-מתכון",
"action-type": "סוג פעולה",
"action-types": {
"link": "Link",
"link": "לינק",
"post": "Post"
}
},
@@ -1466,11 +1467,18 @@
}
},
"validators": {
"required": "This Field is Required",
"required": "חובה למלא שדה זה",
"invalid-email": "Email Must Be Valid",
"invalid-url": "Must Be A Valid URL",
"no-whitespace": "No Whitespace Allowed",
"min-length": "Must Be At Least {min} Characters",
"max-length": "Must Be At Most {max} Character|Must Be At Most {max} Characters"
},
"announcements": {
"announcements": "Announcements",
"all-announcements": "All announcements",
"mark-all-as-read": "Mark All as Read",
"show-announcements-from-mealie": "Show announcements from Mealie",
"show-announcements-setting-description": "Whether or not you want to allow users to see announcements from Mealie. When enabled users can still opt-out from seeing them in their user settings"
}
}

View File

@@ -98,6 +98,7 @@
"dashboard": "Kontrolna ploča",
"delete": "Obriši",
"disabled": "Onemogućeno",
"done": "Done",
"download": "Preuzmi",
"duplicate": "Dupliciraj",
"edit": "Uredi",
@@ -1472,5 +1473,12 @@
"no-whitespace": "No Whitespace Allowed",
"min-length": "Must Be At Least {min} Characters",
"max-length": "Must Be At Most {max} Character|Must Be At Most {max} Characters"
},
"announcements": {
"announcements": "Announcements",
"all-announcements": "All announcements",
"mark-all-as-read": "Mark All as Read",
"show-announcements-from-mealie": "Show announcements from Mealie",
"show-announcements-setting-description": "Whether or not you want to allow users to see announcements from Mealie. When enabled users can still opt-out from seeing them in their user settings"
}
}

View File

@@ -98,6 +98,7 @@
"dashboard": "Vezérlőpult",
"delete": "Törlés",
"disabled": "Letiltva",
"done": "Done",
"download": "Letöltés",
"duplicate": "Duplikálás",
"edit": "Szerkesztés",
@@ -1343,7 +1344,7 @@
"nlp": "NLP",
"brute": "Brute",
"openai": "OpenAI",
"show-individual-confidence": "",
"show-individual-confidence": "Show individual confidence",
"ingredient-text": "Hozzávaló szöveg",
"average-confident": "{0}-os bizonyosság",
"try-an-example": "Próbáljon ki egy példát",
@@ -1472,5 +1473,12 @@
"no-whitespace": "Szóközt nem tartalmazhat",
"min-length": "Legalább {min} karakter legyen",
"max-length": "Legfeljebb {max} karakter lehet|Legfeljebb {max} karakter lehet"
},
"announcements": {
"announcements": "Announcements",
"all-announcements": "All announcements",
"mark-all-as-read": "Mark All as Read",
"show-announcements-from-mealie": "Show announcements from Mealie",
"show-announcements-setting-description": "Whether or not you want to allow users to see announcements from Mealie. When enabled users can still opt-out from seeing them in their user settings"
}
}

View File

@@ -98,6 +98,7 @@
"dashboard": "Yfirlitssíða",
"delete": "Eyða",
"disabled": "Afvirkjað",
"done": "Done",
"download": "Sækja",
"duplicate": "Afrita",
"edit": "Breyta",
@@ -1472,5 +1473,12 @@
"no-whitespace": "Engin bil leyfð",
"min-length": "Verður að vera að lágmarki {min} stafir",
"max-length": "Must Be At Most {max} Character|Must Be At Most {max} Characters"
},
"announcements": {
"announcements": "Tilkynningar",
"all-announcements": "Allar tilkynningar",
"mark-all-as-read": "Merkja allar sem lesnar",
"show-announcements-from-mealie": "Sýna tilkynningar frá Mealie",
"show-announcements-setting-description": "Hvort leyfa eigi notendum að sjá tilkynningar fŕa Mealie. Sé þetta virkt þá getur notandinn sjálfur valið að sjá þær ekki í sínum notenda stillingum"
}
}

View File

@@ -98,6 +98,7 @@
"dashboard": "Pannello di controllo",
"delete": "Elimina",
"disabled": "Disabilita",
"done": "Fatto",
"download": "Download",
"duplicate": "Duplicato",
"edit": "Modifica",
@@ -274,7 +275,7 @@
"disable-organizing-recipe-ingredients-by-units-and-food-description": "Nasconde i campi di alimento, unità e quantità per gli ingredienti e tratta gli ingredienti come campi di testo semplice",
"general-preferences": "Impostazioni Generali",
"group-recipe-preferences": "Impostazioni per le ricette del gruppo",
"report": "Report",
"report": "Segnala",
"report-with-id": "ID Report: {id}",
"group-management": "Gestione Gruppo",
"admin-group-management": "Gestione Gruppo Amministratore",
@@ -544,7 +545,7 @@
"share-recipe-message": "Volevo condividere la mia {0} ricetta con te.",
"show-nutrition-values": "Mostra Valori Nutrizionali",
"sodium-content": "Sodio",
"step-index": "Step: {step}",
"step-index": "Passo {step}",
"sugar-content": "Zuccheri",
"title": "Titolo",
"total-time": "Tempo Totale",
@@ -1472,5 +1473,12 @@
"no-whitespace": "Gli Spazi Non Sono Ammessi",
"min-length": "Deve Essere Almeno {min} Caratteri",
"max-length": "Deve Essere Al Più {max} Carattere|Deve Essere Al Più {max} Caratteri"
},
"announcements": {
"announcements": "Announcements",
"all-announcements": "All announcements",
"mark-all-as-read": "Mark All as Read",
"show-announcements-from-mealie": "Show announcements from Mealie",
"show-announcements-setting-description": "Whether or not you want to allow users to see announcements from Mealie. When enabled users can still opt-out from seeing them in their user settings"
}
}

View File

@@ -98,6 +98,7 @@
"dashboard": "ダッシュボード",
"delete": "削除",
"disabled": "無効",
"done": "Done",
"download": "ダウンロード",
"duplicate": "複製",
"edit": "編集",
@@ -1472,5 +1473,12 @@
"no-whitespace": "No Whitespace Allowed",
"min-length": "Must Be At Least {min} Characters",
"max-length": "Must Be At Most {max} Character|Must Be At Most {max} Characters"
},
"announcements": {
"announcements": "Announcements",
"all-announcements": "All announcements",
"mark-all-as-read": "Mark All as Read",
"show-announcements-from-mealie": "Show announcements from Mealie",
"show-announcements-setting-description": "Whether or not you want to allow users to see announcements from Mealie. When enabled users can still opt-out from seeing them in their user settings"
}
}

View File

@@ -98,6 +98,7 @@
"dashboard": "대시보드",
"delete": "삭제",
"disabled": "비활성화됨",
"done": "Done",
"download": "다운로드",
"duplicate": "복제",
"edit": "편집",
@@ -182,7 +183,7 @@
"start": "시작",
"toggle-view": "뷰 전환",
"date": "날짜",
"id": "",
"id": "Id",
"owner": "작성자",
"change-owner": "소유자 변경",
"date-added": "추가된 날짜",
@@ -1472,5 +1473,12 @@
"no-whitespace": "공백 허용 안 됨",
"min-length": "최소 {min}자 이상이어야 합니다",
"max-length": "최대 {max}자|최대 {max}자\n"
},
"announcements": {
"announcements": "Announcements",
"all-announcements": "All announcements",
"mark-all-as-read": "Mark All as Read",
"show-announcements-from-mealie": "Show announcements from Mealie",
"show-announcements-setting-description": "Whether or not you want to allow users to see announcements from Mealie. When enabled users can still opt-out from seeing them in their user settings"
}
}

View File

@@ -98,6 +98,7 @@
"dashboard": "Prietaisų skydelis",
"delete": "Ištrinti",
"disabled": "Išjungta",
"done": "Done",
"download": "Atsisiųsti",
"duplicate": "Sukurti kopiją",
"edit": "Redaguoti",
@@ -1472,5 +1473,12 @@
"no-whitespace": "No Whitespace Allowed",
"min-length": "Must Be At Least {min} Characters",
"max-length": "Must Be At Most {max} Character|Must Be At Most {max} Characters"
},
"announcements": {
"announcements": "Announcements",
"all-announcements": "All announcements",
"mark-all-as-read": "Mark All as Read",
"show-announcements-from-mealie": "Show announcements from Mealie",
"show-announcements-setting-description": "Whether or not you want to allow users to see announcements from Mealie. When enabled users can still opt-out from seeing them in their user settings"
}
}

View File

@@ -98,6 +98,7 @@
"dashboard": "Informācijas panelis",
"delete": "Dzēst",
"disabled": "Atspējots",
"done": "Done",
"download": "Lejupielādēt",
"duplicate": "Dublēt",
"edit": "Rediģēt",
@@ -1472,5 +1473,12 @@
"no-whitespace": "No Whitespace Allowed",
"min-length": "Must Be At Least {min} Characters",
"max-length": "Must Be At Most {max} Character|Must Be At Most {max} Characters"
},
"announcements": {
"announcements": "Announcements",
"all-announcements": "All announcements",
"mark-all-as-read": "Mark All as Read",
"show-announcements-from-mealie": "Show announcements from Mealie",
"show-announcements-setting-description": "Whether or not you want to allow users to see announcements from Mealie. When enabled users can still opt-out from seeing them in their user settings"
}
}

View File

@@ -98,6 +98,7 @@
"dashboard": "Dashboard",
"delete": "Verwijderen",
"disabled": "Uitgeschakeld",
"done": "Done",
"download": "Downloaden",
"duplicate": "Dupliceren",
"edit": "Bewerken",
@@ -1472,5 +1473,12 @@
"no-whitespace": "Geen spaties toegestaan",
"min-length": "Moet minimaal {min} tekens bevatten",
"max-length": "Moet maximaal {max} tekens bevatten|Moet maximaal {max} tekens bevatten"
},
"announcements": {
"announcements": "Announcements",
"all-announcements": "All announcements",
"mark-all-as-read": "Mark All as Read",
"show-announcements-from-mealie": "Show announcements from Mealie",
"show-announcements-setting-description": "Whether or not you want to allow users to see announcements from Mealie. When enabled users can still opt-out from seeing them in their user settings"
}
}

View File

@@ -98,6 +98,7 @@
"dashboard": "Kontrollpanel",
"delete": "Slett",
"disabled": "Deaktivert",
"done": "Done",
"download": "Last ned",
"duplicate": "Dupliser",
"edit": "Rediger",
@@ -1472,5 +1473,12 @@
"no-whitespace": "Ingen mellomrom tillatt",
"min-length": "Må minst ha {min} tegn",
"max-length": "Må være minst minst {max} tegn må bestå av maks {max} tegn"
},
"announcements": {
"announcements": "Announcements",
"all-announcements": "All announcements",
"mark-all-as-read": "Mark All as Read",
"show-announcements-from-mealie": "Show announcements from Mealie",
"show-announcements-setting-description": "Whether or not you want to allow users to see announcements from Mealie. When enabled users can still opt-out from seeing them in their user settings"
}
}

View File

@@ -98,6 +98,7 @@
"dashboard": "Panel główny",
"delete": "Usuń",
"disabled": "Wyłączone",
"done": "Done",
"download": "Pobierz",
"duplicate": "Duplikuj",
"edit": "Edytuj",
@@ -1472,5 +1473,12 @@
"no-whitespace": "Niedozwolone są puste spacje",
"min-length": "Musi zawierać co najmniej {min} znaków",
"max-length": "Może zawierać co najwyżej {max} znak|Może zawierać co najwyżej {max} znaki|Może zawierać co najwyżej {max} znaków"
},
"announcements": {
"announcements": "Announcements",
"all-announcements": "All announcements",
"mark-all-as-read": "Mark All as Read",
"show-announcements-from-mealie": "Show announcements from Mealie",
"show-announcements-setting-description": "Whether or not you want to allow users to see announcements from Mealie. When enabled users can still opt-out from seeing them in their user settings"
}
}

View File

@@ -98,6 +98,7 @@
"dashboard": "Painel de controle",
"delete": "Excluir",
"disabled": "Desabilitado",
"done": "Done",
"download": "Baixar",
"duplicate": "Duplicar",
"edit": "Editar",
@@ -1472,5 +1473,12 @@
"no-whitespace": "Nenhum espaço em branco é permitido",
"min-length": "Precisa ter pelo menos {min} caracteres",
"max-length": "Precisa ter no máximo {max} caractere|Precisa ter no máximo {max} caracteres"
},
"announcements": {
"announcements": "Announcements",
"all-announcements": "All announcements",
"mark-all-as-read": "Mark All as Read",
"show-announcements-from-mealie": "Show announcements from Mealie",
"show-announcements-setting-description": "Whether or not you want to allow users to see announcements from Mealie. When enabled users can still opt-out from seeing them in their user settings"
}
}

View File

@@ -98,6 +98,7 @@
"dashboard": "Painel de controlo",
"delete": "Eliminar",
"disabled": "Desativado",
"done": "Done",
"download": "Transferir",
"duplicate": "Duplicado",
"edit": "Editar",
@@ -332,7 +333,7 @@
"no-meal-plan-defined-yet": "Nenhum plano de refeições definido",
"no-meal-planned-for-today": "Nenhum plano de refeições definido para hoje",
"numberOfDaysPast-hint": "Number of days in the past on page load",
"numberOfDaysPast-label": "Default Days in the Past",
"numberOfDaysPast-label": "",
"numberOfDays-hint": "Número de dias no carregamento da página",
"numberOfDays-label": "Dias predefinidos",
"only-recipes-with-these-categories-will-be-used-in-meal-plans": "Só serão usadas receitas com estas categorias nos Planos de Refeições",
@@ -1472,5 +1473,12 @@
"no-whitespace": "Não são permitidos espaços em branco",
"min-length": "Deve ter pelo menos {min} caracteres",
"max-length": "Must Be At Most {max} Character|Must Be At Most {max} Characters"
},
"announcements": {
"announcements": "Announcements",
"all-announcements": "All announcements",
"mark-all-as-read": "Mark All as Read",
"show-announcements-from-mealie": "Show announcements from Mealie",
"show-announcements-setting-description": "Whether or not you want to allow users to see announcements from Mealie. When enabled users can still opt-out from seeing them in their user settings"
}
}

View File

@@ -98,6 +98,7 @@
"dashboard": "Panou de control",
"delete": "Șterge",
"disabled": "Inactiv",
"done": "Done",
"download": "Descarcă",
"duplicate": "Duplicat",
"edit": "Editează",
@@ -1472,5 +1473,12 @@
"no-whitespace": "Niciun Spațiu Alb Permis",
"min-length": "Trebuie Să Aibă Cel Puțin {min} Caractere",
"max-length": "Trebuie să aibă cel mult {max} caracter | Trebuie să aibă cel mult {max} caractere"
},
"announcements": {
"announcements": "Announcements",
"all-announcements": "All announcements",
"mark-all-as-read": "Mark All as Read",
"show-announcements-from-mealie": "Show announcements from Mealie",
"show-announcements-setting-description": "Whether or not you want to allow users to see announcements from Mealie. When enabled users can still opt-out from seeing them in their user settings"
}
}

View File

@@ -98,6 +98,7 @@
"dashboard": "Панель инструментов",
"delete": "Удалить",
"disabled": "Отключено",
"done": "Done",
"download": "Загрузить",
"duplicate": "Создать копию",
"edit": "Изменить",
@@ -1472,5 +1473,12 @@
"no-whitespace": "Без пробелов",
"min-length": "Должно быть минимум {min} символов",
"max-length": "Должно быть как минимум {max} знак|Должно быть больше {max} знаков"
},
"announcements": {
"announcements": "Announcements",
"all-announcements": "All announcements",
"mark-all-as-read": "Mark All as Read",
"show-announcements-from-mealie": "Show announcements from Mealie",
"show-announcements-setting-description": "Whether or not you want to allow users to see announcements from Mealie. When enabled users can still opt-out from seeing them in their user settings"
}
}

View File

@@ -98,6 +98,7 @@
"dashboard": "Hlavný panel",
"delete": "Odstrániť",
"disabled": "Deaktivované",
"done": "Hotovo",
"download": "Stiahnuť",
"duplicate": "Duplikovať",
"edit": "Upraviť",
@@ -109,7 +110,7 @@
"field-required": "Povinný údaj",
"file-folder-not-found": "Súbor/priečinok nenájdený",
"file-uploaded": "Súbor nahratý",
"filter": "Filter",
"filter": "Filtrovať",
"friday": "Piatok",
"general": "Všeobecné",
"get": "Získať",
@@ -1472,5 +1473,12 @@
"no-whitespace": "Prázdne znaky nepovolené",
"min-length": "Musí mať aspoň {min} znakov",
"max-length": "Must Be At Most {max} Character|Must Be At Most {max} Characters"
},
"announcements": {
"announcements": "Announcements",
"all-announcements": "All announcements",
"mark-all-as-read": "Mark All as Read",
"show-announcements-from-mealie": "Show announcements from Mealie",
"show-announcements-setting-description": "Whether or not you want to allow users to see announcements from Mealie. When enabled users can still opt-out from seeing them in their user settings"
}
}

View File

@@ -98,6 +98,7 @@
"dashboard": "Nadzorna plošča",
"delete": "Izbriši",
"disabled": "Onemogočeno",
"done": "Končano",
"download": "Prenesi",
"duplicate": "Podvoji",
"edit": "Uredi",
@@ -385,12 +386,12 @@
"chowdown": {
"description": "Migriraj podatke iz Chowdown-a",
"description-long": "Mealie podpira chowdown format shrambe podatkov. Prenesi shrambo podatkov kot .zip datoteko in jo naloži spodaj.",
"title": "Chowdown"
"title": "Prehranjevanje"
},
"nextcloud": {
"description": "Migriraj podatke iz Nextcloud Cookbook",
"description-long": "Nextcloud recepte lahko uvoziš z zip datoteko, ki vsebuje podatke shranjene na Nextcloudu. Poglej primer strukture mape spodaj, da zagotoviš primerno strukturo za uvoz receptov.",
"title": "Nextcloud Cookbook"
"title": "Kuharska knjiga Nextcloud"
},
"copymethat": {
"description-long": "Mealie lahko uvozi recepte iz aplikacije Copy Me That. Izvozi recepte v HTML format in spodaj naloži .zip datoteko.",
@@ -398,11 +399,11 @@
},
"paprika": {
"description-long": "Mealie lahko uvozi recepte iz aplikacije Paprika. Izvozi recepte iz aplikacije Paprika, preimenuj končnico datoteke v .zip in jo naloži spodaj.",
"title": "Paprika Recipe Manager"
"title": "Urejevalnik receptov Paprika"
},
"mealie-pre-v1": {
"description-long": "Mealie lahko uvozi recepte izpred Mealie verzije v1.0. Izvozi recepte iz stare instance in spodaj uvozi zip datoteko. Omogočen je uvoz samo za recepte.",
"title": "Mealie Pre v1.0"
"title": "Mealie pred v1.0"
},
"tandoor": {
"description-long": "Mealie lahko uvozi recepte iz aplikacije Tandoor. Izvozi podatke v \"Default\" formatu, nato spodaj naloži .zip datoteko.",
@@ -424,15 +425,15 @@
"paprika-text": "Mealie lahko uvozi recepte iz aplikacije Paprika. Izvozi recepte iz aplikacije Paprika, preimenuj končnico datoteke v .zip in jo naloži spodaj.",
"mealie-text": "Mealie lahko uvozi recepte izpred Mealie verzije v1.0. Izvozi recepte iz stare instance in spodaj uvozi zip datoteko. Omogočen je uvoz samo za recepte.",
"plantoeat": {
"title": "Plan to Eat",
"title": "Načrt za pojesti",
"description-long": "Mealie lahko uvozi recepte iz aplikacije Plan to Eat."
},
"myrecipebox": {
"title": "My Recipe Box",
"title": "Moj zaboj z recepti",
"description-long": "Mealie lahko uvozi recepte iz aplikacije My Recipe Box. Izvozi recepte v CSV formatu, nato pa .csv datoteko naloži spodaj."
},
"recipekeeper": {
"title": "Recipe Keeper",
"title": "Hranilec receptov",
"description-long": "Mealie lahko uvozi recepte iz Recipe Keeper. Izvozi svoje recepte v .zip formatu, nato spodaj naloži .zip datoteko."
}
},
@@ -556,7 +557,7 @@
"join-the-conversation": "Pridruži se pogovoru",
"add-recipe-to-mealplan": "Dodaj recept v jedilnik",
"entry-type": "Tip vnosa",
"date-format-hint": "MM/DD/YYYY format",
"date-format-hint": "MM/DD/YYYY oblika",
"date-format-hint-yyyy-mm-dd": "YYYY-MM-DD oblika",
"add-to-list": "Dodaj na seznam",
"add-to-plan": "Dodaj v načrt",
@@ -670,7 +671,7 @@
"recipe-debugger-description": "Prilepi povezavo do recepta, ki ga želiš postrgati. Strgalnik receptov bo postrgal spletno stran in prikazal rezultate. Če ne vidiš nobenih podatkov, potem spletna stran, ki jo želiš strgati ni podprta v Mealie oz. v strgalniku, ki ga uporablja.",
"use-openai": "Uporabi OpenAI",
"recipe-debugger-use-openai-description": "Za razčlenitev rezultatov uporabite OpenAI, namesto da se zanašate na knjižnico strgala. Ko ustvarjate recept prek URL-ja, se to izvede samodejno, če knjižnica strgala odpove, vendar ga lahko tukaj preizkusite ročno.",
"debug": "Debug",
"debug": "Razhroščevanje",
"tree-view": "Drevesni prikaz",
"recipe-servings": "Rocept obrokov",
"recipe-yield": "Število porcij",
@@ -857,17 +858,17 @@
"webhooks": {
"test-webhooks": "Test Webhook-ov",
"the-urls-listed-below-will-recieve-webhooks-containing-the-recipe-data-for-the-meal-plan-on-its-scheduled-day-currently-webhooks-will-execute-at": "Spodnji URL naslovi bodo prejeli webhook-e s podatki receptov za načrt obrokov na načrtovani dan. Trenutno se bodo webhooki-i izvedli ob",
"webhook-url": "Webhook URL",
"webhooks-caps": "WEBHOOKS",
"webhook-url": "URL spletnega kavlja",
"webhooks-caps": "SPLETNI KAVLJI",
"webhooks": "Webbhook-i",
"webhook-name": "Ime Webhooka",
"description": "Spodaj definirani webhooki bodo izvedeni na dneve, ki imajo definirane obroke. Ob določenem času bodo na webhook poslani podatki iz recepta, ki je planiran na ta dan. Upoštevaj, da izvedba webhookov ni točna. Webhooki se izvajajo v 5 minutnih intervalih, kar pomeni, da bo webhook izveden v okviru +/- 5 minut od planiranega časa."
},
"bug-report": "Prijava napake",
"bug-report-information": "Uporabi te podatke ob prijavi napake. Sporočanje podrobnosti o tvoji instanci pomaga razvijalcem najhitreje odpraviti tvojo težavo.",
"tracker": "Tracker",
"tracker": "Sledilnik",
"configuration": "Nastavitve",
"docker-volume": "Docker Volume",
"docker-volume": "Docker mapa",
"docker-volume-help": "Mealie zahteva, da vsebnik sprednjega dela in zadnji del delita isto mapo ali shrambo priklopne postaje. To zagotavlja, da lahko sprednji vsebnik pravilno dostopa do slik in sredstev, shranjenih na disku.",
"volumes-are-misconfigured": "Mape so napačno nastavljene.",
"volumes-are-configured-correctly": "Mape so nastavljene pravilno.",
@@ -876,8 +877,8 @@
"email-configuration-status": "Email status",
"email-configured": "Email nastavljen",
"email-test-results": "Email test rezultati",
"ready": "Ready",
"not-ready": "Not Ready - Check Environmental Variables",
"ready": "Pripravljeno",
"not-ready": "Ni pripravljeno - Preverite okoljske spremenljivke",
"succeeded": "Uspelo je",
"failed": "Ni uspelo",
"general-about": "Splošne informacije",
@@ -890,13 +891,13 @@
"server-side-base-url": "Strežniški URL",
"server-side-base-url-error-text": "`BASE_URL` se še vedno ujema s privzeto vrednostjo API strežnika. To bo povzročalo težave s povezavami do obvestil generiranih za emaile ipd.",
"server-side-base-url-success-text": "Strežniški URL se ne ujema s privzeto vrednostjo",
"ldap-ready": "LDAP Ready",
"ldap-ready": "Pripravljeno za LDAP",
"ldap-not-ready": "LDAP ni pripravljen",
"ldap-ready-error-text": "Nekatere LDAP vrednosti niso nastavljene. To lahko ignoriraš, če ne uporabljaš LDAP avtentikacije.",
"ldap-ready-success-text": "Vse potrebne LDAP spremenljivke so nastavljene.",
"build": "Build",
"build": "Gradnja",
"recipe-scraper-version": "Verzija strgalnika receptov",
"oidc-ready": "OIDC Ready",
"oidc-ready": "Pripravljeno za OIDC",
"oidc-not-ready": "OIDC ni pripravljen",
"oidc-ready-error-text": "Nekatere OIDC vrednosti niso nastavljene. To lahko ignoriraš, če ne uporabljaš OIDC avtentikacije.",
"oidc-ready-success-text": "Vse zahtevane OIDC spremenljivke so nastavljene.",
@@ -958,7 +959,7 @@
"language": "Jezik",
"maintenance": "Vzdrževanje",
"background-tasks": "Naloge v ozadju",
"parser": "Parser",
"parser": "Razčlenjevalnik",
"developer": "Razvijalec",
"cookbook": "Kuharska knjiga",
"create-cookbook": "Izdelaj novo kuharsko knjigo"
@@ -1082,7 +1083,7 @@
"authentication-method": "Izberi način avtentikacije",
"authentication-method-hint": "This specifies how a user will authenticate with Mealie. If you're not sure, choose 'Mealie",
"permissions": "Dovoljenja",
"administrator": "Administrator",
"administrator": "Skrbnik",
"user-can-invite-other-to-group": "Uporabnih lahko povabi druge v skupino",
"user-can-manage-group": "Uporabnik lahko upravlja s skupino",
"user-can-manage-household": "Uporabnik lahko upravlja gospodinjstvo",
@@ -1472,5 +1473,12 @@
"no-whitespace": "Presledki niso dovoljeni",
"min-length": "Mora vsebovati vsaj {min} znakov",
"max-length": "Največ {max} znakov|Vsebuje lahko največ {max} znakov"
},
"announcements": {
"announcements": "Obvestila",
"all-announcements": "Vsa obvestila",
"mark-all-as-read": "Označi vse kot prebrano",
"show-announcements-from-mealie": "Prikaži obvestila od Mealie",
"show-announcements-setting-description": "Ali želite uporabnikom dovoliti ogled obvestil Mealie. Ko je to omogočeno, se lahko uporabniki v nastavitvah uporabnika še vedno odjavijo od njihovega prikaza"
}
}

View File

@@ -98,6 +98,7 @@
"dashboard": "Командна табла",
"delete": "Обриши",
"disabled": "Онемогућено",
"done": "Готово",
"download": "Преузми",
"duplicate": "Дуплирај",
"edit": "Измени",
@@ -171,7 +172,7 @@
"update": "Ажурирај",
"updated": "Ажурирано",
"upload": "Отпреми",
"url": "URL",
"url": "Url адреса",
"view": "Преглед",
"wednesday": "среда",
"yes": "Да",
@@ -441,7 +442,7 @@
"error-details": "Само веб-сајтови који садрже ld+json или микроподатке могу бити увезени од стране Mealieја. Већина великих сајтова са рецептима подржава ову структуру података. Ако ваш сајт не може бити увезен, али постоје json подаци у логу, молимо вас пошаљите github issue са URL-ом и подацима.",
"error-title": "Изгледа да нисмо могли ништа да пронађемо",
"from-url": "Увези рецепт",
"github-issues": "GitHub Issues",
"github-issues": "GitHub Problemi",
"google-ld-json-info": "Google ld+json информације",
"must-be-a-valid-url": "Мора бити валидан URL",
"paste-in-your-recipe-data-each-line-will-be-treated-as-an-item-in-a-list": "Налепите ваше податке о рецепту. Свака линија ће бити третирана као ставка на списку",
@@ -857,7 +858,7 @@
"webhooks": {
"test-webhooks": "Тестирај Webhooks",
"the-urls-listed-below-will-recieve-webhooks-containing-the-recipe-data-for-the-meal-plan-on-its-scheduled-day-currently-webhooks-will-execute-at": "URL-ови наведени у наставку ће примити webhook-ове који садрже податке о рецепту за план оброка у заказани дан. Тренутно ће се Webhook-ови извршавати у",
"webhook-url": "Webhook URL",
"webhook-url": "URL Webhook -а",
"webhooks-caps": "WEBHOOK-ОВИ",
"webhooks": "Webhooks",
"webhook-name": "Име Webhook-а",
@@ -1472,5 +1473,12 @@
"no-whitespace": "Размак није дозвољен",
"min-length": "Мора бити најмање {min} карактера",
"max-length": "Мора бити највише {max} карактер|Мора бити највише {max} карактера"
},
"announcements": {
"announcements": "Најава",
"all-announcements": "All announcements",
"mark-all-as-read": "Mark All as Read",
"show-announcements-from-mealie": "Најава",
"show-announcements-setting-description": "Whether or not you want to allow users to see announcements from Mealie. When enabled users can still opt-out from seeing them in their user settings"
}
}

View File

@@ -98,6 +98,7 @@
"dashboard": "Startsida",
"delete": "Ta bort",
"disabled": "Inaktiverad",
"done": "Done",
"download": "Ladda ner",
"duplicate": "Duplicera",
"edit": "Redigera",
@@ -1472,5 +1473,12 @@
"no-whitespace": "Ingen blanksteg tillåten",
"min-length": "Måste vara minst {min} tecken",
"max-length": "Måste Vara Som Mest {max} Tecken|Måste Vara Som Mest {max} Tecken"
},
"announcements": {
"announcements": "Announcements",
"all-announcements": "All announcements",
"mark-all-as-read": "Mark All as Read",
"show-announcements-from-mealie": "Show announcements from Mealie",
"show-announcements-setting-description": "Whether or not you want to allow users to see announcements from Mealie. When enabled users can still opt-out from seeing them in their user settings"
}
}

View File

@@ -98,6 +98,7 @@
"dashboard": "Pano",
"delete": "Sil",
"disabled": "Devre Dışı",
"done": "Done",
"download": "İndir",
"duplicate": "Çiftle",
"edit": "Düzenle",
@@ -773,7 +774,7 @@
"backup-restore": "Yedekleme Geri Yükleme",
"back-restore-description": "Bu yedeği geri yüklemek, veritabanınızdaki ve veri dizinindeki tüm mevcut verilerin üzerine yazacak ve bunları bu yedeğin içeriğiyle değiştirecektir. {cannot-be-undone} Geri yükleme başarılı olursa oturumunuz kapatılacaktır.",
"cannot-be-undone": "Bu işlem geri alınamaz - dikkatli kullanın.",
"postgresql-note": "",
"postgresql-note": "If you are using PostgreSQL, please review the {backup-restore-process} prior to restoring.",
"backup-restore-process-in-the-documentation": "belgelerdeki yedekleme/geri yükleme işlemini",
"irreversible-acknowledgment": "Bu işlemin geri döndürülemez, yıkıcı ve veri kaybına neden olabileceğini anlıyorum",
"restore-backup": "Yedeği Geri Yükle"
@@ -1472,5 +1473,12 @@
"no-whitespace": "No Whitespace Allowed",
"min-length": "En Az {min} Karakter Olmalıdır",
"max-length": "Must Be At Most {max} Character|Must Be At Most {max} Characters"
},
"announcements": {
"announcements": "Announcements",
"all-announcements": "All announcements",
"mark-all-as-read": "Mark All as Read",
"show-announcements-from-mealie": "Show announcements from Mealie",
"show-announcements-setting-description": "Whether or not you want to allow users to see announcements from Mealie. When enabled users can still opt-out from seeing them in their user settings"
}
}

View File

@@ -98,6 +98,7 @@
"dashboard": "Панель керування",
"delete": "Видалити",
"disabled": "Вимкнено",
"done": "Done",
"download": "Завантажити",
"duplicate": "Копіювати",
"edit": "Редагувати",
@@ -1472,5 +1473,12 @@
"no-whitespace": "Пробіли заборонені",
"min-length": "Повинно бути не менше ніж {min} символів ",
"max-length": "Must Be At Most {max} Character|Must Be At Most {max} Characters"
},
"announcements": {
"announcements": "Announcements",
"all-announcements": "All announcements",
"mark-all-as-read": "Mark All as Read",
"show-announcements-from-mealie": "Show announcements from Mealie",
"show-announcements-setting-description": "Whether or not you want to allow users to see announcements from Mealie. When enabled users can still opt-out from seeing them in their user settings"
}
}

View File

@@ -98,6 +98,7 @@
"dashboard": "Bảng điều khiển",
"delete": "Xóa",
"disabled": "Đã vô hiệu",
"done": "Done",
"download": "Tải xuống",
"duplicate": "Tạo bản sao",
"edit": "Chỉnh sửa",
@@ -1472,5 +1473,12 @@
"no-whitespace": "No Whitespace Allowed",
"min-length": "Must Be At Least {min} Characters",
"max-length": "Must Be At Most {max} Character|Must Be At Most {max} Characters"
},
"announcements": {
"announcements": "Announcements",
"all-announcements": "All announcements",
"mark-all-as-read": "Mark All as Read",
"show-announcements-from-mealie": "Show announcements from Mealie",
"show-announcements-setting-description": "Whether or not you want to allow users to see announcements from Mealie. When enabled users can still opt-out from seeing them in their user settings"
}
}

View File

@@ -98,6 +98,7 @@
"dashboard": "仪表盘",
"delete": "删除",
"disabled": "已禁用",
"done": "Done",
"download": "下载",
"duplicate": "创建副本",
"edit": "编辑",
@@ -1472,5 +1473,12 @@
"no-whitespace": "No Whitespace Allowed",
"min-length": "Must Be At Least {min} Characters",
"max-length": "Must Be At Most {max} Character|Must Be At Most {max} Characters"
},
"announcements": {
"announcements": "Announcements",
"all-announcements": "All announcements",
"mark-all-as-read": "Mark All as Read",
"show-announcements-from-mealie": "Show announcements from Mealie",
"show-announcements-setting-description": "Whether or not you want to allow users to see announcements from Mealie. When enabled users can still opt-out from seeing them in their user settings"
}
}

View File

@@ -98,6 +98,7 @@
"dashboard": "控制面板",
"delete": "刪除",
"disabled": "已停用",
"done": "Done",
"download": "下載",
"duplicate": "複製",
"edit": "編輯",
@@ -1472,5 +1473,12 @@
"no-whitespace": "不允許空白字元",
"min-length": "至少需 {min} 個字元",
"max-length": "最多 {max} 個字元|最多 {max} 個字元"
},
"announcements": {
"announcements": "Announcements",
"all-announcements": "All announcements",
"mark-all-as-read": "Mark All as Read",
"show-announcements-from-mealie": "Show announcements from Mealie",
"show-announcements-setting-description": "Whether or not you want to allow users to see announcements from Mealie. When enabled users can still opt-out from seeing them in their user settings"
}
}

View File

@@ -457,13 +457,8 @@ async function seedData() {
return;
}
const tasks = [
seedFoods(),
seedUnits(),
seedLabels(),
];
await Promise.all(tasks);
await seedLabels();
await Promise.all([seedFoods(), seedUnits()]);
}
async function submitCommonSettings() {

View File

@@ -1,8 +1,8 @@
<template>
<div>
<GroupDataPage
:icon="$globals.icons.linkVariantPlus"
:title="$t('data-pages.recipe-actions.new-recipe-action')"
:icon="$globals.icons.link"
:title="$t('data-pages.recipe-actions.recipe-actions-data')"
:create-title="$t('data-pages.recipe-actions.new-recipe-action')"
:edit-title="$t('data-pages.recipe-actions.edit-recipe-action')"
:table-headers="tableHeaders"

View File

@@ -180,12 +180,20 @@
}}
</p>
</v-card-actions>
<div class="mx-2 clip-width">
<v-text-field
v-model="search"
variant="underlined"
:label="$t('search.search')"
/>
</div>
<v-card>
<RecipeDataTable
v-model="selected"
:loading="loading"
:recipes="allRecipes"
:show-headers="headers"
:search="search"
/>
<v-card-actions class="justify-end">
<BaseButton
@@ -263,6 +271,7 @@ useSeoMeta({
const { refreshRecipes } = useRecipes(true, true, false, `householdId=${auth.user.value?.householdId || ""}`);
const selected = ref<Recipe[]>([]);
const search = ref("");
function resetAll() {
selected.value = [];
@@ -513,6 +522,9 @@ const selectedOwnerHousehold = computed(() => {
</script>
<style>
.clip-width {
max-width: 400px;
}
.v-btn--disabled {
opacity: 0.5 !important;
}

View File

@@ -160,8 +160,20 @@
<!-- Viewer -->
<section v-if="!edit" class="py-2 d-flex flex-column ga-4">
<!-- Create Item -->
<div v-if="createEditorOpen">
<ShoppingListAddItemForm
v-if="$vuetify.display.smAndDown"
v-model="createListItemData"
class="my-4"
:labels="allLabels || []"
:units="allUnits || []"
:foods="allFoods || []"
@cancel="createEditorOpen = false"
@save="createListItem"
/>
<div v-else>
<ShoppingListItemEditor
v-if="createEditorOpen"
v-model="createListItemData"
class="my-4"
:labels="allLabels || []"
@@ -172,14 +184,14 @@
@cancel="createEditorOpen = false"
@save="createListItem"
/>
</div>
<div v-else class="d-flex justify-end">
<BaseButton
create
@click="createEditorOpen = true"
>
{{ $t('general.add') }}
</BaseButton>
<InputLabelType
v-else
:items="allFoods"
:label="$t('shopping-list.add-item')"
:icon="$globals.icons.foods"
search
@focus="createEditorOpen = true"
/>
</div>
<TransitionGroup name="scroll-x-transition">
@@ -211,7 +223,10 @@
:units="allUnits || []"
:foods="allFoods || []"
:recipes="recipeMap"
@checked="saveListItem"
@checked="(item) => {
saveListItem(item);
itemCheckedToast(item);
}"
@save="saveListItem"
@delete="deleteListItem(item)"
/>
@@ -338,10 +353,13 @@
import { VueDraggable } from "vue-draggable-plus";
import RecipeList from "~/components/Domain/Recipe/RecipeList.vue";
import MultiPurposeLabelSection from "~/components/Domain/ShoppingList/MultiPurposeLabelSection.vue";
import ShoppingListAddItemForm from "~/components/Domain/ShoppingList/ShoppingListAddItemForm.vue";
import ShoppingListItem from "~/components/Domain/ShoppingList/ShoppingListItem.vue";
import ShoppingListItemEditor from "~/components/Domain/ShoppingList/ShoppingListItemEditor.vue";
import { useShoppingListPage } from "~/composables/shopping-list-page/use-shopping-list-page";
import { useFoodStore, useLabelStore, useUnitStore } from "~/composables/store";
import { useLabelStore, useUnitStore, useFoodStore } from "~/composables/store";
import { alert } from "~/composables/use-toast";
import type { ShoppingListItemOut } from "~/lib/api/types/household";
const { mdAndUp } = useDisplay();
const i18n = useI18n();
@@ -358,6 +376,23 @@ const { store: allLabels } = useLabelStore();
const { store: allUnits } = useUnitStore();
const { store: allFoods } = useFoodStore();
function itemCheckedToast(item: ShoppingListItemOut) {
alert.info(
i18n.t("shopping-list.item-checked-off", { item: item.food?.name || item.note || i18n.t("recipe.ingredient") }),
undefined,
{
timeout: 4000,
action: {
message: i18n.t("general.undo"),
onClick: () => {
item.checked = false;
shoppingListPage.saveListItem(item);
},
},
},
);
}
const {
shoppingList,
state,

View File

@@ -68,6 +68,7 @@ export default defineNuxtPlugin(async (nuxtApp) => {
warning: theme?.darkWarning ?? "#FF6D00",
error: theme?.darkError ?? "#EF5350",
background: "#1E1E1E",
surface: "#1E1E1E",
},
},
},

View File

@@ -50,6 +50,12 @@ export default defineNuxtConfig({
content: "Mealie is a recipe management app for your kitchen.",
},
],
script: [
{
innerHTML: `(function(){try{var d=localStorage.getItem('vueuse-color-scheme');var m=d==='dark'||(d!=='light'&&matchMedia('(prefers-color-scheme:dark)').matches);document.documentElement.style.backgroundColor=m?'#1E1E1E':'#FFFFFF'}catch(e){}})()`,
type: "text/javascript",
},
],
link: [
{ rel: "icon", type: "image/x-icon", href: "/favicon.ico" },
{ rel: "shortcut icon", type: "image/png", href: "/icons/icon-x64.png" },
@@ -228,151 +234,7 @@ export default defineNuxtConfig({
periodicSyncForUpdates: 120,
},
includeAssets: ["favicon.ico", "apple-touch-icon.png", "safari-pinned-tab.svg"],
manifest: {
name: "Mealie",
short_name: "Mealie",
id: "/",
start_url: "/",
scope: "/",
display: "standalone",
background_color: "#FFFFFF",
theme_color: process.env.THEME_LIGHT_PRIMARY || "#E58325",
description: "Mealie is a recipe management and meal planning app",
lang: "en",
display_override: [
"standalone",
"minimal-ui",
"browser",
"window-controls-overlay",
],
categories: ["food", "lifestyle"],
prefer_related_applications: false,
handle_links: "preferred",
launch_handler: {
client_mode: ["focus-existing", "auto"],
},
edge_side_panel: {
preferred_width: 400,
},
share_target: {
action: "/r/create/url",
method: "GET",
enctype: "application/x-www-form-urlencoded",
params: {
text: "recipe_import_url",
},
},
icons: [
{
src: "/icons/android-chrome-192x192.png",
sizes: "192x192",
type: "image/png",
purpose: "any",
},
{
src: "/icons/android-chrome-512x512.png",
sizes: "512x512",
type: "image/png",
purpose: "any",
},
{
src: "/icons/android-chrome-maskable-192x192.png",
sizes: "192x192",
type: "image/png",
purpose: "maskable",
},
{
src: "/icons/android-chrome-maskable-512x512.png",
sizes: "512x512",
type: "image/png",
purpose: "maskable",
},
],
screenshots: [
{
src: "/screenshots/home-narrow.png",
sizes: "1600x2420",
form_factor: "narrow",
label: "Home Page",
},
{
src: "/screenshots/recipe-narrow.png",
sizes: "1600x2420",
form_factor: "narrow",
label: "Recipe Page",
},
{
src: "/screenshots/editor-narrow.png",
sizes: "1600x2420",
form_factor: "narrow",
label: "Editor Page",
},
{
src: "/screenshots/parser-narrow.png",
sizes: "1600x2420",
form_factor: "narrow",
label: "Parser Page",
},
{
src: "/screenshots/home-wide.png",
sizes: "2560x1460",
form_factor: "wide",
label: "Home Page",
},
{
src: "/screenshots/recipe-wide.png",
sizes: "2560x1460",
form_factor: "wide",
label: "Recipe Page",
},
{
src: "/screenshots/editor-wide.png",
sizes: "2560x1460",
form_factor: "wide",
label: "Editor Page",
},
{
src: "/screenshots/parser-wide.png",
sizes: "2560x1460",
form_factor: "wide",
label: "Parser Page",
},
],
shortcuts: [
{
name: "Shopping Lists",
short_name: "Shopping Lists",
description: "Open the shopping lists",
url: "/shopping-lists",
icons: [
{
src: "/icons/mdiFormatListChecks-192x192.png",
sizes: "192x192",
},
{
src: "/icons/mdiFormatListChecks-96x96.png",
sizes: "96x96",
},
],
},
{
name: "Meal Planner",
short_name: "Meal Planner",
description: "Open the meal planner",
url: "/household/mealplan/planner/view",
icons: [
{
src: "/icons/mdiCalendarMultiselect-192x192.png",
sizes: "192x192",
},
{
src: "/icons/mdiCalendarMultiselect-96x96.png",
sizes: "96x96",
},
],
},
],
},
manifest: false, // This is served via the backend, see mealie/routes/spa/manifest.py
},
// Vuetify module configuration: https://go.nuxtjs.dev/config-vuetify

View File

@@ -1,6 +1,6 @@
{
"name": "mealie",
"version": "3.15.0",
"version": "3.17.0",
"private": true,
"scripts": {
"dev": "nuxt dev",
@@ -26,7 +26,7 @@
"axios": "^1.8.1",
"date-fns": "^4.1.0",
"fuse.js": "^7.1.0",
"isomorphic-dompurify": "^2.28.0",
"isomorphic-dompurify": "^3.4.0",
"json-editor-vue": "^0.18.1",
"marked": "^15.0.12",
"nuxt": "^4.4.2",
@@ -55,8 +55,6 @@
},
"packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e",
"resolutions": {
"esbuild": ">=0.25.0",
"glob": ">=10.5.0",
"js-yaml": ">=4.1.1",
"node-forge": ">=1.3.2"
}

File diff suppressed because it is too large Load Diff

View File

@@ -3,7 +3,7 @@ import os
import secrets
from datetime import UTC, datetime
from pathlib import Path
from typing import Annotated, Any, NamedTuple
from typing import Annotated, Any, Literal, NamedTuple
from dateutil.tz import tzlocal
from pydantic import PlainSerializer, field_validator
@@ -349,6 +349,7 @@ class AppSettings(AppLoggingSettings):
OIDC_GROUPS_CLAIM: str | None = "groups"
OIDC_SCOPES_OVERRIDE: str | None = None
OIDC_TLS_CACERTFILE: str | None = None
OIDC_CLIENT_TIMEOUT: float | Literal["None", "default"] = "default"
@property
def OIDC_REQUIRES_GROUP_CLAIM(self) -> bool:

View File

@@ -18,17 +18,17 @@
"yield": "Výnos",
"yields": "Výnosy"
},
"and-amount": "and {amount}",
"or-ingredient": "or {ingredient}",
"and-amount": "a {amount}",
"or-ingredient": "nebo {ingredient}",
"create-progress": {
"creating-recipe-with-ai": "Creating recipe with AI...",
"creating-recipe-from-transcript-with-ai": "Creating recipe from transcript with AI...",
"creating-recipe-from-webpage-data": "Creating recipe from webpage data...",
"downloading-image": "Downloading image...",
"downloading-video": "Downloading video...",
"extracting-recipe-data": "Extracting recipe data...",
"fetching-webpage": "Fetching webpage...",
"transcribing-audio-with-ai": "Transcribing audio with AI..."
"creating-recipe-with-ai": "Vytváření receptu pomocí AI...",
"creating-recipe-from-transcript-with-ai": "Vytváření receptu pomocí AI přepisu...",
"creating-recipe-from-webpage-data": "Vytváření receptu z webových stránek...",
"downloading-image": "Stahování obrázku...",
"downloading-video": "Stahování videa...",
"extracting-recipe-data": "Extrahování dat receptu...",
"fetching-webpage": "Načítání webové stránky...",
"transcribing-audio-with-ai": "Přepisování zvuku pomocí AI..."
}
},
"mealplan": {

View File

@@ -21,14 +21,14 @@
"and-amount": "et {amount}",
"or-ingredient": "ou {ingredient}",
"create-progress": {
"creating-recipe-with-ai": "Creating recipe with AI...",
"creating-recipe-from-transcript-with-ai": "Creating recipe from transcript with AI...",
"creating-recipe-from-webpage-data": "Creating recipe from webpage data...",
"downloading-image": "Downloading image...",
"downloading-video": "Downloading video...",
"extracting-recipe-data": "Extracting recipe data...",
"fetching-webpage": "Fetching webpage...",
"transcribing-audio-with-ai": "Transcribing audio with AI..."
"creating-recipe-with-ai": "Création de la recette avec l'IA...",
"creating-recipe-from-transcript-with-ai": "Création de la recette à partir de la transcription avec l'IA...",
"creating-recipe-from-webpage-data": "Création de la recette à partir des données d'une page web...",
"downloading-image": "Téléchargement de l'image...",
"downloading-video": "Téléchargement de la vidéo...",
"extracting-recipe-data": "Extraction des données de la recette...",
"fetching-webpage": "Récupération de la page web...",
"transcribing-audio-with-ai": "Transcodage audio avec l'AI..."
}
},
"mealplan": {

View File

@@ -21,14 +21,14 @@
"and-amount": "et {amount}",
"or-ingredient": "ou {ingredient}",
"create-progress": {
"creating-recipe-with-ai": "Creating recipe with AI...",
"creating-recipe-from-transcript-with-ai": "Creating recipe from transcript with AI...",
"creating-recipe-from-webpage-data": "Creating recipe from webpage data...",
"downloading-image": "Downloading image...",
"downloading-video": "Downloading video...",
"extracting-recipe-data": "Extracting recipe data...",
"fetching-webpage": "Fetching webpage...",
"transcribing-audio-with-ai": "Transcribing audio with AI..."
"creating-recipe-with-ai": "Création de la recette avec l'IA...",
"creating-recipe-from-transcript-with-ai": "Création de la recette à partir de la transcription avec l'IA...",
"creating-recipe-from-webpage-data": "Création de la recette à partir des données d'une page web...",
"downloading-image": "Téléchargement de l'image...",
"downloading-video": "Téléchargement de la vidéo...",
"extracting-recipe-data": "Extraction des données de la recette...",
"fetching-webpage": "Récupération de la page web...",
"transcribing-audio-with-ai": "Transcodage audio avec l'AI..."
}
},
"mealplan": {

View File

@@ -21,14 +21,14 @@
"and-amount": "et {amount}",
"or-ingredient": "ou {ingredient}",
"create-progress": {
"creating-recipe-with-ai": "Creating recipe with AI...",
"creating-recipe-from-transcript-with-ai": "Creating recipe from transcript with AI...",
"creating-recipe-from-webpage-data": "Creating recipe from webpage data...",
"downloading-image": "Downloading image...",
"downloading-video": "Downloading video...",
"extracting-recipe-data": "Extracting recipe data...",
"fetching-webpage": "Fetching webpage...",
"transcribing-audio-with-ai": "Transcribing audio with AI..."
"creating-recipe-with-ai": "Création de la recette avec l'IA...",
"creating-recipe-from-transcript-with-ai": "Création de la recette à partir de la transcription avec l'IA...",
"creating-recipe-from-webpage-data": "Création de la recette à partir des données d'une page web...",
"downloading-image": "Téléchargement de l'image...",
"downloading-video": "Téléchargement de la vidéo...",
"extracting-recipe-data": "Extraction des données de la recette...",
"fetching-webpage": "Récupération de la page web...",
"transcribing-audio-with-ai": "Transcodage audio avec l'AI..."
}
},
"mealplan": {

View File

@@ -5,7 +5,7 @@
"recipe": {
"unique-name-error": "שמות מתכונים חייבים להיות ייחודיים",
"recipe-created": "מתכון נוצר",
"recipe-image-deleted": "Recipe image deleted",
"recipe-image-deleted": "תמונת מתכון נמחקה",
"recipe-defaults": {
"ingredient-note": "כוס קמח",
"step-text": "שלבי המתכון, כמו גם שדות אחרים בעמוד המתכון, תומכים בתחביר markdown.\n\n**הוספת קישור**\n\n[הקישור שלי](https://demo.mealie.io)\n"
@@ -21,14 +21,14 @@
"and-amount": "and {amount}",
"or-ingredient": "or {ingredient}",
"create-progress": {
"creating-recipe-with-ai": "Creating recipe with AI...",
"creating-recipe-with-ai": "יוצר מתכון עם בינה מלאכותית...",
"creating-recipe-from-transcript-with-ai": "Creating recipe from transcript with AI...",
"creating-recipe-from-webpage-data": "Creating recipe from webpage data...",
"downloading-image": "Downloading image...",
"downloading-video": "Downloading video...",
"extracting-recipe-data": "Extracting recipe data...",
"creating-recipe-from-webpage-data": "יוצר מתכון ממידע מהאתר...",
"downloading-image": "מוריד תמונה...",
"downloading-video": "מוריד וידאו...",
"extracting-recipe-data": "מחלץ פרטי מתכון...",
"fetching-webpage": "Fetching webpage...",
"transcribing-audio-with-ai": "Transcribing audio with AI..."
"transcribing-audio-with-ai": "מתמלל שמע עם בינה מלאכותית..."
}
},
"mealplan": {

View File

@@ -21,14 +21,14 @@
"and-amount": "og {amount}",
"or-ingredient": "eða {ingredient}",
"create-progress": {
"creating-recipe-with-ai": "Creating recipe with AI...",
"creating-recipe-from-transcript-with-ai": "Creating recipe from transcript with AI...",
"creating-recipe-from-webpage-data": "Creating recipe from webpage data...",
"downloading-image": "Downloading image...",
"downloading-video": "Downloading video...",
"extracting-recipe-data": "Extracting recipe data...",
"fetching-webpage": "Fetching webpage...",
"transcribing-audio-with-ai": "Transcribing audio with AI..."
"creating-recipe-with-ai": "Bý til uppskrift með gervigreind...",
"creating-recipe-from-transcript-with-ai": "Bý til uppskrift útfrá umritun með gervigreind...",
"creating-recipe-from-webpage-data": "Bý til uppskrift út frá gögnum á vefsíðu...",
"downloading-image": "Hleð niður mynd...",
"downloading-video": "Hleð niður video...",
"extracting-recipe-data": "Hleð inn uppskriftar gögnum...",
"fetching-webpage": "Sæki vefsíðu...",
"transcribing-audio-with-ai": "Umrita hljóð með gervigreind..."
}
},
"mealplan": {

View File

@@ -4,8 +4,8 @@
},
"recipe": {
"unique-name-error": "Receptes nosaukums nevar atkārtoties",
"recipe-created": "Recipe Created",
"recipe-image-deleted": "Recipe image deleted",
"recipe-created": "Recepte izveidota",
"recipe-image-deleted": "Receptes attēls dzēsts",
"recipe-defaults": {
"ingredient-note": "1 gl. Milti",
"step-text": "Receptes darbības, kā arī citi lauki receptes lapā atbalsta atzīmes sintaksi.\n\n**Pievienot saiti**\n\n[Mana saite](https://demo.mealie.io)\n"
@@ -13,19 +13,19 @@
"servings-text": {
"makes": "Makes",
"serves": "Serves",
"serving": "Serving",
"servings": "Servings",
"yield": "Yield",
"yields": "Yields"
"serving": "Porcija",
"servings": "Porcijas",
"yield": "Rezultāts",
"yields": "Rezultāts"
},
"and-amount": "and {amount}",
"or-ingredient": "or {ingredient}",
"and-amount": "un {amount}",
"or-ingredient": "vai {ingredient}",
"create-progress": {
"creating-recipe-with-ai": "Creating recipe with AI...",
"creating-recipe-from-transcript-with-ai": "Creating recipe from transcript with AI...",
"creating-recipe-from-webpage-data": "Creating recipe from webpage data...",
"downloading-image": "Downloading image...",
"downloading-video": "Downloading video...",
"downloading-image": "Lejupielādē attēlu...",
"downloading-video": "Lejupielādē video...",
"extracting-recipe-data": "Extracting recipe data...",
"fetching-webpage": "Fetching webpage...",
"transcribing-audio-with-ai": "Transcribing audio with AI..."
@@ -45,7 +45,7 @@
},
"exceptions": {
"permission_denied": "Jums nav atļaujas veikt šo darbību",
"recursive-recipe-link": "A recipe cannot reference itself, either directly or indirectly",
"recursive-recipe-link": "Recepte nevar atsaukties uz sevi pašu, ne tieši, ne netieši",
"no-entry-found": "Pieprasītais resurss netika atrasts",
"integrity-error": "Datu bāzes integritātes kļūda",
"username-conflict-error": "Šis lietotājvārds jau ir aizņemts",

View File

@@ -21,14 +21,14 @@
"and-amount": "en {amount}",
"or-ingredient": "of {ingredient}",
"create-progress": {
"creating-recipe-with-ai": "Creating recipe with AI...",
"creating-recipe-from-transcript-with-ai": "Creating recipe from transcript with AI...",
"creating-recipe-from-webpage-data": "Creating recipe from webpage data...",
"downloading-image": "Downloading image...",
"downloading-video": "Downloading video...",
"extracting-recipe-data": "Extracting recipe data...",
"fetching-webpage": "Fetching webpage...",
"transcribing-audio-with-ai": "Transcribing audio with AI..."
"creating-recipe-with-ai": "Recept maken met AI...",
"creating-recipe-from-transcript-with-ai": "Maak recept van een transcript met AI...",
"creating-recipe-from-webpage-data": "Creëren recept van webpagina-gegevens...",
"downloading-image": "Afbeeldingen downloaden...",
"downloading-video": "Video downloaden...",
"extracting-recipe-data": "Receptgegevens ophalen...",
"fetching-webpage": "Webpagina ophalen...",
"transcribing-audio-with-ai": "Audio met AI transcriberen..."
}
},
"mealplan": {

View File

@@ -18,17 +18,17 @@
"yield": "Количество порций",
"yields": "Можно получить порций"
},
"and-amount": "and {amount}",
"or-ingredient": "or {ingredient}",
"and-amount": "И {amount}",
"or-ingredient": "Или {ingredient}",
"create-progress": {
"creating-recipe-with-ai": "Creating recipe with AI...",
"creating-recipe-from-transcript-with-ai": "Creating recipe from transcript with AI...",
"creating-recipe-from-webpage-data": "Creating recipe from webpage data...",
"downloading-image": "Downloading image...",
"downloading-video": "Downloading video...",
"extracting-recipe-data": "Extracting recipe data...",
"fetching-webpage": "Fetching webpage...",
"transcribing-audio-with-ai": "Transcribing audio with AI..."
"creating-recipe-with-ai": "Создание рецепта с ИИ...",
"creating-recipe-from-transcript-with-ai": "Создание рецепта из транскрипции с ИИ...",
"creating-recipe-from-webpage-data": "Создание рецепта из данных веб-страницы...",
"downloading-image": "Загрузка изображения...",
"downloading-video": "Загрузка видео...",
"extracting-recipe-data": "Извлечение данных рецепта...",
"fetching-webpage": "Загрузка веб-страницы...",
"transcribing-audio-with-ai": "Преобразование звука с AI..."
}
},
"mealplan": {

View File

@@ -18,17 +18,17 @@
"yield": "Množstvo",
"yields": "Počet porcií"
},
"and-amount": "and {amount}",
"or-ingredient": "or {ingredient}",
"and-amount": "a {amount}",
"or-ingredient": "alebo {ingredient}",
"create-progress": {
"creating-recipe-with-ai": "Creating recipe with AI...",
"creating-recipe-from-transcript-with-ai": "Creating recipe from transcript with AI...",
"creating-recipe-from-webpage-data": "Creating recipe from webpage data...",
"downloading-image": "Downloading image...",
"downloading-video": "Downloading video...",
"extracting-recipe-data": "Extracting recipe data...",
"fetching-webpage": "Fetching webpage...",
"transcribing-audio-with-ai": "Transcribing audio with AI..."
"creating-recipe-with-ai": "Vytváranie receptu pomocou umelej inteligencie...",
"creating-recipe-from-transcript-with-ai": "Vytvorenie receptu na základe prepisu pomocou umelej inteligencie...",
"creating-recipe-from-webpage-data": "Vytváranie receptu na základe údajov z webovej stránky...",
"downloading-image": "Sťahovanie obrázka...",
"downloading-video": "Sťahovanie videa...",
"extracting-recipe-data": "Získavam údaje z receptu...",
"fetching-webpage": "Načítavam webovú stránku...",
"transcribing-audio-with-ai": "Prepisujem audio pomocou umelej inteligencie..."
}
},
"mealplan": {

View File

@@ -18,16 +18,16 @@
"yield": "菜量(可做数量)",
"yields": "份量"
},
"and-amount": "and {amount}",
"or-ingredient": "or {ingredient}",
"and-amount": " {amount}",
"or-ingredient": " {ingredient}",
"create-progress": {
"creating-recipe-with-ai": "Creating recipe with AI...",
"creating-recipe-from-transcript-with-ai": "Creating recipe from transcript with AI...",
"creating-recipe-from-webpage-data": "Creating recipe from webpage data...",
"downloading-image": "Downloading image...",
"downloading-video": "Downloading video...",
"extracting-recipe-data": "Extracting recipe data...",
"fetching-webpage": "Fetching webpage...",
"creating-recipe-with-ai": "使用 AI 创建食谱……",
"creating-recipe-from-transcript-with-ai": "使用 AI 从转录结果创建食谱……",
"creating-recipe-from-webpage-data": "从网页数据创建食谱……",
"downloading-image": "正在下载图片……",
"downloading-video": "正在下载视频……",
"extracting-recipe-data": "正在提取食谱数据……",
"fetching-webpage": "正在获取网页……",
"transcribing-audio-with-ai": "Transcribing audio with AI..."
}
},

View File

@@ -1051,8 +1051,8 @@
"custard-apple": {
"aliases": [],
"description": "",
"name": "custard-apple",
"plural_name": "custard-apples"
"name": "черимоя",
"plural_name": "черимои"
},
"dried lemon": {
"aliases": [],
@@ -1063,8 +1063,8 @@
"young jackfruit": {
"aliases": [],
"description": "",
"name": "young jackfruit",
"plural_name": "young jackfruits"
"name": "млад жакфрут",
"plural_name": "млади жакфрути"
},
"durian": {
"aliases": [],
@@ -1093,8 +1093,8 @@
"physali": {
"aliases": [],
"description": "",
"name": "physali",
"plural_name": "physalis"
"name": "физалис",
"plural_name": "физалис"
},
"tamarillo": {
"aliases": [],
@@ -1105,32 +1105,32 @@
"ice-apple": {
"aliases": [],
"description": "",
"name": "ice-apple",
"plural_name": "ice-apples"
"name": "ледена ябълка",
"plural_name": "ледени ябълки"
},
"longan": {
"aliases": [],
"description": "",
"name": "longan",
"plural_name": "longans"
"name": "лонган",
"plural_name": "лонгани"
},
"finger lime": {
"aliases": [],
"description": "",
"name": "finger lime",
"plural_name": "finger limes"
"name": "фингер лайм",
"plural_name": "фингер лаймове"
},
"bitter orange": {
"aliases": [],
"description": "",
"name": "bitter orange",
"plural_name": "bitter oranges"
"name": "горчив портокал",
"plural_name": "горчиви портокали"
},
"feijoa": {
"aliases": [],
"description": "",
"name": "feijoa",
"plural_name": "feijoas"
"name": "фейхоа",
"plural_name": "фейхоа"
},
"dried persimmon": {
"aliases": [],
@@ -1307,8 +1307,8 @@
"morel mushroom": {
"aliases": [],
"description": "",
"name": "morel mushroom",
"plural_name": "morel mushrooms"
"name": "смръчкула",
"plural_name": "смръчкули"
},
"field mushroom": {
"aliases": [],
@@ -1325,14 +1325,14 @@
"shimeji mushroom": {
"aliases": [],
"description": "",
"name": "shimeji mushroom",
"plural_name": "shimeji mushrooms"
"name": "шимеджи гъба",
"plural_name": "шимеджи гъби"
},
"straw mushroom": {
"aliases": [],
"description": "",
"name": "straw mushroom",
"plural_name": "straw mushrooms"
"name": "сламена гъба",
"plural_name": "сламени гъби"
},
"dried chinese mushroom": {
"aliases": [],
@@ -1349,8 +1349,8 @@
"trumpet mushroom": {
"aliases": [],
"description": "",
"name": "trumpet mushroom",
"plural_name": "trumpet mushrooms"
"name": "тромпетна гъба",
"plural_name": "тромпетни гъби"
},
"white truffle": {
"aliases": [],
@@ -1361,8 +1361,8 @@
"white fungu": {
"aliases": [],
"description": "",
"name": "white fungus",
"plural_name": "white fungus"
"name": "бяла гъба",
"plural_name": "бели гъби"
},
"pioppini": {
"aliases": [],
@@ -1373,26 +1373,26 @@
"snow fungu": {
"aliases": [],
"description": "",
"name": "snow fungus",
"plural_name": "snow fungus"
"name": "снежна гъба",
"plural_name": "снежни гъби"
},
"white beech mushroom": {
"aliases": [],
"description": "",
"name": "white beech mushroom",
"plural_name": "white beech mushrooms"
"name": "бяла букова гъба",
"plural_name": "бели букови гъби"
},
"boletu": {
"aliases": [],
"description": "",
"name": "boletus",
"plural_name": "boletus"
"name": "манатарка",
"plural_name": "манатарки"
},
"huitlacoche": {
"aliases": [],
"description": "",
"name": "huitlacoche",
"plural_name": "huitlacoches"
"name": "хуитлакоче",
"plural_name": "хуитлакоче"
},
"matsutake": {
"aliases": [],
@@ -1403,14 +1403,14 @@
"nameko": {
"aliases": [],
"description": "",
"name": "nameko",
"plural_name": "namekos"
"name": "намеко",
"plural_name": "намеко"
},
"djon djon mushroom": {
"aliases": [],
"description": "",
"name": "djon djon mushroom",
"plural_name": "djon djon mushrooms"
"name": "джон-джон гъба",
"plural_name": "джон-джон гъби"
},
"mixed asian mushroom": {
"aliases": [],
@@ -1421,26 +1421,26 @@
"puffball": {
"aliases": [],
"description": "",
"name": "puffball",
"plural_name": "puffballs"
"name": "пърхутка",
"plural_name": "пърхутки"
},
"honey fungu": {
"aliases": [],
"description": "",
"name": "honey fungus",
"plural_name": "honey fungus"
"name": "медена гъба",
"plural_name": "медени гъби"
},
"caesar's mushroom": {
"aliases": [],
"description": "",
"name": "caesar's mushroom",
"plural_name": "caesar's mushrooms"
"name": "царска гъба",
"plural_name": "царски гъби"
},
"candy cap mushroom": {
"aliases": [],
"description": "",
"name": "candy cap mushroom",
"plural_name": "candy cap mushrooms"
"name": "кандy кеп гъба",
"plural_name": "кандy кеп гъби"
},
"lions mane mushroom": {
"aliases": [],
@@ -1611,8 +1611,8 @@
"barberry": {
"aliases": [],
"description": "",
"name": "barberry",
"plural_name": "barberries"
"name": "берберис",
"plural_name": "бербериси"
},
"dried berry": {
"aliases": [],
@@ -1623,14 +1623,14 @@
"sea buckthorn": {
"aliases": [],
"description": "",
"name": "sea buckthorn",
"plural_name": "sea buckthorns"
"name": "морски зърнастец",
"plural_name": "морски зърнастци"
},
"saskatoon berry": {
"aliases": [],
"description": "",
"name": "saskatoon berry",
"plural_name": "saskatoon berries"
"name": "саскатунско зрънце",
"plural_name": "саскатунски зрънца"
},
"rosehip": {
"aliases": [],
@@ -1647,14 +1647,14 @@
"boysenberry": {
"aliases": [],
"description": "",
"name": "boysenberry",
"plural_name": "boysenberries"
"name": "бойзенова къпина",
"plural_name": "бойзенови къпини"
},
"cloudberry": {
"aliases": [],
"description": "",
"name": "cloudberry",
"plural_name": "cloudberries"
"name": "къпина морска",
"plural_name": "къпини морски"
},
"freeze-dried berry": {
"aliases": [],
@@ -1677,38 +1677,38 @@
"loganberry": {
"aliases": [],
"description": "",
"name": "loganberry",
"plural_name": "loganberries"
"name": "логанова къпина",
"plural_name": "логанови къпини"
},
"blackcurrant leaf": {
"aliases": [],
"description": "",
"name": "blackcurrant leaf",
"plural_name": "blackcurrant leaves"
"name": "лист от касис",
"plural_name": "листа от касис"
},
"haskap berry": {
"aliases": [],
"description": "",
"name": "haskap berry",
"plural_name": "haskap berries"
"name": "хаскап",
"plural_name": "хаскап"
},
"dewberry": {
"aliases": [],
"description": "",
"name": "dewberry",
"plural_name": "dewberries"
"name": "дивa къпина",
"plural_name": "диви къпини"
},
"sloe berry": {
"aliases": [],
"description": "",
"name": "sloe berry",
"plural_name": "sloe berries"
"name": "трънка",
"plural_name": "трънки"
},
"oregon grape": {
"aliases": [],
"description": "",
"name": "oregon grape",
"plural_name": "oregon grapes"
"name": "орегонско грозде",
"plural_name": "орегонски грозда"
}
}
},
@@ -1909,8 +1909,8 @@
"peanut brittle": {
"aliases": [],
"description": "",
"name": "peanut brittle",
"plural_name": "peanut brittles"
"name": "фъстъчен карамел",
"plural_name": "фъстъчни карамели"
},
"jackfruit seed": {
"aliases": [],
@@ -1934,25 +1934,25 @@
"aliases": [],
"description": "",
"name": "чиронджи",
"plural_name": "chironjis"
"plural_name": "чиронджи"
},
"honey-roasted pecan": {
"aliases": [],
"description": "",
"name": "honey-roasted pecan",
"plural_name": "honey-roasted pecans"
"name": "пекан с мед",
"plural_name": "пекани с мед"
},
"tigernut": {
"aliases": [],
"description": "",
"name": "tigernut",
"plural_name": "tigernuts"
"name": "чуфа",
"plural_name": "чуфи"
},
"sunflower sprout": {
"aliases": [],
"description": "",
"name": "sunflower sprout",
"plural_name": "sunflower sprouts"
"name": "кълн от слънчоглед",
"plural_name": "кълнове от слънчоглед"
},
"apricot kernel": {
"aliases": [],
@@ -1963,26 +1963,26 @@
"palm seed": {
"aliases": [],
"description": "",
"name": "palm seed",
"plural_name": "palm seeds"
"name": "палмово семе",
"plural_name": "палмови семена"
},
"ginkgo nut": {
"aliases": [],
"description": "",
"name": "ginkgo nut",
"plural_name": "ginkgo nuts"
"name": "ядка гинко",
"plural_name": "ядки гинко"
},
"keto trail mix": {
"aliases": [],
"description": "",
"name": "keto trail mix",
"plural_name": "keto trail mixes"
"name": "кето микс",
"plural_name": "кето миксове"
},
"wattleseed": {
"aliases": [],
"description": "",
"name": "wattleseed",
"plural_name": "wattleseeds"
"name": "ватълсийд",
"plural_name": "ватълсийд"
},
"barùka": {
"aliases": [],
@@ -2308,7 +2308,7 @@
"aliases": [],
"description": "",
"name": "oaxaca cheese",
"plural_name": "oaxaca cheese"
"plural_name": "сирена Оахака"
},
"labneh cheese": {
"aliases": [],
@@ -2319,14 +2319,14 @@
"edam cheese": {
"aliases": [],
"description": "",
"name": "edam cheese",
"plural_name": "edam cheese"
"name": "сирене Едам",
"plural_name": "сирена Едам"
},
"creamy cheese wedge": {
"aliases": [],
"description": "",
"name": "creamy cheese wedge",
"plural_name": "creamy cheese wedges"
"name": "кремообразно сирене на клин",
"plural_name": "кремообразни сирена на клин"
},
"cheese powder cheese": {
"aliases": [],

View File

@@ -823,7 +823,7 @@
"nectarine": {
"aliases": [],
"description": "",
"name": "nectarine",
"name": "nectarina",
"plural_name": "nectarines"
},
"dried fig": {
@@ -1009,8 +1009,8 @@
"apple chip": {
"aliases": [],
"description": "",
"name": "apple chip",
"plural_name": "apple chips"
"name": "xip de poma",
"plural_name": "xips de poma"
},
"mixed peel": {
"aliases": [],
@@ -2319,8 +2319,8 @@
"edam cheese": {
"aliases": [],
"description": "",
"name": "edam cheese",
"plural_name": "edam cheese"
"name": "formtage edam",
"plural_name": "formatge edam"
},
"creamy cheese wedge": {
"aliases": [],
@@ -2457,8 +2457,8 @@
"hard goat cheese": {
"aliases": [],
"description": "",
"name": "hard goat cheese",
"plural_name": "hard goat cheese"
"name": "formatge dur de cabra",
"plural_name": "formatges dur de cabra"
},
"kashkaval cheese": {
"aliases": [],
@@ -2469,8 +2469,8 @@
"sheep cheese": {
"aliases": [],
"description": "",
"name": "sheep cheese",
"plural_name": "sheep cheese"
"name": "formatge d'ovella",
"plural_name": "formatges d'ovella"
},
"amul cheese": {
"aliases": [],
@@ -2481,8 +2481,8 @@
"reblochon cheese": {
"aliases": [],
"description": "",
"name": "reblochon cheese",
"plural_name": "reblochon cheese"
"name": "formatge reblochon",
"plural_name": "formatges reblochon"
},
"robiola cheese": {
"aliases": [],
@@ -2517,8 +2517,8 @@
"mimolette cheese": {
"aliases": [],
"description": "",
"name": "mimolette cheese",
"plural_name": "mimolette cheese"
"name": "formatge mimolette",
"plural_name": "formatges mimolette"
},
"queso quesadilla cheese": {
"aliases": [],
@@ -2757,7 +2757,7 @@
"dulce de leche": {
"aliases": [],
"description": "",
"name": "dulce de leche",
"name": "dolç de llet",
"plural_name": "dulce de leche"
},
"custard": {
@@ -3205,8 +3205,8 @@
"coconut butter": {
"aliases": [],
"description": "",
"name": "coconut butter",
"plural_name": "coconut butter"
"name": "mantega de coco",
"plural_name": "mantega de coco"
},
"egg replacer": {
"aliases": [],
@@ -3307,8 +3307,8 @@
"soy yogurt": {
"aliases": [],
"description": "",
"name": "soy yogurt",
"plural_name": "soy yogurts"
"name": "iogurt de soja",
"plural_name": "iogurts de soja"
},
"vegan mozzarella": {
"aliases": [],
@@ -3337,8 +3337,8 @@
"smoked tofu": {
"aliases": [],
"description": "",
"name": "smoked tofu",
"plural_name": "smoked tofus"
"name": "tofu fumat",
"plural_name": "tofus fumat"
},
"coconut powder": {
"aliases": [],
@@ -3797,8 +3797,8 @@
"sausage": {
"aliases": [],
"description": "",
"name": "sausage",
"plural_name": "sausages"
"name": "salsitxa",
"plural_name": "salsitxes"
},
"beef roast": {
"aliases": [],
@@ -3863,8 +3863,8 @@
"smoked sausage": {
"aliases": [],
"description": "",
"name": "smoked sausage",
"plural_name": "smoked sausages"
"name": "salsitxa fumada",
"plural_name": "salsitxes fumades"
},
"breakfast sausage": {
"aliases": [],
@@ -4085,8 +4085,8 @@
"rabbit": {
"aliases": [],
"description": "",
"name": "rabbit",
"plural_name": "rabbits"
"name": "conill",
"plural_name": "conills"
},
"pork cutlet": {
"aliases": [],
@@ -4689,8 +4689,8 @@
"pigeon": {
"aliases": [],
"description": "",
"name": "pigeon",
"plural_name": "pigeons"
"name": "colom",
"plural_name": "coloms"
},
"wild game bird": {
"aliases": [],
@@ -4827,8 +4827,8 @@
"chicken ham": {
"aliases": [],
"description": "",
"name": "chicken ham",
"plural_name": "chicken hams"
"name": "cuixa de pollastre",
"plural_name": "cuixes de pollastre"
},
"duck neck": {
"aliases": [],
@@ -4981,7 +4981,7 @@
"sardine": {
"aliases": [],
"description": "",
"name": "sardine",
"name": "sardina",
"plural_name": "sardines"
},
"sole": {
@@ -5012,7 +5012,7 @@
"aliases": [],
"description": "",
"name": "caviar",
"plural_name": "caviars"
"plural_name": "cabiars"
},
"haddock": {
"aliases": [],
@@ -5179,8 +5179,8 @@
"eel": {
"aliases": [],
"description": "",
"name": "eel",
"plural_name": "eels"
"name": "anguila",
"plural_name": "anguiles"
},
"dried anchovy": {
"aliases": [],
@@ -15997,14 +15997,14 @@
"pineapple extract": {
"aliases": [],
"description": "",
"name": "pineapple extract",
"plural_name": "pineapple extract"
"name": "extracte de pinya",
"plural_name": "extracte de pinyes"
},
"lemon juice concentrate": {
"aliases": [],
"description": "",
"name": "lemon juice concentrate",
"plural_name": "lemon juice concentrate"
"name": "concentrat de suc de llimona",
"plural_name": "concentrat de suc de llimones"
},
"chocolate collagen": {
"aliases": [],
@@ -16027,8 +16027,8 @@
"malt extract": {
"aliases": [],
"description": "",
"name": "malt extract",
"plural_name": "malt extract"
"name": "extracte de malta",
"plural_name": "extracte de maltes"
},
"kombucha starter": {
"aliases": [],
@@ -16123,7 +16123,7 @@
"vitamin e": {
"aliases": [],
"description": "",
"name": "vitamin e",
"name": "vitamina e",
"plural_name": "vitamin es"
},
"wine yeast": {
@@ -16159,7 +16159,7 @@
"vitamin d": {
"aliases": [],
"description": "",
"name": "vitamin d",
"name": "vitamina d",
"plural_name": "vitamin ds"
},
"calcium lactate": {
@@ -16171,8 +16171,8 @@
"mango extract": {
"aliases": [],
"description": "",
"name": "mango extract",
"plural_name": "mango extract"
"name": "extracte de mango",
"plural_name": "extractes de mango"
},
"raspberry powder": {
"aliases": [],
@@ -16201,7 +16201,7 @@
"creatine": {
"aliases": [],
"description": "",
"name": "creatine",
"name": "creatina",
"plural_name": "creatines"
},
"daily vitamin": {

View File

@@ -127,13 +127,13 @@
"aliases": [],
"description": "",
"name": "palmetto",
"plural_name": "heart of palm"
"plural_name": "palmové srdce"
},
"baby greens": {
"aliases": [],
"description": "",
"name": "baby greens",
"plural_name": "baby greens"
"name": "zelené listy",
"plural_name": "zelené listy"
},
"pumpkin": {
"aliases": [],
@@ -169,7 +169,7 @@
"aliases": [],
"description": "",
"name": "rukola",
"plural_name": "arugula"
"plural_name": "rukola"
},
"leek": {
"aliases": [],
@@ -261,7 +261,7 @@
"mixed greens": {
"aliases": [],
"description": "",
"name": "mixed greens",
"name": "míchaná zelenina",
"plural_name": "míchaná zelenina"
},
"parsnip": {
@@ -321,7 +321,7 @@
"iceberg lettuce": {
"aliases": [],
"description": "",
"name": "iceberg lettuce",
"name": "salát ledový",
"plural_name": "saláty ledové"
},
"mashed potato": {
@@ -340,13 +340,13 @@
"aliases": [],
"description": "",
"name": "mangold",
"plural_name": "chard"
"plural_name": "mangold"
},
"pimiento": {
"aliases": [],
"description": "",
"name": "třešňová paprika",
"plural_name": "pimientos"
"plural_name": "třešňové papriky"
},
"spaghetti squash": {
"aliases": [],
@@ -358,7 +358,7 @@
"aliases": [],
"description": "",
"name": "dubáček",
"plural_name": "butter lettuce"
"plural_name": "dubáček"
},
"hash brown": {
"aliases": [],
@@ -438,7 +438,7 @@
"aliases": [],
"description": "",
"name": "stonková brokolice",
"plural_name": "tenderstem broccoli"
"plural_name": "stonková brokolice"
},
"plantain": {
"aliases": [],
@@ -450,7 +450,7 @@
"aliases": [],
"description": "",
"name": "listový salát",
"plural_name": "leaf lettuce"
"plural_name": "listový salát"
},
"pepperoncini": {
"aliases": [],
@@ -462,7 +462,7 @@
"aliases": [],
"description": "",
"name": "čínské baby zelí",
"plural_name": "baby bok choy"
"plural_name": "čínské baby zelí"
},
"jicama": {
"aliases": [],
@@ -974,7 +974,7 @@
"aliases": [],
"description": "",
"name": "pomelo",
"plural_name": "pomelos"
"plural_name": "pomela"
},
"chestnut purée": {
"aliases": [],
@@ -1247,13 +1247,13 @@
"shiitake mushroom": {
"aliases": [],
"description": "",
"name": "shiitake mushroom",
"plural_name": "shiitake mushrooms"
"name": "bílý žampion",
"plural_name": "bílé žampiony"
},
"portobello mushroom": {
"aliases": [],
"description": "",
"name": "portobello mushroom",
"name": "žampiony portobello",
"plural_name": "žampiony portobello"
},
"wild mushroom": {
@@ -15878,19 +15878,19 @@
"aliases": [],
"description": "",
"name": "cannabi",
"plural_name": "cannabis"
"plural_name": "konopí"
},
"banana extract": {
"aliases": [],
"description": "",
"name": "banana extract",
"plural_name": "banana extract"
"name": "banánový extrakt",
"plural_name": "banánový extrakt"
},
"lavender oil": {
"aliases": [],
"description": "",
"name": "lavender oil",
"plural_name": "lavender oil"
"name": "levandulový olej",
"plural_name": "levandulový olej"
},
"essential oil": {
"aliases": [],

Some files were not shown because too many files have changed in this diff Show More