mirror of
https://github.com/mealie-recipes/mealie.git
synced 2026-06-19 07:20:15 -04:00
Compare commits
54 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
418a8ec72b | ||
|
|
770630bf73 | ||
|
|
89ee7475a6 | ||
|
|
bca5dd8282 | ||
|
|
dabd93c919 | ||
|
|
6991dff3e6 | ||
|
|
b0eece789d | ||
|
|
9fad4a9dce | ||
|
|
22d8c4d5dc | ||
|
|
7be24d3479 | ||
|
|
fbceb61b9a | ||
|
|
1be5bfaef1 | ||
|
|
fac1df31d3 | ||
|
|
6957e2fa74 | ||
|
|
4f02fae284 | ||
|
|
f2615c97e9 | ||
|
|
6b4c9a400d | ||
|
|
cca11b5a12 | ||
|
|
f697a7ee34 | ||
|
|
0d73338e12 | ||
|
|
2f4c6bd500 | ||
|
|
3807778e2f | ||
|
|
ee87a14401 | ||
|
|
ec458a0a08 | ||
|
|
2ff37c86d6 | ||
|
|
b7da3c0f73 | ||
|
|
d799136f0d | ||
|
|
d1d5754c6d | ||
|
|
52662fdce2 | ||
|
|
8df6033c19 | ||
|
|
c23660007e | ||
|
|
786aa2279c | ||
|
|
ab8c3be367 | ||
|
|
8bf8dfd3ed | ||
|
|
b3aa7aeb1a | ||
|
|
0f2b1d8d3a | ||
|
|
4de6391684 | ||
|
|
c3e68b7d8a | ||
|
|
7557d2e818 | ||
|
|
c22a2fc4a8 | ||
|
|
ad94a4f42f | ||
|
|
e6bf3b3acd | ||
|
|
711dd93851 | ||
|
|
2b6d7811ca | ||
|
|
3373abf787 | ||
|
|
741d37f59e | ||
|
|
b38c19ce71 | ||
|
|
1a385e941c | ||
|
|
c6f5b62ad0 | ||
|
|
84dad84326 | ||
|
|
f369c8fd6e | ||
|
|
467cf46c6d | ||
|
|
360b8e21d9 | ||
|
|
0b851e79ec |
@@ -12,6 +12,6 @@ repos:
|
|||||||
exclude: ^tests/data/
|
exclude: ^tests/data/
|
||||||
- repo: https://github.com/astral-sh/ruff-pre-commit
|
- repo: https://github.com/astral-sh/ruff-pre-commit
|
||||||
# Ruff version.
|
# Ruff version.
|
||||||
rev: v0.3.5
|
rev: v0.4.3
|
||||||
hooks:
|
hooks:
|
||||||
- id: ruff-format
|
- id: ruff-format
|
||||||
|
|||||||
@@ -0,0 +1,52 @@
|
|||||||
|
"""add group recipe actions
|
||||||
|
|
||||||
|
Revision ID: 7788478a0338
|
||||||
|
Revises: d7c6efd2de42
|
||||||
|
Create Date: 2024-04-07 01:05:20.816270
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
import sqlalchemy as sa
|
||||||
|
|
||||||
|
import mealie.db.migration_types
|
||||||
|
from alembic import op
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision = "7788478a0338"
|
||||||
|
down_revision = "d7c6efd2de42"
|
||||||
|
branch_labels = None
|
||||||
|
depends_on = None
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade():
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
op.create_table(
|
||||||
|
"recipe_actions",
|
||||||
|
sa.Column("id", mealie.db.migration_types.GUID(), nullable=False),
|
||||||
|
sa.Column("group_id", mealie.db.migration_types.GUID(), nullable=False),
|
||||||
|
sa.Column("action_type", sa.String(), nullable=False),
|
||||||
|
sa.Column("title", sa.String(), nullable=False),
|
||||||
|
sa.Column("url", sa.String(), nullable=False),
|
||||||
|
sa.Column("created_at", sa.DateTime(), nullable=True),
|
||||||
|
sa.Column("update_at", sa.DateTime(), nullable=True),
|
||||||
|
sa.ForeignKeyConstraint(
|
||||||
|
["group_id"],
|
||||||
|
["groups.id"],
|
||||||
|
),
|
||||||
|
sa.PrimaryKeyConstraint("id"),
|
||||||
|
)
|
||||||
|
op.create_index(op.f("ix_recipe_actions_action_type"), "recipe_actions", ["action_type"], unique=False)
|
||||||
|
op.create_index(op.f("ix_recipe_actions_created_at"), "recipe_actions", ["created_at"], unique=False)
|
||||||
|
op.create_index(op.f("ix_recipe_actions_group_id"), "recipe_actions", ["group_id"], unique=False)
|
||||||
|
op.create_index(op.f("ix_recipe_actions_title"), "recipe_actions", ["title"], unique=False)
|
||||||
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade():
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
op.drop_index(op.f("ix_recipe_actions_title"), table_name="recipe_actions")
|
||||||
|
op.drop_index(op.f("ix_recipe_actions_group_id"), table_name="recipe_actions")
|
||||||
|
op.drop_index(op.f("ix_recipe_actions_created_at"), table_name="recipe_actions")
|
||||||
|
op.drop_index(op.f("ix_recipe_actions_action_type"), table_name="recipe_actions")
|
||||||
|
op.drop_table("recipe_actions")
|
||||||
|
# ### end Alembic commands ###
|
||||||
@@ -35,18 +35,24 @@ LOCALE_DATA: dict[str, LocaleData] = {
|
|||||||
"es-ES": LocaleData(name="Español (Spanish)"),
|
"es-ES": LocaleData(name="Español (Spanish)"),
|
||||||
"fi-FI": LocaleData(name="Suomi (Finnish)"),
|
"fi-FI": LocaleData(name="Suomi (Finnish)"),
|
||||||
"fr-FR": LocaleData(name="Français (French)"),
|
"fr-FR": LocaleData(name="Français (French)"),
|
||||||
|
"gl-ES": LocaleData(name="Galego (Galician)"),
|
||||||
"he-IL": LocaleData(name="עברית (Hebrew)", dir="rtl"),
|
"he-IL": LocaleData(name="עברית (Hebrew)", dir="rtl"),
|
||||||
|
"hr-HR": LocaleData(name="Hrvatski (Croatian)"),
|
||||||
"hu-HU": LocaleData(name="Magyar (Hungarian)"),
|
"hu-HU": LocaleData(name="Magyar (Hungarian)"),
|
||||||
|
"is-IS": LocaleData(name="Íslenska (Icelandic)"),
|
||||||
"it-IT": LocaleData(name="Italiano (Italian)"),
|
"it-IT": LocaleData(name="Italiano (Italian)"),
|
||||||
"ja-JP": LocaleData(name="日本語 (Japanese)"),
|
"ja-JP": LocaleData(name="日本語 (Japanese)"),
|
||||||
"ko-KR": LocaleData(name="한국어 (Korean)"),
|
"ko-KR": LocaleData(name="한국어 (Korean)"),
|
||||||
"no-NO": LocaleData(name="Norsk (Norwegian)"),
|
"lt-LT": LocaleData(name="Lietuvių (Lithuanian)"),
|
||||||
|
"lv-LV": LocaleData(name="Latviešu (Latvian)"),
|
||||||
"nl-NL": LocaleData(name="Nederlands (Dutch)"),
|
"nl-NL": LocaleData(name="Nederlands (Dutch)"),
|
||||||
|
"no-NO": LocaleData(name="Norsk (Norwegian)"),
|
||||||
"pl-PL": LocaleData(name="Polski (Polish)"),
|
"pl-PL": LocaleData(name="Polski (Polish)"),
|
||||||
"pt-BR": LocaleData(name="Português do Brasil (Brazilian Portuguese)"),
|
"pt-BR": LocaleData(name="Português do Brasil (Brazilian Portuguese)"),
|
||||||
"pt-PT": LocaleData(name="Português (Portuguese)"),
|
"pt-PT": LocaleData(name="Português (Portuguese)"),
|
||||||
"ro-RO": LocaleData(name="Română (Romanian)"),
|
"ro-RO": LocaleData(name="Română (Romanian)"),
|
||||||
"ru-RU": LocaleData(name="Pусский (Russian)"),
|
"ru-RU": LocaleData(name="Pусский (Russian)"),
|
||||||
|
"sl-SI": LocaleData(name="Slovenščina (Slovenian)"),
|
||||||
"sr-SP": LocaleData(name="српски (Serbian)"),
|
"sr-SP": LocaleData(name="српски (Serbian)"),
|
||||||
"sv-SE": LocaleData(name="Svenska (Swedish)"),
|
"sv-SE": LocaleData(name="Svenska (Swedish)"),
|
||||||
"tr-TR": LocaleData(name="Türkçe (Turkish)"),
|
"tr-TR": LocaleData(name="Türkçe (Turkish)"),
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ Before you can start using OIDC Authentication, you must first configure a new c
|
|||||||
1. Create a new client application
|
1. Create a new client application
|
||||||
- The Provider type should be OIDC or OAuth2
|
- The Provider type should be OIDC or OAuth2
|
||||||
- The Grant type should be `Authorization Code`
|
- The Grant type should be `Authorization Code`
|
||||||
- The Application type should be `Web`
|
- The Application type should be `Web` or `SPA`
|
||||||
- The Client type should be `public`
|
- The Client type should be `public`
|
||||||
|
|
||||||
2. Configure redirect URI
|
2. Configure redirect URI
|
||||||
@@ -42,7 +42,9 @@ Before you can start using OIDC Authentication, you must first configure a new c
|
|||||||
|
|
||||||
4. Configure allowed scopes
|
4. Configure allowed scopes
|
||||||
|
|
||||||
The scopes required are `openid profile email groups`
|
The scopes required are `openid profile email`
|
||||||
|
|
||||||
|
If you plan to use the [groups](#groups) to configure access within Mealie, you will need to also add the scope defined by the `OIDC_GROUPS_CLAIM` environment variable. The default claim is `groups`
|
||||||
|
|
||||||
## Mealie Setup
|
## Mealie Setup
|
||||||
|
|
||||||
@@ -50,7 +52,7 @@ Take the client id and your discovery URL and update your environment variables
|
|||||||
|
|
||||||
### Groups
|
### Groups
|
||||||
|
|
||||||
There are two (optional) [environment variables](../installation/backend-config.md#openid-connect-oidc) that can control which of the users in your IdP can log in to Mealie and what permissions they will have. The groups should be **defined in your IdP** and be returned in the `groups` claim.
|
There are two (optional) [environment variables](../installation/backend-config.md#openid-connect-oidc) that can control which of the users in your IdP can log in to Mealie and what permissions they will have. Keep in mind that these groups **do not necessarily correspond to groups in Mealie**. The groups claim is configurable via the `OIDC_GROUPS_CLAIM` environment variable. The groups should be **defined in your IdP** and be returned in the configured claim value.
|
||||||
|
|
||||||
`OIDC_USER_GROUP`: Users must be a part of this group (within your IdP) to be able to log in.
|
`OIDC_USER_GROUP`: Users must be a part of this group (within your IdP) to be able to log in.
|
||||||
|
|
||||||
|
|||||||
@@ -81,12 +81,63 @@ The meal planner has the concept of plan rules. These offer a flexible way to us
|
|||||||
|
|
||||||
The shopping lists feature is a great way to keep track of what you need to buy for your next meal. You can add items directly to the shopping list or link a recipe and all of it's ingredients to track meals during the week.
|
The shopping lists feature is a great way to keep track of what you need to buy for your next meal. You can add items directly to the shopping list or link a recipe and all of it's ingredients to track meals during the week.
|
||||||
|
|
||||||
!!! warning
|
|
||||||
At this time there isn't a tight integration between meal-plans and shopping lists; however, it's something we have planned for the future.
|
|
||||||
|
|
||||||
|
|
||||||
[Shopping List Demo](https://demo.mealie.io/shopping-lists){ .md-button .md-button--primary }
|
[Shopping List Demo](https://demo.mealie.io/shopping-lists){ .md-button .md-button--primary }
|
||||||
|
|
||||||
|
## Integrations
|
||||||
|
|
||||||
|
Mealie is designed to integrate with many different external services. There are several ways you can integrate with Mealie to achieve custom IoT automations, data synchronization, and anything else you can think of. [You can work directly with Mealie through the API](./api-usage.md), or leverage other services to make seamless integrations.
|
||||||
|
|
||||||
|
### Notifiers
|
||||||
|
|
||||||
|
Notifiers are event-driven notifications sent when specific actions are performed within Mealie. Some actions include:
|
||||||
|
- creating a recipe
|
||||||
|
- adding items to a shopping list
|
||||||
|
- creating a new mealplan
|
||||||
|
|
||||||
|
Notifiers use the [Apprise library](https://github.com/caronc/apprise/wiki), which integrates with a large number of notification services. In addition, certain custom notifiers send basic event data to the consumer (e.g. the `id` of the resource). These include:
|
||||||
|
|
||||||
|
- `form` and `forms`
|
||||||
|
- `json` and `jsons`
|
||||||
|
- `xml` and `xmls`
|
||||||
|
|
||||||
|
[Notifiers Demo](https://demo.mealie.io/group/notifiers){ .md-button .md-button--primary }
|
||||||
|
|
||||||
|
### Webhooks
|
||||||
|
|
||||||
|
Unlike notifiers, which are event-driven notifications, Webhooks allow you to send scheduled notifications to your desired endpoint. Webhooks are sent on the day of a scheduled mealplan, at the specified time, and contain the mealplan data in the request.
|
||||||
|
|
||||||
|
[Webhooks Demo](https://demo.mealie.io/group/webhooks){ .md-button .md-button--primary }
|
||||||
|
|
||||||
|
### Recipe Actions
|
||||||
|
|
||||||
|
Recipe Actions are custom actions you can add to all recipes in Mealie. This is a great way to add custom integrations that are fired manually. There are two types of recipe actions:
|
||||||
|
|
||||||
|
1. link - these actions will take you directly to an external page
|
||||||
|
2. post - these actions will send a `POST` request to the specified URL, with the recipe JSON in the request body. These can be used, for instance, to manually trigger a webhook in Home Assistant
|
||||||
|
|
||||||
|
Recipe Action URLs can include merge fields to inject the current recipe's data. For instance, you can use the following URL to include a Google search with the recipe's slug:
|
||||||
|
```
|
||||||
|
https://www.google.com/search?q=${slug}
|
||||||
|
```
|
||||||
|
|
||||||
|
When the action is clicked on, the `${slug}` field is replaced with the recipe's slug value. So, for example, it might take you to this URL on one of your recipes:
|
||||||
|
```
|
||||||
|
https://www.google.com/search?q=pasta-fagioli
|
||||||
|
```
|
||||||
|
|
||||||
|
A common use case for "link" recipe actions is to integrate with the Bring! shopping list. Simply add a Recipe Action with the following URL:
|
||||||
|
```
|
||||||
|
https://api.getbring.com/rest/bringrecipes/deeplink?url=${url}&source=web
|
||||||
|
```
|
||||||
|
|
||||||
|
Below is a list of all valid merge fields:
|
||||||
|
|
||||||
|
- ${id}
|
||||||
|
- ${slug}
|
||||||
|
- ${url}
|
||||||
|
|
||||||
|
To add, modify, or delete Recipe Actions, visit the Data Management page (more on that below).
|
||||||
|
|
||||||
## Data Management
|
## Data Management
|
||||||
|
|
||||||
|
|||||||
@@ -98,7 +98,9 @@ For usage, see [Usage - OpenID Connect](../authentication/oidc.md)
|
|||||||
| OIDC_PROVIDER_NAME | OAuth | The provider name is shown in SSO login button. "Login with <OIDC_PROVIDER_NAME\>" |
|
| OIDC_PROVIDER_NAME | OAuth | The provider name is shown in SSO login button. "Login with <OIDC_PROVIDER_NAME\>" |
|
||||||
| OIDC_REMEMBER_ME | False | Because redirects bypass the login screen, you cant extend your session by clicking the "Remember Me" checkbox. By setting this value to true, a session will be extended as if "Remember Me" was checked |
|
| OIDC_REMEMBER_ME | False | Because redirects bypass the login screen, you cant extend your session by clicking the "Remember Me" checkbox. By setting this value to true, a session will be extended as if "Remember Me" was checked |
|
||||||
| OIDC_SIGNING_ALGORITHM | RS256 | The algorithm used to sign the id token (examples: RS256, HS256) |
|
| OIDC_SIGNING_ALGORITHM | RS256 | The algorithm used to sign the id token (examples: RS256, HS256) |
|
||||||
| OIDC_USER_CLAIM | email | Optional: 'email', 'preferred_username' |
|
| OIDC_USER_CLAIM | email | This is the claim which Mealie will use to look up an existing user by (e.g. "email", "preferred_username") |
|
||||||
|
| 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_TLS_CACERTFILE | None | File path to Certificate Authority used to verify server certificate (e.g. `/path/to/ca.crt`) |
|
||||||
|
|
||||||
### Themeing
|
### Themeing
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ PostgreSQL might be considered if you need to support many concurrent users. In
|
|||||||
```yaml
|
```yaml
|
||||||
services:
|
services:
|
||||||
mealie:
|
mealie:
|
||||||
image: ghcr.io/mealie-recipes/mealie:v1.4.0 # (3)
|
image: ghcr.io/mealie-recipes/mealie:v1.5.1 # (3)
|
||||||
container_name: mealie
|
container_name: mealie
|
||||||
restart: always
|
restart: always
|
||||||
ports:
|
ports:
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ SQLite is a popular, open source, self-contained, zero-configuration database th
|
|||||||
```yaml
|
```yaml
|
||||||
services:
|
services:
|
||||||
mealie:
|
mealie:
|
||||||
image: ghcr.io/mealie-recipes/mealie:v1.4.0 # (3)
|
image: ghcr.io/mealie-recipes/mealie:v1.5.1 # (3)
|
||||||
container_name: mealie
|
container_name: mealie
|
||||||
restart: always
|
restart: always
|
||||||
ports:
|
ports:
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -70,6 +70,7 @@
|
|||||||
print: true,
|
print: true,
|
||||||
printPreferences: true,
|
printPreferences: true,
|
||||||
share: loggedIn,
|
share: loggedIn,
|
||||||
|
recipeActions: true,
|
||||||
}"
|
}"
|
||||||
@print="$emit('print')"
|
@print="$emit('print')"
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -105,6 +105,26 @@
|
|||||||
</v-list-item-icon>
|
</v-list-item-icon>
|
||||||
<v-list-item-title>{{ item.title }}</v-list-item-title>
|
<v-list-item-title>{{ item.title }}</v-list-item-title>
|
||||||
</v-list-item>
|
</v-list-item>
|
||||||
|
<div v-if="useItems.recipeActions && recipeActions && recipeActions.length">
|
||||||
|
<v-divider />
|
||||||
|
<v-list-group @click.stop>
|
||||||
|
<template #activator>
|
||||||
|
<v-list-item-title>{{ $tc("recipe.recipe-actions") }}</v-list-item-title>
|
||||||
|
</template>
|
||||||
|
<v-list dense class="ma-0 pa-0">
|
||||||
|
<v-list-item
|
||||||
|
v-for="(action, index) in recipeActions"
|
||||||
|
:key="index"
|
||||||
|
class="pl-6"
|
||||||
|
@click="executeRecipeAction(action)"
|
||||||
|
>
|
||||||
|
<v-list-item-title>
|
||||||
|
{{ action.title }}
|
||||||
|
</v-list-item-title>
|
||||||
|
</v-list-item>
|
||||||
|
</v-list>
|
||||||
|
</v-list-group>
|
||||||
|
</div>
|
||||||
</v-list>
|
</v-list>
|
||||||
</v-menu>
|
</v-menu>
|
||||||
</div>
|
</div>
|
||||||
@@ -117,11 +137,12 @@ import RecipeDialogPrintPreferences from "./RecipeDialogPrintPreferences.vue";
|
|||||||
import RecipeDialogShare from "./RecipeDialogShare.vue";
|
import RecipeDialogShare from "./RecipeDialogShare.vue";
|
||||||
import { useLoggedInState } from "~/composables/use-logged-in-state";
|
import { useLoggedInState } from "~/composables/use-logged-in-state";
|
||||||
import { useUserApi } from "~/composables/api";
|
import { useUserApi } from "~/composables/api";
|
||||||
|
import { useGroupRecipeActions } from "~/composables/use-group-recipe-actions";
|
||||||
import { useGroupSelf } from "~/composables/use-groups";
|
import { useGroupSelf } from "~/composables/use-groups";
|
||||||
import { alert } from "~/composables/use-toast";
|
import { alert } from "~/composables/use-toast";
|
||||||
import { usePlanTypeOptions } from "~/composables/use-group-mealplan";
|
import { usePlanTypeOptions } from "~/composables/use-group-mealplan";
|
||||||
import { Recipe } from "~/lib/api/types/recipe";
|
import { Recipe } from "~/lib/api/types/recipe";
|
||||||
import { ShoppingListSummary } from "~/lib/api/types/group";
|
import { GroupRecipeActionOut, ShoppingListSummary } from "~/lib/api/types/group";
|
||||||
import { PlanEntryType } from "~/lib/api/types/meal-plan";
|
import { PlanEntryType } from "~/lib/api/types/meal-plan";
|
||||||
import { useAxiosDownloader } from "~/composables/api/use-axios-download";
|
import { useAxiosDownloader } from "~/composables/api/use-axios-download";
|
||||||
|
|
||||||
@@ -134,6 +155,7 @@ export interface ContextMenuIncludes {
|
|||||||
print: boolean;
|
print: boolean;
|
||||||
printPreferences: boolean;
|
printPreferences: boolean;
|
||||||
share: boolean;
|
share: boolean;
|
||||||
|
recipeActions: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ContextMenuItem {
|
export interface ContextMenuItem {
|
||||||
@@ -163,6 +185,7 @@ export default defineComponent({
|
|||||||
print: true,
|
print: true,
|
||||||
printPreferences: true,
|
printPreferences: true,
|
||||||
share: true,
|
share: true,
|
||||||
|
recipeActions: true,
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
// Append items are added at the end of the useItems list
|
// Append items are added at the end of the useItems list
|
||||||
@@ -347,6 +370,19 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
const groupRecipeActionsStore = useGroupRecipeActions();
|
||||||
|
|
||||||
|
async function executeRecipeAction(action: GroupRecipeActionOut) {
|
||||||
|
const response = await groupRecipeActionsStore.execute(action, props.recipe);
|
||||||
|
|
||||||
|
if (action.actionType === "post") {
|
||||||
|
if (!response || (response.status >= 200 && response.status < 300)) {
|
||||||
|
alert.success(i18n.tc("events.message-sent"));
|
||||||
|
} else {
|
||||||
|
alert.error(i18n.tc("events.something-went-wrong"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function deleteRecipe() {
|
async function deleteRecipe() {
|
||||||
await api.recipes.deleteOne(props.slug);
|
await api.recipes.deleteOne(props.slug);
|
||||||
@@ -437,6 +473,8 @@ export default defineComponent({
|
|||||||
...toRefs(state),
|
...toRefs(state),
|
||||||
recipeRef,
|
recipeRef,
|
||||||
recipeRefWithScale,
|
recipeRefWithScale,
|
||||||
|
executeRecipeAction,
|
||||||
|
recipeActions: groupRecipeActionsStore.recipeActions,
|
||||||
shoppingLists,
|
shoppingLists,
|
||||||
duplicateRecipe,
|
duplicateRecipe,
|
||||||
contextMenuEventHandler,
|
contextMenuEventHandler,
|
||||||
|
|||||||
@@ -143,7 +143,7 @@ import { watchDebounced } from "@vueuse/shared";
|
|||||||
import SearchFilter from "~/components/Domain/SearchFilter.vue";
|
import SearchFilter from "~/components/Domain/SearchFilter.vue";
|
||||||
import { useLoggedInState } from "~/composables/use-logged-in-state";
|
import { useLoggedInState } from "~/composables/use-logged-in-state";
|
||||||
import { useCategoryStore, useFoodStore, useTagStore, useToolStore } from "~/composables/store";
|
import { useCategoryStore, useFoodStore, useTagStore, useToolStore } from "~/composables/store";
|
||||||
import { useUserSortPreferences } from "~/composables/use-users/preferences";
|
import { useUserSearchQuerySession } from "~/composables/use-users/preferences";
|
||||||
import RecipeCardSection from "~/components/Domain/Recipe/RecipeCardSection.vue";
|
import RecipeCardSection from "~/components/Domain/Recipe/RecipeCardSection.vue";
|
||||||
import { IngredientFood, RecipeCategory, RecipeTag, RecipeTool } from "~/lib/api/types/recipe";
|
import { IngredientFood, RecipeCategory, RecipeTag, RecipeTool } from "~/lib/api/types/recipe";
|
||||||
import { NoUndefinedField } from "~/lib/api/types/non-generated";
|
import { NoUndefinedField } from "~/lib/api/types/non-generated";
|
||||||
@@ -177,7 +177,7 @@ export default defineComponent({
|
|||||||
|
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const groupSlug = computed(() => route.value.params.groupSlug || $auth.user?.groupSlug || "");
|
const groupSlug = computed(() => route.value.params.groupSlug || $auth.user?.groupSlug || "");
|
||||||
const preferences = useUserSortPreferences();
|
const searchQuerySession = useUserSearchQuerySession();
|
||||||
|
|
||||||
const { recipes, appendRecipes, assignSorted, removeRecipe, replaceRecipes } = useLazyRecipes(isOwnGroup.value ? null : groupSlug.value);
|
const { recipes, appendRecipes, assignSorted, removeRecipe, replaceRecipes } = useLazyRecipes(isOwnGroup.value ? null : groupSlug.value);
|
||||||
const categories = isOwnGroup.value ? useCategoryStore() : usePublicCategoryStore(groupSlug.value);
|
const categories = isOwnGroup.value ? useCategoryStore() : usePublicCategoryStore(groupSlug.value);
|
||||||
@@ -194,7 +194,9 @@ export default defineComponent({
|
|||||||
|
|
||||||
function calcPassedQuery(): RecipeSearchQuery {
|
function calcPassedQuery(): RecipeSearchQuery {
|
||||||
return {
|
return {
|
||||||
search: state.value.search,
|
// the search clear button sets search to null, which still renders the query param for a moment,
|
||||||
|
// whereas an empty string is not rendered
|
||||||
|
search: state.value.search ? state.value.search : "",
|
||||||
categories: toIDArray(selectedCategories.value),
|
categories: toIDArray(selectedCategories.value),
|
||||||
foods: toIDArray(selectedFoods.value),
|
foods: toIDArray(selectedFoods.value),
|
||||||
tags: toIDArray(selectedTags.value),
|
tags: toIDArray(selectedTags.value),
|
||||||
@@ -217,14 +219,24 @@ export default defineComponent({
|
|||||||
};
|
};
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const queryDefaults = {
|
||||||
|
search: "",
|
||||||
|
orderBy: "created_at",
|
||||||
|
orderDirection: "desc" as "asc" | "desc",
|
||||||
|
requireAllCategories: false,
|
||||||
|
requireAllTags: false,
|
||||||
|
requireAllTools: false,
|
||||||
|
requireAllFoods: false,
|
||||||
|
}
|
||||||
|
|
||||||
function reset() {
|
function reset() {
|
||||||
state.value.search = "";
|
state.value.search = queryDefaults.search;
|
||||||
state.value.orderBy = "created_at";
|
state.value.orderBy = queryDefaults.orderBy;
|
||||||
state.value.orderDirection = "desc";
|
state.value.orderDirection = queryDefaults.orderDirection;
|
||||||
state.value.requireAllCategories = false;
|
state.value.requireAllCategories = queryDefaults.requireAllCategories;
|
||||||
state.value.requireAllTags = false;
|
state.value.requireAllTags = queryDefaults.requireAllTags;
|
||||||
state.value.requireAllTools = false;
|
state.value.requireAllTools = queryDefaults.requireAllTools;
|
||||||
state.value.requireAllFoods = false;
|
state.value.requireAllFoods = queryDefaults.requireAllFoods;
|
||||||
selectedCategories.value = [];
|
selectedCategories.value = [];
|
||||||
selectedFoods.value = [];
|
selectedFoods.value = [];
|
||||||
selectedTags.value = [];
|
selectedTags.value = [];
|
||||||
@@ -262,12 +274,12 @@ export default defineComponent({
|
|||||||
foods: passedQuery.value.foods,
|
foods: passedQuery.value.foods,
|
||||||
tags: passedQuery.value.tags,
|
tags: passedQuery.value.tags,
|
||||||
tools: passedQuery.value.tools,
|
tools: passedQuery.value.tools,
|
||||||
// Only add the query param if it's or not default
|
// Only add the query param if it's not the default value
|
||||||
...{
|
...{
|
||||||
auto: state.value.auto ? undefined : "false",
|
auto: state.value.auto ? undefined : "false",
|
||||||
search: passedQuery.value.search === "" ? undefined : passedQuery.value.search,
|
search: passedQuery.value.search === queryDefaults.search ? undefined : passedQuery.value.search,
|
||||||
orderBy: passedQuery.value.orderBy === "created_at" ? undefined : passedQuery.value.orderBy,
|
orderBy: passedQuery.value.orderBy === queryDefaults.orderBy ? undefined : passedQuery.value.orderBy,
|
||||||
orderDirection: passedQuery.value.orderDirection === "desc" ? undefined : passedQuery.value.orderDirection,
|
orderDirection: passedQuery.value.orderDirection === queryDefaults.orderDirection ? undefined : passedQuery.value.orderDirection,
|
||||||
requireAllCategories: passedQuery.value.requireAllCategories ? "true" : undefined,
|
requireAllCategories: passedQuery.value.requireAllCategories ? "true" : undefined,
|
||||||
requireAllTags: passedQuery.value.requireAllTags ? "true" : undefined,
|
requireAllTags: passedQuery.value.requireAllTags ? "true" : undefined,
|
||||||
requireAllTools: passedQuery.value.requireAllTools ? "true" : undefined,
|
requireAllTools: passedQuery.value.requireAllTools ? "true" : undefined,
|
||||||
@@ -275,7 +287,7 @@ export default defineComponent({
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
await router.push({ query });
|
await router.push({ query });
|
||||||
preferences.value.searchQuery = JSON.stringify(query);
|
searchQuerySession.value.recipe = JSON.stringify(query);
|
||||||
}
|
}
|
||||||
|
|
||||||
function waitUntilAndExecute(
|
function waitUntilAndExecute(
|
||||||
@@ -360,25 +372,55 @@ export default defineComponent({
|
|||||||
|
|
||||||
async function hydrateSearch() {
|
async function hydrateSearch() {
|
||||||
const query = router.currentRoute.query;
|
const query = router.currentRoute.query;
|
||||||
if (query.auto) {
|
if (query.auto?.length) {
|
||||||
state.value.auto = query.auto === "true";
|
state.value.auto = query.auto === "true";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (query.search) {
|
if (query.search?.length) {
|
||||||
state.value.search = query.search as string;
|
state.value.search = query.search as string;
|
||||||
|
} else {
|
||||||
|
state.value.search = queryDefaults.search;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (query.orderBy) {
|
if (query.orderBy?.length) {
|
||||||
state.value.orderBy = query.orderBy as string;
|
state.value.orderBy = query.orderBy as string;
|
||||||
|
} else {
|
||||||
|
state.value.orderBy = queryDefaults.orderBy;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (query.orderDirection) {
|
if (query.orderDirection?.length) {
|
||||||
state.value.orderDirection = query.orderDirection as "asc" | "desc";
|
state.value.orderDirection = query.orderDirection as "asc" | "desc";
|
||||||
|
} else {
|
||||||
|
state.value.orderDirection = queryDefaults.orderDirection;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (query.requireAllCategories?.length) {
|
||||||
|
state.value.requireAllCategories = query.requireAllCategories === "true";
|
||||||
|
} else {
|
||||||
|
state.value.requireAllCategories = queryDefaults.requireAllCategories;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (query.requireAllTags?.length) {
|
||||||
|
state.value.requireAllTags = query.requireAllTags === "true";
|
||||||
|
} else {
|
||||||
|
state.value.requireAllTags = queryDefaults.requireAllTags;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (query.requireAllTools?.length) {
|
||||||
|
state.value.requireAllTools = query.requireAllTools === "true";
|
||||||
|
} else {
|
||||||
|
state.value.requireAllTools = queryDefaults.requireAllTools;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (query.requireAllFoods?.length) {
|
||||||
|
state.value.requireAllFoods = query.requireAllFoods === "true";
|
||||||
|
} else {
|
||||||
|
state.value.requireAllFoods = queryDefaults.requireAllFoods;
|
||||||
}
|
}
|
||||||
|
|
||||||
const promises: Promise<void>[] = [];
|
const promises: Promise<void>[] = [];
|
||||||
|
|
||||||
if (query.categories) {
|
if (query.categories?.length) {
|
||||||
promises.push(
|
promises.push(
|
||||||
waitUntilAndExecute(
|
waitUntilAndExecute(
|
||||||
() => categories.items.value.length > 0,
|
() => categories.items.value.length > 0,
|
||||||
@@ -395,7 +437,35 @@ export default defineComponent({
|
|||||||
selectedCategories.value = [];
|
selectedCategories.value = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (query.foods) {
|
if (query.tags?.length) {
|
||||||
|
promises.push(
|
||||||
|
waitUntilAndExecute(
|
||||||
|
() => tags.items.value.length > 0,
|
||||||
|
() => {
|
||||||
|
const result = tags.items.value.filter((item) => (query.tags as string[]).includes(item.id as string));
|
||||||
|
selectedTags.value = result as NoUndefinedField<RecipeTag>[];
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
selectedTags.value = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (query.tools?.length) {
|
||||||
|
promises.push(
|
||||||
|
waitUntilAndExecute(
|
||||||
|
() => tools.items.value.length > 0,
|
||||||
|
() => {
|
||||||
|
const result = tools.items.value.filter((item) => (query.tools as string[]).includes(item.id));
|
||||||
|
selectedTools.value = result as NoUndefinedField<RecipeTool>[];
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
selectedTools.value = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (query.foods?.length) {
|
||||||
promises.push(
|
promises.push(
|
||||||
waitUntilAndExecute(
|
waitUntilAndExecute(
|
||||||
() => {
|
() => {
|
||||||
@@ -414,45 +484,17 @@ export default defineComponent({
|
|||||||
selectedFoods.value = [];
|
selectedFoods.value = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (query.tags) {
|
|
||||||
promises.push(
|
|
||||||
waitUntilAndExecute(
|
|
||||||
() => tags.items.value.length > 0,
|
|
||||||
() => {
|
|
||||||
const result = tags.items.value.filter((item) => (query.tags as string[]).includes(item.id as string));
|
|
||||||
selectedTags.value = result as NoUndefinedField<RecipeTag>[];
|
|
||||||
}
|
|
||||||
)
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
selectedTags.value = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (query.tools) {
|
|
||||||
promises.push(
|
|
||||||
waitUntilAndExecute(
|
|
||||||
() => tools.items.value.length > 0,
|
|
||||||
() => {
|
|
||||||
const result = tools.items.value.filter((item) => (query.tools as string[]).includes(item.id));
|
|
||||||
selectedTools.value = result as NoUndefinedField<RecipeTool>[];
|
|
||||||
}
|
|
||||||
)
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
selectedTools.value = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
await Promise.allSettled(promises);
|
await Promise.allSettled(promises);
|
||||||
};
|
};
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
// restore the user's last search query
|
// restore the user's last search query
|
||||||
if (preferences.value.searchQuery && !(Object.keys(route.value.query).length > 0)) {
|
if (searchQuerySession.value.recipe && !(Object.keys(route.value.query).length > 0)) {
|
||||||
try {
|
try {
|
||||||
const query = JSON.parse(preferences.value.searchQuery);
|
const query = JSON.parse(searchQuerySession.value.recipe);
|
||||||
await router.replace({ query });
|
await router.replace({ query });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
preferences.value.searchQuery = "";
|
searchQuerySession.value.recipe = "";
|
||||||
router.replace({ query: {} });
|
router.replace({ query: {} });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
<template>
|
<template>
|
||||||
<div @click.prevent>
|
<div @click.prevent>
|
||||||
|
<!-- User Rating -->
|
||||||
<v-hover v-slot="{ hover }">
|
<v-hover v-slot="{ hover }">
|
||||||
<v-rating
|
<v-rating
|
||||||
:value="rating.ratingValue"
|
v-if="isOwnGroup && (userRating || hover || !ratingsLoaded)"
|
||||||
:half-increments="(!hover) || (!isOwnGroup)"
|
:value="userRating"
|
||||||
:readonly="!isOwnGroup"
|
color="secondary"
|
||||||
:color="hover ? attrs.hoverColor : attrs.color"
|
background-color="secondary lighten-3"
|
||||||
:background-color="attrs.backgroundColor"
|
|
||||||
length="5"
|
length="5"
|
||||||
:dense="small ? true : undefined"
|
:dense="small ? true : undefined"
|
||||||
:size="small ? 15 : undefined"
|
:size="small ? 15 : undefined"
|
||||||
@@ -15,12 +15,25 @@
|
|||||||
@input="updateRating"
|
@input="updateRating"
|
||||||
@click="updateRating"
|
@click="updateRating"
|
||||||
/>
|
/>
|
||||||
|
<!-- Group Rating -->
|
||||||
|
<v-rating
|
||||||
|
v-else
|
||||||
|
:value="groupRating"
|
||||||
|
:half-increments="true"
|
||||||
|
:readonly="true"
|
||||||
|
color="grey darken-1"
|
||||||
|
background-color="secondary lighten-3"
|
||||||
|
length="5"
|
||||||
|
:dense="small ? true : undefined"
|
||||||
|
:size="small ? 15 : undefined"
|
||||||
|
hover
|
||||||
|
/>
|
||||||
</v-hover>
|
</v-hover>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { computed, defineComponent, ref, useContext, watch } from "@nuxtjs/composition-api";
|
import { computed, defineComponent, ref, watch } from "@nuxtjs/composition-api";
|
||||||
import { useLoggedInState } from "~/composables/use-logged-in-state";
|
import { useLoggedInState } from "~/composables/use-logged-in-state";
|
||||||
import { useUserSelfRatings } from "~/composables/use-users";
|
import { useUserSelfRatings } from "~/composables/use-users";
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
@@ -45,61 +58,29 @@ export default defineComponent({
|
|||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
preferGroupRating: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
setup(props, context) {
|
setup(props, context) {
|
||||||
const { $auth } = useContext();
|
|
||||||
const { isOwnGroup } = useLoggedInState();
|
const { isOwnGroup } = useLoggedInState();
|
||||||
const { userRatings, setRating, ready: ratingsLoaded } = useUserSelfRatings();
|
const { userRatings, setRating, ready: ratingsLoaded } = useUserSelfRatings();
|
||||||
const hideGroupRating = ref(false);
|
|
||||||
|
|
||||||
type Rating = {
|
const userRating = computed(() => {
|
||||||
ratingValue: number | undefined;
|
return userRatings.value.find((r) => r.recipeId === props.recipeId)?.rating;
|
||||||
hasUserRating: boolean | undefined
|
|
||||||
};
|
|
||||||
|
|
||||||
// prefer user rating over group rating
|
|
||||||
const rating = computed<Rating>(() => {
|
|
||||||
if (!ratingsLoaded.value) {
|
|
||||||
return { ratingValue: undefined, hasUserRating: undefined };
|
|
||||||
}
|
|
||||||
if (!($auth.user?.id) || props.preferGroupRating) {
|
|
||||||
return { ratingValue: props.value, hasUserRating: false };
|
|
||||||
}
|
|
||||||
|
|
||||||
const userRating = userRatings.value.find((r) => r.recipeId === props.recipeId);
|
|
||||||
return {
|
|
||||||
ratingValue: userRating?.rating || (hideGroupRating.value ? 0 : props.value),
|
|
||||||
hasUserRating: !!userRating?.rating
|
|
||||||
};
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// if a user unsets their rating, we don't want to fall back to the group rating since it's out of sync
|
// if a user unsets their rating, we don't want to fall back to the group rating since it's out of sync
|
||||||
|
const hideGroupRating = ref(!!userRating.value);
|
||||||
watch(
|
watch(
|
||||||
() => rating.value.hasUserRating,
|
() => userRating.value,
|
||||||
() => {
|
() => {
|
||||||
if (rating.value.hasUserRating && !props.preferGroupRating) {
|
if (userRating.value) {
|
||||||
hideGroupRating.value = true;
|
hideGroupRating.value = true;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
const attrs = computed(() => {
|
const groupRating = computed(() => {
|
||||||
return isOwnGroup.value ? {
|
return hideGroupRating.value ? 0 : props.value;
|
||||||
// Logged-in user
|
});
|
||||||
color: rating.value.hasUserRating ? "secondary" : "grey darken-1",
|
|
||||||
hoverColor: "secondary",
|
|
||||||
backgroundColor: "secondary lighten-3",
|
|
||||||
} : {
|
|
||||||
// Anonymous user
|
|
||||||
color: "secondary",
|
|
||||||
hoverColor: "secondary",
|
|
||||||
backgroundColor: "secondary lighten-3",
|
|
||||||
};
|
|
||||||
})
|
|
||||||
|
|
||||||
function updateRating(val: number | null) {
|
function updateRating(val: number | null) {
|
||||||
if (!isOwnGroup.value) {
|
if (!isOwnGroup.value) {
|
||||||
@@ -113,9 +94,10 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
attrs,
|
|
||||||
isOwnGroup,
|
isOwnGroup,
|
||||||
rating,
|
ratingsLoaded,
|
||||||
|
groupRating,
|
||||||
|
userRating,
|
||||||
updateRating,
|
updateRating,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -8,8 +8,11 @@
|
|||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { computed, defineComponent } from "@nuxtjs/composition-api";
|
import { computed, defineComponent } from "@nuxtjs/composition-api";
|
||||||
|
// @ts-ignore missing color types
|
||||||
|
import Color from "@sphinxxxx/color-conversion";
|
||||||
import { MultiPurposeLabelSummary } from "~/lib/api/types/recipe";
|
import { MultiPurposeLabelSummary } from "~/lib/api/types/recipe";
|
||||||
|
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
props: {
|
props: {
|
||||||
label: {
|
label: {
|
||||||
@@ -34,11 +37,15 @@ export default defineComponent({
|
|||||||
const ACCESSIBILITY_THRESHOLD = 0.179;
|
const ACCESSIBILITY_THRESHOLD = 0.179;
|
||||||
|
|
||||||
function pickTextColorBasedOnBgColorAdvanced(bgColor: string, lightColor: string, darkColor: string) {
|
function pickTextColorBasedOnBgColorAdvanced(bgColor: string, lightColor: string, darkColor: string) {
|
||||||
const color = bgColor.charAt(0) === "#" ? bgColor.substring(1, 7) : bgColor;
|
try {
|
||||||
const r = parseInt(color.substring(0, 2), 16); // hexToR
|
const color = new Color(bgColor);
|
||||||
const g = parseInt(color.substring(2, 4), 16); // hexToG
|
|
||||||
const b = parseInt(color.substring(4, 6), 16); // hexToB
|
// if opacity is less than 0.3 always return dark color
|
||||||
const uicolors = [r / 255, g / 255, b / 255];
|
if (color._rgba[3] < 0.3) {
|
||||||
|
return darkColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
const uicolors = [color._rgba[0] / 255, color._rgba[1] / 255, color._rgba[2] / 255];
|
||||||
const c = uicolors.map((col) => {
|
const c = uicolors.map((col) => {
|
||||||
if (col <= 0.03928) {
|
if (col <= 0.03928) {
|
||||||
return col / 12.92;
|
return col / 12.92;
|
||||||
@@ -47,6 +54,10 @@ export default defineComponent({
|
|||||||
});
|
});
|
||||||
const L = 0.2126 * c[0] + 0.7152 * c[1] + 0.0722 * c[2];
|
const L = 0.2126 * c[0] + 0.7152 * c[1] + 0.0722 * c[2];
|
||||||
return L > ACCESSIBILITY_THRESHOLD ? darkColor : lightColor;
|
return L > ACCESSIBILITY_THRESHOLD ? darkColor : lightColor;
|
||||||
|
} catch (error) {
|
||||||
|
console.warn(error);
|
||||||
|
return "black";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
98
frontend/composables/use-group-recipe-actions.ts
Normal file
98
frontend/composables/use-group-recipe-actions.ts
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
import { computed, reactive, ref } from "@nuxtjs/composition-api";
|
||||||
|
import { useStoreActions } from "./partials/use-actions-factory";
|
||||||
|
import { useUserApi } from "~/composables/api";
|
||||||
|
import { GroupRecipeActionOut, RecipeActionType } from "~/lib/api/types/group";
|
||||||
|
import { Recipe } from "~/lib/api/types/recipe";
|
||||||
|
|
||||||
|
const groupRecipeActions = ref<GroupRecipeActionOut[] | null>(null);
|
||||||
|
const loading = ref(false);
|
||||||
|
|
||||||
|
export function useGroupRecipeActionData() {
|
||||||
|
const data = reactive({
|
||||||
|
id: "",
|
||||||
|
actionType: "link" as RecipeActionType,
|
||||||
|
title: "",
|
||||||
|
url: "",
|
||||||
|
});
|
||||||
|
|
||||||
|
function reset() {
|
||||||
|
data.id = "";
|
||||||
|
data.actionType = "link";
|
||||||
|
data.title = "";
|
||||||
|
data.url = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
data,
|
||||||
|
reset,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useGroupRecipeActions = function (
|
||||||
|
orderBy: string | null = "title",
|
||||||
|
orderDirection: string | null = "asc",
|
||||||
|
) {
|
||||||
|
const api = useUserApi();
|
||||||
|
|
||||||
|
async function refreshGroupRecipeActions() {
|
||||||
|
loading.value = true;
|
||||||
|
const { data } = await api.groupRecipeActions.getAll(1, -1, { orderBy, orderDirection });
|
||||||
|
groupRecipeActions.value = data?.items || null;
|
||||||
|
loading.value = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const recipeActions = computed<GroupRecipeActionOut[] | null>(() => {
|
||||||
|
return groupRecipeActions.value;
|
||||||
|
});
|
||||||
|
|
||||||
|
function parseRecipeActionUrl(url: string, recipe: Recipe): string {
|
||||||
|
/* eslint-disable no-template-curly-in-string */
|
||||||
|
return url
|
||||||
|
.replace("${url}", window.location.href)
|
||||||
|
.replace("${id}", recipe.id || "")
|
||||||
|
.replace("${slug}", recipe.slug || "")
|
||||||
|
/* eslint-enable no-template-curly-in-string */
|
||||||
|
};
|
||||||
|
|
||||||
|
async function execute(action: GroupRecipeActionOut, recipe: Recipe): Promise<void | Response> {
|
||||||
|
const url = parseRecipeActionUrl(action.url, recipe);
|
||||||
|
|
||||||
|
switch (action.actionType) {
|
||||||
|
case "link":
|
||||||
|
window.open(url, "_blank")?.focus();
|
||||||
|
break;
|
||||||
|
case "post":
|
||||||
|
return await fetch(url, {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
// The "text/plain" content type header is used here to skip the CORS preflight request,
|
||||||
|
// since it may fail. This is fine, since we don't care about the response, we just want
|
||||||
|
// the request to get sent.
|
||||||
|
"Content-Type": "text/plain",
|
||||||
|
},
|
||||||
|
body: JSON.stringify(recipe),
|
||||||
|
}).catch((error) => {
|
||||||
|
console.error(error);
|
||||||
|
});
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!groupRecipeActions.value && !loading.value) {
|
||||||
|
refreshGroupRecipeActions();
|
||||||
|
};
|
||||||
|
|
||||||
|
const actions = {
|
||||||
|
...useStoreActions<GroupRecipeActionOut>(api.groupRecipeActions, groupRecipeActions, loading),
|
||||||
|
flushStore() {
|
||||||
|
groupRecipeActions.value = [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
actions,
|
||||||
|
execute,
|
||||||
|
recipeActions,
|
||||||
|
};
|
||||||
|
};
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
import { Ref, useContext } from "@nuxtjs/composition-api";
|
import { Ref, useContext } from "@nuxtjs/composition-api";
|
||||||
import { useLocalStorage } from "@vueuse/core";
|
import { useLocalStorage, useSessionStorage } from "@vueuse/core";
|
||||||
import { TimelineEventType } from "~/lib/api/types/recipe";
|
import { TimelineEventType } from "~/lib/api/types/recipe";
|
||||||
|
|
||||||
export interface UserPrintPreferences {
|
export interface UserPrintPreferences {
|
||||||
@@ -8,6 +8,10 @@ export interface UserPrintPreferences {
|
|||||||
showNotes: boolean;
|
showNotes: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface UserSearchQuery {
|
||||||
|
recipe: string;
|
||||||
|
}
|
||||||
|
|
||||||
export enum ImagePosition {
|
export enum ImagePosition {
|
||||||
hidden = "hidden",
|
hidden = "hidden",
|
||||||
left = "left",
|
left = "left",
|
||||||
@@ -20,7 +24,6 @@ export interface UserRecipePreferences {
|
|||||||
filterNull: boolean;
|
filterNull: boolean;
|
||||||
sortIcon: string;
|
sortIcon: string;
|
||||||
useMobileCards: boolean;
|
useMobileCards: boolean;
|
||||||
searchQuery: string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface UserShoppingListPreferences {
|
export interface UserShoppingListPreferences {
|
||||||
@@ -60,7 +63,6 @@ export function useUserSortPreferences(): Ref<UserRecipePreferences> {
|
|||||||
filterNull: false,
|
filterNull: false,
|
||||||
sortIcon: $globals.icons.sortAlphabeticalAscending,
|
sortIcon: $globals.icons.sortAlphabeticalAscending,
|
||||||
useMobileCards: false,
|
useMobileCards: false,
|
||||||
searchQuery: "",
|
|
||||||
},
|
},
|
||||||
{ mergeDefaults: true }
|
{ mergeDefaults: true }
|
||||||
// we cast to a Ref because by default it will return an optional type ref
|
// we cast to a Ref because by default it will return an optional type ref
|
||||||
@@ -70,6 +72,20 @@ export function useUserSortPreferences(): Ref<UserRecipePreferences> {
|
|||||||
return fromStorage;
|
return fromStorage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function useUserSearchQuerySession(): Ref<UserSearchQuery> {
|
||||||
|
const fromStorage = useSessionStorage(
|
||||||
|
"search-query",
|
||||||
|
{
|
||||||
|
recipe: "",
|
||||||
|
},
|
||||||
|
{ mergeDefaults: true }
|
||||||
|
// we cast to a Ref because by default it will return an optional type ref
|
||||||
|
// but since we pass defaults we know all properties are set.
|
||||||
|
) as unknown as Ref<UserSearchQuery>;
|
||||||
|
|
||||||
|
return fromStorage;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
export function useShoppingListPreferences(): Ref<UserShoppingListPreferences> {
|
export function useShoppingListPreferences(): Ref<UserShoppingListPreferences> {
|
||||||
const fromStorage = useLocalStorage(
|
const fromStorage = useLocalStorage(
|
||||||
|
|||||||
21
frontend/lang/dateTimeFormats/gl-ES.json
Normal file
21
frontend/lang/dateTimeFormats/gl-ES.json
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
{
|
||||||
|
"short": {
|
||||||
|
"month": "short",
|
||||||
|
"day": "numeric",
|
||||||
|
"weekday": "long"
|
||||||
|
},
|
||||||
|
"medium": {
|
||||||
|
"month": "long",
|
||||||
|
"day": "numeric",
|
||||||
|
"weekday": "long",
|
||||||
|
"year": "numeric"
|
||||||
|
},
|
||||||
|
"long": {
|
||||||
|
"year": "numeric",
|
||||||
|
"month": "long",
|
||||||
|
"day": "numeric",
|
||||||
|
"weekday": "long",
|
||||||
|
"hour": "numeric",
|
||||||
|
"minute": "numeric"
|
||||||
|
}
|
||||||
|
}
|
||||||
21
frontend/lang/dateTimeFormats/hr-HR.json
Normal file
21
frontend/lang/dateTimeFormats/hr-HR.json
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
{
|
||||||
|
"short": {
|
||||||
|
"month": "short",
|
||||||
|
"day": "numeric",
|
||||||
|
"weekday": "long"
|
||||||
|
},
|
||||||
|
"medium": {
|
||||||
|
"month": "long",
|
||||||
|
"day": "numeric",
|
||||||
|
"weekday": "long",
|
||||||
|
"year": "numeric"
|
||||||
|
},
|
||||||
|
"long": {
|
||||||
|
"year": "numeric",
|
||||||
|
"month": "long",
|
||||||
|
"day": "numeric",
|
||||||
|
"weekday": "long",
|
||||||
|
"hour": "numeric",
|
||||||
|
"minute": "numeric"
|
||||||
|
}
|
||||||
|
}
|
||||||
21
frontend/lang/dateTimeFormats/is-IS.json
Normal file
21
frontend/lang/dateTimeFormats/is-IS.json
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
{
|
||||||
|
"short": {
|
||||||
|
"month": "short",
|
||||||
|
"day": "numeric",
|
||||||
|
"weekday": "long"
|
||||||
|
},
|
||||||
|
"medium": {
|
||||||
|
"month": "long",
|
||||||
|
"day": "numeric",
|
||||||
|
"weekday": "long",
|
||||||
|
"year": "numeric"
|
||||||
|
},
|
||||||
|
"long": {
|
||||||
|
"year": "numeric",
|
||||||
|
"month": "long",
|
||||||
|
"day": "numeric",
|
||||||
|
"weekday": "long",
|
||||||
|
"hour": "numeric",
|
||||||
|
"minute": "numeric"
|
||||||
|
}
|
||||||
|
}
|
||||||
21
frontend/lang/dateTimeFormats/lt-LT.json
Normal file
21
frontend/lang/dateTimeFormats/lt-LT.json
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
{
|
||||||
|
"short": {
|
||||||
|
"month": "short",
|
||||||
|
"day": "numeric",
|
||||||
|
"weekday": "long"
|
||||||
|
},
|
||||||
|
"medium": {
|
||||||
|
"month": "long",
|
||||||
|
"day": "numeric",
|
||||||
|
"weekday": "long",
|
||||||
|
"year": "numeric"
|
||||||
|
},
|
||||||
|
"long": {
|
||||||
|
"year": "numeric",
|
||||||
|
"month": "long",
|
||||||
|
"day": "numeric",
|
||||||
|
"weekday": "long",
|
||||||
|
"hour": "numeric",
|
||||||
|
"minute": "numeric"
|
||||||
|
}
|
||||||
|
}
|
||||||
21
frontend/lang/dateTimeFormats/lv-LV.json
Normal file
21
frontend/lang/dateTimeFormats/lv-LV.json
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
{
|
||||||
|
"short": {
|
||||||
|
"month": "short",
|
||||||
|
"day": "numeric",
|
||||||
|
"weekday": "long"
|
||||||
|
},
|
||||||
|
"medium": {
|
||||||
|
"month": "long",
|
||||||
|
"day": "numeric",
|
||||||
|
"weekday": "long",
|
||||||
|
"year": "numeric"
|
||||||
|
},
|
||||||
|
"long": {
|
||||||
|
"year": "numeric",
|
||||||
|
"month": "long",
|
||||||
|
"day": "numeric",
|
||||||
|
"weekday": "long",
|
||||||
|
"hour": "numeric",
|
||||||
|
"minute": "numeric"
|
||||||
|
}
|
||||||
|
}
|
||||||
21
frontend/lang/dateTimeFormats/sl-SI.json
Normal file
21
frontend/lang/dateTimeFormats/sl-SI.json
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
{
|
||||||
|
"short": {
|
||||||
|
"month": "short",
|
||||||
|
"day": "numeric",
|
||||||
|
"weekday": "long"
|
||||||
|
},
|
||||||
|
"medium": {
|
||||||
|
"month": "long",
|
||||||
|
"day": "numeric",
|
||||||
|
"weekday": "long",
|
||||||
|
"year": "numeric"
|
||||||
|
},
|
||||||
|
"long": {
|
||||||
|
"year": "numeric",
|
||||||
|
"month": "long",
|
||||||
|
"day": "numeric",
|
||||||
|
"weekday": "long",
|
||||||
|
"hour": "numeric",
|
||||||
|
"minute": "numeric"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -64,6 +64,7 @@
|
|||||||
"something-went-wrong": "Iets het verkeerd geloop!",
|
"something-went-wrong": "Iets het verkeerd geloop!",
|
||||||
"subscribed-events": "Ingetekende Gebeure",
|
"subscribed-events": "Ingetekende Gebeure",
|
||||||
"test-message-sent": "Toets Boodskap Gestuur",
|
"test-message-sent": "Toets Boodskap Gestuur",
|
||||||
|
"message-sent": "Message Sent",
|
||||||
"new-notification": "Nuwe kennisgewing",
|
"new-notification": "Nuwe kennisgewing",
|
||||||
"event-notifiers": "Gebeurteniskennisgewers",
|
"event-notifiers": "Gebeurteniskennisgewers",
|
||||||
"apprise-url-skipped-if-blank": "Apprise URL (oorgeslaan indien leeg)",
|
"apprise-url-skipped-if-blank": "Apprise URL (oorgeslaan indien leeg)",
|
||||||
@@ -160,6 +161,7 @@
|
|||||||
"test": "Toets",
|
"test": "Toets",
|
||||||
"themes": "Temas",
|
"themes": "Temas",
|
||||||
"thursday": "Donderdag",
|
"thursday": "Donderdag",
|
||||||
|
"title": "Title",
|
||||||
"token": "Token",
|
"token": "Token",
|
||||||
"tuesday": "Dinsdag",
|
"tuesday": "Dinsdag",
|
||||||
"type": "Tipe",
|
"type": "Tipe",
|
||||||
@@ -582,7 +584,22 @@
|
|||||||
"upload-image": "Laai prent",
|
"upload-image": "Laai prent",
|
||||||
"screen-awake": "Hou die skerm aan",
|
"screen-awake": "Hou die skerm aan",
|
||||||
"remove-image": "Verwyder prent",
|
"remove-image": "Verwyder prent",
|
||||||
"nextStep": "Next step"
|
"nextStep": "Next step",
|
||||||
|
"recipe-actions": "Recipe Actions",
|
||||||
|
"parser": {
|
||||||
|
"experimental-alert-text": "Mealie uses natural language processing to parse and create units and food items for your recipe ingredients. This feature is experimental and may not always work as expected. If you prefer not to use the parsed results, you can select 'Cancel' and your changes will not be saved.",
|
||||||
|
"ingredient-parser": "Ingredient Parser",
|
||||||
|
"explanation": "To use the ingredient parser, click the 'Parse All' button to start the process. Once the processed ingredients are available, you can review the items and verify that they were parsed correctly. The model's confidence score is displayed on the right of the item title. This score is an average of all the individual scores and may not always be completely accurate.",
|
||||||
|
"alerts-explainer": "Alerts will be displayed if a matching foods or unit is found but does not exists in the database.",
|
||||||
|
"select-parser": "Select Parser",
|
||||||
|
"natural-language-processor": "Natural Language Processor",
|
||||||
|
"brute-parser": "Brute Parser",
|
||||||
|
"parse-all": "Parse All",
|
||||||
|
"no-unit": "No unit",
|
||||||
|
"missing-unit": "Create missing unit: {unit}",
|
||||||
|
"missing-food": "Create missing food: {food}",
|
||||||
|
"no-food": "No Food"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"search": {
|
"search": {
|
||||||
"advanced-search": "Gevorderde soek",
|
"advanced-search": "Gevorderde soek",
|
||||||
@@ -1001,6 +1018,12 @@
|
|||||||
"delete-recipes": "Verwyder resepte",
|
"delete-recipes": "Verwyder resepte",
|
||||||
"source-unit-will-be-deleted": "Bron-eenheid sal verwyder word"
|
"source-unit-will-be-deleted": "Bron-eenheid sal verwyder word"
|
||||||
},
|
},
|
||||||
|
"recipe-actions": {
|
||||||
|
"recipe-actions-data": "Recipe Actions Data",
|
||||||
|
"new-recipe-action": "New Recipe Action",
|
||||||
|
"edit-recipe-action": "Edit Recipe Action",
|
||||||
|
"action-type": "Action Type"
|
||||||
|
},
|
||||||
"create-alias": "Create Alias",
|
"create-alias": "Create Alias",
|
||||||
"manage-aliases": "Manage Aliases",
|
"manage-aliases": "Manage Aliases",
|
||||||
"seed-data": "Voorbeeld data",
|
"seed-data": "Voorbeeld data",
|
||||||
|
|||||||
@@ -64,6 +64,7 @@
|
|||||||
"something-went-wrong": "حدث خطأ ما!",
|
"something-went-wrong": "حدث خطأ ما!",
|
||||||
"subscribed-events": "الأحداث التي تم الاشتراك فيها",
|
"subscribed-events": "الأحداث التي تم الاشتراك فيها",
|
||||||
"test-message-sent": "تم إرسال رسالة تجريبية",
|
"test-message-sent": "تم إرسال رسالة تجريبية",
|
||||||
|
"message-sent": "Message Sent",
|
||||||
"new-notification": "إشعار جديد",
|
"new-notification": "إشعار جديد",
|
||||||
"event-notifiers": "إشعار الحدث",
|
"event-notifiers": "إشعار الحدث",
|
||||||
"apprise-url-skipped-if-blank": "الرابط Apprise (يتم تجاهله إذا ما كان فارغً)",
|
"apprise-url-skipped-if-blank": "الرابط Apprise (يتم تجاهله إذا ما كان فارغً)",
|
||||||
@@ -160,6 +161,7 @@
|
|||||||
"test": "تجربة",
|
"test": "تجربة",
|
||||||
"themes": "السمات",
|
"themes": "السمات",
|
||||||
"thursday": "الخميس",
|
"thursday": "الخميس",
|
||||||
|
"title": "Title",
|
||||||
"token": "الرمز التعريفي",
|
"token": "الرمز التعريفي",
|
||||||
"tuesday": "الثلاثاء",
|
"tuesday": "الثلاثاء",
|
||||||
"type": "النوع",
|
"type": "النوع",
|
||||||
@@ -582,7 +584,22 @@
|
|||||||
"upload-image": "Upload image",
|
"upload-image": "Upload image",
|
||||||
"screen-awake": "Keep Screen Awake",
|
"screen-awake": "Keep Screen Awake",
|
||||||
"remove-image": "Remove image",
|
"remove-image": "Remove image",
|
||||||
"nextStep": "Next step"
|
"nextStep": "Next step",
|
||||||
|
"recipe-actions": "Recipe Actions",
|
||||||
|
"parser": {
|
||||||
|
"experimental-alert-text": "Mealie uses natural language processing to parse and create units and food items for your recipe ingredients. This feature is experimental and may not always work as expected. If you prefer not to use the parsed results, you can select 'Cancel' and your changes will not be saved.",
|
||||||
|
"ingredient-parser": "Ingredient Parser",
|
||||||
|
"explanation": "To use the ingredient parser, click the 'Parse All' button to start the process. Once the processed ingredients are available, you can review the items and verify that they were parsed correctly. The model's confidence score is displayed on the right of the item title. This score is an average of all the individual scores and may not always be completely accurate.",
|
||||||
|
"alerts-explainer": "Alerts will be displayed if a matching foods or unit is found but does not exists in the database.",
|
||||||
|
"select-parser": "Select Parser",
|
||||||
|
"natural-language-processor": "Natural Language Processor",
|
||||||
|
"brute-parser": "Brute Parser",
|
||||||
|
"parse-all": "Parse All",
|
||||||
|
"no-unit": "No unit",
|
||||||
|
"missing-unit": "Create missing unit: {unit}",
|
||||||
|
"missing-food": "Create missing food: {food}",
|
||||||
|
"no-food": "No Food"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"search": {
|
"search": {
|
||||||
"advanced-search": "Advanced Search",
|
"advanced-search": "Advanced Search",
|
||||||
@@ -1001,6 +1018,12 @@
|
|||||||
"delete-recipes": "Delete Recipes",
|
"delete-recipes": "Delete Recipes",
|
||||||
"source-unit-will-be-deleted": "Source Unit will be deleted"
|
"source-unit-will-be-deleted": "Source Unit will be deleted"
|
||||||
},
|
},
|
||||||
|
"recipe-actions": {
|
||||||
|
"recipe-actions-data": "Recipe Actions Data",
|
||||||
|
"new-recipe-action": "New Recipe Action",
|
||||||
|
"edit-recipe-action": "Edit Recipe Action",
|
||||||
|
"action-type": "Action Type"
|
||||||
|
},
|
||||||
"create-alias": "Create Alias",
|
"create-alias": "Create Alias",
|
||||||
"manage-aliases": "Manage Aliases",
|
"manage-aliases": "Manage Aliases",
|
||||||
"seed-data": "Seed Data",
|
"seed-data": "Seed Data",
|
||||||
|
|||||||
@@ -64,6 +64,7 @@
|
|||||||
"something-went-wrong": "Нещо се обърка!",
|
"something-went-wrong": "Нещо се обърка!",
|
||||||
"subscribed-events": "Планирани събития",
|
"subscribed-events": "Планирани събития",
|
||||||
"test-message-sent": "Тестово съобщение е изпратено",
|
"test-message-sent": "Тестово съобщение е изпратено",
|
||||||
|
"message-sent": "Message Sent",
|
||||||
"new-notification": "Ново известие",
|
"new-notification": "Ново известие",
|
||||||
"event-notifiers": "Известия за събитие",
|
"event-notifiers": "Известия за събитие",
|
||||||
"apprise-url-skipped-if-blank": "URL за известяване (пропуска се ако е празно)",
|
"apprise-url-skipped-if-blank": "URL за известяване (пропуска се ако е празно)",
|
||||||
@@ -160,6 +161,7 @@
|
|||||||
"test": "Тест",
|
"test": "Тест",
|
||||||
"themes": "Теми",
|
"themes": "Теми",
|
||||||
"thursday": "четвъртък",
|
"thursday": "четвъртък",
|
||||||
|
"title": "Title",
|
||||||
"token": "Токън",
|
"token": "Токън",
|
||||||
"tuesday": "Вторник",
|
"tuesday": "Вторник",
|
||||||
"type": "Тип",
|
"type": "Тип",
|
||||||
@@ -208,7 +210,7 @@
|
|||||||
"unsaved-changes": "Имате незапазени промени. Желаете ли да ги запазите преди да излезете? Натиснете Ок за запазване и Отказ за отхвърляне на промените.",
|
"unsaved-changes": "Имате незапазени промени. Желаете ли да ги запазите преди да излезете? Натиснете Ок за запазване и Отказ за отхвърляне на промените.",
|
||||||
"clipboard-copy-failure": "Линкът към рецептата е копиран в клипборда.",
|
"clipboard-copy-failure": "Линкът към рецептата е копиран в клипборда.",
|
||||||
"confirm-delete-generic-items": "Сигурни ли сте, че желаете да изтриете следните елементи?",
|
"confirm-delete-generic-items": "Сигурни ли сте, че желаете да изтриете следните елементи?",
|
||||||
"organizers": "Organizers"
|
"organizers": "Органайзер"
|
||||||
},
|
},
|
||||||
"group": {
|
"group": {
|
||||||
"are-you-sure-you-want-to-delete-the-group": "Сигурни ли сте, че искате да изтриете <b>{groupName}<b/>?",
|
"are-you-sure-you-want-to-delete-the-group": "Сигурни ли сте, че искате да изтриете <b>{groupName}<b/>?",
|
||||||
@@ -582,7 +584,22 @@
|
|||||||
"upload-image": "Качване на изображение",
|
"upload-image": "Качване на изображение",
|
||||||
"screen-awake": "Запази екрана активен",
|
"screen-awake": "Запази екрана активен",
|
||||||
"remove-image": "Премахване на изображение",
|
"remove-image": "Премахване на изображение",
|
||||||
"nextStep": "Следваща стъпка"
|
"nextStep": "Следваща стъпка",
|
||||||
|
"recipe-actions": "Recipe Actions",
|
||||||
|
"parser": {
|
||||||
|
"experimental-alert-text": "Mealie uses natural language processing to parse and create units and food items for your recipe ingredients. This feature is experimental and may not always work as expected. If you prefer not to use the parsed results, you can select 'Cancel' and your changes will not be saved.",
|
||||||
|
"ingredient-parser": "Ingredient Parser",
|
||||||
|
"explanation": "To use the ingredient parser, click the 'Parse All' button to start the process. Once the processed ingredients are available, you can review the items and verify that they were parsed correctly. The model's confidence score is displayed on the right of the item title. This score is an average of all the individual scores and may not always be completely accurate.",
|
||||||
|
"alerts-explainer": "Alerts will be displayed if a matching foods or unit is found but does not exists in the database.",
|
||||||
|
"select-parser": "Select Parser",
|
||||||
|
"natural-language-processor": "Natural Language Processor",
|
||||||
|
"brute-parser": "Brute Parser",
|
||||||
|
"parse-all": "Parse All",
|
||||||
|
"no-unit": "No unit",
|
||||||
|
"missing-unit": "Create missing unit: {unit}",
|
||||||
|
"missing-food": "Create missing food: {food}",
|
||||||
|
"no-food": "No Food"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"search": {
|
"search": {
|
||||||
"advanced-search": "Разширено търсене",
|
"advanced-search": "Разширено търсене",
|
||||||
@@ -1001,6 +1018,12 @@
|
|||||||
"delete-recipes": "Изтрий рецепти",
|
"delete-recipes": "Изтрий рецепти",
|
||||||
"source-unit-will-be-deleted": "Изходната мерна единица ще бъде изтрита"
|
"source-unit-will-be-deleted": "Изходната мерна единица ще бъде изтрита"
|
||||||
},
|
},
|
||||||
|
"recipe-actions": {
|
||||||
|
"recipe-actions-data": "Recipe Actions Data",
|
||||||
|
"new-recipe-action": "New Recipe Action",
|
||||||
|
"edit-recipe-action": "Edit Recipe Action",
|
||||||
|
"action-type": "Action Type"
|
||||||
|
},
|
||||||
"create-alias": "Създаване на псевдоним",
|
"create-alias": "Създаване на псевдоним",
|
||||||
"manage-aliases": "Управление на псевдоними",
|
"manage-aliases": "Управление на псевдоними",
|
||||||
"seed-data": "Зареждане на данни",
|
"seed-data": "Зареждане на данни",
|
||||||
@@ -1168,21 +1191,21 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"profile": {
|
"profile": {
|
||||||
"welcome-user": "👋 Welcome, {0}!",
|
"welcome-user": "👋 Добре дошъл(а), {0}!",
|
||||||
"description": "Настройки на профил, рецепти и настройки на групата.",
|
"description": "Настройки на профил, рецепти и настройки на групата.",
|
||||||
"get-invite-link": "Вземи линк за покана",
|
"get-invite-link": "Вземи линк за покана",
|
||||||
"get-public-link": "Вземи публичен линк",
|
"get-public-link": "Вземи публичен линк",
|
||||||
"account-summary": "Обобщение на акаунта",
|
"account-summary": "Обобщение на акаунта",
|
||||||
"account-summary-description": "Here's a summary of your group's information.",
|
"account-summary-description": "Обобщение на информацията за Вашата група.",
|
||||||
"group-statistics": "Статистики на групата",
|
"group-statistics": "Статистики на групата",
|
||||||
"group-statistics-description": "Вашата статистика на групата дава известна представа как използвате Mealie.",
|
"group-statistics-description": "Вашата статистика на групата дава известна представа как използвате Mealie.",
|
||||||
"storage-capacity": "Капацитет за съхранение",
|
"storage-capacity": "Капацитет за съхранение",
|
||||||
"storage-capacity-description": "Вашият капацитет за съхранение е изчисление на изображенията и активите, които сте качили.",
|
"storage-capacity-description": "Вашият капацитет за съхранение е изчисление на изображенията и активите, които сте качили.",
|
||||||
"personal": "Лични",
|
"personal": "Лични",
|
||||||
"personal-description": "These are settings that are personal to you. Changes here won't affect other users.",
|
"personal-description": "Това са настройки, които са лични за Вас. Промените тук няма да засегнат други потребители.",
|
||||||
"user-settings": "Потребителски настройки",
|
"user-settings": "Потребителски настройки",
|
||||||
"user-settings-description": "Manage your preferences, change your password, and update your email.",
|
"user-settings-description": "Нстройки на предпочитанията, смяна на парола и актуализация на имей адрес.",
|
||||||
"api-tokens-description": "Manage your API Tokens for access from external applications.",
|
"api-tokens-description": "Управление на API токени за достъп от външни приложения.",
|
||||||
"group-description": "Тези елементи се споделят във вашата група. Редактирането на един от тях ще го промени за цялата група!",
|
"group-description": "Тези елементи се споделят във вашата група. Редактирането на един от тях ще го промени за цялата група!",
|
||||||
"group-settings": "Настройки на групата",
|
"group-settings": "Настройки на групата",
|
||||||
"group-settings-description": "Общи групови настройки като седмично меню и настройки за поверителност.",
|
"group-settings-description": "Общи групови настройки като седмично меню и настройки за поверителност.",
|
||||||
@@ -1193,9 +1216,9 @@
|
|||||||
"notifiers": "Уведомители",
|
"notifiers": "Уведомители",
|
||||||
"notifiers-description": "Настройте имейл и push известия, които се задействат при конкретни събития.",
|
"notifiers-description": "Настройте имейл и push известия, които се задействат при конкретни събития.",
|
||||||
"manage-data": "Управление на данни",
|
"manage-data": "Управление на данни",
|
||||||
"manage-data-description": "Manage your Mealie data; Foods, Units, Categories, Tags and more.",
|
"manage-data-description": "Управлявай данните в Mealie: Храни, Единици, Категории, Тагове и други.",
|
||||||
"data-migrations": "Миграция на данни",
|
"data-migrations": "Миграция на данни",
|
||||||
"data-migrations-description": "Migrate your existing data from other applications like Nextcloud Recipes and Chowdown.",
|
"data-migrations-description": "Мигрирайте вашите съществуващи данни от други приложения като Nextcloud Recipes и Chowdown.",
|
||||||
"email-sent": "Имейлът е изпратен",
|
"email-sent": "Имейлът е изпратен",
|
||||||
"error-sending-email": "Грешка при изпращане на имейл",
|
"error-sending-email": "Грешка при изпращане на имейл",
|
||||||
"personal-information": "Лична информация",
|
"personal-information": "Лична информация",
|
||||||
|
|||||||
@@ -64,6 +64,7 @@
|
|||||||
"something-went-wrong": "Alguna cosa ha anat malament!",
|
"something-went-wrong": "Alguna cosa ha anat malament!",
|
||||||
"subscribed-events": "Esdeveniments subscrits",
|
"subscribed-events": "Esdeveniments subscrits",
|
||||||
"test-message-sent": "S'ha enviat el missatge",
|
"test-message-sent": "S'ha enviat el missatge",
|
||||||
|
"message-sent": "Message Sent",
|
||||||
"new-notification": "Nova notificació",
|
"new-notification": "Nova notificació",
|
||||||
"event-notifiers": "Notificacions d'esdeveniments",
|
"event-notifiers": "Notificacions d'esdeveniments",
|
||||||
"apprise-url-skipped-if-blank": "Apprise URL (si es deixa buit, s'ignorarà)",
|
"apprise-url-skipped-if-blank": "Apprise URL (si es deixa buit, s'ignorarà)",
|
||||||
@@ -160,6 +161,7 @@
|
|||||||
"test": "Prova",
|
"test": "Prova",
|
||||||
"themes": "Temes",
|
"themes": "Temes",
|
||||||
"thursday": "Dijous",
|
"thursday": "Dijous",
|
||||||
|
"title": "Title",
|
||||||
"token": "Token",
|
"token": "Token",
|
||||||
"tuesday": "Dimarts",
|
"tuesday": "Dimarts",
|
||||||
"type": "Tipus",
|
"type": "Tipus",
|
||||||
@@ -582,7 +584,22 @@
|
|||||||
"upload-image": "Puja una imatge",
|
"upload-image": "Puja una imatge",
|
||||||
"screen-awake": "Mantenir la pantalla encesa",
|
"screen-awake": "Mantenir la pantalla encesa",
|
||||||
"remove-image": "Esborrar la imatge",
|
"remove-image": "Esborrar la imatge",
|
||||||
"nextStep": "Next step"
|
"nextStep": "Next step",
|
||||||
|
"recipe-actions": "Recipe Actions",
|
||||||
|
"parser": {
|
||||||
|
"experimental-alert-text": "Mealie uses natural language processing to parse and create units and food items for your recipe ingredients. This feature is experimental and may not always work as expected. If you prefer not to use the parsed results, you can select 'Cancel' and your changes will not be saved.",
|
||||||
|
"ingredient-parser": "Ingredient Parser",
|
||||||
|
"explanation": "To use the ingredient parser, click the 'Parse All' button to start the process. Once the processed ingredients are available, you can review the items and verify that they were parsed correctly. The model's confidence score is displayed on the right of the item title. This score is an average of all the individual scores and may not always be completely accurate.",
|
||||||
|
"alerts-explainer": "Alerts will be displayed if a matching foods or unit is found but does not exists in the database.",
|
||||||
|
"select-parser": "Select Parser",
|
||||||
|
"natural-language-processor": "Natural Language Processor",
|
||||||
|
"brute-parser": "Brute Parser",
|
||||||
|
"parse-all": "Parse All",
|
||||||
|
"no-unit": "No unit",
|
||||||
|
"missing-unit": "Create missing unit: {unit}",
|
||||||
|
"missing-food": "Create missing food: {food}",
|
||||||
|
"no-food": "No Food"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"search": {
|
"search": {
|
||||||
"advanced-search": "Cerca avançada",
|
"advanced-search": "Cerca avançada",
|
||||||
@@ -1001,6 +1018,12 @@
|
|||||||
"delete-recipes": "Delete Recipes",
|
"delete-recipes": "Delete Recipes",
|
||||||
"source-unit-will-be-deleted": "Source Unit will be deleted"
|
"source-unit-will-be-deleted": "Source Unit will be deleted"
|
||||||
},
|
},
|
||||||
|
"recipe-actions": {
|
||||||
|
"recipe-actions-data": "Recipe Actions Data",
|
||||||
|
"new-recipe-action": "New Recipe Action",
|
||||||
|
"edit-recipe-action": "Edit Recipe Action",
|
||||||
|
"action-type": "Action Type"
|
||||||
|
},
|
||||||
"create-alias": "Create Alias",
|
"create-alias": "Create Alias",
|
||||||
"manage-aliases": "Manage Aliases",
|
"manage-aliases": "Manage Aliases",
|
||||||
"seed-data": "Dades d'exemple",
|
"seed-data": "Dades d'exemple",
|
||||||
|
|||||||
@@ -64,6 +64,7 @@
|
|||||||
"something-went-wrong": "Něco se nepovedlo!",
|
"something-went-wrong": "Něco se nepovedlo!",
|
||||||
"subscribed-events": "Odebírané události",
|
"subscribed-events": "Odebírané události",
|
||||||
"test-message-sent": "Testovací zpráva odeslána",
|
"test-message-sent": "Testovací zpráva odeslána",
|
||||||
|
"message-sent": "Message Sent",
|
||||||
"new-notification": "Nové oznámení",
|
"new-notification": "Nové oznámení",
|
||||||
"event-notifiers": "Notifikace událostí",
|
"event-notifiers": "Notifikace událostí",
|
||||||
"apprise-url-skipped-if-blank": "Apprise URL (přeskočeno pokud je prázdné)",
|
"apprise-url-skipped-if-blank": "Apprise URL (přeskočeno pokud je prázdné)",
|
||||||
@@ -160,6 +161,7 @@
|
|||||||
"test": "Test",
|
"test": "Test",
|
||||||
"themes": "Motivy",
|
"themes": "Motivy",
|
||||||
"thursday": "Čtvrtek",
|
"thursday": "Čtvrtek",
|
||||||
|
"title": "Title",
|
||||||
"token": "Token",
|
"token": "Token",
|
||||||
"tuesday": "Úterý",
|
"tuesday": "Úterý",
|
||||||
"type": "Typ",
|
"type": "Typ",
|
||||||
@@ -582,7 +584,22 @@
|
|||||||
"upload-image": "Nahrát obrázek",
|
"upload-image": "Nahrát obrázek",
|
||||||
"screen-awake": "Keep Screen Awake",
|
"screen-awake": "Keep Screen Awake",
|
||||||
"remove-image": "Remove image",
|
"remove-image": "Remove image",
|
||||||
"nextStep": "Další krok"
|
"nextStep": "Další krok",
|
||||||
|
"recipe-actions": "Recipe Actions",
|
||||||
|
"parser": {
|
||||||
|
"experimental-alert-text": "Mealie uses natural language processing to parse and create units and food items for your recipe ingredients. This feature is experimental and may not always work as expected. If you prefer not to use the parsed results, you can select 'Cancel' and your changes will not be saved.",
|
||||||
|
"ingredient-parser": "Ingredient Parser",
|
||||||
|
"explanation": "To use the ingredient parser, click the 'Parse All' button to start the process. Once the processed ingredients are available, you can review the items and verify that they were parsed correctly. The model's confidence score is displayed on the right of the item title. This score is an average of all the individual scores and may not always be completely accurate.",
|
||||||
|
"alerts-explainer": "Alerts will be displayed if a matching foods or unit is found but does not exists in the database.",
|
||||||
|
"select-parser": "Select Parser",
|
||||||
|
"natural-language-processor": "Natural Language Processor",
|
||||||
|
"brute-parser": "Brute Parser",
|
||||||
|
"parse-all": "Parse All",
|
||||||
|
"no-unit": "No unit",
|
||||||
|
"missing-unit": "Create missing unit: {unit}",
|
||||||
|
"missing-food": "Create missing food: {food}",
|
||||||
|
"no-food": "No Food"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"search": {
|
"search": {
|
||||||
"advanced-search": "Pokročilé vyhledávání",
|
"advanced-search": "Pokročilé vyhledávání",
|
||||||
@@ -1001,6 +1018,12 @@
|
|||||||
"delete-recipes": "Smazat recepty",
|
"delete-recipes": "Smazat recepty",
|
||||||
"source-unit-will-be-deleted": "Source Unit will be deleted"
|
"source-unit-will-be-deleted": "Source Unit will be deleted"
|
||||||
},
|
},
|
||||||
|
"recipe-actions": {
|
||||||
|
"recipe-actions-data": "Recipe Actions Data",
|
||||||
|
"new-recipe-action": "New Recipe Action",
|
||||||
|
"edit-recipe-action": "Edit Recipe Action",
|
||||||
|
"action-type": "Action Type"
|
||||||
|
},
|
||||||
"create-alias": "Create Alias",
|
"create-alias": "Create Alias",
|
||||||
"manage-aliases": "Manage Aliases",
|
"manage-aliases": "Manage Aliases",
|
||||||
"seed-data": "Seed Data",
|
"seed-data": "Seed Data",
|
||||||
|
|||||||
@@ -64,6 +64,7 @@
|
|||||||
"something-went-wrong": "Noget gik galt!",
|
"something-went-wrong": "Noget gik galt!",
|
||||||
"subscribed-events": "Abonnerede begivenheder",
|
"subscribed-events": "Abonnerede begivenheder",
|
||||||
"test-message-sent": "Testbesked sendt",
|
"test-message-sent": "Testbesked sendt",
|
||||||
|
"message-sent": "Message Sent",
|
||||||
"new-notification": "Ny notifikation",
|
"new-notification": "Ny notifikation",
|
||||||
"event-notifiers": "Notifikation om begivenheder",
|
"event-notifiers": "Notifikation om begivenheder",
|
||||||
"apprise-url-skipped-if-blank": "Informations link (sprunget over hvis ladet være tomt)",
|
"apprise-url-skipped-if-blank": "Informations link (sprunget over hvis ladet være tomt)",
|
||||||
@@ -160,6 +161,7 @@
|
|||||||
"test": "Afprøv",
|
"test": "Afprøv",
|
||||||
"themes": "Temaer",
|
"themes": "Temaer",
|
||||||
"thursday": "Torsdag",
|
"thursday": "Torsdag",
|
||||||
|
"title": "Title",
|
||||||
"token": "Token",
|
"token": "Token",
|
||||||
"tuesday": "Tirsdag",
|
"tuesday": "Tirsdag",
|
||||||
"type": "Type",
|
"type": "Type",
|
||||||
@@ -582,7 +584,22 @@
|
|||||||
"upload-image": "Upload billede",
|
"upload-image": "Upload billede",
|
||||||
"screen-awake": "Hold skærmen tændt",
|
"screen-awake": "Hold skærmen tændt",
|
||||||
"remove-image": "Fjern billede",
|
"remove-image": "Fjern billede",
|
||||||
"nextStep": "Næste trin"
|
"nextStep": "Næste trin",
|
||||||
|
"recipe-actions": "Recipe Actions",
|
||||||
|
"parser": {
|
||||||
|
"experimental-alert-text": "Mealie uses natural language processing to parse and create units and food items for your recipe ingredients. This feature is experimental and may not always work as expected. If you prefer not to use the parsed results, you can select 'Cancel' and your changes will not be saved.",
|
||||||
|
"ingredient-parser": "Ingredient Parser",
|
||||||
|
"explanation": "To use the ingredient parser, click the 'Parse All' button to start the process. Once the processed ingredients are available, you can review the items and verify that they were parsed correctly. The model's confidence score is displayed on the right of the item title. This score is an average of all the individual scores and may not always be completely accurate.",
|
||||||
|
"alerts-explainer": "Alerts will be displayed if a matching foods or unit is found but does not exists in the database.",
|
||||||
|
"select-parser": "Select Parser",
|
||||||
|
"natural-language-processor": "Natural Language Processor",
|
||||||
|
"brute-parser": "Brute Parser",
|
||||||
|
"parse-all": "Parse All",
|
||||||
|
"no-unit": "No unit",
|
||||||
|
"missing-unit": "Create missing unit: {unit}",
|
||||||
|
"missing-food": "Create missing food: {food}",
|
||||||
|
"no-food": "No Food"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"search": {
|
"search": {
|
||||||
"advanced-search": "Avanceret søgning",
|
"advanced-search": "Avanceret søgning",
|
||||||
@@ -1001,6 +1018,12 @@
|
|||||||
"delete-recipes": "Slet Opskrifter",
|
"delete-recipes": "Slet Opskrifter",
|
||||||
"source-unit-will-be-deleted": "Kildeenhed vil blive slettet"
|
"source-unit-will-be-deleted": "Kildeenhed vil blive slettet"
|
||||||
},
|
},
|
||||||
|
"recipe-actions": {
|
||||||
|
"recipe-actions-data": "Recipe Actions Data",
|
||||||
|
"new-recipe-action": "New Recipe Action",
|
||||||
|
"edit-recipe-action": "Edit Recipe Action",
|
||||||
|
"action-type": "Action Type"
|
||||||
|
},
|
||||||
"create-alias": "Opret alias",
|
"create-alias": "Opret alias",
|
||||||
"manage-aliases": "Administrer Aliaser",
|
"manage-aliases": "Administrer Aliaser",
|
||||||
"seed-data": "Opret standard data",
|
"seed-data": "Opret standard data",
|
||||||
|
|||||||
@@ -64,6 +64,7 @@
|
|||||||
"something-went-wrong": "Etwas ist schief gelaufen!",
|
"something-went-wrong": "Etwas ist schief gelaufen!",
|
||||||
"subscribed-events": "Abonnierte Ereignisse",
|
"subscribed-events": "Abonnierte Ereignisse",
|
||||||
"test-message-sent": "Testnachricht gesendet",
|
"test-message-sent": "Testnachricht gesendet",
|
||||||
|
"message-sent": "Daten gesendet",
|
||||||
"new-notification": "Neue Benachrichtigung",
|
"new-notification": "Neue Benachrichtigung",
|
||||||
"event-notifiers": "Ereignis-Benachrichtigungen",
|
"event-notifiers": "Ereignis-Benachrichtigungen",
|
||||||
"apprise-url-skipped-if-blank": "Apprise-URL (wird übersprungen, wenn leer)",
|
"apprise-url-skipped-if-blank": "Apprise-URL (wird übersprungen, wenn leer)",
|
||||||
@@ -160,6 +161,7 @@
|
|||||||
"test": "Testen",
|
"test": "Testen",
|
||||||
"themes": "Themen",
|
"themes": "Themen",
|
||||||
"thursday": "Donnerstag",
|
"thursday": "Donnerstag",
|
||||||
|
"title": "Titel",
|
||||||
"token": "Token",
|
"token": "Token",
|
||||||
"tuesday": "Dienstag",
|
"tuesday": "Dienstag",
|
||||||
"type": "Typ",
|
"type": "Typ",
|
||||||
@@ -185,7 +187,7 @@
|
|||||||
"menu": "Menü",
|
"menu": "Menü",
|
||||||
"a-name-is-required": "Ein Name wird benötigt",
|
"a-name-is-required": "Ein Name wird benötigt",
|
||||||
"delete-with-name": "{name} löschen",
|
"delete-with-name": "{name} löschen",
|
||||||
"confirm-delete-generic-with-name": "Bist du dir sicher, dass du \"{name}\" löschen möchtest?",
|
"confirm-delete-generic-with-name": "Bist du dir sicher, dass du dies löschen möchtest?",
|
||||||
"confirm-delete-own-admin-account": "Bitte beachte, dass du versuchst, dein eigenes Administrator-Konto zu löschen! Diese Aktion kann nicht rückgängig gemacht werden und wird dein Konto dauerhaft löschen!",
|
"confirm-delete-own-admin-account": "Bitte beachte, dass du versuchst, dein eigenes Administrator-Konto zu löschen! Diese Aktion kann nicht rückgängig gemacht werden und wird dein Konto dauerhaft löschen!",
|
||||||
"organizer": "Organisator",
|
"organizer": "Organisator",
|
||||||
"transfer": "Übertragen",
|
"transfer": "Übertragen",
|
||||||
@@ -535,7 +537,7 @@
|
|||||||
"last-made-date": "Zuletzt gemacht {date}",
|
"last-made-date": "Zuletzt gemacht {date}",
|
||||||
"api-extras-description": "Rezepte-Extras sind ein Hauptmerkmal der Mealie API. Sie ermöglichen es dir, benutzerdefinierte JSON Key-Value-Paare zu einem Rezept zu erstellen, um Drittanbieter-Anwendungen zu steuern. Du kannst diese dazu verwenden, um Automatisierungen auszulösen oder benutzerdefinierte Nachrichten an bestimmte Geräte zu senden.",
|
"api-extras-description": "Rezepte-Extras sind ein Hauptmerkmal der Mealie API. Sie ermöglichen es dir, benutzerdefinierte JSON Key-Value-Paare zu einem Rezept zu erstellen, um Drittanbieter-Anwendungen zu steuern. Du kannst diese dazu verwenden, um Automatisierungen auszulösen oder benutzerdefinierte Nachrichten an bestimmte Geräte zu senden.",
|
||||||
"message-key": "Nachrichten-Schlüssel",
|
"message-key": "Nachrichten-Schlüssel",
|
||||||
"parse": "Parse",
|
"parse": "Parsen",
|
||||||
"attach-images-hint": "Bilder durch Ziehen & Ablegen in den Editor hinzufügen",
|
"attach-images-hint": "Bilder durch Ziehen & Ablegen in den Editor hinzufügen",
|
||||||
"drop-image": "Bild hier ablegen",
|
"drop-image": "Bild hier ablegen",
|
||||||
"enable-ingredient-amounts-to-use-this-feature": "Aktiviere Zutatenmengen, um diese Funktion zu nutzen",
|
"enable-ingredient-amounts-to-use-this-feature": "Aktiviere Zutatenmengen, um diese Funktion zu nutzen",
|
||||||
@@ -582,7 +584,22 @@
|
|||||||
"upload-image": "Bild hochladen",
|
"upload-image": "Bild hochladen",
|
||||||
"screen-awake": "Bildschirm nicht abschalten",
|
"screen-awake": "Bildschirm nicht abschalten",
|
||||||
"remove-image": "Bild entfernen",
|
"remove-image": "Bild entfernen",
|
||||||
"nextStep": "Nächster Schritt"
|
"nextStep": "Nächster Schritt",
|
||||||
|
"recipe-actions": "Rezept-Aktionen",
|
||||||
|
"parser": {
|
||||||
|
"experimental-alert-text": "Mealie verwendet natürliche Sprachverarbeitung (NLP), um Einheiten und Lebensmittel für deine Zutatenliste zu parsen. Diese Funktion ist experimentell und funktioniert möglicherweise nicht immer wie sie sollte. Wenn du die Parser-Ergebnisse nicht verwenden möchtest, wähle 'Abbrechen' und deine Änderungen werden nicht gespeichert.",
|
||||||
|
"ingredient-parser": "Zutaten-Parser",
|
||||||
|
"explanation": "Um den Zutaten-Parser zu verwenden, klicke auf den Button 'Alles parsen', um den Vorgang zu starten. Nachdem die Zutaten analysiert worden sind, kannst du überprüfen, ob die Einträge korrekt erkannt wurden. Der vom Modell errechnete Zuverlässigkeitswert wird rechts neben der Zutat angezeigt. Diese Angabe ist ein Durchschnitt der Einzelwerte und möglicherweise nicht immer ganz korrekt.",
|
||||||
|
"alerts-explainer": "Es werden Warnungen angezeigt, wenn ein passendes Lebensmittel oder eine Einheit gefunden wurde, aber in der Datenbank nicht vorhanden ist.",
|
||||||
|
"select-parser": "Parser auswählen",
|
||||||
|
"natural-language-processor": "Natürliche Sprachverarbeitung (NLP)",
|
||||||
|
"brute-parser": "Brute Parser",
|
||||||
|
"parse-all": "Alles parsen",
|
||||||
|
"no-unit": "Keine Einheit",
|
||||||
|
"missing-unit": "Fehlende Einheit erstellen: {unit}",
|
||||||
|
"missing-food": "Fehlendes Lebensmittel erstellen: {food}",
|
||||||
|
"no-food": "Kein Lebensmittel"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"search": {
|
"search": {
|
||||||
"advanced-search": "Erweiterte Suche",
|
"advanced-search": "Erweiterte Suche",
|
||||||
@@ -1001,6 +1018,12 @@
|
|||||||
"delete-recipes": "Rezepte löschen",
|
"delete-recipes": "Rezepte löschen",
|
||||||
"source-unit-will-be-deleted": "Quell-Einheit wird gelöscht"
|
"source-unit-will-be-deleted": "Quell-Einheit wird gelöscht"
|
||||||
},
|
},
|
||||||
|
"recipe-actions": {
|
||||||
|
"recipe-actions-data": "Rezept-Aktionen Daten",
|
||||||
|
"new-recipe-action": "Neue Rezept-Aktion",
|
||||||
|
"edit-recipe-action": "Rezept-Aktion bearbeiten",
|
||||||
|
"action-type": "Aktionstyp"
|
||||||
|
},
|
||||||
"create-alias": "Alias erstellen",
|
"create-alias": "Alias erstellen",
|
||||||
"manage-aliases": "Aliasse verwalten",
|
"manage-aliases": "Aliasse verwalten",
|
||||||
"seed-data": "Musterdaten",
|
"seed-data": "Musterdaten",
|
||||||
@@ -1119,10 +1142,10 @@
|
|||||||
"info-description-cleanable-images": "Löschbare Bilder",
|
"info-description-cleanable-images": "Löschbare Bilder",
|
||||||
"storage": {
|
"storage": {
|
||||||
"title-temporary-directory": "Temporäres Verzeichnis (.temp)",
|
"title-temporary-directory": "Temporäres Verzeichnis (.temp)",
|
||||||
"title-backups-directory": "Sicherungsverzeichnis (backups)",
|
"title-backups-directory": "Sicherungen-Verzeichnis (backups)",
|
||||||
"title-groups-directory": "Gruppen-Verzeichnis (groups)",
|
"title-groups-directory": "Gruppen-Verzeichnis (groups)",
|
||||||
"title-recipes-directory": "Rezept-Verzeichnis (recipes)",
|
"title-recipes-directory": "Rezept-Verzeichnis (recipes)",
|
||||||
"title-user-directory": "Benutzerverzeichnis (user)"
|
"title-user-directory": "Benutzer-Verzeichnis (user)"
|
||||||
},
|
},
|
||||||
"action-delete-log-files-name": "Logs löschen",
|
"action-delete-log-files-name": "Logs löschen",
|
||||||
"action-delete-log-files-description": "Löscht alle Logdateien",
|
"action-delete-log-files-description": "Löscht alle Logdateien",
|
||||||
@@ -1147,9 +1170,9 @@
|
|||||||
"ingredients-natural-language-processor-explanation-2": "Es ist nicht perfekt, aber es erzeugt meist sehr gute Ergebnisse und ist ein guter Anfang, um Zutaten manuell den einzelnen Feldern zuzuordnen. Alternativ kannst du auch den \"Brute\" Prozessor benutzen, der eine Musterabgleich-Technik verwendet, um Zutaten zu identifizieren.",
|
"ingredients-natural-language-processor-explanation-2": "Es ist nicht perfekt, aber es erzeugt meist sehr gute Ergebnisse und ist ein guter Anfang, um Zutaten manuell den einzelnen Feldern zuzuordnen. Alternativ kannst du auch den \"Brute\" Prozessor benutzen, der eine Musterabgleich-Technik verwendet, um Zutaten zu identifizieren.",
|
||||||
"nlp": "NLP",
|
"nlp": "NLP",
|
||||||
"brute": "Brute",
|
"brute": "Brute",
|
||||||
"show-individual-confidence": "Zeige individuelle Überzeugungswerte an",
|
"show-individual-confidence": "Zeige individuelle Zuverlässigkeitswerte an",
|
||||||
"ingredient-text": "Zutaten-Angabe",
|
"ingredient-text": "Zutaten-Angabe",
|
||||||
"average-confident": "{0} überzeugt",
|
"average-confident": "{0} zuverlässig",
|
||||||
"try-an-example": "Probier ein Beispiel aus",
|
"try-an-example": "Probier ein Beispiel aus",
|
||||||
"parser": "Parser",
|
"parser": "Parser",
|
||||||
"background-tasks": "Hintergrundaufgaben",
|
"background-tasks": "Hintergrundaufgaben",
|
||||||
|
|||||||
@@ -64,6 +64,7 @@
|
|||||||
"something-went-wrong": "Κάτι δεν πήγε καλά!",
|
"something-went-wrong": "Κάτι δεν πήγε καλά!",
|
||||||
"subscribed-events": "Εγγεγραμμένα Γεγονότα",
|
"subscribed-events": "Εγγεγραμμένα Γεγονότα",
|
||||||
"test-message-sent": "Το δοκιμαστικό μήνυμα εστάλη",
|
"test-message-sent": "Το δοκιμαστικό μήνυμα εστάλη",
|
||||||
|
"message-sent": "Το μήνυμα εστάλη",
|
||||||
"new-notification": "Νέα ειδοποίηση",
|
"new-notification": "Νέα ειδοποίηση",
|
||||||
"event-notifiers": "Ειδοποιητές Συμβάντος",
|
"event-notifiers": "Ειδοποιητές Συμβάντος",
|
||||||
"apprise-url-skipped-if-blank": "Apprise URL (skipped if blank)",
|
"apprise-url-skipped-if-blank": "Apprise URL (skipped if blank)",
|
||||||
@@ -160,6 +161,7 @@
|
|||||||
"test": "Δοκιμή",
|
"test": "Δοκιμή",
|
||||||
"themes": "Θέματα",
|
"themes": "Θέματα",
|
||||||
"thursday": "Τρίτη",
|
"thursday": "Τρίτη",
|
||||||
|
"title": "Τίτλος",
|
||||||
"token": "Token",
|
"token": "Token",
|
||||||
"tuesday": "Τρίτη",
|
"tuesday": "Τρίτη",
|
||||||
"type": "Τύπος",
|
"type": "Τύπος",
|
||||||
@@ -582,7 +584,22 @@
|
|||||||
"upload-image": "Upload image",
|
"upload-image": "Upload image",
|
||||||
"screen-awake": "Keep Screen Awake",
|
"screen-awake": "Keep Screen Awake",
|
||||||
"remove-image": "Remove image",
|
"remove-image": "Remove image",
|
||||||
"nextStep": "Next step"
|
"nextStep": "Next step",
|
||||||
|
"recipe-actions": "Ενέργειες Συνταγής",
|
||||||
|
"parser": {
|
||||||
|
"experimental-alert-text": "Το Mealie χρησιμοποιεί επεξεργασία φυσικής γλώσσας για να αναλύσει και να δημιουργήσει μονάδες και είδη διατροφής για τα συστατικά της συνταγής σας. Αυτή η λειτουργία είναι πειραματική και μπορεί να μην λειτουργεί πάντα όπως πρέπει. Αν προτιμάτε να μην χρησιμοποιείτε τα αναλυμένα αποτελέσματα, μπορείτε να επιλέξετε 'Ακύρωση' και οι αλλαγές σας δεν θα αποθηκευτούν.",
|
||||||
|
"ingredient-parser": "Αναλυτής Συστατικών",
|
||||||
|
"explanation": "Για να χρησιμοποιήσετε τον αναλυτή συστατικών, κάντε κλικ στο πλήκτρο 'Ανάλυση Ολων' για να ξεκινήσετε τη διαδικασία. Μόλις τα αναλυμένα συστατικά είναι διαθέσιμα, μπορείτε να τα επανεξετάσετε και να βεβαιωθείτε ότι έχουν αναλυθεί σωστά. Η βαθμολογία εμπιστοσύνης του μοντέλου εμφανίζεται στα δεξιά του τίτλου αντικειμένου. Αυτό το σκορ είναι ένας μέσος όρος όλων των επιμέρους βαθμολογιών και μπορεί να μην είναι πάντα εντελώς ακριβής.",
|
||||||
|
"alerts-explainer": "Θα εμφανίζονται ειδοποιήσεις αν βρεθεί ένα αντίστοιχο φαγητό ή μονάδα αλλά δεν υπάρχει στη βάση δεδομένων.",
|
||||||
|
"select-parser": "Επιλέξτε Αναλυτή",
|
||||||
|
"natural-language-processor": "Επεξεργαστής Φυσικής Γλώσσας",
|
||||||
|
"brute-parser": "Αναλυτής Ωμής Βίας",
|
||||||
|
"parse-all": "Ανάλυση Ολων",
|
||||||
|
"no-unit": "Καμία μονάδα",
|
||||||
|
"missing-unit": "Δημιουργία μονάδας που λείπει: {unit}",
|
||||||
|
"missing-food": "Δημιουργία φαγητού που λείπει: {food}",
|
||||||
|
"no-food": "Χωρίς Φαγητό"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"search": {
|
"search": {
|
||||||
"advanced-search": "Σύνθετη Αναζήτηση",
|
"advanced-search": "Σύνθετη Αναζήτηση",
|
||||||
@@ -1001,6 +1018,12 @@
|
|||||||
"delete-recipes": "Delete Recipes",
|
"delete-recipes": "Delete Recipes",
|
||||||
"source-unit-will-be-deleted": "Source Unit will be deleted"
|
"source-unit-will-be-deleted": "Source Unit will be deleted"
|
||||||
},
|
},
|
||||||
|
"recipe-actions": {
|
||||||
|
"recipe-actions-data": "Δεδομένα Ενεργειών Συνταγής",
|
||||||
|
"new-recipe-action": "Νέα Ενέργεια Συνταγής",
|
||||||
|
"edit-recipe-action": "Επεξεργασία Ενέργειας Συνταγής",
|
||||||
|
"action-type": "Τύπος Ενέργειας"
|
||||||
|
},
|
||||||
"create-alias": "Create Alias",
|
"create-alias": "Create Alias",
|
||||||
"manage-aliases": "Manage Aliases",
|
"manage-aliases": "Manage Aliases",
|
||||||
"seed-data": "Seed Data",
|
"seed-data": "Seed Data",
|
||||||
|
|||||||
@@ -64,6 +64,7 @@
|
|||||||
"something-went-wrong": "Something Went Wrong!",
|
"something-went-wrong": "Something Went Wrong!",
|
||||||
"subscribed-events": "Subscribed Events",
|
"subscribed-events": "Subscribed Events",
|
||||||
"test-message-sent": "Test Message Sent",
|
"test-message-sent": "Test Message Sent",
|
||||||
|
"message-sent": "Message Sent",
|
||||||
"new-notification": "New Notification",
|
"new-notification": "New Notification",
|
||||||
"event-notifiers": "Event Notifiers",
|
"event-notifiers": "Event Notifiers",
|
||||||
"apprise-url-skipped-if-blank": "Apprise URL (skipped if blank)",
|
"apprise-url-skipped-if-blank": "Apprise URL (skipped if blank)",
|
||||||
@@ -160,6 +161,7 @@
|
|||||||
"test": "Test",
|
"test": "Test",
|
||||||
"themes": "Themes",
|
"themes": "Themes",
|
||||||
"thursday": "Thursday",
|
"thursday": "Thursday",
|
||||||
|
"title": "Title",
|
||||||
"token": "Token",
|
"token": "Token",
|
||||||
"tuesday": "Tuesday",
|
"tuesday": "Tuesday",
|
||||||
"type": "Type",
|
"type": "Type",
|
||||||
@@ -582,7 +584,22 @@
|
|||||||
"upload-image": "Upload image",
|
"upload-image": "Upload image",
|
||||||
"screen-awake": "Keep Screen Awake",
|
"screen-awake": "Keep Screen Awake",
|
||||||
"remove-image": "Remove image",
|
"remove-image": "Remove image",
|
||||||
"nextStep": "Next step"
|
"nextStep": "Next step",
|
||||||
|
"recipe-actions": "Recipe Actions",
|
||||||
|
"parser": {
|
||||||
|
"experimental-alert-text": "Mealie uses natural language processing to parse and create units and food items for your recipe ingredients. This feature is experimental and may not always work as expected. If you prefer not to use the parsed results, you can select 'Cancel' and your changes will not be saved.",
|
||||||
|
"ingredient-parser": "Ingredient Parser",
|
||||||
|
"explanation": "To use the ingredient parser, click the 'Parse All' button to start the process. Once the processed ingredients are available, you can review the items and verify that they were parsed correctly. The model's confidence score is displayed on the right of the item title. This score is an average of all the individual scores and may not always be completely accurate.",
|
||||||
|
"alerts-explainer": "Alerts will be displayed if a matching foods or unit is found but does not exists in the database.",
|
||||||
|
"select-parser": "Select Parser",
|
||||||
|
"natural-language-processor": "Natural Language Processor",
|
||||||
|
"brute-parser": "Brute Parser",
|
||||||
|
"parse-all": "Parse All",
|
||||||
|
"no-unit": "No unit",
|
||||||
|
"missing-unit": "Create missing unit: {unit}",
|
||||||
|
"missing-food": "Create missing food: {food}",
|
||||||
|
"no-food": "No Food"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"search": {
|
"search": {
|
||||||
"advanced-search": "Advanced Search",
|
"advanced-search": "Advanced Search",
|
||||||
@@ -1001,6 +1018,12 @@
|
|||||||
"delete-recipes": "Delete Recipes",
|
"delete-recipes": "Delete Recipes",
|
||||||
"source-unit-will-be-deleted": "Source Unit will be deleted"
|
"source-unit-will-be-deleted": "Source Unit will be deleted"
|
||||||
},
|
},
|
||||||
|
"recipe-actions": {
|
||||||
|
"recipe-actions-data": "Recipe Actions Data",
|
||||||
|
"new-recipe-action": "New Recipe Action",
|
||||||
|
"edit-recipe-action": "Edit Recipe Action",
|
||||||
|
"action-type": "Action Type"
|
||||||
|
},
|
||||||
"create-alias": "Create Alias",
|
"create-alias": "Create Alias",
|
||||||
"manage-aliases": "Manage Aliases",
|
"manage-aliases": "Manage Aliases",
|
||||||
"seed-data": "Seed Data",
|
"seed-data": "Seed Data",
|
||||||
|
|||||||
@@ -64,6 +64,7 @@
|
|||||||
"something-went-wrong": "Something Went Wrong!",
|
"something-went-wrong": "Something Went Wrong!",
|
||||||
"subscribed-events": "Subscribed Events",
|
"subscribed-events": "Subscribed Events",
|
||||||
"test-message-sent": "Test Message Sent",
|
"test-message-sent": "Test Message Sent",
|
||||||
|
"message-sent": "Message Sent",
|
||||||
"new-notification": "New Notification",
|
"new-notification": "New Notification",
|
||||||
"event-notifiers": "Event Notifiers",
|
"event-notifiers": "Event Notifiers",
|
||||||
"apprise-url-skipped-if-blank": "Apprise URL (skipped if blank)",
|
"apprise-url-skipped-if-blank": "Apprise URL (skipped if blank)",
|
||||||
@@ -160,6 +161,7 @@
|
|||||||
"test": "Test",
|
"test": "Test",
|
||||||
"themes": "Themes",
|
"themes": "Themes",
|
||||||
"thursday": "Thursday",
|
"thursday": "Thursday",
|
||||||
|
"title": "Title",
|
||||||
"token": "Token",
|
"token": "Token",
|
||||||
"tuesday": "Tuesday",
|
"tuesday": "Tuesday",
|
||||||
"type": "Type",
|
"type": "Type",
|
||||||
@@ -582,7 +584,22 @@
|
|||||||
"upload-image": "Upload image",
|
"upload-image": "Upload image",
|
||||||
"screen-awake": "Keep Screen Awake",
|
"screen-awake": "Keep Screen Awake",
|
||||||
"remove-image": "Remove image",
|
"remove-image": "Remove image",
|
||||||
"nextStep": "Next step"
|
"nextStep": "Next step",
|
||||||
|
"recipe-actions": "Recipe Actions",
|
||||||
|
"parser": {
|
||||||
|
"experimental-alert-text": "Mealie uses natural language processing to parse and create units and food items for your recipe ingredients. This feature is experimental and may not always work as expected. If you prefer not to use the parsed results, you can select 'Cancel' and your changes will not be saved.",
|
||||||
|
"ingredient-parser": "Ingredient Parser",
|
||||||
|
"explanation": "To use the ingredient parser, click the 'Parse All' button to start the process. Once the processed ingredients are available, you can review the items and verify that they were parsed correctly. The model's confidence score is displayed on the right of the item title. This score is an average of all the individual scores and may not always be completely accurate.",
|
||||||
|
"alerts-explainer": "Alerts will be displayed if a matching foods or unit is found but does not exists in the database.",
|
||||||
|
"select-parser": "Select Parser",
|
||||||
|
"natural-language-processor": "Natural Language Processor",
|
||||||
|
"brute-parser": "Brute Parser",
|
||||||
|
"parse-all": "Parse All",
|
||||||
|
"no-unit": "No unit",
|
||||||
|
"missing-unit": "Create missing unit: {unit}",
|
||||||
|
"missing-food": "Create missing food: {food}",
|
||||||
|
"no-food": "No Food"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"search": {
|
"search": {
|
||||||
"advanced-search": "Advanced Search",
|
"advanced-search": "Advanced Search",
|
||||||
@@ -1001,6 +1018,12 @@
|
|||||||
"delete-recipes": "Delete Recipes",
|
"delete-recipes": "Delete Recipes",
|
||||||
"source-unit-will-be-deleted": "Source Unit will be deleted"
|
"source-unit-will-be-deleted": "Source Unit will be deleted"
|
||||||
},
|
},
|
||||||
|
"recipe-actions": {
|
||||||
|
"recipe-actions-data": "Recipe Actions Data",
|
||||||
|
"new-recipe-action": "New Recipe Action",
|
||||||
|
"edit-recipe-action": "Edit Recipe Action",
|
||||||
|
"action-type": "Action Type"
|
||||||
|
},
|
||||||
"create-alias": "Create Alias",
|
"create-alias": "Create Alias",
|
||||||
"manage-aliases": "Manage Aliases",
|
"manage-aliases": "Manage Aliases",
|
||||||
"seed-data": "Seed Data",
|
"seed-data": "Seed Data",
|
||||||
|
|||||||
@@ -64,6 +64,7 @@
|
|||||||
"something-went-wrong": "¡Algo ha salido mal!",
|
"something-went-wrong": "¡Algo ha salido mal!",
|
||||||
"subscribed-events": "Eventos suscritos",
|
"subscribed-events": "Eventos suscritos",
|
||||||
"test-message-sent": "Mensaje Enviado",
|
"test-message-sent": "Mensaje Enviado",
|
||||||
|
"message-sent": "Message Sent",
|
||||||
"new-notification": "Nueva notificación",
|
"new-notification": "Nueva notificación",
|
||||||
"event-notifiers": "Notificaciones de eventos",
|
"event-notifiers": "Notificaciones de eventos",
|
||||||
"apprise-url-skipped-if-blank": "URL de Apprise (omitida si está en blanco)",
|
"apprise-url-skipped-if-blank": "URL de Apprise (omitida si está en blanco)",
|
||||||
@@ -160,6 +161,7 @@
|
|||||||
"test": "Prueba",
|
"test": "Prueba",
|
||||||
"themes": "Temas",
|
"themes": "Temas",
|
||||||
"thursday": "Jueves",
|
"thursday": "Jueves",
|
||||||
|
"title": "Title",
|
||||||
"token": "Token",
|
"token": "Token",
|
||||||
"tuesday": "Martes",
|
"tuesday": "Martes",
|
||||||
"type": "Tipo",
|
"type": "Tipo",
|
||||||
@@ -582,7 +584,22 @@
|
|||||||
"upload-image": "Subir imagen",
|
"upload-image": "Subir imagen",
|
||||||
"screen-awake": "Mantener la pantalla encendida",
|
"screen-awake": "Mantener la pantalla encendida",
|
||||||
"remove-image": "Eliminar imagen",
|
"remove-image": "Eliminar imagen",
|
||||||
"nextStep": "Siguiente paso"
|
"nextStep": "Siguiente paso",
|
||||||
|
"recipe-actions": "Recipe Actions",
|
||||||
|
"parser": {
|
||||||
|
"experimental-alert-text": "Mealie uses natural language processing to parse and create units and food items for your recipe ingredients. This feature is experimental and may not always work as expected. If you prefer not to use the parsed results, you can select 'Cancel' and your changes will not be saved.",
|
||||||
|
"ingredient-parser": "Ingredient Parser",
|
||||||
|
"explanation": "To use the ingredient parser, click the 'Parse All' button to start the process. Once the processed ingredients are available, you can review the items and verify that they were parsed correctly. The model's confidence score is displayed on the right of the item title. This score is an average of all the individual scores and may not always be completely accurate.",
|
||||||
|
"alerts-explainer": "Alerts will be displayed if a matching foods or unit is found but does not exists in the database.",
|
||||||
|
"select-parser": "Select Parser",
|
||||||
|
"natural-language-processor": "Natural Language Processor",
|
||||||
|
"brute-parser": "Brute Parser",
|
||||||
|
"parse-all": "Parse All",
|
||||||
|
"no-unit": "No unit",
|
||||||
|
"missing-unit": "Create missing unit: {unit}",
|
||||||
|
"missing-food": "Create missing food: {food}",
|
||||||
|
"no-food": "No Food"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"search": {
|
"search": {
|
||||||
"advanced-search": "Búsqueda avanzada",
|
"advanced-search": "Búsqueda avanzada",
|
||||||
@@ -1001,6 +1018,12 @@
|
|||||||
"delete-recipes": "Borrar Recetas",
|
"delete-recipes": "Borrar Recetas",
|
||||||
"source-unit-will-be-deleted": "Se eliminará la unidad de origen"
|
"source-unit-will-be-deleted": "Se eliminará la unidad de origen"
|
||||||
},
|
},
|
||||||
|
"recipe-actions": {
|
||||||
|
"recipe-actions-data": "Recipe Actions Data",
|
||||||
|
"new-recipe-action": "New Recipe Action",
|
||||||
|
"edit-recipe-action": "Edit Recipe Action",
|
||||||
|
"action-type": "Action Type"
|
||||||
|
},
|
||||||
"create-alias": "Crear un Alias",
|
"create-alias": "Crear un Alias",
|
||||||
"manage-aliases": "Administrar Alias",
|
"manage-aliases": "Administrar Alias",
|
||||||
"seed-data": "Datos de ejemplo",
|
"seed-data": "Datos de ejemplo",
|
||||||
|
|||||||
@@ -64,6 +64,7 @@
|
|||||||
"something-went-wrong": "Jotain meni pieleen!",
|
"something-went-wrong": "Jotain meni pieleen!",
|
||||||
"subscribed-events": "Tilatut tapahtumat",
|
"subscribed-events": "Tilatut tapahtumat",
|
||||||
"test-message-sent": "Viesti lähetetty",
|
"test-message-sent": "Viesti lähetetty",
|
||||||
|
"message-sent": "Message Sent",
|
||||||
"new-notification": "Uusi ilmoitus",
|
"new-notification": "Uusi ilmoitus",
|
||||||
"event-notifiers": "Tapahtumien ilmoitukset",
|
"event-notifiers": "Tapahtumien ilmoitukset",
|
||||||
"apprise-url-skipped-if-blank": "Ilmoitusverkko-osoite (voi jättää tyhjäksi)",
|
"apprise-url-skipped-if-blank": "Ilmoitusverkko-osoite (voi jättää tyhjäksi)",
|
||||||
@@ -160,6 +161,7 @@
|
|||||||
"test": "Testi",
|
"test": "Testi",
|
||||||
"themes": "Teemat",
|
"themes": "Teemat",
|
||||||
"thursday": "Torstai",
|
"thursday": "Torstai",
|
||||||
|
"title": "Title",
|
||||||
"token": "Tunniste",
|
"token": "Tunniste",
|
||||||
"tuesday": "Tiistai",
|
"tuesday": "Tiistai",
|
||||||
"type": "Tyyppi",
|
"type": "Tyyppi",
|
||||||
@@ -582,7 +584,22 @@
|
|||||||
"upload-image": "Lataa kuva",
|
"upload-image": "Lataa kuva",
|
||||||
"screen-awake": "Pidä näyttö aina päällä",
|
"screen-awake": "Pidä näyttö aina päällä",
|
||||||
"remove-image": "Poista kuva",
|
"remove-image": "Poista kuva",
|
||||||
"nextStep": "Seuraava askel"
|
"nextStep": "Seuraava askel",
|
||||||
|
"recipe-actions": "Recipe Actions",
|
||||||
|
"parser": {
|
||||||
|
"experimental-alert-text": "Mealie uses natural language processing to parse and create units and food items for your recipe ingredients. This feature is experimental and may not always work as expected. If you prefer not to use the parsed results, you can select 'Cancel' and your changes will not be saved.",
|
||||||
|
"ingredient-parser": "Ingredient Parser",
|
||||||
|
"explanation": "To use the ingredient parser, click the 'Parse All' button to start the process. Once the processed ingredients are available, you can review the items and verify that they were parsed correctly. The model's confidence score is displayed on the right of the item title. This score is an average of all the individual scores and may not always be completely accurate.",
|
||||||
|
"alerts-explainer": "Alerts will be displayed if a matching foods or unit is found but does not exists in the database.",
|
||||||
|
"select-parser": "Select Parser",
|
||||||
|
"natural-language-processor": "Natural Language Processor",
|
||||||
|
"brute-parser": "Brute Parser",
|
||||||
|
"parse-all": "Parse All",
|
||||||
|
"no-unit": "No unit",
|
||||||
|
"missing-unit": "Create missing unit: {unit}",
|
||||||
|
"missing-food": "Create missing food: {food}",
|
||||||
|
"no-food": "No Food"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"search": {
|
"search": {
|
||||||
"advanced-search": "Tarkennettu haku",
|
"advanced-search": "Tarkennettu haku",
|
||||||
@@ -1001,6 +1018,12 @@
|
|||||||
"delete-recipes": "Poista Reseptit",
|
"delete-recipes": "Poista Reseptit",
|
||||||
"source-unit-will-be-deleted": "Lähdeyksikkö poistetaan"
|
"source-unit-will-be-deleted": "Lähdeyksikkö poistetaan"
|
||||||
},
|
},
|
||||||
|
"recipe-actions": {
|
||||||
|
"recipe-actions-data": "Recipe Actions Data",
|
||||||
|
"new-recipe-action": "New Recipe Action",
|
||||||
|
"edit-recipe-action": "Edit Recipe Action",
|
||||||
|
"action-type": "Action Type"
|
||||||
|
},
|
||||||
"create-alias": "Create Alias",
|
"create-alias": "Create Alias",
|
||||||
"manage-aliases": "Manage Aliases",
|
"manage-aliases": "Manage Aliases",
|
||||||
"seed-data": "Tietokannan pohjadata",
|
"seed-data": "Tietokannan pohjadata",
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
"download-log": "Télécharger les logs",
|
"download-log": "Télécharger les logs",
|
||||||
"download-recipe-json": "Dernier JSON récupéré",
|
"download-recipe-json": "Dernier JSON récupéré",
|
||||||
"github": "GitHub",
|
"github": "GitHub",
|
||||||
"log-lines": "Lignes de log",
|
"log-lines": "Lignes du journal",
|
||||||
"not-demo": "Non démo",
|
"not-demo": "Non démo",
|
||||||
"portfolio": "Portfolio",
|
"portfolio": "Portfolio",
|
||||||
"production": "Production",
|
"production": "Production",
|
||||||
@@ -50,7 +50,7 @@
|
|||||||
"category": "Catégorie"
|
"category": "Catégorie"
|
||||||
},
|
},
|
||||||
"events": {
|
"events": {
|
||||||
"apprise-url": "URL apprise",
|
"apprise-url": "URL Apprise",
|
||||||
"database": "Base de données",
|
"database": "Base de données",
|
||||||
"delete-event": "Supprimer l'événement",
|
"delete-event": "Supprimer l'événement",
|
||||||
"event-delete-confirmation": "Voulez-vous vraiment supprimer cet évènement ?",
|
"event-delete-confirmation": "Voulez-vous vraiment supprimer cet évènement ?",
|
||||||
@@ -64,15 +64,16 @@
|
|||||||
"something-went-wrong": "Une erreur s'est produite!",
|
"something-went-wrong": "Une erreur s'est produite!",
|
||||||
"subscribed-events": "Évènements suivis",
|
"subscribed-events": "Évènements suivis",
|
||||||
"test-message-sent": "Message de test envoyé",
|
"test-message-sent": "Message de test envoyé",
|
||||||
|
"message-sent": "Message envoyé",
|
||||||
"new-notification": "Nouvelle notification",
|
"new-notification": "Nouvelle notification",
|
||||||
"event-notifiers": "Notifications d'événements",
|
"event-notifiers": "Notifications d'événements",
|
||||||
"apprise-url-skipped-if-blank": "URL Apprise (ignoré si vide)",
|
"apprise-url-skipped-if-blank": "URL Apprise (ignoré si vide)",
|
||||||
"enable-notifier": "Activer la notification",
|
"enable-notifier": "Activer la notification",
|
||||||
"what-events": "À quels événements cette notification doit-elle s'abonner ?",
|
"what-events": "À quels événements cette notification doit-elle s'abonner ?",
|
||||||
"user-events": "Evénements utilisateur",
|
"user-events": "Événements de l'utilisateur",
|
||||||
"mealplan-events": "Évènements du menu",
|
"mealplan-events": "Événements du menu",
|
||||||
"when-a-user-in-your-group-creates-a-new-mealplan": "Lorsqu'un utilisateur de votre groupe crée un nouveau menu",
|
"when-a-user-in-your-group-creates-a-new-mealplan": "Lorsqu'un utilisateur de votre groupe crée un nouveau menu",
|
||||||
"shopping-list-events": "Événements de la liste de courses",
|
"shopping-list-events": "Événements de la liste d'épicerie",
|
||||||
"cookbook-events": "Événements du livre de recettes",
|
"cookbook-events": "Événements du livre de recettes",
|
||||||
"tag-events": "Événements des mots-clés",
|
"tag-events": "Événements des mots-clés",
|
||||||
"category-events": "Événements de catégories",
|
"category-events": "Événements de catégories",
|
||||||
@@ -147,8 +148,8 @@
|
|||||||
"show-all": "Tout afficher",
|
"show-all": "Tout afficher",
|
||||||
"shuffle": "Mélanger",
|
"shuffle": "Mélanger",
|
||||||
"sort": "Trier",
|
"sort": "Trier",
|
||||||
"sort-ascending": "Tri croissant",
|
"sort-ascending": "Trier par ordre croissant",
|
||||||
"sort-descending": "Tri décroissant",
|
"sort-descending": "Trier par ordre décroissant",
|
||||||
"sort-alphabetically": "Alphabétique",
|
"sort-alphabetically": "Alphabétique",
|
||||||
"status": "Statut",
|
"status": "Statut",
|
||||||
"subject": "Sujet",
|
"subject": "Sujet",
|
||||||
@@ -160,6 +161,7 @@
|
|||||||
"test": "Tester",
|
"test": "Tester",
|
||||||
"themes": "Thèmes",
|
"themes": "Thèmes",
|
||||||
"thursday": "Jeudi",
|
"thursday": "Jeudi",
|
||||||
|
"title": "Titre",
|
||||||
"token": "Jeton",
|
"token": "Jeton",
|
||||||
"tuesday": "Mardi",
|
"tuesday": "Mardi",
|
||||||
"type": "Type",
|
"type": "Type",
|
||||||
@@ -203,12 +205,12 @@
|
|||||||
"selected-count": "Sélectionné : {count}",
|
"selected-count": "Sélectionné : {count}",
|
||||||
"export-all": "Exporter tout",
|
"export-all": "Exporter tout",
|
||||||
"refresh": "Actualiser",
|
"refresh": "Actualiser",
|
||||||
"upload-file": "Transférer un fichier",
|
"upload-file": "Téléverser un fichier",
|
||||||
"created-on-date": "Créé le {0}",
|
"created-on-date": "Créé le {0}",
|
||||||
"unsaved-changes": "Vous avez des modifications non enregistrées. Voulez-vous les enregistrer ? Ok pour enregistrer, annuler pour ignorer les modifications.",
|
"unsaved-changes": "Vous avez des modifications non enregistrées. Voulez-vous les enregistrer ? Ok pour enregistrer, annuler pour ignorer les modifications.",
|
||||||
"clipboard-copy-failure": "Échec de la copie vers le presse-papiers.",
|
"clipboard-copy-failure": "Échec de la copie vers le presse-papiers.",
|
||||||
"confirm-delete-generic-items": "Êtes-vous sûr de vouloir supprimer les éléments suivants ?",
|
"confirm-delete-generic-items": "Êtes-vous sûr de vouloir supprimer les éléments suivants ?",
|
||||||
"organizers": "Organizers"
|
"organizers": "Classification"
|
||||||
},
|
},
|
||||||
"group": {
|
"group": {
|
||||||
"are-you-sure-you-want-to-delete-the-group": "Êtes-vous certain de vouloir supprimer <b>{groupName}<b/>?",
|
"are-you-sure-you-want-to-delete-the-group": "Êtes-vous certain de vouloir supprimer <b>{groupName}<b/>?",
|
||||||
@@ -582,7 +584,22 @@
|
|||||||
"upload-image": "Ajouter une image",
|
"upload-image": "Ajouter une image",
|
||||||
"screen-awake": "Garder l’écran allumé",
|
"screen-awake": "Garder l’écran allumé",
|
||||||
"remove-image": "Supprimer l’image",
|
"remove-image": "Supprimer l’image",
|
||||||
"nextStep": "Étape suivante"
|
"nextStep": "Étape suivante",
|
||||||
|
"recipe-actions": "Actions de recette",
|
||||||
|
"parser": {
|
||||||
|
"experimental-alert-text": "Mealie utilise le traitement du langage naturel pour analyser et créer des unités et des aliments pour vos ingrédients de recettes. Cette fonctionnalité est expérimentale et peut ne pas toujours fonctionner comme prévu. Si vous préférez ne pas utiliser les résultats analysés, vous pouvez sélectionner « Annuler » et vos modifications ne seront pas enregistrées.",
|
||||||
|
"ingredient-parser": "Analyseur d'ingrédients",
|
||||||
|
"explanation": "Pour utiliser l'analyseur d'ingrédients, cliquez sur le bouton « Tout analyser » pour démarrer le processus. Une fois les ingrédients disponibles, vous pouvez vérifier qu'ils ont été analysés correctement. Le score de confiance du modèle est affiché à droite du titre de l'article. Ce score est une moyenne de tous les scores individuels et peut ne pas toujours être complètement exact.",
|
||||||
|
"alerts-explainer": "Les alertes seront affichées si un produit ou unité correspondant est trouvé mais n'existe pas dans la base de données.",
|
||||||
|
"select-parser": "Sélectionner l'analyseur",
|
||||||
|
"natural-language-processor": "Traitement du Langage Naturel",
|
||||||
|
"brute-parser": "Analyseur brut",
|
||||||
|
"parse-all": "Tout analyser",
|
||||||
|
"no-unit": "Pas d'unité",
|
||||||
|
"missing-unit": "Créer une unité manquante : {unit}",
|
||||||
|
"missing-food": "Créer un aliment manquant : {food}",
|
||||||
|
"no-food": "Aucun aliment"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"search": {
|
"search": {
|
||||||
"advanced-search": "Recherche avancée",
|
"advanced-search": "Recherche avancée",
|
||||||
@@ -723,8 +740,8 @@
|
|||||||
"volumes-are-configured-correctly": "Les volumes sont configurés correctement.",
|
"volumes-are-configured-correctly": "Les volumes sont configurés correctement.",
|
||||||
"status-unknown-try-running-a-validation": "Statut inconnu. Essayez de lancer une validation.",
|
"status-unknown-try-running-a-validation": "Statut inconnu. Essayez de lancer une validation.",
|
||||||
"validate": "Valider",
|
"validate": "Valider",
|
||||||
"email-configuration-status": "État de la configuration e-mail",
|
"email-configuration-status": "État de la configuration courriel",
|
||||||
"email-configured": "E-mail configuré",
|
"email-configured": "Courriel configuré",
|
||||||
"email-test-results": "Résultats des tests e-mail",
|
"email-test-results": "Résultats des tests e-mail",
|
||||||
"ready": "Prêt",
|
"ready": "Prêt",
|
||||||
"not-ready": "Pas prêt - Vérifier les variables d'environnement",
|
"not-ready": "Pas prêt - Vérifier les variables d'environnement",
|
||||||
@@ -897,9 +914,9 @@
|
|||||||
"enable-advanced-content": "Activer le contenu avancé",
|
"enable-advanced-content": "Activer le contenu avancé",
|
||||||
"enable-advanced-content-description": "Active les fonctionnalités avancées comme la mise à l'échelle des recettes, les clés API, les Webhooks, et la gestion des données. Ne vous inquiétez pas, vous pouvez toujours modifier cela plus tard",
|
"enable-advanced-content-description": "Active les fonctionnalités avancées comme la mise à l'échelle des recettes, les clés API, les Webhooks, et la gestion des données. Ne vous inquiétez pas, vous pouvez toujours modifier cela plus tard",
|
||||||
"favorite-recipes": "Recettes préférées",
|
"favorite-recipes": "Recettes préférées",
|
||||||
"email-or-username": "E-mail ou nom d'utilisateur",
|
"email-or-username": "Courriel ou nom d'utilisateur",
|
||||||
"remember-me": "Se souvenir de moi",
|
"remember-me": "Se souvenir de moi",
|
||||||
"please-enter-your-email-and-password": "Veuillez saisir votre e-mail et votre mot de passe",
|
"please-enter-your-email-and-password": "Veuillez entrer votre adresse courriel et votre mot de passe",
|
||||||
"invalid-credentials": "Identifiants invalides",
|
"invalid-credentials": "Identifiants invalides",
|
||||||
"account-locked-please-try-again-later": "Compte verrouillé. Veuillez réessayer plus tard",
|
"account-locked-please-try-again-later": "Compte verrouillé. Veuillez réessayer plus tard",
|
||||||
"user-favorites": "Favoris utilisateur",
|
"user-favorites": "Favoris utilisateur",
|
||||||
@@ -1001,6 +1018,12 @@
|
|||||||
"delete-recipes": "Supprimer les recettes",
|
"delete-recipes": "Supprimer les recettes",
|
||||||
"source-unit-will-be-deleted": "L'unité source sera supprimée"
|
"source-unit-will-be-deleted": "L'unité source sera supprimée"
|
||||||
},
|
},
|
||||||
|
"recipe-actions": {
|
||||||
|
"recipe-actions-data": "Données des actions de recette",
|
||||||
|
"new-recipe-action": "Nouvelle action de recette",
|
||||||
|
"edit-recipe-action": "Modifier l'action de recette",
|
||||||
|
"action-type": "Type d'action"
|
||||||
|
},
|
||||||
"create-alias": "Créer un alias",
|
"create-alias": "Créer un alias",
|
||||||
"manage-aliases": "Gérer les alias",
|
"manage-aliases": "Gérer les alias",
|
||||||
"seed-data": "Initialiser les données",
|
"seed-data": "Initialiser les données",
|
||||||
@@ -1042,7 +1065,7 @@
|
|||||||
"validation": {
|
"validation": {
|
||||||
"group-name-is-taken": "Le nom du groupe est déjà pris",
|
"group-name-is-taken": "Le nom du groupe est déjà pris",
|
||||||
"username-is-taken": "Nom d’utilisateur déjà utilisé",
|
"username-is-taken": "Nom d’utilisateur déjà utilisé",
|
||||||
"email-is-taken": "Cet e-mail est déjà pris",
|
"email-is-taken": "Cette adresse courriel est déjà prise",
|
||||||
"this-field-is-required": "Ce champ est obligatoire"
|
"this-field-is-required": "Ce champ est obligatoire"
|
||||||
},
|
},
|
||||||
"export": {
|
"export": {
|
||||||
@@ -1168,21 +1191,21 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"profile": {
|
"profile": {
|
||||||
"welcome-user": "👋 Welcome, {0}!",
|
"welcome-user": "👋 Bienvenue, {0}!",
|
||||||
"description": "Gérez votre profil, les recettes et les paramètres de groupe.",
|
"description": "Gérez votre profil, les recettes et les paramètres de groupe.",
|
||||||
"get-invite-link": "Obtenir un lien d'invitation",
|
"get-invite-link": "Obtenir un lien d'invitation",
|
||||||
"get-public-link": "Voir le lien public",
|
"get-public-link": "Voir le lien public",
|
||||||
"account-summary": "Aperçu du compte",
|
"account-summary": "Aperçu du compte",
|
||||||
"account-summary-description": "Here's a summary of your group's information.",
|
"account-summary-description": "Voici un résumé des informations de votre groupe.",
|
||||||
"group-statistics": "Statistiques du groupe",
|
"group-statistics": "Statistiques du groupe",
|
||||||
"group-statistics-description": "Les statistiques de votre groupe vous donnent un aperçu de la façon dont vous utilisez Mealie.",
|
"group-statistics-description": "Les statistiques de votre groupe vous donnent un aperçu de la façon dont vous utilisez Mealie.",
|
||||||
"storage-capacity": "Capacité de stockage",
|
"storage-capacity": "Capacité de stockage",
|
||||||
"storage-capacity-description": "Votre capacité de stockage est un calcul des images et des ressources que vous avez téléchargées.",
|
"storage-capacity-description": "Votre capacité de stockage est un calcul des images et des ressources que vous avez téléchargées.",
|
||||||
"personal": "Personnel",
|
"personal": "Personnel",
|
||||||
"personal-description": "These are settings that are personal to you. Changes here won't affect other users.",
|
"personal-description": "Il s'agit de paramètres qui vous sont personnels. Les modifications ici n'affecteront pas les autres utilisateurs.",
|
||||||
"user-settings": "Paramètres utilisateur",
|
"user-settings": "Paramètres utilisateur",
|
||||||
"user-settings-description": "Manage your preferences, change your password, and update your email.",
|
"user-settings-description": "Gérez vos préférences, changez votre mot de passe et mettez à jour votre adresse courriel.",
|
||||||
"api-tokens-description": "Manage your API Tokens for access from external applications.",
|
"api-tokens-description": "Gérez vos jetons d'API pour accéder à partir d'applications externes.",
|
||||||
"group-description": "Ces éléments sont partagés au sein de votre groupe. Un changement impactera l'ensemble du groupe !",
|
"group-description": "Ces éléments sont partagés au sein de votre groupe. Un changement impactera l'ensemble du groupe !",
|
||||||
"group-settings": "Paramètres de groupe",
|
"group-settings": "Paramètres de groupe",
|
||||||
"group-settings-description": "Gérez vos paramètres de groupe habituels tels que le menu de la semaine et les paramètres de confidentialité.",
|
"group-settings-description": "Gérez vos paramètres de groupe habituels tels que le menu de la semaine et les paramètres de confidentialité.",
|
||||||
@@ -1191,13 +1214,13 @@
|
|||||||
"members-description": "Voyez qui est dans votre groupe et gérez leurs autorisations.",
|
"members-description": "Voyez qui est dans votre groupe et gérez leurs autorisations.",
|
||||||
"webhooks-description": "Configurez les webhooks qui se déclenchent les jours où il y a un plan au menu.",
|
"webhooks-description": "Configurez les webhooks qui se déclenchent les jours où il y a un plan au menu.",
|
||||||
"notifiers": "Notifications",
|
"notifiers": "Notifications",
|
||||||
"notifiers-description": "Configurer les e-mails et les notifications push qui se déclenchent sur des événements spécifiques.",
|
"notifiers-description": "Configurer les courriels et les notifications push qui se déclenchent sur des événements spécifiques.",
|
||||||
"manage-data": "Gérer les données",
|
"manage-data": "Gérer les données",
|
||||||
"manage-data-description": "Manage your Mealie data; Foods, Units, Categories, Tags and more.",
|
"manage-data-description": "Gérez vos données Mealie, Aliments, Unités, Catégories, Tags et plus.",
|
||||||
"data-migrations": "Migration des données",
|
"data-migrations": "Migration des données",
|
||||||
"data-migrations-description": "Migrate your existing data from other applications like Nextcloud Recipes and Chowdown.",
|
"data-migrations-description": "Migrez vos données existantes à partir d'autres applications comme Nextcloud Cookbook et Chowdown.",
|
||||||
"email-sent": "E-mail envoyé",
|
"email-sent": "Courriel envoyé",
|
||||||
"error-sending-email": "Erreur lors de l'envoi de l'email",
|
"error-sending-email": "Erreur lors de l'envoi du courriel",
|
||||||
"personal-information": "Informations personnelles",
|
"personal-information": "Informations personnelles",
|
||||||
"preferences": "Préférences",
|
"preferences": "Préférences",
|
||||||
"show-advanced-description": "Afficher les fonctionnalités avancées (clés API, Webhooks, et gestion des données)",
|
"show-advanced-description": "Afficher les fonctionnalités avancées (clés API, Webhooks, et gestion des données)",
|
||||||
|
|||||||
@@ -64,6 +64,7 @@
|
|||||||
"something-went-wrong": "Une erreur s’est produite !",
|
"something-went-wrong": "Une erreur s’est produite !",
|
||||||
"subscribed-events": "Évènements suivis",
|
"subscribed-events": "Évènements suivis",
|
||||||
"test-message-sent": "Message de test envoyé",
|
"test-message-sent": "Message de test envoyé",
|
||||||
|
"message-sent": "Message envoyé",
|
||||||
"new-notification": "Nouvelle notification",
|
"new-notification": "Nouvelle notification",
|
||||||
"event-notifiers": "Notifications d'événements",
|
"event-notifiers": "Notifications d'événements",
|
||||||
"apprise-url-skipped-if-blank": "URL Apprise (ignoré si vide)",
|
"apprise-url-skipped-if-blank": "URL Apprise (ignoré si vide)",
|
||||||
@@ -160,6 +161,7 @@
|
|||||||
"test": "Tester",
|
"test": "Tester",
|
||||||
"themes": "Thèmes",
|
"themes": "Thèmes",
|
||||||
"thursday": "Jeudi",
|
"thursday": "Jeudi",
|
||||||
|
"title": "Titre",
|
||||||
"token": "Jeton",
|
"token": "Jeton",
|
||||||
"tuesday": "Mardi",
|
"tuesday": "Mardi",
|
||||||
"type": "Type",
|
"type": "Type",
|
||||||
@@ -208,7 +210,7 @@
|
|||||||
"unsaved-changes": "Vous avez des modifications non enregistrées. Voulez-vous enregistrer avant de partir ? OK pour enregistrer, Annuler pour ignorer les modifications.",
|
"unsaved-changes": "Vous avez des modifications non enregistrées. Voulez-vous enregistrer avant de partir ? OK pour enregistrer, Annuler pour ignorer les modifications.",
|
||||||
"clipboard-copy-failure": "Échec de la copie dans le presse-papiers.",
|
"clipboard-copy-failure": "Échec de la copie dans le presse-papiers.",
|
||||||
"confirm-delete-generic-items": "Êtes-vous sûr de vouloir supprimer les éléments suivants ?",
|
"confirm-delete-generic-items": "Êtes-vous sûr de vouloir supprimer les éléments suivants ?",
|
||||||
"organizers": "Organizers"
|
"organizers": "Classification"
|
||||||
},
|
},
|
||||||
"group": {
|
"group": {
|
||||||
"are-you-sure-you-want-to-delete-the-group": "Voulez-vous vraiment supprimer <b>{groupName}<b/> ?",
|
"are-you-sure-you-want-to-delete-the-group": "Voulez-vous vraiment supprimer <b>{groupName}<b/> ?",
|
||||||
@@ -582,7 +584,22 @@
|
|||||||
"upload-image": "Envoyer une image",
|
"upload-image": "Envoyer une image",
|
||||||
"screen-awake": "Garder l’écran allumé",
|
"screen-awake": "Garder l’écran allumé",
|
||||||
"remove-image": "Supprimer l’image",
|
"remove-image": "Supprimer l’image",
|
||||||
"nextStep": "Étape suivante"
|
"nextStep": "Étape suivante",
|
||||||
|
"recipe-actions": "Actions de recette",
|
||||||
|
"parser": {
|
||||||
|
"experimental-alert-text": "Mealie utilise le traitement du langage naturel pour analyser et créer des unités et des aliments pour vos ingrédients de recettes. Cette fonctionnalité est expérimentale et peut ne pas toujours fonctionner comme prévu. Si vous préférez ne pas utiliser les résultats analysés, vous pouvez sélectionner « Annuler » et vos modifications ne seront pas enregistrées.",
|
||||||
|
"ingredient-parser": "Analyseur d'ingrédients",
|
||||||
|
"explanation": "Pour utiliser l'analyseur d'ingrédients, cliquez sur le bouton « Tout analyser » pour démarrer le processus. Une fois les ingrédients disponibles, vous pouvez vérifier qu'ils ont été analysés correctement. Le score de confiance du modèle est affiché à droite du titre de l'article. Ce score est une moyenne de tous les scores individuels et peut ne pas toujours être complètement exact.",
|
||||||
|
"alerts-explainer": "Les alertes seront affichées si un produit ou unité correspondant est trouvé mais n'existe pas dans la base de données.",
|
||||||
|
"select-parser": "Sélectionner l'analyseur",
|
||||||
|
"natural-language-processor": "Traitement du Langage Naturel",
|
||||||
|
"brute-parser": "Analyseur brut",
|
||||||
|
"parse-all": "Tout analyser",
|
||||||
|
"no-unit": "Pas d'unité",
|
||||||
|
"missing-unit": "Créer une unité manquante : {unit}",
|
||||||
|
"missing-food": "Créer un aliment manquant : {food}",
|
||||||
|
"no-food": "Aucun aliment"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"search": {
|
"search": {
|
||||||
"advanced-search": "Recherche avancée",
|
"advanced-search": "Recherche avancée",
|
||||||
@@ -1001,6 +1018,12 @@
|
|||||||
"delete-recipes": "Supprimer les recettes",
|
"delete-recipes": "Supprimer les recettes",
|
||||||
"source-unit-will-be-deleted": "L'unité source sera supprimée"
|
"source-unit-will-be-deleted": "L'unité source sera supprimée"
|
||||||
},
|
},
|
||||||
|
"recipe-actions": {
|
||||||
|
"recipe-actions-data": "Données des actions de recette",
|
||||||
|
"new-recipe-action": "Nouvelle action de recette",
|
||||||
|
"edit-recipe-action": "Modifier l'action de recette",
|
||||||
|
"action-type": "Type d'action"
|
||||||
|
},
|
||||||
"create-alias": "Créer un alias",
|
"create-alias": "Créer un alias",
|
||||||
"manage-aliases": "Gérer les alias",
|
"manage-aliases": "Gérer les alias",
|
||||||
"seed-data": "Initialiser les données",
|
"seed-data": "Initialiser les données",
|
||||||
@@ -1168,21 +1191,21 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"profile": {
|
"profile": {
|
||||||
"welcome-user": "👋 Welcome, {0}!",
|
"welcome-user": "👋 Bienvenue, {0} !",
|
||||||
"description": "Gérez votre profil, les recettes et les paramètres de groupe.",
|
"description": "Gérez votre profil, les recettes et les paramètres de groupe.",
|
||||||
"get-invite-link": "Obtenir un lien d'invitation",
|
"get-invite-link": "Obtenir un lien d'invitation",
|
||||||
"get-public-link": "Voir le lien public",
|
"get-public-link": "Voir le lien public",
|
||||||
"account-summary": "Aperçu du compte",
|
"account-summary": "Aperçu du compte",
|
||||||
"account-summary-description": "Here's a summary of your group's information.",
|
"account-summary-description": "Voici un résumé des informations de votre groupe.",
|
||||||
"group-statistics": "Statistiques du groupe",
|
"group-statistics": "Statistiques du groupe",
|
||||||
"group-statistics-description": "Les statistiques de votre groupe vous donnent un aperçu de la façon dont vous utilisez Mealie.",
|
"group-statistics-description": "Les statistiques de votre groupe vous donnent un aperçu de la façon dont vous utilisez Mealie.",
|
||||||
"storage-capacity": "Capacité de stockage",
|
"storage-capacity": "Capacité de stockage",
|
||||||
"storage-capacity-description": "Votre capacité de stockage est un calcul des images et des ressources que vous avez téléchargées.",
|
"storage-capacity-description": "Votre capacité de stockage est un calcul des images et des ressources que vous avez téléchargées.",
|
||||||
"personal": "Personnel",
|
"personal": "Personnel",
|
||||||
"personal-description": "These are settings that are personal to you. Changes here won't affect other users.",
|
"personal-description": "Ici se trouvent des paramètres qui vous sont propres personnellement. Toute modification n'affectera pas les autres utilisateurs.",
|
||||||
"user-settings": "Paramètres utilisateur",
|
"user-settings": "Paramètres utilisateur",
|
||||||
"user-settings-description": "Manage your preferences, change your password, and update your email.",
|
"user-settings-description": "Gérez vos préférences, changez votre mot de passe et mettez à jour votre adresse e-mail.",
|
||||||
"api-tokens-description": "Manage your API Tokens for access from external applications.",
|
"api-tokens-description": "Gérez vos jetons API pour un accès à partir d'applications externes.",
|
||||||
"group-description": "Ces éléments sont partagés au sein de votre groupe. Un changement impactera l'ensemble du groupe !",
|
"group-description": "Ces éléments sont partagés au sein de votre groupe. Un changement impactera l'ensemble du groupe !",
|
||||||
"group-settings": "Paramètres de groupe",
|
"group-settings": "Paramètres de groupe",
|
||||||
"group-settings-description": "Gérez vos paramètres de groupe habituels tels que le menu de la semaine et les paramètres de confidentialité.",
|
"group-settings-description": "Gérez vos paramètres de groupe habituels tels que le menu de la semaine et les paramètres de confidentialité.",
|
||||||
@@ -1193,9 +1216,9 @@
|
|||||||
"notifiers": "Notifications",
|
"notifiers": "Notifications",
|
||||||
"notifiers-description": "Configurer les e-mails et les notifications push qui se déclenchent sur des événements spécifiques.",
|
"notifiers-description": "Configurer les e-mails et les notifications push qui se déclenchent sur des événements spécifiques.",
|
||||||
"manage-data": "Gérer les données",
|
"manage-data": "Gérer les données",
|
||||||
"manage-data-description": "Manage your Mealie data; Foods, Units, Categories, Tags and more.",
|
"manage-data-description": "Gérez vos données Mealie, Aliments, Unités, Catégories, Tags et plus.",
|
||||||
"data-migrations": "Migration des données",
|
"data-migrations": "Migration des données",
|
||||||
"data-migrations-description": "Migrate your existing data from other applications like Nextcloud Recipes and Chowdown.",
|
"data-migrations-description": "Migrez vos données existantes à partir d'autres applications comme Nextcloud Cookbook et Chowdown.",
|
||||||
"email-sent": "E-mail envoyé",
|
"email-sent": "E-mail envoyé",
|
||||||
"error-sending-email": "Erreur lors de l'envoi de l'email",
|
"error-sending-email": "Erreur lors de l'envoi de l'email",
|
||||||
"personal-information": "Informations personnelles",
|
"personal-information": "Informations personnelles",
|
||||||
|
|||||||
@@ -64,6 +64,7 @@
|
|||||||
"something-went-wrong": "Something Went Wrong!",
|
"something-went-wrong": "Something Went Wrong!",
|
||||||
"subscribed-events": "Subscribed Events",
|
"subscribed-events": "Subscribed Events",
|
||||||
"test-message-sent": "Test Message Sent",
|
"test-message-sent": "Test Message Sent",
|
||||||
|
"message-sent": "Message Sent",
|
||||||
"new-notification": "New Notification",
|
"new-notification": "New Notification",
|
||||||
"event-notifiers": "Event Notifiers",
|
"event-notifiers": "Event Notifiers",
|
||||||
"apprise-url-skipped-if-blank": "Apprise URL (skipped if blank)",
|
"apprise-url-skipped-if-blank": "Apprise URL (skipped if blank)",
|
||||||
@@ -160,6 +161,7 @@
|
|||||||
"test": "Probar",
|
"test": "Probar",
|
||||||
"themes": "Temas",
|
"themes": "Temas",
|
||||||
"thursday": "Xoves",
|
"thursday": "Xoves",
|
||||||
|
"title": "Title",
|
||||||
"token": "Identificador",
|
"token": "Identificador",
|
||||||
"tuesday": "Martes",
|
"tuesday": "Martes",
|
||||||
"type": "Tipo",
|
"type": "Tipo",
|
||||||
@@ -582,7 +584,22 @@
|
|||||||
"upload-image": "Upload image",
|
"upload-image": "Upload image",
|
||||||
"screen-awake": "Keep Screen Awake",
|
"screen-awake": "Keep Screen Awake",
|
||||||
"remove-image": "Remove image",
|
"remove-image": "Remove image",
|
||||||
"nextStep": "Next step"
|
"nextStep": "Next step",
|
||||||
|
"recipe-actions": "Recipe Actions",
|
||||||
|
"parser": {
|
||||||
|
"experimental-alert-text": "Mealie uses natural language processing to parse and create units and food items for your recipe ingredients. This feature is experimental and may not always work as expected. If you prefer not to use the parsed results, you can select 'Cancel' and your changes will not be saved.",
|
||||||
|
"ingredient-parser": "Ingredient Parser",
|
||||||
|
"explanation": "To use the ingredient parser, click the 'Parse All' button to start the process. Once the processed ingredients are available, you can review the items and verify that they were parsed correctly. The model's confidence score is displayed on the right of the item title. This score is an average of all the individual scores and may not always be completely accurate.",
|
||||||
|
"alerts-explainer": "Alerts will be displayed if a matching foods or unit is found but does not exists in the database.",
|
||||||
|
"select-parser": "Select Parser",
|
||||||
|
"natural-language-processor": "Natural Language Processor",
|
||||||
|
"brute-parser": "Brute Parser",
|
||||||
|
"parse-all": "Parse All",
|
||||||
|
"no-unit": "No unit",
|
||||||
|
"missing-unit": "Create missing unit: {unit}",
|
||||||
|
"missing-food": "Create missing food: {food}",
|
||||||
|
"no-food": "No Food"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"search": {
|
"search": {
|
||||||
"advanced-search": "Advanced Search",
|
"advanced-search": "Advanced Search",
|
||||||
@@ -1001,6 +1018,12 @@
|
|||||||
"delete-recipes": "Delete Recipes",
|
"delete-recipes": "Delete Recipes",
|
||||||
"source-unit-will-be-deleted": "Source Unit will be deleted"
|
"source-unit-will-be-deleted": "Source Unit will be deleted"
|
||||||
},
|
},
|
||||||
|
"recipe-actions": {
|
||||||
|
"recipe-actions-data": "Recipe Actions Data",
|
||||||
|
"new-recipe-action": "New Recipe Action",
|
||||||
|
"edit-recipe-action": "Edit Recipe Action",
|
||||||
|
"action-type": "Action Type"
|
||||||
|
},
|
||||||
"create-alias": "Create Alias",
|
"create-alias": "Create Alias",
|
||||||
"manage-aliases": "Manage Aliases",
|
"manage-aliases": "Manage Aliases",
|
||||||
"seed-data": "Seed Data",
|
"seed-data": "Seed Data",
|
||||||
|
|||||||
@@ -64,6 +64,7 @@
|
|||||||
"something-went-wrong": "משהו השתבש!",
|
"something-went-wrong": "משהו השתבש!",
|
||||||
"subscribed-events": "אירועים שנרשמת אליהם",
|
"subscribed-events": "אירועים שנרשמת אליהם",
|
||||||
"test-message-sent": "הודעת בדיקה נשלחה",
|
"test-message-sent": "הודעת בדיקה נשלחה",
|
||||||
|
"message-sent": "Message Sent",
|
||||||
"new-notification": "התראה חדשה",
|
"new-notification": "התראה חדשה",
|
||||||
"event-notifiers": "אירועי נוטיפיקציות",
|
"event-notifiers": "אירועי נוטיפיקציות",
|
||||||
"apprise-url-skipped-if-blank": "כתובת Apprise (דלג אם ריק)",
|
"apprise-url-skipped-if-blank": "כתובת Apprise (דלג אם ריק)",
|
||||||
@@ -160,6 +161,7 @@
|
|||||||
"test": "ניסיון",
|
"test": "ניסיון",
|
||||||
"themes": "ערכות נושא",
|
"themes": "ערכות נושא",
|
||||||
"thursday": "חמישי",
|
"thursday": "חמישי",
|
||||||
|
"title": "Title",
|
||||||
"token": "טוקן",
|
"token": "טוקן",
|
||||||
"tuesday": "שלישי",
|
"tuesday": "שלישי",
|
||||||
"type": "סוג",
|
"type": "סוג",
|
||||||
@@ -582,7 +584,22 @@
|
|||||||
"upload-image": "העלה תמונה",
|
"upload-image": "העלה תמונה",
|
||||||
"screen-awake": "השאר את המסך פעיל",
|
"screen-awake": "השאר את המסך פעיל",
|
||||||
"remove-image": "האם למחוק את התמונה?",
|
"remove-image": "האם למחוק את התמונה?",
|
||||||
"nextStep": "השלב הבא"
|
"nextStep": "השלב הבא",
|
||||||
|
"recipe-actions": "Recipe Actions",
|
||||||
|
"parser": {
|
||||||
|
"experimental-alert-text": "Mealie uses natural language processing to parse and create units and food items for your recipe ingredients. This feature is experimental and may not always work as expected. If you prefer not to use the parsed results, you can select 'Cancel' and your changes will not be saved.",
|
||||||
|
"ingredient-parser": "Ingredient Parser",
|
||||||
|
"explanation": "To use the ingredient parser, click the 'Parse All' button to start the process. Once the processed ingredients are available, you can review the items and verify that they were parsed correctly. The model's confidence score is displayed on the right of the item title. This score is an average of all the individual scores and may not always be completely accurate.",
|
||||||
|
"alerts-explainer": "Alerts will be displayed if a matching foods or unit is found but does not exists in the database.",
|
||||||
|
"select-parser": "Select Parser",
|
||||||
|
"natural-language-processor": "Natural Language Processor",
|
||||||
|
"brute-parser": "Brute Parser",
|
||||||
|
"parse-all": "Parse All",
|
||||||
|
"no-unit": "No unit",
|
||||||
|
"missing-unit": "Create missing unit: {unit}",
|
||||||
|
"missing-food": "Create missing food: {food}",
|
||||||
|
"no-food": "No Food"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"search": {
|
"search": {
|
||||||
"advanced-search": "חיפוש מתקדם",
|
"advanced-search": "חיפוש מתקדם",
|
||||||
@@ -1001,6 +1018,12 @@
|
|||||||
"delete-recipes": "מחיקת מתכונים",
|
"delete-recipes": "מחיקת מתכונים",
|
||||||
"source-unit-will-be-deleted": "יחידת המקור תמחק"
|
"source-unit-will-be-deleted": "יחידת המקור תמחק"
|
||||||
},
|
},
|
||||||
|
"recipe-actions": {
|
||||||
|
"recipe-actions-data": "Recipe Actions Data",
|
||||||
|
"new-recipe-action": "New Recipe Action",
|
||||||
|
"edit-recipe-action": "Edit Recipe Action",
|
||||||
|
"action-type": "Action Type"
|
||||||
|
},
|
||||||
"create-alias": "יצירת שם נרדף",
|
"create-alias": "יצירת שם נרדף",
|
||||||
"manage-aliases": "נהל שמות נרדפים",
|
"manage-aliases": "נהל שמות נרדפים",
|
||||||
"seed-data": "אכלס נתונים",
|
"seed-data": "אכלס נתונים",
|
||||||
|
|||||||
@@ -64,6 +64,7 @@
|
|||||||
"something-went-wrong": "Nešto nije bilo u redu!",
|
"something-went-wrong": "Nešto nije bilo u redu!",
|
||||||
"subscribed-events": "Pretplaćeni Događaji",
|
"subscribed-events": "Pretplaćeni Događaji",
|
||||||
"test-message-sent": "Testna Poruka je Poslana",
|
"test-message-sent": "Testna Poruka je Poslana",
|
||||||
|
"message-sent": "Message Sent",
|
||||||
"new-notification": "Nova Obavijest",
|
"new-notification": "Nova Obavijest",
|
||||||
"event-notifiers": "Obavještavatelji Događaja",
|
"event-notifiers": "Obavještavatelji Događaja",
|
||||||
"apprise-url-skipped-if-blank": "Apprise URL (preskočeno ako je prazno)",
|
"apprise-url-skipped-if-blank": "Apprise URL (preskočeno ako je prazno)",
|
||||||
@@ -160,6 +161,7 @@
|
|||||||
"test": "Test",
|
"test": "Test",
|
||||||
"themes": "Teme",
|
"themes": "Teme",
|
||||||
"thursday": "Četvrtak",
|
"thursday": "Četvrtak",
|
||||||
|
"title": "Title",
|
||||||
"token": "Token",
|
"token": "Token",
|
||||||
"tuesday": "Utorak",
|
"tuesday": "Utorak",
|
||||||
"type": "Tip",
|
"type": "Tip",
|
||||||
@@ -582,7 +584,22 @@
|
|||||||
"upload-image": "Učitavanje Slike",
|
"upload-image": "Učitavanje Slike",
|
||||||
"screen-awake": "Keep Screen Awake",
|
"screen-awake": "Keep Screen Awake",
|
||||||
"remove-image": "Remove image",
|
"remove-image": "Remove image",
|
||||||
"nextStep": "Next step"
|
"nextStep": "Next step",
|
||||||
|
"recipe-actions": "Recipe Actions",
|
||||||
|
"parser": {
|
||||||
|
"experimental-alert-text": "Mealie uses natural language processing to parse and create units and food items for your recipe ingredients. This feature is experimental and may not always work as expected. If you prefer not to use the parsed results, you can select 'Cancel' and your changes will not be saved.",
|
||||||
|
"ingredient-parser": "Ingredient Parser",
|
||||||
|
"explanation": "To use the ingredient parser, click the 'Parse All' button to start the process. Once the processed ingredients are available, you can review the items and verify that they were parsed correctly. The model's confidence score is displayed on the right of the item title. This score is an average of all the individual scores and may not always be completely accurate.",
|
||||||
|
"alerts-explainer": "Alerts will be displayed if a matching foods or unit is found but does not exists in the database.",
|
||||||
|
"select-parser": "Select Parser",
|
||||||
|
"natural-language-processor": "Natural Language Processor",
|
||||||
|
"brute-parser": "Brute Parser",
|
||||||
|
"parse-all": "Parse All",
|
||||||
|
"no-unit": "No unit",
|
||||||
|
"missing-unit": "Create missing unit: {unit}",
|
||||||
|
"missing-food": "Create missing food: {food}",
|
||||||
|
"no-food": "No Food"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"search": {
|
"search": {
|
||||||
"advanced-search": "Napredno Pretraživanje",
|
"advanced-search": "Napredno Pretraživanje",
|
||||||
@@ -1001,6 +1018,12 @@
|
|||||||
"delete-recipes": "Obriši Recepte",
|
"delete-recipes": "Obriši Recepte",
|
||||||
"source-unit-will-be-deleted": "Izvorna jedinica će biti izbrisana"
|
"source-unit-will-be-deleted": "Izvorna jedinica će biti izbrisana"
|
||||||
},
|
},
|
||||||
|
"recipe-actions": {
|
||||||
|
"recipe-actions-data": "Recipe Actions Data",
|
||||||
|
"new-recipe-action": "New Recipe Action",
|
||||||
|
"edit-recipe-action": "Edit Recipe Action",
|
||||||
|
"action-type": "Action Type"
|
||||||
|
},
|
||||||
"create-alias": "Create Alias",
|
"create-alias": "Create Alias",
|
||||||
"manage-aliases": "Manage Aliases",
|
"manage-aliases": "Manage Aliases",
|
||||||
"seed-data": "Unesi Podatke",
|
"seed-data": "Unesi Podatke",
|
||||||
|
|||||||
@@ -64,6 +64,7 @@
|
|||||||
"something-went-wrong": "Hiba történt!",
|
"something-went-wrong": "Hiba történt!",
|
||||||
"subscribed-events": "Feliratkozott események",
|
"subscribed-events": "Feliratkozott események",
|
||||||
"test-message-sent": "Teszt üzenet elküldve",
|
"test-message-sent": "Teszt üzenet elküldve",
|
||||||
|
"message-sent": "Üzenet elküldve",
|
||||||
"new-notification": "Új értesítés",
|
"new-notification": "Új értesítés",
|
||||||
"event-notifiers": "Esemény értesítők",
|
"event-notifiers": "Esemény értesítők",
|
||||||
"apprise-url-skipped-if-blank": "Értesítendő URL (kihagy, ha üres)",
|
"apprise-url-skipped-if-blank": "Értesítendő URL (kihagy, ha üres)",
|
||||||
@@ -85,7 +86,7 @@
|
|||||||
"clear": "Törlés",
|
"clear": "Törlés",
|
||||||
"close": "Bezár",
|
"close": "Bezár",
|
||||||
"confirm": "Megerősítés",
|
"confirm": "Megerősítés",
|
||||||
"confirm-how-does-everything-look": "How does everything look?",
|
"confirm-how-does-everything-look": "Hogy néz ki?",
|
||||||
"confirm-delete-generic": "Biztosan törölni szeretnéd ezt?",
|
"confirm-delete-generic": "Biztosan törölni szeretnéd ezt?",
|
||||||
"copied_message": "Másolva!",
|
"copied_message": "Másolva!",
|
||||||
"create": "Létrehozás",
|
"create": "Létrehozás",
|
||||||
@@ -144,11 +145,11 @@
|
|||||||
"save": "Mentés",
|
"save": "Mentés",
|
||||||
"settings": "Beállítások",
|
"settings": "Beállítások",
|
||||||
"share": "Megosztás",
|
"share": "Megosztás",
|
||||||
"show-all": "Show All",
|
"show-all": "Mutasd az összeset",
|
||||||
"shuffle": "Véletlenszerű",
|
"shuffle": "Véletlenszerű",
|
||||||
"sort": "Rendezés",
|
"sort": "Rendezés",
|
||||||
"sort-ascending": "Sort Ascending",
|
"sort-ascending": "Rendezés növekvő sorrendben",
|
||||||
"sort-descending": "Sort Descending",
|
"sort-descending": "Rendezés csökkenő sorrendben",
|
||||||
"sort-alphabetically": "Betűrendben",
|
"sort-alphabetically": "Betűrendben",
|
||||||
"status": "Állapot",
|
"status": "Állapot",
|
||||||
"subject": "Tárgy",
|
"subject": "Tárgy",
|
||||||
@@ -160,6 +161,7 @@
|
|||||||
"test": "Teszt",
|
"test": "Teszt",
|
||||||
"themes": "Témák",
|
"themes": "Témák",
|
||||||
"thursday": "Csütörtök",
|
"thursday": "Csütörtök",
|
||||||
|
"title": "Cím",
|
||||||
"token": "Token",
|
"token": "Token",
|
||||||
"tuesday": "Kedd",
|
"tuesday": "Kedd",
|
||||||
"type": "Típus",
|
"type": "Típus",
|
||||||
@@ -245,7 +247,7 @@
|
|||||||
"private-group": "Privát csoport",
|
"private-group": "Privát csoport",
|
||||||
"private-group-description": "Ha a csoportot privátra állítja, az összes nyilvános nézeti beállítás alapértelmezettre lesz állítva. Ez felülírja az egyes receptek nyilvános nézet beállításait.",
|
"private-group-description": "Ha a csoportot privátra állítja, az összes nyilvános nézeti beállítás alapértelmezettre lesz állítva. Ez felülírja az egyes receptek nyilvános nézet beállításait.",
|
||||||
"enable-public-access": "Nyilvános hozzáférés engedélyezése",
|
"enable-public-access": "Nyilvános hozzáférés engedélyezése",
|
||||||
"enable-public-access-description": "Make group recipes public by default, and allow visitors to view recipes without logging-in",
|
"enable-public-access-description": "Legyenek a csoport receptek alapértelmezetten publikusak és engedélyezze a látogatóknak a megtekintést belépés nélkül",
|
||||||
"allow-users-outside-of-your-group-to-see-your-recipes": "Engedélyezze a csoporton kívüli felhasználók számára a receptek megtekintését",
|
"allow-users-outside-of-your-group-to-see-your-recipes": "Engedélyezze a csoporton kívüli felhasználók számára a receptek megtekintését",
|
||||||
"allow-users-outside-of-your-group-to-see-your-recipes-description": "Ha engedélyezve van, nyilvános megosztási hivatkozással megoszthat adott recepteket a felhasználó felhatalmazása nélkül. Ha le van tiltva, csak olyan felhasználókkal oszthat meg recepteket, akik a csoportjába tartoznak, vagy egy előre generált privát linkkel",
|
"allow-users-outside-of-your-group-to-see-your-recipes-description": "Ha engedélyezve van, nyilvános megosztási hivatkozással megoszthat adott recepteket a felhasználó felhatalmazása nélkül. Ha le van tiltva, csak olyan felhasználókkal oszthat meg recepteket, akik a csoportjába tartoznak, vagy egy előre generált privát linkkel",
|
||||||
"show-nutrition-information": "Táplálkozási információk megjelenítése",
|
"show-nutrition-information": "Táplálkozási információk megjelenítése",
|
||||||
@@ -359,11 +361,11 @@
|
|||||||
},
|
},
|
||||||
"recipe-data-migrations": "Receptadatok migrációja",
|
"recipe-data-migrations": "Receptadatok migrációja",
|
||||||
"recipe-data-migrations-explanation": "A receptek átemelhetők más támogatott alkalmazásból Mealie-be. Ez egy remek módja a Mealie használatának elkezdésére.",
|
"recipe-data-migrations-explanation": "A receptek átemelhetők más támogatott alkalmazásból Mealie-be. Ez egy remek módja a Mealie használatának elkezdésére.",
|
||||||
"coming-from-another-application-or-an-even-older-version-of-mealie": "Coming from another application or an even older version of Mealie? Check out migrations and see if your data can be imported.",
|
"coming-from-another-application-or-an-even-older-version-of-mealie": "A Mealie egy másik verzióját használtad vagy valami teljesen más applikációt? Nézd meg az adat importálási lehetőségeinket.",
|
||||||
"choose-migration-type": "Válassza ki a migrációs típusát",
|
"choose-migration-type": "Válassza ki a migrációs típusát",
|
||||||
"tag-all-recipes": "Az összes recept címkézése a {tag-name} címkével",
|
"tag-all-recipes": "Az összes recept címkézése a {tag-name} címkével",
|
||||||
"nextcloud-text": "A Nextcloud-receptek importálhatók a Nextcloudban tárolt adatokat tartalmazó zip-fájlból. Tekintse meg az alábbi példamappaszerkezetet, hogy receptjei biztosan importálhatók legyenek.",
|
"nextcloud-text": "A Nextcloud-receptek importálhatók a Nextcloudban tárolt adatokat tartalmazó zip-fájlból. Tekintse meg az alábbi példamappaszerkezetet, hogy receptjei biztosan importálhatók legyenek.",
|
||||||
"chowdown-text": "Mealie natively supports the chowdown repository format. Download the code repository as a .zip file and upload it below.",
|
"chowdown-text": "Mealie natívan támogatja a chowdown repository formátumot. Töltse le a kódtárat .zip fájlként, és töltse fel alább.",
|
||||||
"recipe-1": "Recept 1",
|
"recipe-1": "Recept 1",
|
||||||
"recipe-2": "Recept 2",
|
"recipe-2": "Recept 2",
|
||||||
"paprika-text": "Mealie képes recepteket importálni a Paprika alkalmazásból. Exportálja a receptjeit a Paprikából, nevezze át az export kiterjesztést .zip-re, és töltse fel alább.",
|
"paprika-text": "Mealie képes recepteket importálni a Paprika alkalmazásból. Exportálja a receptjeit a Paprikából, nevezze át az export kiterjesztést .zip-re, és töltse fel alább.",
|
||||||
@@ -373,8 +375,8 @@
|
|||||||
"description-long": "Mealie képes recepteket importálni a Plan to Eat alkalmazásból."
|
"description-long": "Mealie képes recepteket importálni a Plan to Eat alkalmazásból."
|
||||||
},
|
},
|
||||||
"myrecipebox": {
|
"myrecipebox": {
|
||||||
"title": "My Recipe Box",
|
"title": "Az én receptes dobozom",
|
||||||
"description-long": "Mealie can import recipes from My Recipe Box. Export your recipes in CSV format, then upload the .csv file below."
|
"description-long": "A Mealie képest recepteket importálni az Én Receptes Dobozomból. Exportáld a receptjeidet CSV formátúmba, aztán töltsd fel a .csv fájlt lentebb."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"new-recipe": {
|
"new-recipe": {
|
||||||
@@ -509,8 +511,8 @@
|
|||||||
"cook-mode": "Főzési mód",
|
"cook-mode": "Főzési mód",
|
||||||
"link-ingredients": "Hozzávalók összekapcsolása",
|
"link-ingredients": "Hozzávalók összekapcsolása",
|
||||||
"merge-above": "Összevonás a fentivel",
|
"merge-above": "Összevonás a fentivel",
|
||||||
"move-to-bottom": "Move To Bottom",
|
"move-to-bottom": "Ugrás az aljára",
|
||||||
"move-to-top": "Move To Top",
|
"move-to-top": "Ugrás a tetejére",
|
||||||
"reset-scale": "Skála alaphelyzetbe állítása",
|
"reset-scale": "Skála alaphelyzetbe állítása",
|
||||||
"decrease-scale-label": "Skála csökkentése 1-gyel",
|
"decrease-scale-label": "Skála csökkentése 1-gyel",
|
||||||
"increase-scale-label": "Skála növelése 1-gyel",
|
"increase-scale-label": "Skála növelése 1-gyel",
|
||||||
@@ -526,7 +528,7 @@
|
|||||||
"edit-timeline-event": "Idővonal-esemény szerkesztése",
|
"edit-timeline-event": "Idővonal-esemény szerkesztése",
|
||||||
"timeline": "Idővonal",
|
"timeline": "Idővonal",
|
||||||
"timeline-is-empty": "Az idővonalon még semmi sincs. Próbálja meg elkészíteni ezt a receptet!",
|
"timeline-is-empty": "Az idővonalon még semmi sincs. Próbálja meg elkészíteni ezt a receptet!",
|
||||||
"timeline-no-events-found-try-adjusting-filters": "No events found. Try adjusting your search filters.",
|
"timeline-no-events-found-try-adjusting-filters": "Nem találtunk eseményeket. Próbáld meg átállítani a keresési szűrőket.",
|
||||||
"group-global-timeline": "{groupName} Globális idővonal",
|
"group-global-timeline": "{groupName} Globális idővonal",
|
||||||
"open-timeline": "Idővonal megnyitása",
|
"open-timeline": "Idővonal megnyitása",
|
||||||
"made-this": "Elkészítettem ezt",
|
"made-this": "Elkészítettem ezt",
|
||||||
@@ -547,7 +549,7 @@
|
|||||||
"looking-for-migrations": "Migrációt keres?",
|
"looking-for-migrations": "Migrációt keres?",
|
||||||
"import-with-url": "Importálás URL-címről",
|
"import-with-url": "Importálás URL-címről",
|
||||||
"create-recipe": "Recept létrehozása",
|
"create-recipe": "Recept létrehozása",
|
||||||
"create-recipe-description": "Create a new recipe from scratch.",
|
"create-recipe-description": "Adj hozzá egy új receptet a nulláról kezdve.",
|
||||||
"create-recipes": "Receptek létrehozása",
|
"create-recipes": "Receptek létrehozása",
|
||||||
"import-with-zip": "Importálás .zip formátummal",
|
"import-with-zip": "Importálás .zip formátummal",
|
||||||
"create-recipe-from-an-image": "Recept létrehozása fotóról",
|
"create-recipe-from-an-image": "Recept létrehozása fotóról",
|
||||||
@@ -582,7 +584,22 @@
|
|||||||
"upload-image": "Kép feltöltése",
|
"upload-image": "Kép feltöltése",
|
||||||
"screen-awake": "Képernyő ébren tartása",
|
"screen-awake": "Képernyő ébren tartása",
|
||||||
"remove-image": "Kép etávolítása",
|
"remove-image": "Kép etávolítása",
|
||||||
"nextStep": "Következő lépés"
|
"nextStep": "Következő lépés",
|
||||||
|
"recipe-actions": "Recipe Actions",
|
||||||
|
"parser": {
|
||||||
|
"experimental-alert-text": "A Mealie természetes nyelvi feldolgozást használ a recept összetevőinek elemzésére, az egységek és az élelmiszerelemek létrehozására. Ez a funkció kísérleti jellegű, és előfordulhat, hogy nem mindig működik az elvárt módon. Ha nem szeretné használni az elemzett eredményeket, válassza a 'Mégse' lehetőséget, és a módosítások nem kerülnek mentésre.",
|
||||||
|
"ingredient-parser": "Hozzávaló elemző",
|
||||||
|
"explanation": "A hozzávalók elemzőjének használatához kattintson a 'Parse All' gombra a folyamat elindításához. Amint a feldolgozott hozzávalók elérhetővé válnak, áttekintheti az elemeket, és ellenőrizheti, hogy azok helyesen lettek-e elemezve. A modell megbízhatósági pontszáma az elem címének jobb oldalán jelenik meg. Ez a pontszám az összes egyéni pontszám átlaga, és nem biztos, hogy mindig teljesen pontos.",
|
||||||
|
"alerts-explainer": "Figyelmeztetések jelennek meg, ha talál egy megfelelő élelmiszert vagy egységet, de az nem létezik az adatbázisban.",
|
||||||
|
"select-parser": "Válasszon elemzőt",
|
||||||
|
"natural-language-processor": "Természetes nyelvi feldolgozó",
|
||||||
|
"brute-parser": "Brute elemző",
|
||||||
|
"parse-all": "Összes elemzése",
|
||||||
|
"no-unit": "Mértékegység nélkül",
|
||||||
|
"missing-unit": "Hiányzó mértékegység létrehozása: {unit}",
|
||||||
|
"missing-food": "Hiányzó élelmiszer létrehozása: {food}",
|
||||||
|
"no-food": "Élelmiszer nélküli"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"search": {
|
"search": {
|
||||||
"advanced-search": "Részletes keresés",
|
"advanced-search": "Részletes keresés",
|
||||||
@@ -619,7 +636,7 @@
|
|||||||
"import-summary": "Import összefoglaló",
|
"import-summary": "Import összefoglaló",
|
||||||
"partial-backup": "Részleges biztonsági mentés",
|
"partial-backup": "Részleges biztonsági mentés",
|
||||||
"unable-to-delete-backup": "Nem lehetett létrehozni a biztonsági mentést.",
|
"unable-to-delete-backup": "Nem lehetett létrehozni a biztonsági mentést.",
|
||||||
"experimental-description": "Backups are total snapshots of the database and data directory of the site. This includes all data and cannot be set to exclude subsets of data. You can think of this as a snapshot of Mealie at a specific time. These serve as a database agnostic way to export and import data, or back up the site to an external location.",
|
"experimental-description": "A biztonsági mentések az oldal adatbázisának és adatkönyvtárának teljes pillanatfelvételei. Ez az összes adatot tartalmazza, és nem lehet beállítani, hogy az adatok részhalmazait kizárja. Ezt úgy is elképzelheti, mint a Mealie egy adott időpontban készült pillanatfelvételét. Ezek adatbázis-független módon szolgálnak az adatok exportálására és importálására, vagy a webhely külső helyre történő mentésére.",
|
||||||
"backup-restore": "Biztonsági Mentés/Visszaállítás",
|
"backup-restore": "Biztonsági Mentés/Visszaállítás",
|
||||||
"back-restore-description": "A biztonsági mentés visszaállítása felülírja az adatbázisban és az adatkönyvtárban lévő összes aktuális adatot, és a biztonsági mentés tartalmával helyettesíti azokat. {cannot-be-undone} Ha a visszaállítás sikeres, akkor a rendszer kilépteti Önt.",
|
"back-restore-description": "A biztonsági mentés visszaállítása felülírja az adatbázisban és az adatkönyvtárban lévő összes aktuális adatot, és a biztonsági mentés tartalmával helyettesíti azokat. {cannot-be-undone} Ha a visszaállítás sikeres, akkor a rendszer kilépteti Önt.",
|
||||||
"cannot-be-undone": "Ezt a műveletet visszavonható - óvatosan használja.",
|
"cannot-be-undone": "Ezt a műveletet visszavonható - óvatosan használja.",
|
||||||
@@ -745,9 +762,9 @@
|
|||||||
"ldap-ready-success-text": "A szükséges LDAP-változók mind beállítva.",
|
"ldap-ready-success-text": "A szükséges LDAP-változók mind beállítva.",
|
||||||
"build": "Build",
|
"build": "Build",
|
||||||
"recipe-scraper-version": "Receptkinyerő verziója",
|
"recipe-scraper-version": "Receptkinyerő verziója",
|
||||||
"oidc-ready": "OIDC Ready",
|
"oidc-ready": "OIDC készen áll",
|
||||||
"oidc-ready-error-text": "Not all OIDC Values are configured. This can be ignored if you are not using OIDC Authentication.",
|
"oidc-ready-error-text": "Nem minden OIDC érték van beállítva. Ezt figyelmen kívül lehet hagyni ha nem használ OIDC hitelesítést.",
|
||||||
"oidc-ready-success-text": "Required OIDC variables are all set."
|
"oidc-ready-success-text": "A szükséges OIDC változók mind beállítva."
|
||||||
},
|
},
|
||||||
"shopping-list": {
|
"shopping-list": {
|
||||||
"all-lists": "Összes lista",
|
"all-lists": "Összes lista",
|
||||||
@@ -1001,6 +1018,12 @@
|
|||||||
"delete-recipes": "Receptek törlése",
|
"delete-recipes": "Receptek törlése",
|
||||||
"source-unit-will-be-deleted": "A forrás mennyiségi egység törlésre kerül"
|
"source-unit-will-be-deleted": "A forrás mennyiségi egység törlésre kerül"
|
||||||
},
|
},
|
||||||
|
"recipe-actions": {
|
||||||
|
"recipe-actions-data": "Recipe Actions Data",
|
||||||
|
"new-recipe-action": "New Recipe Action",
|
||||||
|
"edit-recipe-action": "Edit Recipe Action",
|
||||||
|
"action-type": "Action Type"
|
||||||
|
},
|
||||||
"create-alias": "Alias készítése",
|
"create-alias": "Alias készítése",
|
||||||
"manage-aliases": "Alias kezelése",
|
"manage-aliases": "Alias kezelése",
|
||||||
"seed-data": "Kezdőérték adat",
|
"seed-data": "Kezdőérték adat",
|
||||||
@@ -1159,12 +1182,12 @@
|
|||||||
"setup": {
|
"setup": {
|
||||||
"first-time-setup": "Első beállítás",
|
"first-time-setup": "Első beállítás",
|
||||||
"welcome-to-mealie-get-started": "Üdvözöl a Mealie! Vágjunk bele",
|
"welcome-to-mealie-get-started": "Üdvözöl a Mealie! Vágjunk bele",
|
||||||
"already-set-up-bring-to-homepage": "I'm already set up, just bring me to the homepage",
|
"already-set-up-bring-to-homepage": "Már kész is vagyok, vigyél az új kezdőoldalamra",
|
||||||
"common-settings-for-new-sites": "Here are some common settings for new sites",
|
"common-settings-for-new-sites": "Itt van egy pár alap beállítás az új oldaladhoz",
|
||||||
"setup-complete": "Beállítás kész!",
|
"setup-complete": "Beállítás kész!",
|
||||||
"here-are-a-few-things-to-help-you-get-started": "Here are a few things to help you get started with Mealie",
|
"here-are-a-few-things-to-help-you-get-started": "Itt van egy pár dolog ami segíthet a kezdésben a Mealie-vel",
|
||||||
"restore-from-v1-backup": "Van egy korábbi Mealie v1 biztonsági másolatod? Itt visszaállíthatod.",
|
"restore-from-v1-backup": "Van egy korábbi Mealie v1 biztonsági másolatod? Itt visszaállíthatod.",
|
||||||
"manage-profile-or-get-invite-link": "Manage your own profile, or grab an invite link to share with others."
|
"manage-profile-or-get-invite-link": "Alakítsa a profilját vagy szerezze meg a meghívó link-jét hogy megoszthassa másokkal."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"profile": {
|
"profile": {
|
||||||
@@ -1179,7 +1202,7 @@
|
|||||||
"storage-capacity": "Tárhely mérete",
|
"storage-capacity": "Tárhely mérete",
|
||||||
"storage-capacity-description": "A tárhely kapacitása az Ön által feltöltött képek és eszközök számításából adódik.",
|
"storage-capacity-description": "A tárhely kapacitása az Ön által feltöltött képek és eszközök számításából adódik.",
|
||||||
"personal": "Személyes",
|
"personal": "Személyes",
|
||||||
"personal-description": "These are settings that are personal to you. Changes here won't affect other users.",
|
"personal-description": "Ezek a beállítások az Ön személyes beállításai. Az itt végzett változtatások nincsenek hatással más felhasználókra.",
|
||||||
"user-settings": "Felhasználói beállítások",
|
"user-settings": "Felhasználói beállítások",
|
||||||
"user-settings-description": "Itt kezelheti beállításait, módosíthatja jelszavát és frissítheti e-mail címét.",
|
"user-settings-description": "Itt kezelheti beállításait, módosíthatja jelszavát és frissítheti e-mail címét.",
|
||||||
"api-tokens-description": "API kulcsok kezelése külső alkalmazásokból.",
|
"api-tokens-description": "API kulcsok kezelése külső alkalmazásokból.",
|
||||||
|
|||||||
@@ -64,6 +64,7 @@
|
|||||||
"something-went-wrong": "Something Went Wrong!",
|
"something-went-wrong": "Something Went Wrong!",
|
||||||
"subscribed-events": "Subscribed Events",
|
"subscribed-events": "Subscribed Events",
|
||||||
"test-message-sent": "Test Message Sent",
|
"test-message-sent": "Test Message Sent",
|
||||||
|
"message-sent": "Message Sent",
|
||||||
"new-notification": "New Notification",
|
"new-notification": "New Notification",
|
||||||
"event-notifiers": "Event Notifiers",
|
"event-notifiers": "Event Notifiers",
|
||||||
"apprise-url-skipped-if-blank": "Apprise URL (skipped if blank)",
|
"apprise-url-skipped-if-blank": "Apprise URL (skipped if blank)",
|
||||||
@@ -160,6 +161,7 @@
|
|||||||
"test": "Test",
|
"test": "Test",
|
||||||
"themes": "Themes",
|
"themes": "Themes",
|
||||||
"thursday": "Thursday",
|
"thursday": "Thursday",
|
||||||
|
"title": "Title",
|
||||||
"token": "Token",
|
"token": "Token",
|
||||||
"tuesday": "Tuesday",
|
"tuesday": "Tuesday",
|
||||||
"type": "Type",
|
"type": "Type",
|
||||||
@@ -582,7 +584,22 @@
|
|||||||
"upload-image": "Upload image",
|
"upload-image": "Upload image",
|
||||||
"screen-awake": "Keep Screen Awake",
|
"screen-awake": "Keep Screen Awake",
|
||||||
"remove-image": "Remove image",
|
"remove-image": "Remove image",
|
||||||
"nextStep": "Next step"
|
"nextStep": "Next step",
|
||||||
|
"recipe-actions": "Recipe Actions",
|
||||||
|
"parser": {
|
||||||
|
"experimental-alert-text": "Mealie uses natural language processing to parse and create units and food items for your recipe ingredients. This feature is experimental and may not always work as expected. If you prefer not to use the parsed results, you can select 'Cancel' and your changes will not be saved.",
|
||||||
|
"ingredient-parser": "Ingredient Parser",
|
||||||
|
"explanation": "To use the ingredient parser, click the 'Parse All' button to start the process. Once the processed ingredients are available, you can review the items and verify that they were parsed correctly. The model's confidence score is displayed on the right of the item title. This score is an average of all the individual scores and may not always be completely accurate.",
|
||||||
|
"alerts-explainer": "Alerts will be displayed if a matching foods or unit is found but does not exists in the database.",
|
||||||
|
"select-parser": "Select Parser",
|
||||||
|
"natural-language-processor": "Natural Language Processor",
|
||||||
|
"brute-parser": "Brute Parser",
|
||||||
|
"parse-all": "Parse All",
|
||||||
|
"no-unit": "No unit",
|
||||||
|
"missing-unit": "Create missing unit: {unit}",
|
||||||
|
"missing-food": "Create missing food: {food}",
|
||||||
|
"no-food": "No Food"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"search": {
|
"search": {
|
||||||
"advanced-search": "Advanced Search",
|
"advanced-search": "Advanced Search",
|
||||||
@@ -1001,6 +1018,12 @@
|
|||||||
"delete-recipes": "Delete Recipes",
|
"delete-recipes": "Delete Recipes",
|
||||||
"source-unit-will-be-deleted": "Source Unit will be deleted"
|
"source-unit-will-be-deleted": "Source Unit will be deleted"
|
||||||
},
|
},
|
||||||
|
"recipe-actions": {
|
||||||
|
"recipe-actions-data": "Recipe Actions Data",
|
||||||
|
"new-recipe-action": "New Recipe Action",
|
||||||
|
"edit-recipe-action": "Edit Recipe Action",
|
||||||
|
"action-type": "Action Type"
|
||||||
|
},
|
||||||
"create-alias": "Create Alias",
|
"create-alias": "Create Alias",
|
||||||
"manage-aliases": "Manage Aliases",
|
"manage-aliases": "Manage Aliases",
|
||||||
"seed-data": "Seed Data",
|
"seed-data": "Seed Data",
|
||||||
|
|||||||
@@ -64,6 +64,7 @@
|
|||||||
"something-went-wrong": "Si è verificato un errore!",
|
"something-went-wrong": "Si è verificato un errore!",
|
||||||
"subscribed-events": "Eventi Sottoscritti",
|
"subscribed-events": "Eventi Sottoscritti",
|
||||||
"test-message-sent": "Messaggio di prova inviato",
|
"test-message-sent": "Messaggio di prova inviato",
|
||||||
|
"message-sent": "Message Sent",
|
||||||
"new-notification": "Nuova Notifica",
|
"new-notification": "Nuova Notifica",
|
||||||
"event-notifiers": "Notifiche Evento",
|
"event-notifiers": "Notifiche Evento",
|
||||||
"apprise-url-skipped-if-blank": "Url di Apprise (ignorato se vuoto)",
|
"apprise-url-skipped-if-blank": "Url di Apprise (ignorato se vuoto)",
|
||||||
@@ -85,7 +86,7 @@
|
|||||||
"clear": "Resetta",
|
"clear": "Resetta",
|
||||||
"close": "Chiudi",
|
"close": "Chiudi",
|
||||||
"confirm": "Conferma",
|
"confirm": "Conferma",
|
||||||
"confirm-how-does-everything-look": "How does everything look?",
|
"confirm-how-does-everything-look": "Come ti sembra tutto questo?",
|
||||||
"confirm-delete-generic": "Sei sicuro di volere eliminare?",
|
"confirm-delete-generic": "Sei sicuro di volere eliminare?",
|
||||||
"copied_message": "Copiato!",
|
"copied_message": "Copiato!",
|
||||||
"create": "Crea",
|
"create": "Crea",
|
||||||
@@ -160,6 +161,7 @@
|
|||||||
"test": "Test",
|
"test": "Test",
|
||||||
"themes": "Temi",
|
"themes": "Temi",
|
||||||
"thursday": "Giovedì",
|
"thursday": "Giovedì",
|
||||||
|
"title": "Title",
|
||||||
"token": "Token",
|
"token": "Token",
|
||||||
"tuesday": "Martedì",
|
"tuesday": "Martedì",
|
||||||
"type": "Tipo",
|
"type": "Tipo",
|
||||||
@@ -174,7 +176,7 @@
|
|||||||
"units": "Unità",
|
"units": "Unità",
|
||||||
"back": "Indietro",
|
"back": "Indietro",
|
||||||
"next": "Avanti",
|
"next": "Avanti",
|
||||||
"start": "Start",
|
"start": "Inizia",
|
||||||
"toggle-view": "Cambia Vista",
|
"toggle-view": "Cambia Vista",
|
||||||
"date": "Data",
|
"date": "Data",
|
||||||
"id": "Id",
|
"id": "Id",
|
||||||
@@ -208,7 +210,7 @@
|
|||||||
"unsaved-changes": "Sono state apportate modifiche non salvate. Salvare prima di uscire? Premi Ok per salvare, Annulla per scartare le modifiche.",
|
"unsaved-changes": "Sono state apportate modifiche non salvate. Salvare prima di uscire? Premi Ok per salvare, Annulla per scartare le modifiche.",
|
||||||
"clipboard-copy-failure": "Impossibile copiare negli appunti.",
|
"clipboard-copy-failure": "Impossibile copiare negli appunti.",
|
||||||
"confirm-delete-generic-items": "Sei sicuro di voler eliminare i seguenti elementi?",
|
"confirm-delete-generic-items": "Sei sicuro di voler eliminare i seguenti elementi?",
|
||||||
"organizers": "Organizers"
|
"organizers": "Organizzatori"
|
||||||
},
|
},
|
||||||
"group": {
|
"group": {
|
||||||
"are-you-sure-you-want-to-delete-the-group": "Sei sicuro di volerlo eliminare <b>{groupName}<b/>'?",
|
"are-you-sure-you-want-to-delete-the-group": "Sei sicuro di volerlo eliminare <b>{groupName}<b/>'?",
|
||||||
@@ -244,8 +246,8 @@
|
|||||||
"group-preferences": "Preferenze Gruppo",
|
"group-preferences": "Preferenze Gruppo",
|
||||||
"private-group": "Gruppo Privato",
|
"private-group": "Gruppo Privato",
|
||||||
"private-group-description": "Impostando il tuo gruppo su privato verranno ripristinate tutte le opzioni di visualizzazione pubblica. Questa opzione sovrascrive le impostazioni di visualizzazione pubblica della singola ricetta.",
|
"private-group-description": "Impostando il tuo gruppo su privato verranno ripristinate tutte le opzioni di visualizzazione pubblica. Questa opzione sovrascrive le impostazioni di visualizzazione pubblica della singola ricetta.",
|
||||||
"enable-public-access": "Enable Public Access",
|
"enable-public-access": "Abilita accesso pubblico",
|
||||||
"enable-public-access-description": "Make group recipes public by default, and allow visitors to view recipes without logging-in",
|
"enable-public-access-description": "Rendi pubbliche le ricette di gruppo per impostazione predefinita, e consenti ai visitatori di visualizzare le ricette senza effettuare l'accesso",
|
||||||
"allow-users-outside-of-your-group-to-see-your-recipes": "Consenti agli utenti al di fuori del tuo gruppo di vedere le tue ricette",
|
"allow-users-outside-of-your-group-to-see-your-recipes": "Consenti agli utenti al di fuori del tuo gruppo di vedere le tue ricette",
|
||||||
"allow-users-outside-of-your-group-to-see-your-recipes-description": "Se abilitato, è possibile utilizzare un link pubblico per condividere ricette specifiche senza autorizzare l'utente. Se disabilitato, puoi condividere ricette solo con gli utenti che sono nel tuo gruppo o con un link privato pre-generato",
|
"allow-users-outside-of-your-group-to-see-your-recipes-description": "Se abilitato, è possibile utilizzare un link pubblico per condividere ricette specifiche senza autorizzare l'utente. Se disabilitato, puoi condividere ricette solo con gli utenti che sono nel tuo gruppo o con un link privato pre-generato",
|
||||||
"show-nutrition-information": "Mostra informazioni nutrizionali",
|
"show-nutrition-information": "Mostra informazioni nutrizionali",
|
||||||
@@ -359,11 +361,11 @@
|
|||||||
},
|
},
|
||||||
"recipe-data-migrations": "Migrazione Dati Ricetta",
|
"recipe-data-migrations": "Migrazione Dati Ricetta",
|
||||||
"recipe-data-migrations-explanation": "Le ricette possono essere migrate da un'altra applicazione supportata da Mealie. Questo è un ottimo modo per iniziare con Mealie.",
|
"recipe-data-migrations-explanation": "Le ricette possono essere migrate da un'altra applicazione supportata da Mealie. Questo è un ottimo modo per iniziare con Mealie.",
|
||||||
"coming-from-another-application-or-an-even-older-version-of-mealie": "Coming from another application or an even older version of Mealie? Check out migrations and see if your data can be imported.",
|
"coming-from-another-application-or-an-even-older-version-of-mealie": "Arrivi da un'altra applicazione o da una versione più vecchia di Mealie? Scopri le migrazioni e scopri se i tuoi dati possono essere importati.",
|
||||||
"choose-migration-type": "Scegli Il Tipo Di Migrazione",
|
"choose-migration-type": "Scegli Il Tipo Di Migrazione",
|
||||||
"tag-all-recipes": "Etichetta tutte le ricette con {tag-name} etichetta",
|
"tag-all-recipes": "Etichetta tutte le ricette con {tag-name} etichetta",
|
||||||
"nextcloud-text": "Le ricette di Nextcloud possono essere importate da un file zip che contiene i dati memorizzati in Nextcloud. Osserva la struttura della cartella di esempio qui sotto per assicurarti che le tue ricette siano in grado di essere importate.",
|
"nextcloud-text": "Le ricette di Nextcloud possono essere importate da un file zip che contiene i dati memorizzati in Nextcloud. Osserva la struttura della cartella di esempio qui sotto per assicurarti che le tue ricette siano in grado di essere importate.",
|
||||||
"chowdown-text": "Mealie natively supports the chowdown repository format. Download the code repository as a .zip file and upload it below.",
|
"chowdown-text": "Mealie supporta nativamente il formato del repository chowdown. Scarica il repository del codice come file .zip e caricalo qui sotto.",
|
||||||
"recipe-1": "Ricetta 1",
|
"recipe-1": "Ricetta 1",
|
||||||
"recipe-2": "Ricetta 2",
|
"recipe-2": "Ricetta 2",
|
||||||
"paprika-text": "Mealie può importare ricette dall'applicazione Paprika. Esporta le tue ricette da paprika, rinomina l'estensione di esportazione in .zip e caricala qui sotto.",
|
"paprika-text": "Mealie può importare ricette dall'applicazione Paprika. Esporta le tue ricette da paprika, rinomina l'estensione di esportazione in .zip e caricala qui sotto.",
|
||||||
@@ -373,8 +375,8 @@
|
|||||||
"description-long": "Mealie può importare le ricette da Plan to Eat."
|
"description-long": "Mealie può importare le ricette da Plan to Eat."
|
||||||
},
|
},
|
||||||
"myrecipebox": {
|
"myrecipebox": {
|
||||||
"title": "My Recipe Box",
|
"title": "Il mio ricettario",
|
||||||
"description-long": "Mealie can import recipes from My Recipe Box. Export your recipes in CSV format, then upload the .csv file below."
|
"description-long": "Mealie può importare ricette da My Recipe Box. Esporta le tue ricette in formato HTML, quindi carica il .zip qui sotto."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"new-recipe": {
|
"new-recipe": {
|
||||||
@@ -547,8 +549,8 @@
|
|||||||
"looking-for-migrations": "Stai Cercando Le Migrazioni?",
|
"looking-for-migrations": "Stai Cercando Le Migrazioni?",
|
||||||
"import-with-url": "Importa da URL",
|
"import-with-url": "Importa da URL",
|
||||||
"create-recipe": "Crea Ricetta",
|
"create-recipe": "Crea Ricetta",
|
||||||
"create-recipe-description": "Create a new recipe from scratch.",
|
"create-recipe-description": "Crea una nuova ricetta da zero.",
|
||||||
"create-recipes": "Create Recipes",
|
"create-recipes": "Crea Ricette",
|
||||||
"import-with-zip": "Importa da .zip",
|
"import-with-zip": "Importa da .zip",
|
||||||
"create-recipe-from-an-image": "Crea ricetta da un'immagine",
|
"create-recipe-from-an-image": "Crea ricetta da un'immagine",
|
||||||
"bulk-url-import": "Importazione multipla URL",
|
"bulk-url-import": "Importazione multipla URL",
|
||||||
@@ -582,7 +584,22 @@
|
|||||||
"upload-image": "Carica immagine",
|
"upload-image": "Carica immagine",
|
||||||
"screen-awake": "Mantieni lo schermo acceso",
|
"screen-awake": "Mantieni lo schermo acceso",
|
||||||
"remove-image": "Rimuovi immagine",
|
"remove-image": "Rimuovi immagine",
|
||||||
"nextStep": "Passo successivo"
|
"nextStep": "Passo successivo",
|
||||||
|
"recipe-actions": "Recipe Actions",
|
||||||
|
"parser": {
|
||||||
|
"experimental-alert-text": "Mealie uses natural language processing to parse and create units and food items for your recipe ingredients. This feature is experimental and may not always work as expected. If you prefer not to use the parsed results, you can select 'Cancel' and your changes will not be saved.",
|
||||||
|
"ingredient-parser": "Ingredient Parser",
|
||||||
|
"explanation": "To use the ingredient parser, click the 'Parse All' button to start the process. Once the processed ingredients are available, you can review the items and verify that they were parsed correctly. The model's confidence score is displayed on the right of the item title. This score is an average of all the individual scores and may not always be completely accurate.",
|
||||||
|
"alerts-explainer": "Alerts will be displayed if a matching foods or unit is found but does not exists in the database.",
|
||||||
|
"select-parser": "Select Parser",
|
||||||
|
"natural-language-processor": "Natural Language Processor",
|
||||||
|
"brute-parser": "Brute Parser",
|
||||||
|
"parse-all": "Parse All",
|
||||||
|
"no-unit": "No unit",
|
||||||
|
"missing-unit": "Create missing unit: {unit}",
|
||||||
|
"missing-food": "Create missing food: {food}",
|
||||||
|
"no-food": "No Food"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"search": {
|
"search": {
|
||||||
"advanced-search": "Ricerca Avanzata",
|
"advanced-search": "Ricerca Avanzata",
|
||||||
@@ -745,9 +762,9 @@
|
|||||||
"ldap-ready-success-text": "Le variabili LDAP richieste sono tutte configurate.",
|
"ldap-ready-success-text": "Le variabili LDAP richieste sono tutte configurate.",
|
||||||
"build": "Versione",
|
"build": "Versione",
|
||||||
"recipe-scraper-version": "Versione Recipe Scraper",
|
"recipe-scraper-version": "Versione Recipe Scraper",
|
||||||
"oidc-ready": "OIDC Ready",
|
"oidc-ready": "Pronto per OIDC",
|
||||||
"oidc-ready-error-text": "Not all OIDC Values are configured. This can be ignored if you are not using OIDC Authentication.",
|
"oidc-ready-error-text": "I valori OIDC non sono configurati. Questo può essere ignorato se non si utilizza Autenticazione OIDC.",
|
||||||
"oidc-ready-success-text": "Required OIDC variables are all set."
|
"oidc-ready-success-text": "Le variabili OIDC richieste sono tutte impostate."
|
||||||
},
|
},
|
||||||
"shopping-list": {
|
"shopping-list": {
|
||||||
"all-lists": "Tutte le Liste",
|
"all-lists": "Tutte le Liste",
|
||||||
@@ -855,11 +872,11 @@
|
|||||||
"link-id": "Link ID",
|
"link-id": "Link ID",
|
||||||
"link-name": "Link Nome",
|
"link-name": "Link Nome",
|
||||||
"login": "Login",
|
"login": "Login",
|
||||||
"login-oidc": "Login with",
|
"login-oidc": "Accedi con",
|
||||||
"or": "or",
|
"or": "oppure",
|
||||||
"logout": "Logout",
|
"logout": "Logout",
|
||||||
"manage-users": "Gestisci Utenti",
|
"manage-users": "Gestisci Utenti",
|
||||||
"manage-users-description": "Create and manage users.",
|
"manage-users-description": "Crea e gestisci gli utenti.",
|
||||||
"new-password": "Nuova Password",
|
"new-password": "Nuova Password",
|
||||||
"new-user": "Nuovo Utente",
|
"new-user": "Nuovo Utente",
|
||||||
"password-has-been-reset-to-the-default-password": "La password è stata reimpostata a quella di default",
|
"password-has-been-reset-to-the-default-password": "La password è stata reimpostata a quella di default",
|
||||||
@@ -1001,6 +1018,12 @@
|
|||||||
"delete-recipes": "Elimina Ricette",
|
"delete-recipes": "Elimina Ricette",
|
||||||
"source-unit-will-be-deleted": "L'unità di origine verrà eliminata"
|
"source-unit-will-be-deleted": "L'unità di origine verrà eliminata"
|
||||||
},
|
},
|
||||||
|
"recipe-actions": {
|
||||||
|
"recipe-actions-data": "Recipe Actions Data",
|
||||||
|
"new-recipe-action": "New Recipe Action",
|
||||||
|
"edit-recipe-action": "Edit Recipe Action",
|
||||||
|
"action-type": "Action Type"
|
||||||
|
},
|
||||||
"create-alias": "Crea Alias",
|
"create-alias": "Crea Alias",
|
||||||
"manage-aliases": "Gestisci Alias",
|
"manage-aliases": "Gestisci Alias",
|
||||||
"seed-data": "Dati Predefiniti",
|
"seed-data": "Dati Predefiniti",
|
||||||
@@ -1157,32 +1180,32 @@
|
|||||||
"no-logs-found": "Nessun Log Trovato",
|
"no-logs-found": "Nessun Log Trovato",
|
||||||
"tasks": "Compiti",
|
"tasks": "Compiti",
|
||||||
"setup": {
|
"setup": {
|
||||||
"first-time-setup": "First Time Setup",
|
"first-time-setup": "Configurazione iniziale",
|
||||||
"welcome-to-mealie-get-started": "Welcome to Mealie! Let's get started",
|
"welcome-to-mealie-get-started": "Un benvenuto su Mealie! Iniziamo",
|
||||||
"already-set-up-bring-to-homepage": "I'm already set up, just bring me to the homepage",
|
"already-set-up-bring-to-homepage": "Ho già configurato tutto, portami alla pagina iniziale",
|
||||||
"common-settings-for-new-sites": "Here are some common settings for new sites",
|
"common-settings-for-new-sites": "Ecco alcune impostazioni comuni per i nuovi siti",
|
||||||
"setup-complete": "Setup Complete!",
|
"setup-complete": "Configurazione completata!",
|
||||||
"here-are-a-few-things-to-help-you-get-started": "Here are a few things to help you get started with Mealie",
|
"here-are-a-few-things-to-help-you-get-started": "Qui ci sono alcune cose per aiutarvi a iniziare con Mealie",
|
||||||
"restore-from-v1-backup": "Have a backup from a previous instance of Mealie v1? You can restore it here.",
|
"restore-from-v1-backup": "Hai un backup da un'istanza precedente di Mealie v1? Puoi ripristinarlo qui.",
|
||||||
"manage-profile-or-get-invite-link": "Manage your own profile, or grab an invite link to share with others."
|
"manage-profile-or-get-invite-link": "Gestisci il tuo profilo, o parti da un link di invito per condividere con gli altri."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"profile": {
|
"profile": {
|
||||||
"welcome-user": "👋 Welcome, {0}!",
|
"welcome-user": "👋 Benvenutǝ, {0}!",
|
||||||
"description": "Gestisci il tuo profilo, le ricette e le impostazioni di gruppo.",
|
"description": "Gestisci il tuo profilo, le ricette e le impostazioni di gruppo.",
|
||||||
"get-invite-link": "Ottieni Link Di Invito",
|
"get-invite-link": "Ottieni Link Di Invito",
|
||||||
"get-public-link": "Ottieni link pubblico",
|
"get-public-link": "Ottieni link pubblico",
|
||||||
"account-summary": "Riepilogo Account",
|
"account-summary": "Riepilogo Account",
|
||||||
"account-summary-description": "Here's a summary of your group's information.",
|
"account-summary-description": "Ecco un riepilogo delle informazioni del tuo gruppo.",
|
||||||
"group-statistics": "Statistiche Gruppo",
|
"group-statistics": "Statistiche Gruppo",
|
||||||
"group-statistics-description": "Le statistiche di gruppo forniscono alcune informazioni su come stai usando Mealie.",
|
"group-statistics-description": "Le statistiche di gruppo forniscono alcune informazioni su come stai usando Mealie.",
|
||||||
"storage-capacity": "Capacità di Archiviazione",
|
"storage-capacity": "Capacità di Archiviazione",
|
||||||
"storage-capacity-description": "La capacità di archiviazione è data dall'insieme delle immagini e delle risorse caricate.",
|
"storage-capacity-description": "La capacità di archiviazione è data dall'insieme delle immagini e delle risorse caricate.",
|
||||||
"personal": "Personale",
|
"personal": "Personale",
|
||||||
"personal-description": "These are settings that are personal to you. Changes here won't affect other users.",
|
"personal-description": "Queste sono le tue impostazioni personali. Le modifiche non influenzeranno gli altri utenti.",
|
||||||
"user-settings": "Impostazioni Utente",
|
"user-settings": "Impostazioni Utente",
|
||||||
"user-settings-description": "Manage your preferences, change your password, and update your email.",
|
"user-settings-description": "Gestisci le tue preferenze, modifica la tua password e aggiorna la tua email.",
|
||||||
"api-tokens-description": "Manage your API Tokens for access from external applications.",
|
"api-tokens-description": "Gestisci i tuoi Token API per l'accesso da applicazioni esterne.",
|
||||||
"group-description": "Questi elementi sono condivisi all'interno del tuo gruppo. Modificando uno di essi cambierà per l'intero gruppo!",
|
"group-description": "Questi elementi sono condivisi all'interno del tuo gruppo. Modificando uno di essi cambierà per l'intero gruppo!",
|
||||||
"group-settings": "Impostazioni Gruppo",
|
"group-settings": "Impostazioni Gruppo",
|
||||||
"group-settings-description": "Gestisci le impostazioni comuni del gruppo, come il piano alimentare e impostazioni di privacy.",
|
"group-settings-description": "Gestisci le impostazioni comuni del gruppo, come il piano alimentare e impostazioni di privacy.",
|
||||||
@@ -1193,9 +1216,9 @@
|
|||||||
"notifiers": "Notifiche",
|
"notifiers": "Notifiche",
|
||||||
"notifiers-description": "Imposta email e notifiche push che si attivano per eventi specifici.",
|
"notifiers-description": "Imposta email e notifiche push che si attivano per eventi specifici.",
|
||||||
"manage-data": "Gestisci Dati",
|
"manage-data": "Gestisci Dati",
|
||||||
"manage-data-description": "Manage your Mealie data; Foods, Units, Categories, Tags and more.",
|
"manage-data-description": "Gestisci i tuoi dati di Mealie; Alimenti, Unità, Categorie, Tag e altro ancora.",
|
||||||
"data-migrations": "Migrazioni Dati",
|
"data-migrations": "Migrazioni Dati",
|
||||||
"data-migrations-description": "Migrate your existing data from other applications like Nextcloud Recipes and Chowdown.",
|
"data-migrations-description": "Migra i dati esistenti da altre applicazioni come Nextcloud Recipes e Chowdown.",
|
||||||
"email-sent": "Email Inviata",
|
"email-sent": "Email Inviata",
|
||||||
"error-sending-email": "Errore Nell'Invio Email",
|
"error-sending-email": "Errore Nell'Invio Email",
|
||||||
"personal-information": "Informazioni Personali",
|
"personal-information": "Informazioni Personali",
|
||||||
|
|||||||
@@ -64,6 +64,7 @@
|
|||||||
"something-went-wrong": "問題が発生しました",
|
"something-went-wrong": "問題が発生しました",
|
||||||
"subscribed-events": "購読中のイベント",
|
"subscribed-events": "購読中のイベント",
|
||||||
"test-message-sent": "テストメッセージを送信しました",
|
"test-message-sent": "テストメッセージを送信しました",
|
||||||
|
"message-sent": "Message Sent",
|
||||||
"new-notification": "新着通知",
|
"new-notification": "新着通知",
|
||||||
"event-notifiers": "イベント通知",
|
"event-notifiers": "イベント通知",
|
||||||
"apprise-url-skipped-if-blank": "通知用URL (空欄の場合はスキップ)",
|
"apprise-url-skipped-if-blank": "通知用URL (空欄の場合はスキップ)",
|
||||||
@@ -160,6 +161,7 @@
|
|||||||
"test": "テスト",
|
"test": "テスト",
|
||||||
"themes": "テーマ",
|
"themes": "テーマ",
|
||||||
"thursday": "木曜日",
|
"thursday": "木曜日",
|
||||||
|
"title": "Title",
|
||||||
"token": "トークン",
|
"token": "トークン",
|
||||||
"tuesday": "火曜日",
|
"tuesday": "火曜日",
|
||||||
"type": "タイプ",
|
"type": "タイプ",
|
||||||
@@ -582,7 +584,22 @@
|
|||||||
"upload-image": "画像をアップロード",
|
"upload-image": "画像をアップロード",
|
||||||
"screen-awake": "画面をスリープ状態にしない",
|
"screen-awake": "画面をスリープ状態にしない",
|
||||||
"remove-image": "画像を削除",
|
"remove-image": "画像を削除",
|
||||||
"nextStep": "次のステップ"
|
"nextStep": "次のステップ",
|
||||||
|
"recipe-actions": "Recipe Actions",
|
||||||
|
"parser": {
|
||||||
|
"experimental-alert-text": "Mealie uses natural language processing to parse and create units and food items for your recipe ingredients. This feature is experimental and may not always work as expected. If you prefer not to use the parsed results, you can select 'Cancel' and your changes will not be saved.",
|
||||||
|
"ingredient-parser": "Ingredient Parser",
|
||||||
|
"explanation": "To use the ingredient parser, click the 'Parse All' button to start the process. Once the processed ingredients are available, you can review the items and verify that they were parsed correctly. The model's confidence score is displayed on the right of the item title. This score is an average of all the individual scores and may not always be completely accurate.",
|
||||||
|
"alerts-explainer": "Alerts will be displayed if a matching foods or unit is found but does not exists in the database.",
|
||||||
|
"select-parser": "Select Parser",
|
||||||
|
"natural-language-processor": "Natural Language Processor",
|
||||||
|
"brute-parser": "Brute Parser",
|
||||||
|
"parse-all": "Parse All",
|
||||||
|
"no-unit": "No unit",
|
||||||
|
"missing-unit": "Create missing unit: {unit}",
|
||||||
|
"missing-food": "Create missing food: {food}",
|
||||||
|
"no-food": "No Food"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"search": {
|
"search": {
|
||||||
"advanced-search": "詳細検索",
|
"advanced-search": "詳細検索",
|
||||||
@@ -1001,6 +1018,12 @@
|
|||||||
"delete-recipes": "レシピを削除",
|
"delete-recipes": "レシピを削除",
|
||||||
"source-unit-will-be-deleted": "元の単位が削除されます"
|
"source-unit-will-be-deleted": "元の単位が削除されます"
|
||||||
},
|
},
|
||||||
|
"recipe-actions": {
|
||||||
|
"recipe-actions-data": "Recipe Actions Data",
|
||||||
|
"new-recipe-action": "New Recipe Action",
|
||||||
|
"edit-recipe-action": "Edit Recipe Action",
|
||||||
|
"action-type": "Action Type"
|
||||||
|
},
|
||||||
"create-alias": "エイリアスを作成",
|
"create-alias": "エイリアスを作成",
|
||||||
"manage-aliases": "エイリアスの管理",
|
"manage-aliases": "エイリアスの管理",
|
||||||
"seed-data": "シードデータ",
|
"seed-data": "シードデータ",
|
||||||
|
|||||||
@@ -64,6 +64,7 @@
|
|||||||
"something-went-wrong": "Something Went Wrong!",
|
"something-went-wrong": "Something Went Wrong!",
|
||||||
"subscribed-events": "구독한 이벤트",
|
"subscribed-events": "구독한 이벤트",
|
||||||
"test-message-sent": "Test Message Sent",
|
"test-message-sent": "Test Message Sent",
|
||||||
|
"message-sent": "Message Sent",
|
||||||
"new-notification": "새 알림",
|
"new-notification": "새 알림",
|
||||||
"event-notifiers": "Event Notifiers",
|
"event-notifiers": "Event Notifiers",
|
||||||
"apprise-url-skipped-if-blank": "Apprise URL (skipped if blank)",
|
"apprise-url-skipped-if-blank": "Apprise URL (skipped if blank)",
|
||||||
@@ -160,6 +161,7 @@
|
|||||||
"test": "Test",
|
"test": "Test",
|
||||||
"themes": "Themes",
|
"themes": "Themes",
|
||||||
"thursday": "목요일",
|
"thursday": "목요일",
|
||||||
|
"title": "Title",
|
||||||
"token": "Token",
|
"token": "Token",
|
||||||
"tuesday": "화요일",
|
"tuesday": "화요일",
|
||||||
"type": "Type",
|
"type": "Type",
|
||||||
@@ -582,7 +584,22 @@
|
|||||||
"upload-image": "이미지 업로드",
|
"upload-image": "이미지 업로드",
|
||||||
"screen-awake": "화면을 항상 켠 상태로 유지",
|
"screen-awake": "화면을 항상 켠 상태로 유지",
|
||||||
"remove-image": "이미지 제거",
|
"remove-image": "이미지 제거",
|
||||||
"nextStep": "다음 단계"
|
"nextStep": "다음 단계",
|
||||||
|
"recipe-actions": "Recipe Actions",
|
||||||
|
"parser": {
|
||||||
|
"experimental-alert-text": "Mealie uses natural language processing to parse and create units and food items for your recipe ingredients. This feature is experimental and may not always work as expected. If you prefer not to use the parsed results, you can select 'Cancel' and your changes will not be saved.",
|
||||||
|
"ingredient-parser": "Ingredient Parser",
|
||||||
|
"explanation": "To use the ingredient parser, click the 'Parse All' button to start the process. Once the processed ingredients are available, you can review the items and verify that they were parsed correctly. The model's confidence score is displayed on the right of the item title. This score is an average of all the individual scores and may not always be completely accurate.",
|
||||||
|
"alerts-explainer": "Alerts will be displayed if a matching foods or unit is found but does not exists in the database.",
|
||||||
|
"select-parser": "Select Parser",
|
||||||
|
"natural-language-processor": "Natural Language Processor",
|
||||||
|
"brute-parser": "Brute Parser",
|
||||||
|
"parse-all": "Parse All",
|
||||||
|
"no-unit": "No unit",
|
||||||
|
"missing-unit": "Create missing unit: {unit}",
|
||||||
|
"missing-food": "Create missing food: {food}",
|
||||||
|
"no-food": "No Food"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"search": {
|
"search": {
|
||||||
"advanced-search": "고급 검색",
|
"advanced-search": "고급 검색",
|
||||||
@@ -1001,6 +1018,12 @@
|
|||||||
"delete-recipes": "Delete Recipes",
|
"delete-recipes": "Delete Recipes",
|
||||||
"source-unit-will-be-deleted": "Source Unit will be deleted"
|
"source-unit-will-be-deleted": "Source Unit will be deleted"
|
||||||
},
|
},
|
||||||
|
"recipe-actions": {
|
||||||
|
"recipe-actions-data": "Recipe Actions Data",
|
||||||
|
"new-recipe-action": "New Recipe Action",
|
||||||
|
"edit-recipe-action": "Edit Recipe Action",
|
||||||
|
"action-type": "Action Type"
|
||||||
|
},
|
||||||
"create-alias": "Create Alias",
|
"create-alias": "Create Alias",
|
||||||
"manage-aliases": "Manage Aliases",
|
"manage-aliases": "Manage Aliases",
|
||||||
"seed-data": "Seed Data",
|
"seed-data": "Seed Data",
|
||||||
|
|||||||
@@ -64,6 +64,7 @@
|
|||||||
"something-went-wrong": "Įvyko klaida!",
|
"something-went-wrong": "Įvyko klaida!",
|
||||||
"subscribed-events": "Prenumeruojami įvykiai",
|
"subscribed-events": "Prenumeruojami įvykiai",
|
||||||
"test-message-sent": "Testinė žinutė išsiųsta",
|
"test-message-sent": "Testinė žinutė išsiųsta",
|
||||||
|
"message-sent": "Message Sent",
|
||||||
"new-notification": "Naujas pranešimas",
|
"new-notification": "Naujas pranešimas",
|
||||||
"event-notifiers": "Įvykių pranešimai",
|
"event-notifiers": "Įvykių pranešimai",
|
||||||
"apprise-url-skipped-if-blank": "Apprise URL (praleidžiama, jei tuščia)",
|
"apprise-url-skipped-if-blank": "Apprise URL (praleidžiama, jei tuščia)",
|
||||||
@@ -160,6 +161,7 @@
|
|||||||
"test": "Tikrinti",
|
"test": "Tikrinti",
|
||||||
"themes": "Temos",
|
"themes": "Temos",
|
||||||
"thursday": "Ketvirtadienis",
|
"thursday": "Ketvirtadienis",
|
||||||
|
"title": "Title",
|
||||||
"token": "Prieeigos raktas",
|
"token": "Prieeigos raktas",
|
||||||
"tuesday": "Antradienis",
|
"tuesday": "Antradienis",
|
||||||
"type": "Tipas",
|
"type": "Tipas",
|
||||||
@@ -582,7 +584,22 @@
|
|||||||
"upload-image": "Įkelti nuotrauką",
|
"upload-image": "Įkelti nuotrauką",
|
||||||
"screen-awake": "Keep Screen Awake",
|
"screen-awake": "Keep Screen Awake",
|
||||||
"remove-image": "Remove image",
|
"remove-image": "Remove image",
|
||||||
"nextStep": "Next step"
|
"nextStep": "Next step",
|
||||||
|
"recipe-actions": "Recipe Actions",
|
||||||
|
"parser": {
|
||||||
|
"experimental-alert-text": "Mealie uses natural language processing to parse and create units and food items for your recipe ingredients. This feature is experimental and may not always work as expected. If you prefer not to use the parsed results, you can select 'Cancel' and your changes will not be saved.",
|
||||||
|
"ingredient-parser": "Ingredient Parser",
|
||||||
|
"explanation": "To use the ingredient parser, click the 'Parse All' button to start the process. Once the processed ingredients are available, you can review the items and verify that they were parsed correctly. The model's confidence score is displayed on the right of the item title. This score is an average of all the individual scores and may not always be completely accurate.",
|
||||||
|
"alerts-explainer": "Alerts will be displayed if a matching foods or unit is found but does not exists in the database.",
|
||||||
|
"select-parser": "Select Parser",
|
||||||
|
"natural-language-processor": "Natural Language Processor",
|
||||||
|
"brute-parser": "Brute Parser",
|
||||||
|
"parse-all": "Parse All",
|
||||||
|
"no-unit": "No unit",
|
||||||
|
"missing-unit": "Create missing unit: {unit}",
|
||||||
|
"missing-food": "Create missing food: {food}",
|
||||||
|
"no-food": "No Food"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"search": {
|
"search": {
|
||||||
"advanced-search": "Išplėstinė paieška",
|
"advanced-search": "Išplėstinė paieška",
|
||||||
@@ -1001,6 +1018,12 @@
|
|||||||
"delete-recipes": "Ištrinti receptus",
|
"delete-recipes": "Ištrinti receptus",
|
||||||
"source-unit-will-be-deleted": "Pirminis vienetas bus ištrintas"
|
"source-unit-will-be-deleted": "Pirminis vienetas bus ištrintas"
|
||||||
},
|
},
|
||||||
|
"recipe-actions": {
|
||||||
|
"recipe-actions-data": "Recipe Actions Data",
|
||||||
|
"new-recipe-action": "New Recipe Action",
|
||||||
|
"edit-recipe-action": "Edit Recipe Action",
|
||||||
|
"action-type": "Action Type"
|
||||||
|
},
|
||||||
"create-alias": "Create Alias",
|
"create-alias": "Create Alias",
|
||||||
"manage-aliases": "Manage Aliases",
|
"manage-aliases": "Manage Aliases",
|
||||||
"seed-data": "Pradiniai duomenys",
|
"seed-data": "Pradiniai duomenys",
|
||||||
|
|||||||
@@ -1,18 +1,18 @@
|
|||||||
{
|
{
|
||||||
"about": {
|
"about": {
|
||||||
"about": "About",
|
"about": "Par",
|
||||||
"about-mealie": "About Mealie",
|
"about-mealie": "Par Mealie",
|
||||||
"api-docs": "API Docs",
|
"api-docs": "API Dokumentācija",
|
||||||
"api-port": "API Port",
|
"api-port": "API ports",
|
||||||
"application-mode": "Application Mode",
|
"application-mode": "Lietojumprogrammas režīms",
|
||||||
"database-type": "Database Type",
|
"database-type": "Datubāzes tips",
|
||||||
"database-url": "Database URL",
|
"database-url": "Datubāzes URL",
|
||||||
"default-group": "Default Group",
|
"default-group": "Noklusētā grupa",
|
||||||
"demo": "Demo",
|
"demo": "Demo",
|
||||||
"demo-status": "Demo Status",
|
"demo-status": "Demonstrācijas statuss",
|
||||||
"development": "Development",
|
"development": "Izstrāde",
|
||||||
"docs": "Docs",
|
"docs": "Dokumentācija",
|
||||||
"download-log": "Download Log",
|
"download-log": "Lejupielādēt žurnālu",
|
||||||
"download-recipe-json": "Last Scraped JSON",
|
"download-recipe-json": "Last Scraped JSON",
|
||||||
"github": "Github",
|
"github": "Github",
|
||||||
"log-lines": "Log Lines",
|
"log-lines": "Log Lines",
|
||||||
@@ -64,6 +64,7 @@
|
|||||||
"something-went-wrong": "Something Went Wrong!",
|
"something-went-wrong": "Something Went Wrong!",
|
||||||
"subscribed-events": "Subscribed Events",
|
"subscribed-events": "Subscribed Events",
|
||||||
"test-message-sent": "Test Message Sent",
|
"test-message-sent": "Test Message Sent",
|
||||||
|
"message-sent": "Message Sent",
|
||||||
"new-notification": "New Notification",
|
"new-notification": "New Notification",
|
||||||
"event-notifiers": "Event Notifiers",
|
"event-notifiers": "Event Notifiers",
|
||||||
"apprise-url-skipped-if-blank": "Apprise URL (skipped if blank)",
|
"apprise-url-skipped-if-blank": "Apprise URL (skipped if blank)",
|
||||||
@@ -160,6 +161,7 @@
|
|||||||
"test": "Test",
|
"test": "Test",
|
||||||
"themes": "Themes",
|
"themes": "Themes",
|
||||||
"thursday": "Thursday",
|
"thursday": "Thursday",
|
||||||
|
"title": "Title",
|
||||||
"token": "Token",
|
"token": "Token",
|
||||||
"tuesday": "Tuesday",
|
"tuesday": "Tuesday",
|
||||||
"type": "Type",
|
"type": "Type",
|
||||||
@@ -582,7 +584,22 @@
|
|||||||
"upload-image": "Upload image",
|
"upload-image": "Upload image",
|
||||||
"screen-awake": "Keep Screen Awake",
|
"screen-awake": "Keep Screen Awake",
|
||||||
"remove-image": "Remove image",
|
"remove-image": "Remove image",
|
||||||
"nextStep": "Next step"
|
"nextStep": "Next step",
|
||||||
|
"recipe-actions": "Recipe Actions",
|
||||||
|
"parser": {
|
||||||
|
"experimental-alert-text": "Mealie uses natural language processing to parse and create units and food items for your recipe ingredients. This feature is experimental and may not always work as expected. If you prefer not to use the parsed results, you can select 'Cancel' and your changes will not be saved.",
|
||||||
|
"ingredient-parser": "Ingredient Parser",
|
||||||
|
"explanation": "To use the ingredient parser, click the 'Parse All' button to start the process. Once the processed ingredients are available, you can review the items and verify that they were parsed correctly. The model's confidence score is displayed on the right of the item title. This score is an average of all the individual scores and may not always be completely accurate.",
|
||||||
|
"alerts-explainer": "Alerts will be displayed if a matching foods or unit is found but does not exists in the database.",
|
||||||
|
"select-parser": "Select Parser",
|
||||||
|
"natural-language-processor": "Natural Language Processor",
|
||||||
|
"brute-parser": "Brute Parser",
|
||||||
|
"parse-all": "Parse All",
|
||||||
|
"no-unit": "No unit",
|
||||||
|
"missing-unit": "Create missing unit: {unit}",
|
||||||
|
"missing-food": "Create missing food: {food}",
|
||||||
|
"no-food": "No Food"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"search": {
|
"search": {
|
||||||
"advanced-search": "Advanced Search",
|
"advanced-search": "Advanced Search",
|
||||||
@@ -1001,6 +1018,12 @@
|
|||||||
"delete-recipes": "Delete Recipes",
|
"delete-recipes": "Delete Recipes",
|
||||||
"source-unit-will-be-deleted": "Source Unit will be deleted"
|
"source-unit-will-be-deleted": "Source Unit will be deleted"
|
||||||
},
|
},
|
||||||
|
"recipe-actions": {
|
||||||
|
"recipe-actions-data": "Recipe Actions Data",
|
||||||
|
"new-recipe-action": "New Recipe Action",
|
||||||
|
"edit-recipe-action": "Edit Recipe Action",
|
||||||
|
"action-type": "Action Type"
|
||||||
|
},
|
||||||
"create-alias": "Create Alias",
|
"create-alias": "Create Alias",
|
||||||
"manage-aliases": "Manage Aliases",
|
"manage-aliases": "Manage Aliases",
|
||||||
"seed-data": "Seed Data",
|
"seed-data": "Seed Data",
|
||||||
|
|||||||
@@ -64,6 +64,7 @@
|
|||||||
"something-went-wrong": "Er is iets fout gegaan!",
|
"something-went-wrong": "Er is iets fout gegaan!",
|
||||||
"subscribed-events": "Geabonneerde gebeurtenissen",
|
"subscribed-events": "Geabonneerde gebeurtenissen",
|
||||||
"test-message-sent": "Testbericht verzonden",
|
"test-message-sent": "Testbericht verzonden",
|
||||||
|
"message-sent": "Bericht verstuurd",
|
||||||
"new-notification": "Nieuwe melding",
|
"new-notification": "Nieuwe melding",
|
||||||
"event-notifiers": "Meldingen van gebeurtenissen",
|
"event-notifiers": "Meldingen van gebeurtenissen",
|
||||||
"apprise-url-skipped-if-blank": "URL van Apprise (overgeslagen als veld leeg is)",
|
"apprise-url-skipped-if-blank": "URL van Apprise (overgeslagen als veld leeg is)",
|
||||||
@@ -160,6 +161,7 @@
|
|||||||
"test": "Test",
|
"test": "Test",
|
||||||
"themes": "Thema's",
|
"themes": "Thema's",
|
||||||
"thursday": "donderdag",
|
"thursday": "donderdag",
|
||||||
|
"title": "Titel",
|
||||||
"token": "Token",
|
"token": "Token",
|
||||||
"tuesday": "dinsdag",
|
"tuesday": "dinsdag",
|
||||||
"type": "Soort",
|
"type": "Soort",
|
||||||
@@ -582,7 +584,22 @@
|
|||||||
"upload-image": "Afbeelding uploaden",
|
"upload-image": "Afbeelding uploaden",
|
||||||
"screen-awake": "Scherm aan laten staan",
|
"screen-awake": "Scherm aan laten staan",
|
||||||
"remove-image": "Afbeelding verwijderen",
|
"remove-image": "Afbeelding verwijderen",
|
||||||
"nextStep": "Volgende stap"
|
"nextStep": "Volgende stap",
|
||||||
|
"recipe-actions": "Acties met recepten ",
|
||||||
|
"parser": {
|
||||||
|
"experimental-alert-text": "Mealie gebruikt natuurlijke taalverwerking om te ontleden en maakt eenheden en levensmiddelen voor de ingrediënten van je recept. Deze functie is experimenteel en werkt misschien niet altijd zoals verwacht. Als u liever niet de bewerkte resultaten gebruikt, kunt u 'Annuleren' selecteren en de wijzigingen worden niet opgeslagen.",
|
||||||
|
"ingredient-parser": "",
|
||||||
|
"explanation": "To use the ingredient parser, click the 'Parse All' button to start the process. Once the processed ingredients are available, you can review the items and verify that they were parsed correctly. The model's confidence score is displayed on the right of the item title. This score is an average of all the individual scores and may not always be completely accurate.",
|
||||||
|
"alerts-explainer": "Alerts will be displayed if a matching foods or unit is found but does not exists in the database.",
|
||||||
|
"select-parser": "Select Parser",
|
||||||
|
"natural-language-processor": "Natural Language Processor",
|
||||||
|
"brute-parser": "Brute Parser",
|
||||||
|
"parse-all": "Parse All",
|
||||||
|
"no-unit": "No unit",
|
||||||
|
"missing-unit": "Create missing unit: {unit}",
|
||||||
|
"missing-food": "Create missing food: {food}",
|
||||||
|
"no-food": "No Food"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"search": {
|
"search": {
|
||||||
"advanced-search": "Geavanceerd zoeken",
|
"advanced-search": "Geavanceerd zoeken",
|
||||||
@@ -1001,6 +1018,12 @@
|
|||||||
"delete-recipes": "Verwijder recepten",
|
"delete-recipes": "Verwijder recepten",
|
||||||
"source-unit-will-be-deleted": "Broneenheid zal worden verwijderd"
|
"source-unit-will-be-deleted": "Broneenheid zal worden verwijderd"
|
||||||
},
|
},
|
||||||
|
"recipe-actions": {
|
||||||
|
"recipe-actions-data": "Gegevens voor acties met recepten",
|
||||||
|
"new-recipe-action": "Nieuwe actie met recept",
|
||||||
|
"edit-recipe-action": "Pas actie met recept aan",
|
||||||
|
"action-type": "Soort actie"
|
||||||
|
},
|
||||||
"create-alias": "Maak alias",
|
"create-alias": "Maak alias",
|
||||||
"manage-aliases": "Beheer aliassen ",
|
"manage-aliases": "Beheer aliassen ",
|
||||||
"seed-data": "Voorbeeldgegevens",
|
"seed-data": "Voorbeeldgegevens",
|
||||||
|
|||||||
@@ -64,6 +64,7 @@
|
|||||||
"something-went-wrong": "Noe gikk galt!",
|
"something-went-wrong": "Noe gikk galt!",
|
||||||
"subscribed-events": "Abonnerte hendelser",
|
"subscribed-events": "Abonnerte hendelser",
|
||||||
"test-message-sent": "Testmelding sendt",
|
"test-message-sent": "Testmelding sendt",
|
||||||
|
"message-sent": "Melding sendt",
|
||||||
"new-notification": "Ny varsel",
|
"new-notification": "Ny varsel",
|
||||||
"event-notifiers": "Hendelsesvarsler",
|
"event-notifiers": "Hendelsesvarsler",
|
||||||
"apprise-url-skipped-if-blank": "Apprise URL (hoppes over hvis tom)",
|
"apprise-url-skipped-if-blank": "Apprise URL (hoppes over hvis tom)",
|
||||||
@@ -160,6 +161,7 @@
|
|||||||
"test": "Test",
|
"test": "Test",
|
||||||
"themes": "Temaer",
|
"themes": "Temaer",
|
||||||
"thursday": "Torsdag",
|
"thursday": "Torsdag",
|
||||||
|
"title": "Tittel",
|
||||||
"token": "Token",
|
"token": "Token",
|
||||||
"tuesday": "Tirsdag",
|
"tuesday": "Tirsdag",
|
||||||
"type": "Type",
|
"type": "Type",
|
||||||
@@ -208,7 +210,7 @@
|
|||||||
"unsaved-changes": "Du har ulagrede endringer. Ønsker du å lagre før du forlater? Trykk 'OK' for å lagre, 'Avbryt' for å forkaste endringene.",
|
"unsaved-changes": "Du har ulagrede endringer. Ønsker du å lagre før du forlater? Trykk 'OK' for å lagre, 'Avbryt' for å forkaste endringene.",
|
||||||
"clipboard-copy-failure": "Kunne ikke kopiere til utklippstavlen.",
|
"clipboard-copy-failure": "Kunne ikke kopiere til utklippstavlen.",
|
||||||
"confirm-delete-generic-items": "Er du sikker på at du vil følgende elementer?",
|
"confirm-delete-generic-items": "Er du sikker på at du vil følgende elementer?",
|
||||||
"organizers": "Organizers"
|
"organizers": "Organisatorer"
|
||||||
},
|
},
|
||||||
"group": {
|
"group": {
|
||||||
"are-you-sure-you-want-to-delete-the-group": "Er du sikker på at du vil slette <b>{groupName}<b/>?",
|
"are-you-sure-you-want-to-delete-the-group": "Er du sikker på at du vil slette <b>{groupName}<b/>?",
|
||||||
@@ -363,7 +365,7 @@
|
|||||||
"choose-migration-type": "Velg type overføring",
|
"choose-migration-type": "Velg type overføring",
|
||||||
"tag-all-recipes": "Merk alle oppskrifter med emneordet {tag-name}",
|
"tag-all-recipes": "Merk alle oppskrifter med emneordet {tag-name}",
|
||||||
"nextcloud-text": "Oppskrifter fra Nextcloud kan importeres fra en zip-fil som inneholder dataene lagret i Nextcloud. Se eksempelet på mappestrukture nedenfor for å sikre at oppskriftene kan importeres.",
|
"nextcloud-text": "Oppskrifter fra Nextcloud kan importeres fra en zip-fil som inneholder dataene lagret i Nextcloud. Se eksempelet på mappestrukture nedenfor for å sikre at oppskriftene kan importeres.",
|
||||||
"chowdown-text": "Mealie natively supports the chowdown repository format. Download the code repository as a .zip file and upload it below.",
|
"chowdown-text": "Mealie støtter Chowdown-arkivformatet. Last ned kodearkivet som en .zip-fil og last den opp nedenfor.",
|
||||||
"recipe-1": "Oppskrift 1",
|
"recipe-1": "Oppskrift 1",
|
||||||
"recipe-2": "Oppskrift 2",
|
"recipe-2": "Oppskrift 2",
|
||||||
"paprika-text": "Mealie kan importere oppskrifter fra Paprika. Eksporter oppskriftene fra Paprika, endre filnavnutvidelsen til .zip og last den opp nedenfor.",
|
"paprika-text": "Mealie kan importere oppskrifter fra Paprika. Eksporter oppskriftene fra Paprika, endre filnavnutvidelsen til .zip og last den opp nedenfor.",
|
||||||
@@ -374,7 +376,7 @@
|
|||||||
},
|
},
|
||||||
"myrecipebox": {
|
"myrecipebox": {
|
||||||
"title": "My Recipe Box",
|
"title": "My Recipe Box",
|
||||||
"description-long": "Mealie can import recipes from My Recipe Box. Export your recipes in CSV format, then upload the .csv file below."
|
"description-long": "Mealie kan importere oppskrifter fra My Recipe Box. Eksporter oppskrifter i CSV-format, og last deretter opp .csv-filen nedenfor."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"new-recipe": {
|
"new-recipe": {
|
||||||
@@ -582,7 +584,22 @@
|
|||||||
"upload-image": "Last opp bilde",
|
"upload-image": "Last opp bilde",
|
||||||
"screen-awake": "Hold skjermen på",
|
"screen-awake": "Hold skjermen på",
|
||||||
"remove-image": "Slett bilde",
|
"remove-image": "Slett bilde",
|
||||||
"nextStep": "Neste trinn"
|
"nextStep": "Neste trinn",
|
||||||
|
"recipe-actions": "Oppskriftshandlinger",
|
||||||
|
"parser": {
|
||||||
|
"experimental-alert-text": "Mealie uses natural language processing to parse and create units and food items for your recipe ingredients. This feature is experimental and may not always work as expected. If you prefer not to use the parsed results, you can select 'Cancel' and your changes will not be saved.",
|
||||||
|
"ingredient-parser": "Ingrediens-parser",
|
||||||
|
"explanation": "To use the ingredient parser, click the 'Parse All' button to start the process. Once the processed ingredients are available, you can review the items and verify that they were parsed correctly. The model's confidence score is displayed on the right of the item title. This score is an average of all the individual scores and may not always be completely accurate.",
|
||||||
|
"alerts-explainer": "Alerts will be displayed if a matching foods or unit is found but does not exists in the database.",
|
||||||
|
"select-parser": "Select Parser",
|
||||||
|
"natural-language-processor": "Natural Language Processor",
|
||||||
|
"brute-parser": "Brute Parser",
|
||||||
|
"parse-all": "Parse All",
|
||||||
|
"no-unit": "No unit",
|
||||||
|
"missing-unit": "Create missing unit: {unit}",
|
||||||
|
"missing-food": "Create missing food: {food}",
|
||||||
|
"no-food": "No Food"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"search": {
|
"search": {
|
||||||
"advanced-search": "Avansert søk",
|
"advanced-search": "Avansert søk",
|
||||||
@@ -1001,6 +1018,12 @@
|
|||||||
"delete-recipes": "Slett oppskrifter",
|
"delete-recipes": "Slett oppskrifter",
|
||||||
"source-unit-will-be-deleted": "Kildeenheten vil bli slettet"
|
"source-unit-will-be-deleted": "Kildeenheten vil bli slettet"
|
||||||
},
|
},
|
||||||
|
"recipe-actions": {
|
||||||
|
"recipe-actions-data": "Opppgavehandlings-data",
|
||||||
|
"new-recipe-action": "Ny oppskriftshandling",
|
||||||
|
"edit-recipe-action": "Rediger oppskriftshandling",
|
||||||
|
"action-type": "Handlingstype"
|
||||||
|
},
|
||||||
"create-alias": "Opprett alias",
|
"create-alias": "Opprett alias",
|
||||||
"manage-aliases": "Administrer aliaser",
|
"manage-aliases": "Administrer aliaser",
|
||||||
"seed-data": "Tilføringsdata",
|
"seed-data": "Tilføringsdata",
|
||||||
@@ -1168,21 +1191,21 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"profile": {
|
"profile": {
|
||||||
"welcome-user": "👋 Welcome, {0}!",
|
"welcome-user": "Velkommen, {0}!",
|
||||||
"description": "Administrer din profil, oppskrifter og gruppeinnstillinger.",
|
"description": "Administrer din profil, oppskrifter og gruppeinnstillinger.",
|
||||||
"get-invite-link": "Få invitasjonslenke",
|
"get-invite-link": "Få invitasjonslenke",
|
||||||
"get-public-link": "Få offentlig lenke",
|
"get-public-link": "Få offentlig lenke",
|
||||||
"account-summary": "Kontosammendrag",
|
"account-summary": "Kontosammendrag",
|
||||||
"account-summary-description": "Here's a summary of your group's information.",
|
"account-summary-description": "Her er en oppsummering av informasjonen til gruppen din.",
|
||||||
"group-statistics": "Gruppestatistikk",
|
"group-statistics": "Gruppestatistikk",
|
||||||
"group-statistics-description": "Gruppestatistikken din gir deg et innblikk i hvordan du bruker Mealie.",
|
"group-statistics-description": "Gruppestatistikken din gir deg et innblikk i hvordan du bruker Mealie.",
|
||||||
"storage-capacity": "Lagringskapasitet",
|
"storage-capacity": "Lagringskapasitet",
|
||||||
"storage-capacity-description": "Lagringskapasiteten er en beregning av bildene og ressursene du har lastet opp.",
|
"storage-capacity-description": "Lagringskapasiteten er en beregning av bildene og ressursene du har lastet opp.",
|
||||||
"personal": "Personlig",
|
"personal": "Personlig",
|
||||||
"personal-description": "These are settings that are personal to you. Changes here won't affect other users.",
|
"personal-description": "Dette er personlige innstillinger. Endringer gjort her påvirker ikke andre brukere.",
|
||||||
"user-settings": "Brukerinnstillinger",
|
"user-settings": "Brukerinnstillinger",
|
||||||
"user-settings-description": "Manage your preferences, change your password, and update your email.",
|
"user-settings-description": "Administrer innstillingene, endre passordet og oppdater e-postadressen din.",
|
||||||
"api-tokens-description": "Manage your API Tokens for access from external applications.",
|
"api-tokens-description": "Administrer dine API-tokens for tilgang fra eksterne programmer.",
|
||||||
"group-description": "Disse elementene deles innad i gruppen din. Redigering av elementenee vil føre til endringer for hele gruppen!",
|
"group-description": "Disse elementene deles innad i gruppen din. Redigering av elementenee vil føre til endringer for hele gruppen!",
|
||||||
"group-settings": "Gruppeinnstillinger",
|
"group-settings": "Gruppeinnstillinger",
|
||||||
"group-settings-description": "Administrer felles gruppeinnstillinger som innstillinger for måltidsplaner og personvern.",
|
"group-settings-description": "Administrer felles gruppeinnstillinger som innstillinger for måltidsplaner og personvern.",
|
||||||
@@ -1193,9 +1216,9 @@
|
|||||||
"notifiers": "Varslingsagenter",
|
"notifiers": "Varslingsagenter",
|
||||||
"notifiers-description": "Sett opp e-post- og pushvarsler som utløses av spesifikke hendelser.",
|
"notifiers-description": "Sett opp e-post- og pushvarsler som utløses av spesifikke hendelser.",
|
||||||
"manage-data": "Administrer data",
|
"manage-data": "Administrer data",
|
||||||
"manage-data-description": "Manage your Mealie data; Foods, Units, Categories, Tags and more.",
|
"manage-data-description": "Administrer dine Mealie-data; Ingredienser, enheter, kategorier, emneknagger og mer.",
|
||||||
"data-migrations": "Dataoverføringer",
|
"data-migrations": "Dataoverføringer",
|
||||||
"data-migrations-description": "Migrate your existing data from other applications like Nextcloud Recipes and Chowdown.",
|
"data-migrations-description": "Overfør eksisterende data fra andre programmer som Nextcloud Recipes og Chowdown.",
|
||||||
"email-sent": "E-post sendt",
|
"email-sent": "E-post sendt",
|
||||||
"error-sending-email": "Feil ved sending av e-post",
|
"error-sending-email": "Feil ved sending av e-post",
|
||||||
"personal-information": "Personlig informasjon",
|
"personal-information": "Personlig informasjon",
|
||||||
|
|||||||
@@ -64,6 +64,7 @@
|
|||||||
"something-went-wrong": "Coś poszło nie tak!",
|
"something-went-wrong": "Coś poszło nie tak!",
|
||||||
"subscribed-events": "Zasubskrybowane wydarzenia",
|
"subscribed-events": "Zasubskrybowane wydarzenia",
|
||||||
"test-message-sent": "Wiadomość została wysłana",
|
"test-message-sent": "Wiadomość została wysłana",
|
||||||
|
"message-sent": "Message Sent",
|
||||||
"new-notification": "Nowe powiadomienie",
|
"new-notification": "Nowe powiadomienie",
|
||||||
"event-notifiers": "Powiadomienia o zdarzeniach",
|
"event-notifiers": "Powiadomienia o zdarzeniach",
|
||||||
"apprise-url-skipped-if-blank": "URL Apprise (pominięty, jeśli puste)",
|
"apprise-url-skipped-if-blank": "URL Apprise (pominięty, jeśli puste)",
|
||||||
@@ -160,6 +161,7 @@
|
|||||||
"test": "Testuj",
|
"test": "Testuj",
|
||||||
"themes": "Motywy",
|
"themes": "Motywy",
|
||||||
"thursday": "Czwartek",
|
"thursday": "Czwartek",
|
||||||
|
"title": "Title",
|
||||||
"token": "Token",
|
"token": "Token",
|
||||||
"tuesday": "Wtorek",
|
"tuesday": "Wtorek",
|
||||||
"type": "Typ",
|
"type": "Typ",
|
||||||
@@ -582,7 +584,22 @@
|
|||||||
"upload-image": "Prześlij obraz",
|
"upload-image": "Prześlij obraz",
|
||||||
"screen-awake": "Pozostaw ekran włączony",
|
"screen-awake": "Pozostaw ekran włączony",
|
||||||
"remove-image": "Usuń obraz",
|
"remove-image": "Usuń obraz",
|
||||||
"nextStep": "Następny krok"
|
"nextStep": "Następny krok",
|
||||||
|
"recipe-actions": "Recipe Actions",
|
||||||
|
"parser": {
|
||||||
|
"experimental-alert-text": "Mealie uses natural language processing to parse and create units and food items for your recipe ingredients. This feature is experimental and may not always work as expected. If you prefer not to use the parsed results, you can select 'Cancel' and your changes will not be saved.",
|
||||||
|
"ingredient-parser": "Ingredient Parser",
|
||||||
|
"explanation": "To use the ingredient parser, click the 'Parse All' button to start the process. Once the processed ingredients are available, you can review the items and verify that they were parsed correctly. The model's confidence score is displayed on the right of the item title. This score is an average of all the individual scores and may not always be completely accurate.",
|
||||||
|
"alerts-explainer": "Alerts will be displayed if a matching foods or unit is found but does not exists in the database.",
|
||||||
|
"select-parser": "Select Parser",
|
||||||
|
"natural-language-processor": "Natural Language Processor",
|
||||||
|
"brute-parser": "Brute Parser",
|
||||||
|
"parse-all": "Parse All",
|
||||||
|
"no-unit": "No unit",
|
||||||
|
"missing-unit": "Create missing unit: {unit}",
|
||||||
|
"missing-food": "Create missing food: {food}",
|
||||||
|
"no-food": "No Food"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"search": {
|
"search": {
|
||||||
"advanced-search": "Wyszukiwanie zaawansowane",
|
"advanced-search": "Wyszukiwanie zaawansowane",
|
||||||
@@ -1001,6 +1018,12 @@
|
|||||||
"delete-recipes": "Usuń Przepisy",
|
"delete-recipes": "Usuń Przepisy",
|
||||||
"source-unit-will-be-deleted": "Jednostka źródłowa zostanie usunięta"
|
"source-unit-will-be-deleted": "Jednostka źródłowa zostanie usunięta"
|
||||||
},
|
},
|
||||||
|
"recipe-actions": {
|
||||||
|
"recipe-actions-data": "Recipe Actions Data",
|
||||||
|
"new-recipe-action": "New Recipe Action",
|
||||||
|
"edit-recipe-action": "Edit Recipe Action",
|
||||||
|
"action-type": "Action Type"
|
||||||
|
},
|
||||||
"create-alias": "Utwórz alias",
|
"create-alias": "Utwórz alias",
|
||||||
"manage-aliases": "Zarządzaj aliasami",
|
"manage-aliases": "Zarządzaj aliasami",
|
||||||
"seed-data": "Dane przykładowe",
|
"seed-data": "Dane przykładowe",
|
||||||
|
|||||||
@@ -64,6 +64,7 @@
|
|||||||
"something-went-wrong": "Algo deu errado!",
|
"something-went-wrong": "Algo deu errado!",
|
||||||
"subscribed-events": "Eventos Inscritos",
|
"subscribed-events": "Eventos Inscritos",
|
||||||
"test-message-sent": "Mensagem de teste enviada",
|
"test-message-sent": "Mensagem de teste enviada",
|
||||||
|
"message-sent": "Message Sent",
|
||||||
"new-notification": "Nova Notificação",
|
"new-notification": "Nova Notificação",
|
||||||
"event-notifiers": "Notificações de Eventos",
|
"event-notifiers": "Notificações de Eventos",
|
||||||
"apprise-url-skipped-if-blank": "URL Apprise (ignorado se estiver em branco)",
|
"apprise-url-skipped-if-blank": "URL Apprise (ignorado se estiver em branco)",
|
||||||
@@ -160,6 +161,7 @@
|
|||||||
"test": "Teste",
|
"test": "Teste",
|
||||||
"themes": "Temas",
|
"themes": "Temas",
|
||||||
"thursday": "Quinta-feira",
|
"thursday": "Quinta-feira",
|
||||||
|
"title": "Title",
|
||||||
"token": "Token",
|
"token": "Token",
|
||||||
"tuesday": "Terça-feira",
|
"tuesday": "Terça-feira",
|
||||||
"type": "Tipo",
|
"type": "Tipo",
|
||||||
@@ -582,7 +584,22 @@
|
|||||||
"upload-image": "Enviar imagem",
|
"upload-image": "Enviar imagem",
|
||||||
"screen-awake": "Manter a tela ligada",
|
"screen-awake": "Manter a tela ligada",
|
||||||
"remove-image": "Remover imagem",
|
"remove-image": "Remover imagem",
|
||||||
"nextStep": "Next step"
|
"nextStep": "Next step",
|
||||||
|
"recipe-actions": "Recipe Actions",
|
||||||
|
"parser": {
|
||||||
|
"experimental-alert-text": "Mealie uses natural language processing to parse and create units and food items for your recipe ingredients. This feature is experimental and may not always work as expected. If you prefer not to use the parsed results, you can select 'Cancel' and your changes will not be saved.",
|
||||||
|
"ingredient-parser": "Ingredient Parser",
|
||||||
|
"explanation": "To use the ingredient parser, click the 'Parse All' button to start the process. Once the processed ingredients are available, you can review the items and verify that they were parsed correctly. The model's confidence score is displayed on the right of the item title. This score is an average of all the individual scores and may not always be completely accurate.",
|
||||||
|
"alerts-explainer": "Alerts will be displayed if a matching foods or unit is found but does not exists in the database.",
|
||||||
|
"select-parser": "Select Parser",
|
||||||
|
"natural-language-processor": "Natural Language Processor",
|
||||||
|
"brute-parser": "Brute Parser",
|
||||||
|
"parse-all": "Parse All",
|
||||||
|
"no-unit": "No unit",
|
||||||
|
"missing-unit": "Create missing unit: {unit}",
|
||||||
|
"missing-food": "Create missing food: {food}",
|
||||||
|
"no-food": "No Food"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"search": {
|
"search": {
|
||||||
"advanced-search": "Pesquisa avançada",
|
"advanced-search": "Pesquisa avançada",
|
||||||
@@ -1001,6 +1018,12 @@
|
|||||||
"delete-recipes": "Excluir Receitas",
|
"delete-recipes": "Excluir Receitas",
|
||||||
"source-unit-will-be-deleted": "Unidade de origem será excluída"
|
"source-unit-will-be-deleted": "Unidade de origem será excluída"
|
||||||
},
|
},
|
||||||
|
"recipe-actions": {
|
||||||
|
"recipe-actions-data": "Recipe Actions Data",
|
||||||
|
"new-recipe-action": "New Recipe Action",
|
||||||
|
"edit-recipe-action": "Edit Recipe Action",
|
||||||
|
"action-type": "Action Type"
|
||||||
|
},
|
||||||
"create-alias": "Criar Apelido",
|
"create-alias": "Criar Apelido",
|
||||||
"manage-aliases": "Gerenciar apelidos",
|
"manage-aliases": "Gerenciar apelidos",
|
||||||
"seed-data": "Semear dados",
|
"seed-data": "Semear dados",
|
||||||
|
|||||||
@@ -64,6 +64,7 @@
|
|||||||
"something-went-wrong": "Algo correu mal!",
|
"something-went-wrong": "Algo correu mal!",
|
||||||
"subscribed-events": "Eventos Subscritos",
|
"subscribed-events": "Eventos Subscritos",
|
||||||
"test-message-sent": "Mensagem de teste enviada",
|
"test-message-sent": "Mensagem de teste enviada",
|
||||||
|
"message-sent": "Mensagem Enviada",
|
||||||
"new-notification": "Nova Notificação",
|
"new-notification": "Nova Notificação",
|
||||||
"event-notifiers": "Notificadores de eventos",
|
"event-notifiers": "Notificadores de eventos",
|
||||||
"apprise-url-skipped-if-blank": "URL da Apprise (ignorado se vazio)",
|
"apprise-url-skipped-if-blank": "URL da Apprise (ignorado se vazio)",
|
||||||
@@ -160,6 +161,7 @@
|
|||||||
"test": "Teste",
|
"test": "Teste",
|
||||||
"themes": "Temas",
|
"themes": "Temas",
|
||||||
"thursday": "Quinta-feira",
|
"thursday": "Quinta-feira",
|
||||||
|
"title": "Título",
|
||||||
"token": "Token",
|
"token": "Token",
|
||||||
"tuesday": "Terça-feira",
|
"tuesday": "Terça-feira",
|
||||||
"type": "Tipo",
|
"type": "Tipo",
|
||||||
@@ -582,7 +584,22 @@
|
|||||||
"upload-image": "Carregar imagem",
|
"upload-image": "Carregar imagem",
|
||||||
"screen-awake": "Manter ecrã ligado",
|
"screen-awake": "Manter ecrã ligado",
|
||||||
"remove-image": "Remover imagem",
|
"remove-image": "Remover imagem",
|
||||||
"nextStep": "Próximo passo"
|
"nextStep": "Próximo passo",
|
||||||
|
"recipe-actions": "Ações da Receita",
|
||||||
|
"parser": {
|
||||||
|
"experimental-alert-text": "Mealie uses natural language processing to parse and create units and food items for your recipe ingredients. This feature is experimental and may not always work as expected. If you prefer not to use the parsed results, you can select 'Cancel' and your changes will not be saved.",
|
||||||
|
"ingredient-parser": "Ingredient Parser",
|
||||||
|
"explanation": "To use the ingredient parser, click the 'Parse All' button to start the process. Once the processed ingredients are available, you can review the items and verify that they were parsed correctly. The model's confidence score is displayed on the right of the item title. This score is an average of all the individual scores and may not always be completely accurate.",
|
||||||
|
"alerts-explainer": "Alerts will be displayed if a matching foods or unit is found but does not exists in the database.",
|
||||||
|
"select-parser": "Select Parser",
|
||||||
|
"natural-language-processor": "Natural Language Processor",
|
||||||
|
"brute-parser": "Brute Parser",
|
||||||
|
"parse-all": "Parse All",
|
||||||
|
"no-unit": "No unit",
|
||||||
|
"missing-unit": "Create missing unit: {unit}",
|
||||||
|
"missing-food": "Create missing food: {food}",
|
||||||
|
"no-food": "No Food"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"search": {
|
"search": {
|
||||||
"advanced-search": "Pesquisa Avançada",
|
"advanced-search": "Pesquisa Avançada",
|
||||||
@@ -1001,6 +1018,12 @@
|
|||||||
"delete-recipes": "Eliminar Receitas",
|
"delete-recipes": "Eliminar Receitas",
|
||||||
"source-unit-will-be-deleted": "Unidade de origem será eliminada"
|
"source-unit-will-be-deleted": "Unidade de origem será eliminada"
|
||||||
},
|
},
|
||||||
|
"recipe-actions": {
|
||||||
|
"recipe-actions-data": "Dados das Ações da Receita",
|
||||||
|
"new-recipe-action": "Nova Ação da Receita",
|
||||||
|
"edit-recipe-action": "Editar Ação da Receita",
|
||||||
|
"action-type": "Tipo de Ação"
|
||||||
|
},
|
||||||
"create-alias": "Criar Pseudónimo",
|
"create-alias": "Criar Pseudónimo",
|
||||||
"manage-aliases": "Gerir Pseudónimos",
|
"manage-aliases": "Gerir Pseudónimos",
|
||||||
"seed-data": "Gerar dados",
|
"seed-data": "Gerar dados",
|
||||||
|
|||||||
@@ -64,6 +64,7 @@
|
|||||||
"something-went-wrong": "Ceva nu a funcţionat corect!",
|
"something-went-wrong": "Ceva nu a funcţionat corect!",
|
||||||
"subscribed-events": "Evenimente la care ești Abonat",
|
"subscribed-events": "Evenimente la care ești Abonat",
|
||||||
"test-message-sent": "Mesaj de test trimis",
|
"test-message-sent": "Mesaj de test trimis",
|
||||||
|
"message-sent": "Message Sent",
|
||||||
"new-notification": "Notificare nouă",
|
"new-notification": "Notificare nouă",
|
||||||
"event-notifiers": "Notificatori de evenimente",
|
"event-notifiers": "Notificatori de evenimente",
|
||||||
"apprise-url-skipped-if-blank": "URL Apprise (ignorat daca e gol)",
|
"apprise-url-skipped-if-blank": "URL Apprise (ignorat daca e gol)",
|
||||||
@@ -160,6 +161,7 @@
|
|||||||
"test": "Testează",
|
"test": "Testează",
|
||||||
"themes": "Teme",
|
"themes": "Teme",
|
||||||
"thursday": "Joi",
|
"thursday": "Joi",
|
||||||
|
"title": "Title",
|
||||||
"token": "Token",
|
"token": "Token",
|
||||||
"tuesday": "Marţi",
|
"tuesday": "Marţi",
|
||||||
"type": "Tip",
|
"type": "Tip",
|
||||||
@@ -582,7 +584,22 @@
|
|||||||
"upload-image": "Încărcare imagine",
|
"upload-image": "Încărcare imagine",
|
||||||
"screen-awake": "Păstrare ecran aprins",
|
"screen-awake": "Păstrare ecran aprins",
|
||||||
"remove-image": "Șterge Imaginea",
|
"remove-image": "Șterge Imaginea",
|
||||||
"nextStep": "Pasul următor"
|
"nextStep": "Pasul următor",
|
||||||
|
"recipe-actions": "Recipe Actions",
|
||||||
|
"parser": {
|
||||||
|
"experimental-alert-text": "Mealie uses natural language processing to parse and create units and food items for your recipe ingredients. This feature is experimental and may not always work as expected. If you prefer not to use the parsed results, you can select 'Cancel' and your changes will not be saved.",
|
||||||
|
"ingredient-parser": "Ingredient Parser",
|
||||||
|
"explanation": "To use the ingredient parser, click the 'Parse All' button to start the process. Once the processed ingredients are available, you can review the items and verify that they were parsed correctly. The model's confidence score is displayed on the right of the item title. This score is an average of all the individual scores and may not always be completely accurate.",
|
||||||
|
"alerts-explainer": "Alerts will be displayed if a matching foods or unit is found but does not exists in the database.",
|
||||||
|
"select-parser": "Select Parser",
|
||||||
|
"natural-language-processor": "Natural Language Processor",
|
||||||
|
"brute-parser": "Brute Parser",
|
||||||
|
"parse-all": "Parse All",
|
||||||
|
"no-unit": "No unit",
|
||||||
|
"missing-unit": "Create missing unit: {unit}",
|
||||||
|
"missing-food": "Create missing food: {food}",
|
||||||
|
"no-food": "No Food"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"search": {
|
"search": {
|
||||||
"advanced-search": "Căutare avansată",
|
"advanced-search": "Căutare avansată",
|
||||||
@@ -1001,6 +1018,12 @@
|
|||||||
"delete-recipes": "Delete Recipes",
|
"delete-recipes": "Delete Recipes",
|
||||||
"source-unit-will-be-deleted": "Source Unit will be deleted"
|
"source-unit-will-be-deleted": "Source Unit will be deleted"
|
||||||
},
|
},
|
||||||
|
"recipe-actions": {
|
||||||
|
"recipe-actions-data": "Recipe Actions Data",
|
||||||
|
"new-recipe-action": "New Recipe Action",
|
||||||
|
"edit-recipe-action": "Edit Recipe Action",
|
||||||
|
"action-type": "Action Type"
|
||||||
|
},
|
||||||
"create-alias": "Create Alias",
|
"create-alias": "Create Alias",
|
||||||
"manage-aliases": "Manage Aliases",
|
"manage-aliases": "Manage Aliases",
|
||||||
"seed-data": "Seed Data",
|
"seed-data": "Seed Data",
|
||||||
|
|||||||
@@ -64,6 +64,7 @@
|
|||||||
"something-went-wrong": "Что-то пошло не так!",
|
"something-went-wrong": "Что-то пошло не так!",
|
||||||
"subscribed-events": "События с подпиской",
|
"subscribed-events": "События с подпиской",
|
||||||
"test-message-sent": "Тестовое сообщение отправлено",
|
"test-message-sent": "Тестовое сообщение отправлено",
|
||||||
|
"message-sent": "Message Sent",
|
||||||
"new-notification": "Новое уведомление",
|
"new-notification": "Новое уведомление",
|
||||||
"event-notifiers": "Уведомления о событии",
|
"event-notifiers": "Уведомления о событии",
|
||||||
"apprise-url-skipped-if-blank": "URL-адрес (пропущен, если пусто)",
|
"apprise-url-skipped-if-blank": "URL-адрес (пропущен, если пусто)",
|
||||||
@@ -160,6 +161,7 @@
|
|||||||
"test": "Тест",
|
"test": "Тест",
|
||||||
"themes": "Темы",
|
"themes": "Темы",
|
||||||
"thursday": "Четверг",
|
"thursday": "Четверг",
|
||||||
|
"title": "Title",
|
||||||
"token": "Токен",
|
"token": "Токен",
|
||||||
"tuesday": "Вторник",
|
"tuesday": "Вторник",
|
||||||
"type": "Тип",
|
"type": "Тип",
|
||||||
@@ -582,7 +584,22 @@
|
|||||||
"upload-image": "Загрузить изображение",
|
"upload-image": "Загрузить изображение",
|
||||||
"screen-awake": "Держать экран включенным",
|
"screen-awake": "Держать экран включенным",
|
||||||
"remove-image": "Удалить изображение",
|
"remove-image": "Удалить изображение",
|
||||||
"nextStep": "След. шаг"
|
"nextStep": "След. шаг",
|
||||||
|
"recipe-actions": "Recipe Actions",
|
||||||
|
"parser": {
|
||||||
|
"experimental-alert-text": "Mealie uses natural language processing to parse and create units and food items for your recipe ingredients. This feature is experimental and may not always work as expected. If you prefer not to use the parsed results, you can select 'Cancel' and your changes will not be saved.",
|
||||||
|
"ingredient-parser": "Ingredient Parser",
|
||||||
|
"explanation": "To use the ingredient parser, click the 'Parse All' button to start the process. Once the processed ingredients are available, you can review the items and verify that they were parsed correctly. The model's confidence score is displayed on the right of the item title. This score is an average of all the individual scores and may not always be completely accurate.",
|
||||||
|
"alerts-explainer": "Alerts will be displayed if a matching foods or unit is found but does not exists in the database.",
|
||||||
|
"select-parser": "Select Parser",
|
||||||
|
"natural-language-processor": "Natural Language Processor",
|
||||||
|
"brute-parser": "Brute Parser",
|
||||||
|
"parse-all": "Parse All",
|
||||||
|
"no-unit": "No unit",
|
||||||
|
"missing-unit": "Create missing unit: {unit}",
|
||||||
|
"missing-food": "Create missing food: {food}",
|
||||||
|
"no-food": "No Food"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"search": {
|
"search": {
|
||||||
"advanced-search": "Расширенный поиск",
|
"advanced-search": "Расширенный поиск",
|
||||||
@@ -1001,6 +1018,12 @@
|
|||||||
"delete-recipes": "Удалить рецепты",
|
"delete-recipes": "Удалить рецепты",
|
||||||
"source-unit-will-be-deleted": "Первая единица измерения будет удалена"
|
"source-unit-will-be-deleted": "Первая единица измерения будет удалена"
|
||||||
},
|
},
|
||||||
|
"recipe-actions": {
|
||||||
|
"recipe-actions-data": "Recipe Actions Data",
|
||||||
|
"new-recipe-action": "New Recipe Action",
|
||||||
|
"edit-recipe-action": "Edit Recipe Action",
|
||||||
|
"action-type": "Action Type"
|
||||||
|
},
|
||||||
"create-alias": "Создать псевдоним",
|
"create-alias": "Создать псевдоним",
|
||||||
"manage-aliases": "Управление псевдонимами",
|
"manage-aliases": "Управление псевдонимами",
|
||||||
"seed-data": "Заполнить данные",
|
"seed-data": "Заполнить данные",
|
||||||
|
|||||||
@@ -64,6 +64,7 @@
|
|||||||
"something-went-wrong": "Vyskytla sa chyba",
|
"something-went-wrong": "Vyskytla sa chyba",
|
||||||
"subscribed-events": "Prihlásené akcie",
|
"subscribed-events": "Prihlásené akcie",
|
||||||
"test-message-sent": "Testovacia správa bola odoslaná",
|
"test-message-sent": "Testovacia správa bola odoslaná",
|
||||||
|
"message-sent": "Message Sent",
|
||||||
"new-notification": "Nové upozornenie",
|
"new-notification": "Nové upozornenie",
|
||||||
"event-notifiers": "Upozornenia udalostí",
|
"event-notifiers": "Upozornenia udalostí",
|
||||||
"apprise-url-skipped-if-blank": "Informačná URL (preskočená, ak je prázdna)",
|
"apprise-url-skipped-if-blank": "Informačná URL (preskočená, ak je prázdna)",
|
||||||
@@ -160,6 +161,7 @@
|
|||||||
"test": "Otestovať",
|
"test": "Otestovať",
|
||||||
"themes": "Motívy",
|
"themes": "Motívy",
|
||||||
"thursday": "Štvrtok",
|
"thursday": "Štvrtok",
|
||||||
|
"title": "Title",
|
||||||
"token": "Token",
|
"token": "Token",
|
||||||
"tuesday": "Utorok",
|
"tuesday": "Utorok",
|
||||||
"type": "Typ",
|
"type": "Typ",
|
||||||
@@ -582,7 +584,22 @@
|
|||||||
"upload-image": "Nahrať obrázok",
|
"upload-image": "Nahrať obrázok",
|
||||||
"screen-awake": "Ponechať obrazovku stále zapnutú",
|
"screen-awake": "Ponechať obrazovku stále zapnutú",
|
||||||
"remove-image": "Odstrániť obrázok",
|
"remove-image": "Odstrániť obrázok",
|
||||||
"nextStep": "Ďalší krok"
|
"nextStep": "Ďalší krok",
|
||||||
|
"recipe-actions": "Recipe Actions",
|
||||||
|
"parser": {
|
||||||
|
"experimental-alert-text": "Mealie uses natural language processing to parse and create units and food items for your recipe ingredients. This feature is experimental and may not always work as expected. If you prefer not to use the parsed results, you can select 'Cancel' and your changes will not be saved.",
|
||||||
|
"ingredient-parser": "Ingredient Parser",
|
||||||
|
"explanation": "To use the ingredient parser, click the 'Parse All' button to start the process. Once the processed ingredients are available, you can review the items and verify that they were parsed correctly. The model's confidence score is displayed on the right of the item title. This score is an average of all the individual scores and may not always be completely accurate.",
|
||||||
|
"alerts-explainer": "Alerts will be displayed if a matching foods or unit is found but does not exists in the database.",
|
||||||
|
"select-parser": "Select Parser",
|
||||||
|
"natural-language-processor": "Natural Language Processor",
|
||||||
|
"brute-parser": "Brute Parser",
|
||||||
|
"parse-all": "Parse All",
|
||||||
|
"no-unit": "No unit",
|
||||||
|
"missing-unit": "Create missing unit: {unit}",
|
||||||
|
"missing-food": "Create missing food: {food}",
|
||||||
|
"no-food": "No Food"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"search": {
|
"search": {
|
||||||
"advanced-search": "Rozšírené vyhľadávanie",
|
"advanced-search": "Rozšírené vyhľadávanie",
|
||||||
@@ -1001,6 +1018,12 @@
|
|||||||
"delete-recipes": "Odstrániť recepty",
|
"delete-recipes": "Odstrániť recepty",
|
||||||
"source-unit-will-be-deleted": "Zdroj bude vymazaný"
|
"source-unit-will-be-deleted": "Zdroj bude vymazaný"
|
||||||
},
|
},
|
||||||
|
"recipe-actions": {
|
||||||
|
"recipe-actions-data": "Recipe Actions Data",
|
||||||
|
"new-recipe-action": "New Recipe Action",
|
||||||
|
"edit-recipe-action": "Edit Recipe Action",
|
||||||
|
"action-type": "Action Type"
|
||||||
|
},
|
||||||
"create-alias": "Vytvoriť alias",
|
"create-alias": "Vytvoriť alias",
|
||||||
"manage-aliases": "Spravovať aliasy",
|
"manage-aliases": "Spravovať aliasy",
|
||||||
"seed-data": "Naplniť dáta",
|
"seed-data": "Naplniť dáta",
|
||||||
|
|||||||
@@ -64,6 +64,7 @@
|
|||||||
"something-went-wrong": "Nekaj je šlo narobe!",
|
"something-went-wrong": "Nekaj je šlo narobe!",
|
||||||
"subscribed-events": "Naročeni dogodki",
|
"subscribed-events": "Naročeni dogodki",
|
||||||
"test-message-sent": "Testno sporočilo je bilo poslano",
|
"test-message-sent": "Testno sporočilo je bilo poslano",
|
||||||
|
"message-sent": "Sporočilo poslano",
|
||||||
"new-notification": "Novo obvestilo",
|
"new-notification": "Novo obvestilo",
|
||||||
"event-notifiers": "Obvestila o dogodkih",
|
"event-notifiers": "Obvestila o dogodkih",
|
||||||
"apprise-url-skipped-if-blank": "Apprise URL (preskočeno, če je prazno)",
|
"apprise-url-skipped-if-blank": "Apprise URL (preskočeno, če je prazno)",
|
||||||
@@ -160,6 +161,7 @@
|
|||||||
"test": "Test",
|
"test": "Test",
|
||||||
"themes": "Teme",
|
"themes": "Teme",
|
||||||
"thursday": "Četrtek",
|
"thursday": "Četrtek",
|
||||||
|
"title": "Naslov",
|
||||||
"token": "Žeton",
|
"token": "Žeton",
|
||||||
"tuesday": "Torek",
|
"tuesday": "Torek",
|
||||||
"type": "Tip",
|
"type": "Tip",
|
||||||
@@ -460,7 +462,7 @@
|
|||||||
"recipe-deleted": "Recept je izbrisan",
|
"recipe-deleted": "Recept je izbrisan",
|
||||||
"recipe-image": "Slika recepta",
|
"recipe-image": "Slika recepta",
|
||||||
"recipe-image-updated": "Slika recepta je posodobljena",
|
"recipe-image-updated": "Slika recepta je posodobljena",
|
||||||
"recipe-name": "Ime recepta",
|
"recipe-name": "Naslov recepta",
|
||||||
"recipe-settings": "Nastavitve recepta",
|
"recipe-settings": "Nastavitve recepta",
|
||||||
"recipe-update-failed": "Napaka pri posodobitvi recepta",
|
"recipe-update-failed": "Napaka pri posodobitvi recepta",
|
||||||
"recipe-updated": "Recept je posodobljen",
|
"recipe-updated": "Recept je posodobljen",
|
||||||
@@ -582,7 +584,22 @@
|
|||||||
"upload-image": "Naloži sliko",
|
"upload-image": "Naloži sliko",
|
||||||
"screen-awake": "Ohranjanje budnega zaslona",
|
"screen-awake": "Ohranjanje budnega zaslona",
|
||||||
"remove-image": "Odstrani sliko",
|
"remove-image": "Odstrani sliko",
|
||||||
"nextStep": "Naslednji korak"
|
"nextStep": "Naslednji korak",
|
||||||
|
"recipe-actions": "Opravila na receptu",
|
||||||
|
"parser": {
|
||||||
|
"experimental-alert-text": "Mealie uporablja procesiranje naravnega jezika za razčlenjevanje in ustvarjanje živil in enot v seznamu sestavin. Ta storitev je eksperimentalna in včasih ne deluje kot pričakovano. Če dobljenega rezultata ne želiš uporabiti, izberi 'Prekliči' in tvoje spremembe ne bodo shranjene.",
|
||||||
|
"ingredient-parser": "Razčlenjevalnik sestavin",
|
||||||
|
"explanation": "Če želiš uporabiti razčlenjevalnik sestavin, izberi 'Razčleni vse', da pričneš s postopkom. Ko bodo sestavine na voljo, lahko pregledaš podatke in preveriš, če so bili pravilno razčlenjeni. Stopnja zaupanja je prikazana desno od podatka. Ta vrednost je povprečje vseh posameznih vrednosti in ni nujno popolnoma natančna.",
|
||||||
|
"alerts-explainer": "Opozorila bodo prikazana v primeru, da obstaja ujemajoče živilo ali enota, ampak še ne obstaja v podatkovni bazi.",
|
||||||
|
"select-parser": "Izberi razčlenjevalnik",
|
||||||
|
"natural-language-processor": "Procesor naravnega jezika",
|
||||||
|
"brute-parser": "Brute Parser",
|
||||||
|
"parse-all": "Razčleni vse",
|
||||||
|
"no-unit": "Ni enote",
|
||||||
|
"missing-unit": "Ustvari manjkajočo enoto: {unit}",
|
||||||
|
"missing-food": "Ustvari manjkajoče živilo: {food}",
|
||||||
|
"no-food": "Ni živila"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"search": {
|
"search": {
|
||||||
"advanced-search": "Napredno iskanje",
|
"advanced-search": "Napredno iskanje",
|
||||||
@@ -1001,6 +1018,12 @@
|
|||||||
"delete-recipes": "Izbriši recepte",
|
"delete-recipes": "Izbriši recepte",
|
||||||
"source-unit-will-be-deleted": "Izvorna enota bo izbrisana"
|
"source-unit-will-be-deleted": "Izvorna enota bo izbrisana"
|
||||||
},
|
},
|
||||||
|
"recipe-actions": {
|
||||||
|
"recipe-actions-data": "Podatki o opravilu na receptu",
|
||||||
|
"new-recipe-action": "Novo opravilo na receptu",
|
||||||
|
"edit-recipe-action": "Urejaj opravilo na receptu",
|
||||||
|
"action-type": "Tip opravila"
|
||||||
|
},
|
||||||
"create-alias": "Ustvari alias",
|
"create-alias": "Ustvari alias",
|
||||||
"manage-aliases": "Upravljanje z aliasi",
|
"manage-aliases": "Upravljanje z aliasi",
|
||||||
"seed-data": "Napolni podatke",
|
"seed-data": "Napolni podatke",
|
||||||
|
|||||||
@@ -64,6 +64,7 @@
|
|||||||
"something-went-wrong": "Нешто је кренуло погрешно!",
|
"something-went-wrong": "Нешто је кренуло погрешно!",
|
||||||
"subscribed-events": "Догађаји на које сте претплаћени",
|
"subscribed-events": "Догађаји на које сте претплаћени",
|
||||||
"test-message-sent": "Тест порука је послата",
|
"test-message-sent": "Тест порука је послата",
|
||||||
|
"message-sent": "Message Sent",
|
||||||
"new-notification": "Ново обавештење",
|
"new-notification": "Ново обавештење",
|
||||||
"event-notifiers": "Обавештавач о догађају",
|
"event-notifiers": "Обавештавач о догађају",
|
||||||
"apprise-url-skipped-if-blank": "Apprise URL (прескочено ако је празно)",
|
"apprise-url-skipped-if-blank": "Apprise URL (прескочено ако је празно)",
|
||||||
@@ -160,6 +161,7 @@
|
|||||||
"test": "Тест",
|
"test": "Тест",
|
||||||
"themes": "Теме",
|
"themes": "Теме",
|
||||||
"thursday": "четвртак",
|
"thursday": "четвртак",
|
||||||
|
"title": "Title",
|
||||||
"token": "Токен",
|
"token": "Токен",
|
||||||
"tuesday": "уторак",
|
"tuesday": "уторак",
|
||||||
"type": "Тип",
|
"type": "Тип",
|
||||||
@@ -582,7 +584,22 @@
|
|||||||
"upload-image": "Upload image",
|
"upload-image": "Upload image",
|
||||||
"screen-awake": "Keep Screen Awake",
|
"screen-awake": "Keep Screen Awake",
|
||||||
"remove-image": "Remove image",
|
"remove-image": "Remove image",
|
||||||
"nextStep": "Next step"
|
"nextStep": "Next step",
|
||||||
|
"recipe-actions": "Recipe Actions",
|
||||||
|
"parser": {
|
||||||
|
"experimental-alert-text": "Mealie uses natural language processing to parse and create units and food items for your recipe ingredients. This feature is experimental and may not always work as expected. If you prefer not to use the parsed results, you can select 'Cancel' and your changes will not be saved.",
|
||||||
|
"ingredient-parser": "Ingredient Parser",
|
||||||
|
"explanation": "To use the ingredient parser, click the 'Parse All' button to start the process. Once the processed ingredients are available, you can review the items and verify that they were parsed correctly. The model's confidence score is displayed on the right of the item title. This score is an average of all the individual scores and may not always be completely accurate.",
|
||||||
|
"alerts-explainer": "Alerts will be displayed if a matching foods or unit is found but does not exists in the database.",
|
||||||
|
"select-parser": "Select Parser",
|
||||||
|
"natural-language-processor": "Natural Language Processor",
|
||||||
|
"brute-parser": "Brute Parser",
|
||||||
|
"parse-all": "Parse All",
|
||||||
|
"no-unit": "No unit",
|
||||||
|
"missing-unit": "Create missing unit: {unit}",
|
||||||
|
"missing-food": "Create missing food: {food}",
|
||||||
|
"no-food": "No Food"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"search": {
|
"search": {
|
||||||
"advanced-search": "Напредна претрага",
|
"advanced-search": "Напредна претрага",
|
||||||
@@ -1001,6 +1018,12 @@
|
|||||||
"delete-recipes": "Delete Recipes",
|
"delete-recipes": "Delete Recipes",
|
||||||
"source-unit-will-be-deleted": "Source Unit will be deleted"
|
"source-unit-will-be-deleted": "Source Unit will be deleted"
|
||||||
},
|
},
|
||||||
|
"recipe-actions": {
|
||||||
|
"recipe-actions-data": "Recipe Actions Data",
|
||||||
|
"new-recipe-action": "New Recipe Action",
|
||||||
|
"edit-recipe-action": "Edit Recipe Action",
|
||||||
|
"action-type": "Action Type"
|
||||||
|
},
|
||||||
"create-alias": "Create Alias",
|
"create-alias": "Create Alias",
|
||||||
"manage-aliases": "Manage Aliases",
|
"manage-aliases": "Manage Aliases",
|
||||||
"seed-data": "Seed Data",
|
"seed-data": "Seed Data",
|
||||||
|
|||||||
@@ -64,6 +64,7 @@
|
|||||||
"something-went-wrong": "Någonting gick fel",
|
"something-went-wrong": "Någonting gick fel",
|
||||||
"subscribed-events": "Prenumererade händelser",
|
"subscribed-events": "Prenumererade händelser",
|
||||||
"test-message-sent": "Testmeddelande Skickat",
|
"test-message-sent": "Testmeddelande Skickat",
|
||||||
|
"message-sent": "Message Sent",
|
||||||
"new-notification": "Ny avisering",
|
"new-notification": "Ny avisering",
|
||||||
"event-notifiers": "Händelseavisering",
|
"event-notifiers": "Händelseavisering",
|
||||||
"apprise-url-skipped-if-blank": "Apprise-URL (hoppa över om tom)",
|
"apprise-url-skipped-if-blank": "Apprise-URL (hoppa över om tom)",
|
||||||
@@ -160,6 +161,7 @@
|
|||||||
"test": "Test",
|
"test": "Test",
|
||||||
"themes": "Tema",
|
"themes": "Tema",
|
||||||
"thursday": "Torsdag",
|
"thursday": "Torsdag",
|
||||||
|
"title": "Title",
|
||||||
"token": "Token",
|
"token": "Token",
|
||||||
"tuesday": "Tisdag",
|
"tuesday": "Tisdag",
|
||||||
"type": "Typ",
|
"type": "Typ",
|
||||||
@@ -582,7 +584,22 @@
|
|||||||
"upload-image": "Ladda upp bild",
|
"upload-image": "Ladda upp bild",
|
||||||
"screen-awake": "Håll skärmen vaken",
|
"screen-awake": "Håll skärmen vaken",
|
||||||
"remove-image": "Ta bort bild",
|
"remove-image": "Ta bort bild",
|
||||||
"nextStep": "Nästa steg"
|
"nextStep": "Nästa steg",
|
||||||
|
"recipe-actions": "Recipe Actions",
|
||||||
|
"parser": {
|
||||||
|
"experimental-alert-text": "Mealie uses natural language processing to parse and create units and food items for your recipe ingredients. This feature is experimental and may not always work as expected. If you prefer not to use the parsed results, you can select 'Cancel' and your changes will not be saved.",
|
||||||
|
"ingredient-parser": "Ingredient Parser",
|
||||||
|
"explanation": "To use the ingredient parser, click the 'Parse All' button to start the process. Once the processed ingredients are available, you can review the items and verify that they were parsed correctly. The model's confidence score is displayed on the right of the item title. This score is an average of all the individual scores and may not always be completely accurate.",
|
||||||
|
"alerts-explainer": "Alerts will be displayed if a matching foods or unit is found but does not exists in the database.",
|
||||||
|
"select-parser": "Select Parser",
|
||||||
|
"natural-language-processor": "Natural Language Processor",
|
||||||
|
"brute-parser": "Brute Parser",
|
||||||
|
"parse-all": "Parse All",
|
||||||
|
"no-unit": "No unit",
|
||||||
|
"missing-unit": "Create missing unit: {unit}",
|
||||||
|
"missing-food": "Create missing food: {food}",
|
||||||
|
"no-food": "No Food"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"search": {
|
"search": {
|
||||||
"advanced-search": "Avancerad sökning",
|
"advanced-search": "Avancerad sökning",
|
||||||
@@ -1001,6 +1018,12 @@
|
|||||||
"delete-recipes": "Radera recept",
|
"delete-recipes": "Radera recept",
|
||||||
"source-unit-will-be-deleted": "Källenheten kommer att raderas"
|
"source-unit-will-be-deleted": "Källenheten kommer att raderas"
|
||||||
},
|
},
|
||||||
|
"recipe-actions": {
|
||||||
|
"recipe-actions-data": "Recipe Actions Data",
|
||||||
|
"new-recipe-action": "New Recipe Action",
|
||||||
|
"edit-recipe-action": "Edit Recipe Action",
|
||||||
|
"action-type": "Action Type"
|
||||||
|
},
|
||||||
"create-alias": "Skapa alias",
|
"create-alias": "Skapa alias",
|
||||||
"manage-aliases": "Hantera alias",
|
"manage-aliases": "Hantera alias",
|
||||||
"seed-data": "Exempeldata",
|
"seed-data": "Exempeldata",
|
||||||
|
|||||||
@@ -64,6 +64,7 @@
|
|||||||
"something-went-wrong": "Bir sorun oluştu!",
|
"something-went-wrong": "Bir sorun oluştu!",
|
||||||
"subscribed-events": "Abone Olunan Etkinlikler",
|
"subscribed-events": "Abone Olunan Etkinlikler",
|
||||||
"test-message-sent": "Test Mesajı Gönderildi",
|
"test-message-sent": "Test Mesajı Gönderildi",
|
||||||
|
"message-sent": "Message Sent",
|
||||||
"new-notification": "Yeni bildirim",
|
"new-notification": "Yeni bildirim",
|
||||||
"event-notifiers": "Etkinlik Bildirimleri",
|
"event-notifiers": "Etkinlik Bildirimleri",
|
||||||
"apprise-url-skipped-if-blank": "Apprise URL'si (boşsa geçilir)",
|
"apprise-url-skipped-if-blank": "Apprise URL'si (boşsa geçilir)",
|
||||||
@@ -160,6 +161,7 @@
|
|||||||
"test": "Dene",
|
"test": "Dene",
|
||||||
"themes": "Temalar",
|
"themes": "Temalar",
|
||||||
"thursday": "Perşembe",
|
"thursday": "Perşembe",
|
||||||
|
"title": "Title",
|
||||||
"token": "Anahtar",
|
"token": "Anahtar",
|
||||||
"tuesday": "Salı",
|
"tuesday": "Salı",
|
||||||
"type": "Tür",
|
"type": "Tür",
|
||||||
@@ -582,7 +584,22 @@
|
|||||||
"upload-image": "Resim yükleyin",
|
"upload-image": "Resim yükleyin",
|
||||||
"screen-awake": "Ekranı Açık Tut",
|
"screen-awake": "Ekranı Açık Tut",
|
||||||
"remove-image": "Resmi kaldır",
|
"remove-image": "Resmi kaldır",
|
||||||
"nextStep": "Sonraki adım"
|
"nextStep": "Sonraki adım",
|
||||||
|
"recipe-actions": "Recipe Actions",
|
||||||
|
"parser": {
|
||||||
|
"experimental-alert-text": "Mealie uses natural language processing to parse and create units and food items for your recipe ingredients. This feature is experimental and may not always work as expected. If you prefer not to use the parsed results, you can select 'Cancel' and your changes will not be saved.",
|
||||||
|
"ingredient-parser": "Ingredient Parser",
|
||||||
|
"explanation": "To use the ingredient parser, click the 'Parse All' button to start the process. Once the processed ingredients are available, you can review the items and verify that they were parsed correctly. The model's confidence score is displayed on the right of the item title. This score is an average of all the individual scores and may not always be completely accurate.",
|
||||||
|
"alerts-explainer": "Alerts will be displayed if a matching foods or unit is found but does not exists in the database.",
|
||||||
|
"select-parser": "Select Parser",
|
||||||
|
"natural-language-processor": "Natural Language Processor",
|
||||||
|
"brute-parser": "Brute Parser",
|
||||||
|
"parse-all": "Parse All",
|
||||||
|
"no-unit": "No unit",
|
||||||
|
"missing-unit": "Create missing unit: {unit}",
|
||||||
|
"missing-food": "Create missing food: {food}",
|
||||||
|
"no-food": "No Food"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"search": {
|
"search": {
|
||||||
"advanced-search": "Advanced Search",
|
"advanced-search": "Advanced Search",
|
||||||
@@ -1001,6 +1018,12 @@
|
|||||||
"delete-recipes": "Delete Recipes",
|
"delete-recipes": "Delete Recipes",
|
||||||
"source-unit-will-be-deleted": "Source Unit will be deleted"
|
"source-unit-will-be-deleted": "Source Unit will be deleted"
|
||||||
},
|
},
|
||||||
|
"recipe-actions": {
|
||||||
|
"recipe-actions-data": "Recipe Actions Data",
|
||||||
|
"new-recipe-action": "New Recipe Action",
|
||||||
|
"edit-recipe-action": "Edit Recipe Action",
|
||||||
|
"action-type": "Action Type"
|
||||||
|
},
|
||||||
"create-alias": "Takma Ad Oluştur",
|
"create-alias": "Takma Ad Oluştur",
|
||||||
"manage-aliases": "Takma Adları Yönet",
|
"manage-aliases": "Takma Adları Yönet",
|
||||||
"seed-data": "Seed Data",
|
"seed-data": "Seed Data",
|
||||||
|
|||||||
@@ -64,6 +64,7 @@
|
|||||||
"something-went-wrong": "Щось пішло не так!",
|
"something-went-wrong": "Щось пішло не так!",
|
||||||
"subscribed-events": "Події, на які підписано",
|
"subscribed-events": "Події, на які підписано",
|
||||||
"test-message-sent": "Тестове повідомлення надіслано",
|
"test-message-sent": "Тестове повідомлення надіслано",
|
||||||
|
"message-sent": "Повідомлення надіслано",
|
||||||
"new-notification": "Нове сповіщення",
|
"new-notification": "Нове сповіщення",
|
||||||
"event-notifiers": "Сповіщувачі",
|
"event-notifiers": "Сповіщувачі",
|
||||||
"apprise-url-skipped-if-blank": "Apprise URL (пропущено якщо порожній)",
|
"apprise-url-skipped-if-blank": "Apprise URL (пропущено якщо порожній)",
|
||||||
@@ -160,6 +161,7 @@
|
|||||||
"test": "Тест",
|
"test": "Тест",
|
||||||
"themes": "Теми",
|
"themes": "Теми",
|
||||||
"thursday": "Четвер",
|
"thursday": "Четвер",
|
||||||
|
"title": "Назва",
|
||||||
"token": "Токен",
|
"token": "Токен",
|
||||||
"tuesday": "Вівторок",
|
"tuesday": "Вівторок",
|
||||||
"type": "Тип",
|
"type": "Тип",
|
||||||
@@ -582,7 +584,22 @@
|
|||||||
"upload-image": "Вивантажити зображення",
|
"upload-image": "Вивантажити зображення",
|
||||||
"screen-awake": "Тримати екран активним",
|
"screen-awake": "Тримати екран активним",
|
||||||
"remove-image": "Видалити зображення",
|
"remove-image": "Видалити зображення",
|
||||||
"nextStep": "Наступний крок"
|
"nextStep": "Наступний крок",
|
||||||
|
"recipe-actions": "Дії рецепту",
|
||||||
|
"parser": {
|
||||||
|
"experimental-alert-text": "Mealie використовує аналіз природної мови для аналізу та створення інгредієнтів та одиниць виміру. Це експериментальна функція і може не завжди працювати належним чином. Якщо ви не хочете використовувати результати аналізу виберіть \"Скасувати\", і зміни не будуть збережені.",
|
||||||
|
"ingredient-parser": "Аналізатор інгредієнтів",
|
||||||
|
"explanation": "Щоб використати аналізатор інгредієнтів, натисніть кнопку 'Аналізувати все', щоб запустити процес. Після того, як інгредієнти проаналізовані, ви можете їх переглянути та переконатися, що вони були проаналізовані правильно. Оцінка надійності аналізу відображена праворуч від назви елемента. Ця оцінка розраховується як середнє значення усіх індивідуальних оцінок і не завжди може бути абсолютно точним.",
|
||||||
|
"alerts-explainer": "Оповіщення будуть відображатися, якщо знайдені продукти або одиниці знайдені яких не існує в базі даних.",
|
||||||
|
"select-parser": "Вибрати аналізатор",
|
||||||
|
"natural-language-processor": "Аналізатор природної мови",
|
||||||
|
"brute-parser": "Простий аналізатор",
|
||||||
|
"parse-all": "Аналізувати все",
|
||||||
|
"no-unit": "Без одиниці",
|
||||||
|
"missing-unit": "Створити відсутню одиниці: {unit}",
|
||||||
|
"missing-food": "Створити відсутню їжу: {food}",
|
||||||
|
"no-food": "Немає їжі"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"search": {
|
"search": {
|
||||||
"advanced-search": "Розширений пошук",
|
"advanced-search": "Розширений пошук",
|
||||||
@@ -794,7 +811,7 @@
|
|||||||
"language": "Мова",
|
"language": "Мова",
|
||||||
"maintenance": "Обслуговування",
|
"maintenance": "Обслуговування",
|
||||||
"background-tasks": "Фонові завдання",
|
"background-tasks": "Фонові завдання",
|
||||||
"parser": "Парсер",
|
"parser": "Синтаксичний аналізатор (парсер)",
|
||||||
"developer": "Розробник",
|
"developer": "Розробник",
|
||||||
"cookbook": "Кулінарна книга",
|
"cookbook": "Кулінарна книга",
|
||||||
"create-cookbook": "Створити нову кулінарну книгу"
|
"create-cookbook": "Створити нову кулінарну книгу"
|
||||||
@@ -1001,6 +1018,12 @@
|
|||||||
"delete-recipes": "Видалити рецепти",
|
"delete-recipes": "Видалити рецепти",
|
||||||
"source-unit-will-be-deleted": "Початкову одиницю вимірювання буде видалено"
|
"source-unit-will-be-deleted": "Початкову одиницю вимірювання буде видалено"
|
||||||
},
|
},
|
||||||
|
"recipe-actions": {
|
||||||
|
"recipe-actions-data": "Дані дій рецепта",
|
||||||
|
"new-recipe-action": "Нова дія рецепту",
|
||||||
|
"edit-recipe-action": "Редагувати дії рецепта",
|
||||||
|
"action-type": "Тип Дії"
|
||||||
|
},
|
||||||
"create-alias": "Створити псевдонім",
|
"create-alias": "Створити псевдонім",
|
||||||
"manage-aliases": "Керувати псевдонімами",
|
"manage-aliases": "Керувати псевдонімами",
|
||||||
"seed-data": "Підготовлені дані",
|
"seed-data": "Підготовлені дані",
|
||||||
@@ -1151,7 +1174,7 @@
|
|||||||
"ingredient-text": "Текст інгредієнта",
|
"ingredient-text": "Текст інгредієнта",
|
||||||
"average-confident": "Впевненість {0}",
|
"average-confident": "Впевненість {0}",
|
||||||
"try-an-example": "Спробувати приклад",
|
"try-an-example": "Спробувати приклад",
|
||||||
"parser": "Парсер",
|
"parser": "Синтаксичний аналізатор (парсер)",
|
||||||
"background-tasks": "Фонові задачі",
|
"background-tasks": "Фонові задачі",
|
||||||
"background-tasks-description": "Тут ви можете переглянути всі запущені фонові задачі та їх статус",
|
"background-tasks-description": "Тут ви можете переглянути всі запущені фонові задачі та їх статус",
|
||||||
"no-logs-found": "Журналів не знайдено",
|
"no-logs-found": "Журналів не знайдено",
|
||||||
@@ -1168,21 +1191,21 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"profile": {
|
"profile": {
|
||||||
"welcome-user": "👋 Welcome, {0}!",
|
"welcome-user": "👋 Ласкаво просимо, {0}!",
|
||||||
"description": "Керування вашим профілем, рецептами та налаштуваннями групи.",
|
"description": "Керування вашим профілем, рецептами та налаштуваннями групи.",
|
||||||
"get-invite-link": "Отримати посилання-запрошення",
|
"get-invite-link": "Отримати посилання-запрошення",
|
||||||
"get-public-link": "Отримати публічне посилання",
|
"get-public-link": "Отримати публічне посилання",
|
||||||
"account-summary": "Аккаунт",
|
"account-summary": "Аккаунт",
|
||||||
"account-summary-description": "Here's a summary of your group's information.",
|
"account-summary-description": "Ось підсумок інформації про вашу групу.",
|
||||||
"group-statistics": "Статистика групи",
|
"group-statistics": "Статистика групи",
|
||||||
"group-statistics-description": "Статистика вашої групи дає можливість зрозуміти, як ви користуєтеся Mealie.",
|
"group-statistics-description": "Статистика вашої групи дає можливість зрозуміти, як ви користуєтеся Mealie.",
|
||||||
"storage-capacity": "Обсяг сховища",
|
"storage-capacity": "Обсяг сховища",
|
||||||
"storage-capacity-description": "Об'єм сховища це сума зображені та відвантажених медіаресурсів.",
|
"storage-capacity-description": "Об'єм сховища це сума зображені та відвантажених медіаресурсів.",
|
||||||
"personal": "Особисте",
|
"personal": "Особисте",
|
||||||
"personal-description": "These are settings that are personal to you. Changes here won't affect other users.",
|
"personal-description": "Це особисті налаштування. Зміни тут не впливають на інших користувачів.",
|
||||||
"user-settings": "Налаштування користувача",
|
"user-settings": "Налаштування користувача",
|
||||||
"user-settings-description": "Manage your preferences, change your password, and update your email.",
|
"user-settings-description": "Керуйте вашими налаштуваннями, змінюйте пароль і оновлюйте адресу електронної пошти.",
|
||||||
"api-tokens-description": "Manage your API Tokens for access from external applications.",
|
"api-tokens-description": "Керуйте своїми ключами API для доступу із зовнішніх програм.",
|
||||||
"group-description": "Ці елементи є спільними для вашої групи. Редагування одного з них змінить його для всієї групи!",
|
"group-description": "Ці елементи є спільними для вашої групи. Редагування одного з них змінить його для всієї групи!",
|
||||||
"group-settings": "Налаштування групи",
|
"group-settings": "Налаштування групи",
|
||||||
"group-settings-description": "Керуйте спільними налаштуванням груп, такими як плани харчування і налаштування конфіденційності.",
|
"group-settings-description": "Керуйте спільними налаштуванням груп, такими як плани харчування і налаштування конфіденційності.",
|
||||||
@@ -1193,9 +1216,9 @@
|
|||||||
"notifiers": "Сповіщувачі",
|
"notifiers": "Сповіщувачі",
|
||||||
"notifiers-description": "Налаштуйте email та push сповіщення, що спрацьовують для певних подій.",
|
"notifiers-description": "Налаштуйте email та push сповіщення, що спрацьовують для певних подій.",
|
||||||
"manage-data": "Керування даними",
|
"manage-data": "Керування даними",
|
||||||
"manage-data-description": "Manage your Mealie data; Foods, Units, Categories, Tags and more.",
|
"manage-data-description": "Керуйте своїми даними Mealie; їжа, одиниці, категорії, мітки та багато іншого.",
|
||||||
"data-migrations": "Міграції даних",
|
"data-migrations": "Міграції даних",
|
||||||
"data-migrations-description": "Migrate your existing data from other applications like Nextcloud Recipes and Chowdown.",
|
"data-migrations-description": "Перенести наявні дані з таких програм, як Nextcloud Recipes і Chowdown.",
|
||||||
"email-sent": "Лист надіслано",
|
"email-sent": "Лист надіслано",
|
||||||
"error-sending-email": "Помилка надсилання листа",
|
"error-sending-email": "Помилка надсилання листа",
|
||||||
"personal-information": "Персональні данні",
|
"personal-information": "Персональні данні",
|
||||||
|
|||||||
@@ -64,6 +64,7 @@
|
|||||||
"something-went-wrong": "Something Went Wrong!",
|
"something-went-wrong": "Something Went Wrong!",
|
||||||
"subscribed-events": "Subscribed Events",
|
"subscribed-events": "Subscribed Events",
|
||||||
"test-message-sent": "Test Message Sent",
|
"test-message-sent": "Test Message Sent",
|
||||||
|
"message-sent": "Message Sent",
|
||||||
"new-notification": "New Notification",
|
"new-notification": "New Notification",
|
||||||
"event-notifiers": "Event Notifiers",
|
"event-notifiers": "Event Notifiers",
|
||||||
"apprise-url-skipped-if-blank": "Apprise URL (skipped if blank)",
|
"apprise-url-skipped-if-blank": "Apprise URL (skipped if blank)",
|
||||||
@@ -160,6 +161,7 @@
|
|||||||
"test": "Test",
|
"test": "Test",
|
||||||
"themes": "Themes",
|
"themes": "Themes",
|
||||||
"thursday": "Thursday",
|
"thursday": "Thursday",
|
||||||
|
"title": "Title",
|
||||||
"token": "Token",
|
"token": "Token",
|
||||||
"tuesday": "Tuesday",
|
"tuesday": "Tuesday",
|
||||||
"type": "Type",
|
"type": "Type",
|
||||||
@@ -582,7 +584,22 @@
|
|||||||
"upload-image": "Upload image",
|
"upload-image": "Upload image",
|
||||||
"screen-awake": "Keep Screen Awake",
|
"screen-awake": "Keep Screen Awake",
|
||||||
"remove-image": "Remove image",
|
"remove-image": "Remove image",
|
||||||
"nextStep": "Next step"
|
"nextStep": "Next step",
|
||||||
|
"recipe-actions": "Recipe Actions",
|
||||||
|
"parser": {
|
||||||
|
"experimental-alert-text": "Mealie uses natural language processing to parse and create units and food items for your recipe ingredients. This feature is experimental and may not always work as expected. If you prefer not to use the parsed results, you can select 'Cancel' and your changes will not be saved.",
|
||||||
|
"ingredient-parser": "Ingredient Parser",
|
||||||
|
"explanation": "To use the ingredient parser, click the 'Parse All' button to start the process. Once the processed ingredients are available, you can review the items and verify that they were parsed correctly. The model's confidence score is displayed on the right of the item title. This score is an average of all the individual scores and may not always be completely accurate.",
|
||||||
|
"alerts-explainer": "Alerts will be displayed if a matching foods or unit is found but does not exists in the database.",
|
||||||
|
"select-parser": "Select Parser",
|
||||||
|
"natural-language-processor": "Natural Language Processor",
|
||||||
|
"brute-parser": "Brute Parser",
|
||||||
|
"parse-all": "Parse All",
|
||||||
|
"no-unit": "No unit",
|
||||||
|
"missing-unit": "Create missing unit: {unit}",
|
||||||
|
"missing-food": "Create missing food: {food}",
|
||||||
|
"no-food": "No Food"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"search": {
|
"search": {
|
||||||
"advanced-search": "Advanced Search",
|
"advanced-search": "Advanced Search",
|
||||||
@@ -1001,6 +1018,12 @@
|
|||||||
"delete-recipes": "Delete Recipes",
|
"delete-recipes": "Delete Recipes",
|
||||||
"source-unit-will-be-deleted": "Source Unit will be deleted"
|
"source-unit-will-be-deleted": "Source Unit will be deleted"
|
||||||
},
|
},
|
||||||
|
"recipe-actions": {
|
||||||
|
"recipe-actions-data": "Recipe Actions Data",
|
||||||
|
"new-recipe-action": "New Recipe Action",
|
||||||
|
"edit-recipe-action": "Edit Recipe Action",
|
||||||
|
"action-type": "Action Type"
|
||||||
|
},
|
||||||
"create-alias": "Create Alias",
|
"create-alias": "Create Alias",
|
||||||
"manage-aliases": "Manage Aliases",
|
"manage-aliases": "Manage Aliases",
|
||||||
"seed-data": "Seed Data",
|
"seed-data": "Seed Data",
|
||||||
|
|||||||
@@ -64,6 +64,7 @@
|
|||||||
"something-went-wrong": "出错了\t#",
|
"something-went-wrong": "出错了\t#",
|
||||||
"subscribed-events": "订阅事件",
|
"subscribed-events": "订阅事件",
|
||||||
"test-message-sent": "测试消息已发送",
|
"test-message-sent": "测试消息已发送",
|
||||||
|
"message-sent": "Message Sent",
|
||||||
"new-notification": "新通知",
|
"new-notification": "新通知",
|
||||||
"event-notifiers": "事件通知器",
|
"event-notifiers": "事件通知器",
|
||||||
"apprise-url-skipped-if-blank": "Apprise URL (如果为空则跳过)",
|
"apprise-url-skipped-if-blank": "Apprise URL (如果为空则跳过)",
|
||||||
@@ -160,6 +161,7 @@
|
|||||||
"test": "测试",
|
"test": "测试",
|
||||||
"themes": "布景主题",
|
"themes": "布景主题",
|
||||||
"thursday": "周四",
|
"thursday": "周四",
|
||||||
|
"title": "Title",
|
||||||
"token": "密钥",
|
"token": "密钥",
|
||||||
"tuesday": "周二",
|
"tuesday": "周二",
|
||||||
"type": "类型",
|
"type": "类型",
|
||||||
@@ -582,7 +584,22 @@
|
|||||||
"upload-image": "上传图片",
|
"upload-image": "上传图片",
|
||||||
"screen-awake": "保持屏幕唤醒",
|
"screen-awake": "保持屏幕唤醒",
|
||||||
"remove-image": "删除图片",
|
"remove-image": "删除图片",
|
||||||
"nextStep": "下一步"
|
"nextStep": "下一步",
|
||||||
|
"recipe-actions": "Recipe Actions",
|
||||||
|
"parser": {
|
||||||
|
"experimental-alert-text": "Mealie uses natural language processing to parse and create units and food items for your recipe ingredients. This feature is experimental and may not always work as expected. If you prefer not to use the parsed results, you can select 'Cancel' and your changes will not be saved.",
|
||||||
|
"ingredient-parser": "Ingredient Parser",
|
||||||
|
"explanation": "To use the ingredient parser, click the 'Parse All' button to start the process. Once the processed ingredients are available, you can review the items and verify that they were parsed correctly. The model's confidence score is displayed on the right of the item title. This score is an average of all the individual scores and may not always be completely accurate.",
|
||||||
|
"alerts-explainer": "Alerts will be displayed if a matching foods or unit is found but does not exists in the database.",
|
||||||
|
"select-parser": "Select Parser",
|
||||||
|
"natural-language-processor": "Natural Language Processor",
|
||||||
|
"brute-parser": "Brute Parser",
|
||||||
|
"parse-all": "Parse All",
|
||||||
|
"no-unit": "No unit",
|
||||||
|
"missing-unit": "Create missing unit: {unit}",
|
||||||
|
"missing-food": "Create missing food: {food}",
|
||||||
|
"no-food": "No Food"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"search": {
|
"search": {
|
||||||
"advanced-search": "高级搜索",
|
"advanced-search": "高级搜索",
|
||||||
@@ -1001,6 +1018,12 @@
|
|||||||
"delete-recipes": "删除食谱",
|
"delete-recipes": "删除食谱",
|
||||||
"source-unit-will-be-deleted": "“待合并单位”将会被删除"
|
"source-unit-will-be-deleted": "“待合并单位”将会被删除"
|
||||||
},
|
},
|
||||||
|
"recipe-actions": {
|
||||||
|
"recipe-actions-data": "Recipe Actions Data",
|
||||||
|
"new-recipe-action": "New Recipe Action",
|
||||||
|
"edit-recipe-action": "Edit Recipe Action",
|
||||||
|
"action-type": "Action Type"
|
||||||
|
},
|
||||||
"create-alias": "创建别名",
|
"create-alias": "创建别名",
|
||||||
"manage-aliases": "管理别名",
|
"manage-aliases": "管理别名",
|
||||||
"seed-data": "初始数据",
|
"seed-data": "初始数据",
|
||||||
|
|||||||
@@ -64,6 +64,7 @@
|
|||||||
"something-went-wrong": "出了點問題...",
|
"something-went-wrong": "出了點問題...",
|
||||||
"subscribed-events": "關注的事件",
|
"subscribed-events": "關注的事件",
|
||||||
"test-message-sent": "測試訊息已發送",
|
"test-message-sent": "測試訊息已發送",
|
||||||
|
"message-sent": "Message Sent",
|
||||||
"new-notification": "新通知",
|
"new-notification": "新通知",
|
||||||
"event-notifiers": "Event Notifiers",
|
"event-notifiers": "Event Notifiers",
|
||||||
"apprise-url-skipped-if-blank": "Apprise URL (skipped if blank)",
|
"apprise-url-skipped-if-blank": "Apprise URL (skipped if blank)",
|
||||||
@@ -160,6 +161,7 @@
|
|||||||
"test": "測試",
|
"test": "測試",
|
||||||
"themes": "佈景主題",
|
"themes": "佈景主題",
|
||||||
"thursday": "星期四",
|
"thursday": "星期四",
|
||||||
|
"title": "Title",
|
||||||
"token": "密鑰",
|
"token": "密鑰",
|
||||||
"tuesday": "星期二",
|
"tuesday": "星期二",
|
||||||
"type": "類型",
|
"type": "類型",
|
||||||
@@ -582,7 +584,22 @@
|
|||||||
"upload-image": "Upload image",
|
"upload-image": "Upload image",
|
||||||
"screen-awake": "Keep Screen Awake",
|
"screen-awake": "Keep Screen Awake",
|
||||||
"remove-image": "Remove image",
|
"remove-image": "Remove image",
|
||||||
"nextStep": "Next step"
|
"nextStep": "Next step",
|
||||||
|
"recipe-actions": "Recipe Actions",
|
||||||
|
"parser": {
|
||||||
|
"experimental-alert-text": "Mealie uses natural language processing to parse and create units and food items for your recipe ingredients. This feature is experimental and may not always work as expected. If you prefer not to use the parsed results, you can select 'Cancel' and your changes will not be saved.",
|
||||||
|
"ingredient-parser": "Ingredient Parser",
|
||||||
|
"explanation": "To use the ingredient parser, click the 'Parse All' button to start the process. Once the processed ingredients are available, you can review the items and verify that they were parsed correctly. The model's confidence score is displayed on the right of the item title. This score is an average of all the individual scores and may not always be completely accurate.",
|
||||||
|
"alerts-explainer": "Alerts will be displayed if a matching foods or unit is found but does not exists in the database.",
|
||||||
|
"select-parser": "Select Parser",
|
||||||
|
"natural-language-processor": "Natural Language Processor",
|
||||||
|
"brute-parser": "Brute Parser",
|
||||||
|
"parse-all": "Parse All",
|
||||||
|
"no-unit": "No unit",
|
||||||
|
"missing-unit": "Create missing unit: {unit}",
|
||||||
|
"missing-food": "Create missing food: {food}",
|
||||||
|
"no-food": "No Food"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"search": {
|
"search": {
|
||||||
"advanced-search": "進階搜尋",
|
"advanced-search": "進階搜尋",
|
||||||
@@ -1001,6 +1018,12 @@
|
|||||||
"delete-recipes": "Delete Recipes",
|
"delete-recipes": "Delete Recipes",
|
||||||
"source-unit-will-be-deleted": "Source Unit will be deleted"
|
"source-unit-will-be-deleted": "Source Unit will be deleted"
|
||||||
},
|
},
|
||||||
|
"recipe-actions": {
|
||||||
|
"recipe-actions-data": "Recipe Actions Data",
|
||||||
|
"new-recipe-action": "New Recipe Action",
|
||||||
|
"edit-recipe-action": "Edit Recipe Action",
|
||||||
|
"action-type": "Action Type"
|
||||||
|
},
|
||||||
"create-alias": "Create Alias",
|
"create-alias": "Create Alias",
|
||||||
"manage-aliases": "Manage Aliases",
|
"manage-aliases": "Manage Aliases",
|
||||||
"seed-data": "Seed Data",
|
"seed-data": "Seed Data",
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import { UtilsAPI } from "./user/utils";
|
|||||||
import { FoodAPI } from "./user/recipe-foods";
|
import { FoodAPI } from "./user/recipe-foods";
|
||||||
import { UnitAPI } from "./user/recipe-units";
|
import { UnitAPI } from "./user/recipe-units";
|
||||||
import { CookbookAPI } from "./user/group-cookbooks";
|
import { CookbookAPI } from "./user/group-cookbooks";
|
||||||
|
import { GroupRecipeActionsAPI } from "./user/group-recipe-actions";
|
||||||
import { WebhooksAPI } from "./user/group-webhooks";
|
import { WebhooksAPI } from "./user/group-webhooks";
|
||||||
import { RegisterAPI } from "./user/user-registration";
|
import { RegisterAPI } from "./user/user-registration";
|
||||||
import { MealPlanAPI } from "./user/group-mealplan";
|
import { MealPlanAPI } from "./user/group-mealplan";
|
||||||
@@ -36,6 +37,7 @@ export class UserApiClient {
|
|||||||
public foods: FoodAPI;
|
public foods: FoodAPI;
|
||||||
public units: UnitAPI;
|
public units: UnitAPI;
|
||||||
public cookbooks: CookbookAPI;
|
public cookbooks: CookbookAPI;
|
||||||
|
public groupRecipeActions: GroupRecipeActionsAPI;
|
||||||
public groupWebhooks: WebhooksAPI;
|
public groupWebhooks: WebhooksAPI;
|
||||||
public register: RegisterAPI;
|
public register: RegisterAPI;
|
||||||
public mealplans: MealPlanAPI;
|
public mealplans: MealPlanAPI;
|
||||||
@@ -65,6 +67,7 @@ export class UserApiClient {
|
|||||||
this.users = new UserApi(requests);
|
this.users = new UserApi(requests);
|
||||||
this.groups = new GroupAPI(requests);
|
this.groups = new GroupAPI(requests);
|
||||||
this.cookbooks = new CookbookAPI(requests);
|
this.cookbooks = new CookbookAPI(requests);
|
||||||
|
this.groupRecipeActions = new GroupRecipeActionsAPI(requests);
|
||||||
this.groupWebhooks = new WebhooksAPI(requests);
|
this.groupWebhooks = new WebhooksAPI(requests);
|
||||||
this.register = new RegisterAPI(requests);
|
this.register = new RegisterAPI(requests);
|
||||||
this.mealplans = new MealPlanAPI(requests);
|
this.mealplans = new MealPlanAPI(requests);
|
||||||
|
|||||||
@@ -5,6 +5,9 @@
|
|||||||
/* Do not modify it by hand - just update the pydantic models and then re-run the script
|
/* Do not modify it by hand - just update the pydantic models and then re-run the script
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
export type RecipeActionType =
|
||||||
|
| "link"
|
||||||
|
| "post";
|
||||||
export type WebhookType = "mealplan";
|
export type WebhookType = "mealplan";
|
||||||
export type SupportedMigrations =
|
export type SupportedMigrations =
|
||||||
| "nextcloud"
|
| "nextcloud"
|
||||||
@@ -26,6 +29,11 @@ export interface CreateGroupPreferences {
|
|||||||
recipeDisableAmount?: boolean;
|
recipeDisableAmount?: boolean;
|
||||||
groupId: string;
|
groupId: string;
|
||||||
}
|
}
|
||||||
|
export interface CreateGroupRecipeAction {
|
||||||
|
actionType: RecipeActionType;
|
||||||
|
title: string;
|
||||||
|
url: string;
|
||||||
|
}
|
||||||
export interface CreateInviteToken {
|
export interface CreateInviteToken {
|
||||||
uses: number;
|
uses: number;
|
||||||
}
|
}
|
||||||
@@ -191,6 +199,13 @@ export interface GroupEventNotifierUpdate {
|
|||||||
options?: GroupEventNotifierOptions;
|
options?: GroupEventNotifierOptions;
|
||||||
id: string;
|
id: string;
|
||||||
}
|
}
|
||||||
|
export interface GroupRecipeActionOut {
|
||||||
|
actionType: RecipeActionType;
|
||||||
|
title: string;
|
||||||
|
url: string;
|
||||||
|
groupId: string;
|
||||||
|
id: string;
|
||||||
|
}
|
||||||
export interface GroupStatistics {
|
export interface GroupStatistics {
|
||||||
totalRecipes: number;
|
totalRecipes: number;
|
||||||
totalUsers: number;
|
totalUsers: number;
|
||||||
@@ -230,6 +245,12 @@ export interface ReadWebhook {
|
|||||||
groupId: string;
|
groupId: string;
|
||||||
id: string;
|
id: string;
|
||||||
}
|
}
|
||||||
|
export interface SaveGroupRecipeAction {
|
||||||
|
actionType: RecipeActionType;
|
||||||
|
title: string;
|
||||||
|
url: string;
|
||||||
|
groupId: string;
|
||||||
|
}
|
||||||
export interface SaveInviteToken {
|
export interface SaveInviteToken {
|
||||||
usesLeft: number;
|
usesLeft: number;
|
||||||
groupId: string;
|
groupId: string;
|
||||||
|
|||||||
14
frontend/lib/api/user/group-recipe-actions.ts
Normal file
14
frontend/lib/api/user/group-recipe-actions.ts
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
import { BaseCRUDAPI } from "../base/base-clients";
|
||||||
|
import { CreateGroupRecipeAction, GroupRecipeActionOut } from "~/lib/api/types/group";
|
||||||
|
|
||||||
|
const prefix = "/api";
|
||||||
|
|
||||||
|
const routes = {
|
||||||
|
groupRecipeActions: `${prefix}/groups/recipe-actions`,
|
||||||
|
groupRecipeActionsId: (id: string | number) => `${prefix}/groups/recipe-actions/${id}`,
|
||||||
|
};
|
||||||
|
|
||||||
|
export class GroupRecipeActionsAPI extends BaseCRUDAPI<CreateGroupRecipeAction, GroupRecipeActionOut> {
|
||||||
|
baseRoute = routes.groupRecipeActions;
|
||||||
|
itemRoute = routes.groupRecipeActionsId;
|
||||||
|
}
|
||||||
@@ -1,10 +1,9 @@
|
|||||||
import { BaseCRUDAPI } from "../base/base-clients";
|
import { BaseCRUDAPI } from "../base/base-clients";
|
||||||
import { QueryValue, route } from "~/lib/api/base/route";
|
import { QueryValue, route } from "~/lib/api/base/route";
|
||||||
import { PaginationData, RequestResponse } from "~/lib/api/types/non-generated";
|
import { PaginationData } from "~/lib/api/types/non-generated";
|
||||||
import {
|
import {
|
||||||
ChangePassword,
|
ChangePassword,
|
||||||
DeleteTokenResponse,
|
DeleteTokenResponse,
|
||||||
GroupInDB,
|
|
||||||
LongLiveTokenIn,
|
LongLiveTokenIn,
|
||||||
LongLiveTokenOut,
|
LongLiveTokenOut,
|
||||||
ResetPassword,
|
ResetPassword,
|
||||||
@@ -30,7 +29,6 @@ const routes = {
|
|||||||
groupUsers: `${prefix}/users/group-users`,
|
groupUsers: `${prefix}/users/group-users`,
|
||||||
usersSelf: `${prefix}/users/self`,
|
usersSelf: `${prefix}/users/self`,
|
||||||
ratingsSelf: `${prefix}/users/self/ratings`,
|
ratingsSelf: `${prefix}/users/self/ratings`,
|
||||||
groupsSelf: `${prefix}/users/self/group`,
|
|
||||||
passwordReset: `${prefix}/users/reset-password`,
|
passwordReset: `${prefix}/users/reset-password`,
|
||||||
passwordChange: `${prefix}/users/password`,
|
passwordChange: `${prefix}/users/password`,
|
||||||
users: `${prefix}/users`,
|
users: `${prefix}/users`,
|
||||||
@@ -57,10 +55,6 @@ export class UserApi extends BaseCRUDAPI<UserIn, UserOut, UserBase> {
|
|||||||
return await this.requests.get<PaginationData<UserSummary>>(route(routes.groupUsers, { page, perPage, ...params }));
|
return await this.requests.get<PaginationData<UserSummary>>(route(routes.groupUsers, { page, perPage, ...params }));
|
||||||
}
|
}
|
||||||
|
|
||||||
async getSelfGroup(): Promise<RequestResponse<GroupInDB>> {
|
|
||||||
return await this.requests.get(routes.groupsSelf, {});
|
|
||||||
}
|
|
||||||
|
|
||||||
async addFavorite(id: string, slug: string) {
|
async addFavorite(id: string, slug: string) {
|
||||||
return await this.requests.post(routes.usersIdFavoritesSlug(id, slug), {});
|
return await this.requests.post(routes.usersIdFavoritesSlug(id, slug), {});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -156,6 +156,7 @@ export default {
|
|||||||
propertyName: "access_token",
|
propertyName: "access_token",
|
||||||
},
|
},
|
||||||
refresh: { url: "api/auth/refresh", method: "post" },
|
refresh: { url: "api/auth/refresh", method: "post" },
|
||||||
|
logout: { url: "api/auth/logout", method: "post" },
|
||||||
user: { url: "api/users/self", method: "get" },
|
user: { url: "api/users/self", method: "get" },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -260,6 +261,12 @@ export default {
|
|||||||
"en-GB": require("./lang/dateTimeFormats/en-GB.json"),
|
"en-GB": require("./lang/dateTimeFormats/en-GB.json"),
|
||||||
"fi-FI": require("./lang/dateTimeFormats/fi-FI.json"),
|
"fi-FI": require("./lang/dateTimeFormats/fi-FI.json"),
|
||||||
"vi-VN": require("./lang/dateTimeFormats/vi-VN.json"),
|
"vi-VN": require("./lang/dateTimeFormats/vi-VN.json"),
|
||||||
|
"sl-SI": require("./lang/dateTimeFormats/sl-SI.json"),
|
||||||
|
"lv-LV": require("./lang/dateTimeFormats/lv-LV.json"),
|
||||||
|
"is-IS": require("./lang/dateTimeFormats/is-IS.json"),
|
||||||
|
"gl-ES": require("./lang/dateTimeFormats/gl-ES.json"),
|
||||||
|
"lt-LT": require("./lang/dateTimeFormats/lt-LT.json"),
|
||||||
|
"hr-HR": require("./lang/dateTimeFormats/hr-HR.json"),
|
||||||
// END: DATE_LOCALES
|
// END: DATE_LOCALES
|
||||||
},
|
},
|
||||||
fallbackLocale: "en-US",
|
fallbackLocale: "en-US",
|
||||||
|
|||||||
@@ -2,35 +2,30 @@
|
|||||||
<v-container v-if="recipe">
|
<v-container v-if="recipe">
|
||||||
<v-container>
|
<v-container>
|
||||||
<v-alert dismissible border="left" colored-border type="warning" elevation="2" :icon="$globals.icons.alert">
|
<v-alert dismissible border="left" colored-border type="warning" elevation="2" :icon="$globals.icons.alert">
|
||||||
<b>Experimental Feature</b>
|
<b>{{ $tc("banner-experimental.title") }}</b>
|
||||||
<div>
|
<div>
|
||||||
Mealie can use natural language processing to attempt to parse and create units, and foods for your Recipe
|
{{ $tc("recipe.parser.experimental-alert-text") }}
|
||||||
ingredients. This is experimental and may not work as expected. If you choose to not use the parsed results
|
|
||||||
you can select cancel and your changes will not be saved.
|
|
||||||
</div>
|
</div>
|
||||||
</v-alert>
|
</v-alert>
|
||||||
|
|
||||||
<BaseCardSectionTitle title="Ingredients Processor">
|
<BaseCardSectionTitle :title="$tc('recipe.parser.ingredient-parser')">
|
||||||
To use the ingredient parser, click the "Parse All" button and the process will start. When the processed
|
<div class="mt-4">{{ $tc("recipe.parser.explanation") }}</div>
|
||||||
ingredients are available, you can look through the items and verify that they were parsed correctly. The models
|
|
||||||
confidence score is displayed on the right of the title item. This is an average of all scores and may not be
|
|
||||||
wholely accurate.
|
|
||||||
|
|
||||||
<div class="my-4">
|
<div class="my-4">
|
||||||
Alerts will be displayed if a matching foods or unit is found but does not exists in the database.
|
{{ $tc("recipe.parser.alerts-explainer") }}
|
||||||
</div>
|
</div>
|
||||||
<div class="d-flex align-center mb-n4">
|
<div class="d-flex align-center mb-n4">
|
||||||
<div class="mb-4">Select Parser</div>
|
<div class="mb-4">{{ $tc("recipe.parser.select-parser") }}</div>
|
||||||
<BaseOverflowButton
|
<BaseOverflowButton
|
||||||
v-model="parser"
|
v-model="parser"
|
||||||
btn-class="mx-2 mb-4"
|
btn-class="mx-2 mb-4"
|
||||||
:items="[
|
:items="[
|
||||||
{
|
{
|
||||||
text: 'Natural Language Processor ',
|
text: $tc('recipe.parser.natural-language-processor'),
|
||||||
value: 'nlp',
|
value: 'nlp',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
text: 'Brute Parser',
|
text: $tc('recipe.parser.brute-parser'),
|
||||||
value: 'brute',
|
value: 'brute',
|
||||||
},
|
},
|
||||||
]"
|
]"
|
||||||
@@ -42,9 +37,9 @@
|
|||||||
<BaseButton cancel class="mr-auto" @click="$router.go(-1)"></BaseButton>
|
<BaseButton cancel class="mr-auto" @click="$router.go(-1)"></BaseButton>
|
||||||
<BaseButton color="info" @click="fetchParsed">
|
<BaseButton color="info" @click="fetchParsed">
|
||||||
<template #icon> {{ $globals.icons.foods }}</template>
|
<template #icon> {{ $globals.icons.foods }}</template>
|
||||||
Parse All
|
{{ $tc("recipe.parser.parse-all") }}
|
||||||
</BaseButton>
|
</BaseButton>
|
||||||
<BaseButton save @click="saveAll"> Save All </BaseButton>
|
<BaseButton save @click="saveAll" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<v-expansion-panels v-model="panels" multiple>
|
<v-expansion-panels v-model="panels" multiple>
|
||||||
@@ -145,6 +140,8 @@ export default defineComponent({
|
|||||||
const slug = route.value.params.slug;
|
const slug = route.value.params.slug;
|
||||||
const api = useUserApi();
|
const api = useUserApi();
|
||||||
|
|
||||||
|
const { i18n } = useContext();
|
||||||
|
|
||||||
const { recipe, loading } = useRecipe(slug);
|
const { recipe, loading } = useRecipe(slug);
|
||||||
|
|
||||||
invoke(async () => {
|
invoke(async () => {
|
||||||
@@ -170,13 +167,15 @@ export default defineComponent({
|
|||||||
if (unitError || foodError) {
|
if (unitError || foodError) {
|
||||||
if (unitError) {
|
if (unitError) {
|
||||||
if (ing?.ingredient?.unit?.name) {
|
if (ing?.ingredient?.unit?.name) {
|
||||||
unitErrorMessage = `Create missing unit '${ing?.ingredient?.unit?.name || "No unit"}'`;
|
const unit = ing.ingredient.unit.name || i18n.tc("recipe.parser.no-unit");
|
||||||
|
unitErrorMessage = i18n.t("recipe.parser.missing-unit", { unit }).toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (foodError) {
|
if (foodError) {
|
||||||
if (ing?.ingredient?.food?.name) {
|
if (ing?.ingredient?.food?.name) {
|
||||||
foodErrorMessage = `Create missing food '${ing.ingredient.food.name || "No food"}'?`;
|
const food = ing.ingredient.food.name || i18n.tc("recipe.parser.no-food");
|
||||||
|
foodErrorMessage = i18n.t("recipe.parser.missing-food", { food }).toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -364,7 +363,7 @@ export default defineComponent({
|
|||||||
},
|
},
|
||||||
head() {
|
head() {
|
||||||
return {
|
return {
|
||||||
title: "Parser",
|
title: this.$tc("recipe.parser.ingredient-parser"),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ export default defineComponent({
|
|||||||
const { i18n } = useContext();
|
const { i18n } = useContext();
|
||||||
const buttonLookup: { [key: string]: string } = {
|
const buttonLookup: { [key: string]: string } = {
|
||||||
recipes: i18n.tc("general.recipes"),
|
recipes: i18n.tc("general.recipes"),
|
||||||
|
recipeActions: i18n.tc("recipe.recipe-actions"),
|
||||||
foods: i18n.tc("general.foods"),
|
foods: i18n.tc("general.foods"),
|
||||||
units: i18n.tc("general.units"),
|
units: i18n.tc("general.units"),
|
||||||
labels: i18n.tc("data-pages.labels.labels"),
|
labels: i18n.tc("data-pages.labels.labels"),
|
||||||
@@ -56,6 +57,11 @@ export default defineComponent({
|
|||||||
text: i18n.t("general.recipes"),
|
text: i18n.t("general.recipes"),
|
||||||
value: "new",
|
value: "new",
|
||||||
to: "/group/data/recipes",
|
to: "/group/data/recipes",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: i18n.t("recipe.recipe-actions"),
|
||||||
|
value: "new",
|
||||||
|
to: "/group/data/recipe-actions",
|
||||||
divider: true,
|
divider: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -92,7 +98,13 @@ export default defineComponent({
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
const buttonText = computed(() => {
|
const buttonText = computed(() => {
|
||||||
const last = route.value.path.split("/").pop();
|
const last = route.value.path
|
||||||
|
.split("/")
|
||||||
|
.pop()
|
||||||
|
// convert hypenated-values to camelCase
|
||||||
|
?.replace(/-([a-z])/g, function (g) {
|
||||||
|
return g[1].toUpperCase();
|
||||||
|
})
|
||||||
|
|
||||||
if (last) {
|
if (last) {
|
||||||
return buttonLookup[last];
|
return buttonLookup[last];
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
v-model="state.editDialog"
|
v-model="state.editDialog"
|
||||||
:icon="$globals.icons.tags"
|
:icon="$globals.icons.tags"
|
||||||
:title="$t('data-pages.labels.edit-label')"
|
:title="$t('data-pages.labels.edit-label')"
|
||||||
|
:submit-icon="$globals.icons.save"
|
||||||
:submit-text="$tc('general.save')"
|
:submit-text="$tc('general.save')"
|
||||||
@submit="editSaveLabel"
|
@submit="editSaveLabel"
|
||||||
>
|
>
|
||||||
|
|||||||
265
frontend/pages/group/data/recipe-actions.vue
Normal file
265
frontend/pages/group/data/recipe-actions.vue
Normal file
@@ -0,0 +1,265 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<!-- Create Dialog -->
|
||||||
|
<BaseDialog
|
||||||
|
v-model="state.createDialog"
|
||||||
|
:title="$t('data-pages.recipe-actions.new-recipe-action')"
|
||||||
|
:icon="$globals.icons.primary"
|
||||||
|
@submit="createAction"
|
||||||
|
>
|
||||||
|
<v-card-text>
|
||||||
|
<v-form ref="domNewActionForm">
|
||||||
|
<v-text-field
|
||||||
|
v-model="createTarget.title"
|
||||||
|
autofocus
|
||||||
|
:label="$t('general.title')"
|
||||||
|
:rules="[validators.required]"
|
||||||
|
/>
|
||||||
|
<v-text-field
|
||||||
|
v-model="createTarget.url"
|
||||||
|
:label="$t('general.url')"
|
||||||
|
:rules="[validators.required]"
|
||||||
|
/>
|
||||||
|
<v-select
|
||||||
|
v-model="createTarget.actionType"
|
||||||
|
:items="actionTypeOptions"
|
||||||
|
:label="$t('data-pages.recipe-actions.action-type')"
|
||||||
|
:rules="[validators.required]"
|
||||||
|
/>
|
||||||
|
</v-form>
|
||||||
|
</v-card-text>
|
||||||
|
</BaseDialog>
|
||||||
|
|
||||||
|
<!-- Edit Dialog -->
|
||||||
|
<BaseDialog
|
||||||
|
v-model="state.editDialog"
|
||||||
|
:icon="$globals.icons.primary"
|
||||||
|
:title="$t('data-pages.recipe-actions.edit-recipe-action')"
|
||||||
|
:submit-text="$tc('general.save')"
|
||||||
|
@submit="editSaveAction"
|
||||||
|
>
|
||||||
|
<v-card-text v-if="editTarget">
|
||||||
|
<div class="mt-4">
|
||||||
|
<v-text-field v-model="editTarget.title" :label="$t('general.title')"/>
|
||||||
|
</div>
|
||||||
|
<div class="mt-4">
|
||||||
|
<v-text-field v-model="editTarget.url" :label="$t('general.url')"/>
|
||||||
|
</div>
|
||||||
|
<div class="mt-4">
|
||||||
|
<v-select
|
||||||
|
v-model="editTarget.actionType"
|
||||||
|
:items="actionTypeOptions"
|
||||||
|
:label="$t('data-pages.recipe-actions.action-type')"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</v-card-text>
|
||||||
|
</BaseDialog>
|
||||||
|
|
||||||
|
<!-- Delete Dialog -->
|
||||||
|
<BaseDialog
|
||||||
|
v-model="state.deleteDialog"
|
||||||
|
:title="$tc('general.confirm')"
|
||||||
|
:icon="$globals.icons.alertCircle"
|
||||||
|
color="error"
|
||||||
|
@confirm="deleteAction"
|
||||||
|
>
|
||||||
|
<v-card-text>
|
||||||
|
{{ $t("general.confirm-delete-generic") }}
|
||||||
|
<p v-if="deleteTarget" class="mt-4 ml-4">{{ deleteTarget.title }}</p>
|
||||||
|
</v-card-text>
|
||||||
|
</BaseDialog>
|
||||||
|
|
||||||
|
<!-- Bulk Delete Dialog -->
|
||||||
|
<BaseDialog
|
||||||
|
v-model="state.bulkDeleteDialog"
|
||||||
|
width="650px"
|
||||||
|
:title="$tc('general.confirm')"
|
||||||
|
:icon="$globals.icons.alertCircle"
|
||||||
|
color="error"
|
||||||
|
@confirm="deleteSelected"
|
||||||
|
>
|
||||||
|
<v-card-text>
|
||||||
|
<p class="h4">{{ $t('general.confirm-delete-generic-items') }}</p>
|
||||||
|
<v-card outlined>
|
||||||
|
<v-virtual-scroll height="400" item-height="25" :items="bulkDeleteTarget">
|
||||||
|
<template #default="{ item }">
|
||||||
|
<v-list-item class="pb-2">
|
||||||
|
<v-list-item-content>
|
||||||
|
<v-list-item-title>{{ item.name }}</v-list-item-title>
|
||||||
|
</v-list-item-content>
|
||||||
|
</v-list-item>
|
||||||
|
</template>
|
||||||
|
</v-virtual-scroll>
|
||||||
|
</v-card>
|
||||||
|
</v-card-text>
|
||||||
|
</BaseDialog>
|
||||||
|
|
||||||
|
<!-- Data Table -->
|
||||||
|
<BaseCardSectionTitle :icon="$globals.icons.primary" section :title="$tc('data-pages.recipe-actions.recipe-actions-data')"> </BaseCardSectionTitle>
|
||||||
|
<CrudTable
|
||||||
|
:table-config="tableConfig"
|
||||||
|
:headers.sync="tableHeaders"
|
||||||
|
:data="actions || []"
|
||||||
|
:bulk-actions="[{icon: $globals.icons.delete, text: $tc('general.delete'), event: 'delete-selected'}]"
|
||||||
|
@delete-one="deleteEventHandler"
|
||||||
|
@edit-one="editEventHandler"
|
||||||
|
@delete-selected="bulkDeleteEventHandler"
|
||||||
|
>
|
||||||
|
<template #button-row>
|
||||||
|
<BaseButton create @click="state.createDialog = true">{{ $t("general.create") }}</BaseButton>
|
||||||
|
</template>
|
||||||
|
<template #item.onHand="{ item }">
|
||||||
|
<v-icon :color="item.onHand ? 'success' : undefined">
|
||||||
|
{{ item.onHand ? $globals.icons.check : $globals.icons.close }}
|
||||||
|
</v-icon>
|
||||||
|
</template>
|
||||||
|
</CrudTable>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import { defineComponent, reactive, ref, useContext } from "@nuxtjs/composition-api";
|
||||||
|
import { validators } from "~/composables/use-validators";
|
||||||
|
import { useGroupRecipeActions, useGroupRecipeActionData } from "~/composables/use-group-recipe-actions";
|
||||||
|
import { GroupRecipeActionOut } from "~/lib/api/types/group";
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
setup() {
|
||||||
|
const { i18n } = useContext();
|
||||||
|
const tableConfig = {
|
||||||
|
hideColumns: true,
|
||||||
|
canExport: true,
|
||||||
|
};
|
||||||
|
const tableHeaders = [
|
||||||
|
{
|
||||||
|
text: i18n.t("general.id"),
|
||||||
|
value: "id",
|
||||||
|
show: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: i18n.t("general.title"),
|
||||||
|
value: "title",
|
||||||
|
show: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: i18n.t("general.url"),
|
||||||
|
value: "url",
|
||||||
|
show: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: i18n.t("data-pages.recipe-actions.action-type"),
|
||||||
|
value: "actionType",
|
||||||
|
show: true,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const state = reactive({
|
||||||
|
createDialog: false,
|
||||||
|
editDialog: false,
|
||||||
|
deleteDialog: false,
|
||||||
|
bulkDeleteDialog: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
const actionData = useGroupRecipeActionData();
|
||||||
|
const actionStore = useGroupRecipeActions(null, null);
|
||||||
|
const actionTypeOptions = ["link", "post"]
|
||||||
|
|
||||||
|
|
||||||
|
// ============================================================
|
||||||
|
// Create Action
|
||||||
|
|
||||||
|
async function createAction() {
|
||||||
|
// @ts-ignore groupId isn't required
|
||||||
|
await actionStore.actions.createOne({
|
||||||
|
actionType: actionData.data.actionType,
|
||||||
|
title: actionData.data.title,
|
||||||
|
url: actionData.data.url,
|
||||||
|
});
|
||||||
|
actionData.reset();
|
||||||
|
state.createDialog = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ============================================================
|
||||||
|
// Edit Action
|
||||||
|
|
||||||
|
const editTarget = ref<GroupRecipeActionOut | null>(null);
|
||||||
|
|
||||||
|
function editEventHandler(item: GroupRecipeActionOut) {
|
||||||
|
state.editDialog = true;
|
||||||
|
editTarget.value = item;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function editSaveAction() {
|
||||||
|
if (!editTarget.value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
await actionStore.actions.updateOne(editTarget.value);
|
||||||
|
state.editDialog = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ============================================================
|
||||||
|
// Delete Action
|
||||||
|
|
||||||
|
const deleteTarget = ref<GroupRecipeActionOut | null>(null);
|
||||||
|
|
||||||
|
function deleteEventHandler(item: GroupRecipeActionOut) {
|
||||||
|
state.deleteDialog = true;
|
||||||
|
deleteTarget.value = item;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function deleteAction() {
|
||||||
|
if (!deleteTarget.value || deleteTarget.value.id === undefined) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
await actionStore.actions.deleteOne(deleteTarget.value.id);
|
||||||
|
state.deleteDialog = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================
|
||||||
|
// Bulk Delete Action
|
||||||
|
|
||||||
|
const bulkDeleteTarget = ref<GroupRecipeActionOut[]>([]);
|
||||||
|
function bulkDeleteEventHandler(selection: GroupRecipeActionOut[]) {
|
||||||
|
bulkDeleteTarget.value = selection;
|
||||||
|
state.bulkDeleteDialog = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function deleteSelected() {
|
||||||
|
for (const item of bulkDeleteTarget.value) {
|
||||||
|
await actionStore.actions.deleteOne(item.id);
|
||||||
|
}
|
||||||
|
bulkDeleteTarget.value = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
state,
|
||||||
|
tableConfig,
|
||||||
|
tableHeaders,
|
||||||
|
actionTypeOptions,
|
||||||
|
actions: actionStore.recipeActions,
|
||||||
|
validators,
|
||||||
|
|
||||||
|
// create
|
||||||
|
createTarget: actionData.data,
|
||||||
|
createAction,
|
||||||
|
|
||||||
|
// edit
|
||||||
|
editTarget,
|
||||||
|
editEventHandler,
|
||||||
|
editSaveAction,
|
||||||
|
|
||||||
|
// delete
|
||||||
|
deleteTarget,
|
||||||
|
deleteEventHandler,
|
||||||
|
deleteAction,
|
||||||
|
|
||||||
|
// bulk delete
|
||||||
|
bulkDeleteTarget,
|
||||||
|
bulkDeleteEventHandler,
|
||||||
|
deleteSelected,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
||||||
@@ -201,7 +201,7 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
|
|
||||||
function isDirectLogin() {
|
function isDirectLogin() {
|
||||||
return router.currentRoute.query.direct
|
return Object.keys(router.currentRoute.query).includes("direct")
|
||||||
}
|
}
|
||||||
|
|
||||||
async function oidcAuthenticate() {
|
async function oidcAuthenticate() {
|
||||||
|
|||||||
@@ -58,11 +58,18 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Reorder Labels -->
|
<!-- Reorder Labels -->
|
||||||
<BaseDialog v-model="reorderLabelsDialog" :icon="$globals.icons.tagArrowUp" :title="$t('shopping-list.reorder-labels')">
|
<BaseDialog
|
||||||
|
v-model="reorderLabelsDialog"
|
||||||
|
:icon="$globals.icons.tagArrowUp"
|
||||||
|
:title="$t('shopping-list.reorder-labels')"
|
||||||
|
:submit-icon="$globals.icons.save"
|
||||||
|
:submit-text="$tc('general.save')"
|
||||||
|
@submit="saveLabelOrder"
|
||||||
|
@close="cancelLabelOrder">
|
||||||
<v-card height="fit-content" max-height="70vh" style="overflow-y: auto;">
|
<v-card height="fit-content" max-height="70vh" style="overflow-y: auto;">
|
||||||
<draggable :value="shoppingList.labelSettings" handle=".handle" class="my-2" @start="loadingCounter += 1" @end="loadingCounter -= 1" @input="updateLabelOrder">
|
<draggable v-if="localLabels" :value="localLabels" handle=".handle" class="my-2" @input="updateLabelOrder">
|
||||||
<div v-for="(labelSetting, index) in shoppingList.labelSettings" :key="labelSetting.id">
|
<div v-for="(labelSetting, index) in localLabels" :key="labelSetting.id">
|
||||||
<MultiPurposeLabelSection v-model="shoppingList.labelSettings[index]" use-color />
|
<MultiPurposeLabelSection v-model="localLabels[index]" use-color />
|
||||||
</div>
|
</div>
|
||||||
</draggable>
|
</draggable>
|
||||||
</v-card>
|
</v-card>
|
||||||
@@ -103,7 +110,9 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div v-else class="mt-4 d-flex justify-end">
|
<div v-else class="mt-4 d-flex justify-end">
|
||||||
<BaseButton v-if="preferences.viewByLabel" edit class="mr-2" @click="reorderLabelsDialog = true">
|
<BaseButton
|
||||||
|
v-if="preferences.viewByLabel" edit class="mr-2"
|
||||||
|
@click="toggleReorderLabelsDialog">
|
||||||
<template #icon> {{ $globals.icons.tags }} </template>
|
<template #icon> {{ $globals.icons.tags }} </template>
|
||||||
{{ $t('shopping-list.reorder-labels') }}
|
{{ $t('shopping-list.reorder-labels') }}
|
||||||
</BaseButton>
|
</BaseButton>
|
||||||
@@ -279,6 +288,7 @@ export default defineComponent({
|
|||||||
const edit = ref(false);
|
const edit = ref(false);
|
||||||
const reorderLabelsDialog = ref(false);
|
const reorderLabelsDialog = ref(false);
|
||||||
const settingsDialog = ref(false);
|
const settingsDialog = ref(false);
|
||||||
|
const preserveItemOrder = ref(false);
|
||||||
|
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const groupSlug = computed(() => route.value.params.groupSlug || $auth.user?.groupSlug || "");
|
const groupSlug = computed(() => route.value.params.groupSlug || $auth.user?.groupSlug || "");
|
||||||
@@ -299,8 +309,19 @@ export default defineComponent({
|
|||||||
loadingCounter.value -= 1;
|
loadingCounter.value -= 1;
|
||||||
|
|
||||||
// only update the list with the new value if we're not loading, to prevent UI jitter
|
// only update the list with the new value if we're not loading, to prevent UI jitter
|
||||||
if (!loadingCounter.value) {
|
if (loadingCounter.value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
shoppingList.value = newListValue;
|
shoppingList.value = newListValue;
|
||||||
|
updateListItemOrder();
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateListItemOrder() {
|
||||||
|
if (!preserveItemOrder.value) {
|
||||||
|
groupAndSortListItemsByFood();
|
||||||
|
updateItemsByLabel();
|
||||||
|
} else {
|
||||||
sortListItems();
|
sortListItems();
|
||||||
updateItemsByLabel();
|
updateItemsByLabel();
|
||||||
}
|
}
|
||||||
@@ -480,6 +501,8 @@ export default defineComponent({
|
|||||||
// Labels, Units, Foods
|
// Labels, Units, Foods
|
||||||
// TODO: Extract to Composable
|
// TODO: Extract to Composable
|
||||||
|
|
||||||
|
const localLabels = ref<ShoppingListMultiPurposeLabelOut[]>()
|
||||||
|
|
||||||
const { labels: allLabels } = useLabelStore();
|
const { labels: allLabels } = useLabelStore();
|
||||||
const { units: allUnits } = useUnitStore();
|
const { units: allUnits } = useUnitStore();
|
||||||
const { foods: allFoods } = useFoodStore();
|
const { foods: allFoods } = useFoodStore();
|
||||||
@@ -493,7 +516,10 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
|
|
||||||
function toggleReorderLabelsDialog() {
|
function toggleReorderLabelsDialog() {
|
||||||
|
// stop polling and populate localLabels
|
||||||
|
loadingCounter.value += 1
|
||||||
reorderLabelsDialog.value = !reorderLabelsDialog.value
|
reorderLabelsDialog.value = !reorderLabelsDialog.value
|
||||||
|
localLabels.value = shoppingList.value?.labelSettings
|
||||||
}
|
}
|
||||||
|
|
||||||
async function toggleSettingsDialog() {
|
async function toggleSettingsDialog() {
|
||||||
@@ -503,7 +529,7 @@ export default defineComponent({
|
|||||||
settingsDialog.value = !settingsDialog.value;
|
settingsDialog.value = !settingsDialog.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function updateLabelOrder(labelSettings: ShoppingListMultiPurposeLabelOut[]) {
|
function updateLabelOrder(labelSettings: ShoppingListMultiPurposeLabelOut[]) {
|
||||||
if (!shoppingList.value) {
|
if (!shoppingList.value) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -513,16 +539,31 @@ export default defineComponent({
|
|||||||
return labelSetting;
|
return labelSetting;
|
||||||
});
|
});
|
||||||
|
|
||||||
// setting this doesn't have any effect on the data since it's refreshed automatically, but it makes the ux feel smoother
|
localLabels.value = labelSettings
|
||||||
shoppingList.value.labelSettings = labelSettings;
|
}
|
||||||
updateItemsByLabel();
|
|
||||||
|
function cancelLabelOrder() {
|
||||||
|
loadingCounter.value -= 1
|
||||||
|
if (!shoppingList.value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// restore original state
|
||||||
|
localLabels.value = shoppingList.value.labelSettings
|
||||||
|
}
|
||||||
|
|
||||||
|
async function saveLabelOrder() {
|
||||||
|
if (!shoppingList.value || !localLabels.value || (localLabels.value === shoppingList.value.labelSettings)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
loadingCounter.value += 1;
|
loadingCounter.value += 1;
|
||||||
const { data } = await userApi.shopping.lists.updateLabelSettings(shoppingList.value.id, labelSettings);
|
const { data } = await userApi.shopping.lists.updateLabelSettings(shoppingList.value.id, localLabels.value);
|
||||||
loadingCounter.value -= 1;
|
loadingCounter.value -= 1;
|
||||||
|
|
||||||
if (data) {
|
if (data) {
|
||||||
refresh();
|
// update shoppingList labels using the API response
|
||||||
|
shoppingList.value.labelSettings = (data as ShoppingListOut).labelSettings;
|
||||||
|
updateItemsByLabel();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -543,12 +584,62 @@ export default defineComponent({
|
|||||||
|
|
||||||
const itemsByLabel = ref<{ [key: string]: ShoppingListItemOut[] }>({});
|
const itemsByLabel = ref<{ [key: string]: ShoppingListItemOut[] }>({});
|
||||||
|
|
||||||
|
interface ListItemGroup {
|
||||||
|
position: number;
|
||||||
|
createdAt: string;
|
||||||
|
items: ShoppingListItemOut[];
|
||||||
|
}
|
||||||
|
|
||||||
|
function groupAndSortListItemsByFood() {
|
||||||
|
if (!shoppingList.value?.listItems?.length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const checkedItemKey = "__checkedItem"
|
||||||
|
const listItemGroupsMap = new Map<string, ListItemGroup>();
|
||||||
|
listItemGroupsMap.set(checkedItemKey, {position: Number.MAX_SAFE_INTEGER, createdAt: "", items: []});
|
||||||
|
|
||||||
|
// group items by checked status, food, or note
|
||||||
|
shoppingList.value.listItems.forEach((item) => {
|
||||||
|
const key = item.checked ? checkedItemKey : item.isFood && item.food?.name
|
||||||
|
? item.food.name
|
||||||
|
: item.note || ""
|
||||||
|
|
||||||
|
const group = listItemGroupsMap.get(key);
|
||||||
|
if (!group) {
|
||||||
|
listItemGroupsMap.set(key, {position: item.position || 0, createdAt: item.createdAt || "", items: [item]});
|
||||||
|
} else {
|
||||||
|
group.items.push(item);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// sort group items by position ascending, then createdAt descending
|
||||||
|
const listItemGroups = Array.from(listItemGroupsMap.values());
|
||||||
|
listItemGroups.sort((a, b) => (a.position > b.position || a.createdAt < b.createdAt ? 1 : -1));
|
||||||
|
|
||||||
|
// sort group items by position ascending, then createdAt descending, and aggregate them
|
||||||
|
const sortedItems: ShoppingListItemOut[] = [];
|
||||||
|
let nextPosition = 0;
|
||||||
|
listItemGroups.forEach((listItemGroup) => {
|
||||||
|
// @ts-ignore none of these fields are undefined
|
||||||
|
listItemGroup.items.sort((a, b) => (a.position > b.position || a.createdAt < b.createdAt ? 1 : -1));
|
||||||
|
listItemGroup.items.forEach((item) => {
|
||||||
|
item.position = nextPosition;
|
||||||
|
nextPosition += 1;
|
||||||
|
sortedItems.push(item);
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
shoppingList.value.listItems = sortedItems;
|
||||||
|
}
|
||||||
|
|
||||||
function sortListItems() {
|
function sortListItems() {
|
||||||
if (!shoppingList.value?.listItems?.length) {
|
if (!shoppingList.value?.listItems?.length) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// sort by position ascending, then createdAt descending
|
// sort by position ascending, then createdAt descending
|
||||||
|
// @ts-ignore none of these fields are undefined
|
||||||
shoppingList.value.listItems.sort((a, b) => (a.position > b.position || a.createdAt < b.createdAt ? 1 : -1))
|
shoppingList.value.listItems.sort((a, b) => (a.position > b.position || a.createdAt < b.createdAt ? 1 : -1))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -682,8 +773,7 @@ export default defineComponent({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
sortListItems();
|
updateListItemOrder();
|
||||||
updateItemsByLabel();
|
|
||||||
|
|
||||||
loadingCounter.value += 1;
|
loadingCounter.value += 1;
|
||||||
const { data } = await userApi.shopping.items.updateOne(item.id, item);
|
const { data } = await userApi.shopping.items.updateOne(item.id, item);
|
||||||
@@ -759,6 +849,9 @@ export default defineComponent({
|
|||||||
shoppingList.value.listItems = uncheckedItems.concat(listItems.value.checked);
|
shoppingList.value.listItems = uncheckedItems.concat(listItems.value.checked);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// since the user has manually reordered the list, we should preserve this order
|
||||||
|
preserveItemOrder.value = true;
|
||||||
|
|
||||||
updateListItems();
|
updateListItems();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -776,6 +869,9 @@ export default defineComponent({
|
|||||||
allUncheckedItems.push(...itemsByLabel.value[labelName]);
|
allUncheckedItems.push(...itemsByLabel.value[labelName]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// since the user has manually reordered the list, we should preserve this order
|
||||||
|
preserveItemOrder.value = true;
|
||||||
|
|
||||||
// save changes
|
// save changes
|
||||||
return updateIndexUnchecked(allUncheckedItems);
|
return updateIndexUnchecked(allUncheckedItems);
|
||||||
}
|
}
|
||||||
@@ -873,7 +969,10 @@ export default defineComponent({
|
|||||||
toggleReorderLabelsDialog,
|
toggleReorderLabelsDialog,
|
||||||
settingsDialog,
|
settingsDialog,
|
||||||
toggleSettingsDialog,
|
toggleSettingsDialog,
|
||||||
|
localLabels,
|
||||||
updateLabelOrder,
|
updateLabelOrder,
|
||||||
|
cancelLabelOrder,
|
||||||
|
saveLabelOrder,
|
||||||
saveListItem,
|
saveListItem,
|
||||||
shoppingList,
|
shoppingList,
|
||||||
showChecked,
|
showChecked,
|
||||||
|
|||||||
@@ -190,7 +190,6 @@
|
|||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { computed, defineComponent, useContext, ref, toRefs, reactive, useAsync, useRoute } from "@nuxtjs/composition-api";
|
import { computed, defineComponent, useContext, ref, toRefs, reactive, useAsync, useRoute } from "@nuxtjs/composition-api";
|
||||||
import { invoke, until } from "@vueuse/core";
|
|
||||||
import UserProfileLinkCard from "@/components/Domain/User/UserProfileLinkCard.vue";
|
import UserProfileLinkCard from "@/components/Domain/User/UserProfileLinkCard.vue";
|
||||||
import { useUserApi } from "~/composables/api";
|
import { useUserApi } from "~/composables/api";
|
||||||
import { validators } from "~/composables/use-validators";
|
import { validators } from "~/composables/use-validators";
|
||||||
@@ -198,7 +197,7 @@ import { alert } from "~/composables/use-toast";
|
|||||||
import UserAvatar from "@/components/Domain/User/UserAvatar.vue";
|
import UserAvatar from "@/components/Domain/User/UserAvatar.vue";
|
||||||
import { useAsyncKey } from "~/composables/use-utils";
|
import { useAsyncKey } from "~/composables/use-utils";
|
||||||
import StatsCards from "~/components/global/StatsCards.vue";
|
import StatsCards from "~/components/global/StatsCards.vue";
|
||||||
import { GroupInDB, UserOut } from "~/lib/api/types/user";
|
import { UserOut } from "~/lib/api/types/user";
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: "UserProfile",
|
name: "UserProfile",
|
||||||
@@ -216,7 +215,6 @@ export default defineComponent({
|
|||||||
|
|
||||||
// @ts-ignore $auth.user is typed as unknown, but it's a user
|
// @ts-ignore $auth.user is typed as unknown, but it's a user
|
||||||
const user = computed<UserOut | null>(() => $auth.user);
|
const user = computed<UserOut | null>(() => $auth.user);
|
||||||
const group = ref<GroupInDB | null>(null);
|
|
||||||
|
|
||||||
const showPublicLink = ref(false);
|
const showPublicLink = ref(false);
|
||||||
const publicLink = ref("");
|
const publicLink = ref("");
|
||||||
@@ -225,16 +223,6 @@ export default defineComponent({
|
|||||||
const token = ref("");
|
const token = ref("");
|
||||||
const api = useUserApi();
|
const api = useUserApi();
|
||||||
|
|
||||||
invoke(async () => {
|
|
||||||
await until(user.value).not.toBeNull();
|
|
||||||
if (!user.value) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const { data } = await api.users.getSelfGroup();
|
|
||||||
group.value = data;
|
|
||||||
});
|
|
||||||
|
|
||||||
async function getSignupLink() {
|
async function getSignupLink() {
|
||||||
const { data } = await api.groups.createInvitation({ uses: 1 });
|
const { data } = await api.groups.createInvitation({ uses: 1 });
|
||||||
if (data) {
|
if (data) {
|
||||||
@@ -333,7 +321,6 @@ export default defineComponent({
|
|||||||
getStatsTitle,
|
getStatsTitle,
|
||||||
getStatsIcon,
|
getStatsIcon,
|
||||||
getStatsTo,
|
getStatsTo,
|
||||||
group,
|
|
||||||
stats,
|
stats,
|
||||||
user,
|
user,
|
||||||
constructLink,
|
constructLink,
|
||||||
|
|||||||
@@ -9,14 +9,12 @@ export default class DynamicOpenIDConnectScheme extends OpenIDConnectScheme {
|
|||||||
|
|
||||||
async mounted() {
|
async mounted() {
|
||||||
await this.getConfiguration();
|
await this.getConfiguration();
|
||||||
this.options.scope = ["openid", "profile", "email", "groups"]
|
|
||||||
|
|
||||||
this.configurationDocument = new ConfigurationDocument(
|
this.configurationDocument = new ConfigurationDocument(
|
||||||
this,
|
this,
|
||||||
this.$auth.$storage
|
this.$auth.$storage
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
||||||
return await super.mounted()
|
return await super.mounted()
|
||||||
}
|
}
|
||||||
@@ -78,7 +76,10 @@ export default class DynamicOpenIDConnectScheme extends OpenIDConnectScheme {
|
|||||||
})
|
})
|
||||||
// Update tokens with mealie token
|
// Update tokens with mealie token
|
||||||
this.updateTokens(response)
|
this.updateTokens(response)
|
||||||
} catch {
|
} catch (e) {
|
||||||
|
if (e.response?.status === 401 || e.response?.status === 500) {
|
||||||
|
this.$auth.reset()
|
||||||
|
}
|
||||||
const currentUrl = new URL(window.location.href)
|
const currentUrl = new URL(window.location.href)
|
||||||
if (currentUrl.pathname === "/login" && currentUrl.searchParams.has("direct")) {
|
if (currentUrl.pathname === "/login" && currentUrl.searchParams.has("direct")) {
|
||||||
return
|
return
|
||||||
@@ -109,6 +110,11 @@ export default class DynamicOpenIDConnectScheme extends OpenIDConnectScheme {
|
|||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
this.options.endpoints.configuration = data.configurationUrl;
|
this.options.endpoints.configuration = data.configurationUrl;
|
||||||
this.options.clientId = data.clientId;
|
this.options.clientId = data.clientId;
|
||||||
|
this.options.scope = ["openid", "profile", "email"]
|
||||||
|
if (data.groupsClaim !== null) {
|
||||||
|
this.options.scope.push(data.groupsClaim)
|
||||||
|
}
|
||||||
|
console.log(this.options.scope)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// pass
|
// pass
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,9 +5,10 @@ from pathlib import Path
|
|||||||
from uuid import uuid4
|
from uuid import uuid4
|
||||||
|
|
||||||
import fastapi
|
import fastapi
|
||||||
|
import jwt
|
||||||
from fastapi import BackgroundTasks, Depends, HTTPException, Request, status
|
from fastapi import BackgroundTasks, Depends, HTTPException, Request, status
|
||||||
from fastapi.security import OAuth2PasswordBearer
|
from fastapi.security import OAuth2PasswordBearer
|
||||||
from jose import JWTError, jwt
|
from jwt.exceptions import PyJWTError
|
||||||
from sqlalchemy.orm.session import Session
|
from sqlalchemy.orm.session import Session
|
||||||
|
|
||||||
from mealie.core import root_logger
|
from mealie.core import root_logger
|
||||||
@@ -96,8 +97,8 @@ async def get_current_user(
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
payload = jwt.decode(token, settings.SECRET, algorithms=[ALGORITHM])
|
payload = jwt.decode(token, settings.SECRET, algorithms=[ALGORITHM])
|
||||||
user_id: str = payload.get("sub")
|
user_id: str | None = payload.get("sub")
|
||||||
long_token: str = payload.get("long_token")
|
long_token: str | None = payload.get("long_token")
|
||||||
|
|
||||||
if long_token is not None:
|
if long_token is not None:
|
||||||
return validate_long_live_token(session, token, payload.get("id"))
|
return validate_long_live_token(session, token, payload.get("id"))
|
||||||
@@ -106,7 +107,7 @@ async def get_current_user(
|
|||||||
raise credentials_exception
|
raise credentials_exception
|
||||||
|
|
||||||
token_data = TokenData(user_id=user_id)
|
token_data = TokenData(user_id=user_id)
|
||||||
except JWTError as e:
|
except PyJWTError as e:
|
||||||
raise credentials_exception from e
|
raise credentials_exception from e
|
||||||
|
|
||||||
repos = get_repositories(session)
|
repos = get_repositories(session)
|
||||||
@@ -126,7 +127,7 @@ async def get_integration_id(token: str = Depends(oauth2_scheme)) -> str:
|
|||||||
decoded_token = jwt.decode(token, settings.SECRET, algorithms=[ALGORITHM])
|
decoded_token = jwt.decode(token, settings.SECRET, algorithms=[ALGORITHM])
|
||||||
return decoded_token.get("integration_id", DEFAULT_INTEGRATION_ID)
|
return decoded_token.get("integration_id", DEFAULT_INTEGRATION_ID)
|
||||||
|
|
||||||
except JWTError as e:
|
except PyJWTError as e:
|
||||||
raise credentials_exception from e
|
raise credentials_exception from e
|
||||||
|
|
||||||
|
|
||||||
@@ -162,7 +163,7 @@ def validate_file_token(token: str | None = None) -> Path:
|
|||||||
try:
|
try:
|
||||||
payload = jwt.decode(token, settings.SECRET, algorithms=[ALGORITHM])
|
payload = jwt.decode(token, settings.SECRET, algorithms=[ALGORITHM])
|
||||||
file_path = Path(payload.get("file"))
|
file_path = Path(payload.get("file"))
|
||||||
except JWTError as e:
|
except PyJWTError as e:
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
status_code=status.HTTP_401_UNAUTHORIZED,
|
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||||
detail="could not validate file token",
|
detail="could not validate file token",
|
||||||
@@ -181,7 +182,7 @@ def validate_recipe_token(token: str | None = None) -> str:
|
|||||||
|
|
||||||
Raises:
|
Raises:
|
||||||
HTTPException: 400 Bad Request when no token or the recipe doesn't exist
|
HTTPException: 400 Bad Request when no token or the recipe doesn't exist
|
||||||
HTTPException: 401 JWTError when token is invalid
|
HTTPException: 401 PyJWTError when token is invalid
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
str: token data
|
str: token data
|
||||||
@@ -192,7 +193,7 @@ def validate_recipe_token(token: str | None = None) -> str:
|
|||||||
try:
|
try:
|
||||||
payload = jwt.decode(token, settings.SECRET, algorithms=[ALGORITHM])
|
payload = jwt.decode(token, settings.SECRET, algorithms=[ALGORITHM])
|
||||||
slug: str | None = payload.get("slug")
|
slug: str | None = payload.get("slug")
|
||||||
except JWTError as e:
|
except PyJWTError as e:
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
status_code=status.HTTP_401_UNAUTHORIZED,
|
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||||
detail="could not validate file token",
|
detail="could not validate file token",
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import abc
|
|||||||
from datetime import datetime, timedelta, timezone
|
from datetime import datetime, timedelta, timezone
|
||||||
from typing import Generic, TypeVar
|
from typing import Generic, TypeVar
|
||||||
|
|
||||||
from jose import jwt
|
import jwt
|
||||||
from sqlalchemy.orm.session import Session
|
from sqlalchemy.orm.session import Session
|
||||||
|
|
||||||
from mealie.core.config import get_app_settings
|
from mealie.core.config import get_app_settings
|
||||||
|
|||||||
@@ -35,7 +35,9 @@ class OpenIDProvider(AuthProvider[OIDCRequest]):
|
|||||||
repos = get_repositories(self.session)
|
repos = get_repositories(self.session)
|
||||||
|
|
||||||
user = self.try_get_user(claims.get(settings.OIDC_USER_CLAIM))
|
user = self.try_get_user(claims.get(settings.OIDC_USER_CLAIM))
|
||||||
group_claim = claims.get("groups", [])
|
is_admin = False
|
||||||
|
if settings.OIDC_USER_GROUP or settings.OIDC_ADMIN_GROUP:
|
||||||
|
group_claim = claims.get(settings.OIDC_GROUPS_CLAIM, [])
|
||||||
is_admin = settings.OIDC_ADMIN_GROUP in group_claim if settings.OIDC_ADMIN_GROUP else False
|
is_admin = settings.OIDC_ADMIN_GROUP in group_claim if settings.OIDC_ADMIN_GROUP else False
|
||||||
is_valid_user = settings.OIDC_USER_GROUP in group_claim if settings.OIDC_USER_GROUP else True
|
is_valid_user = settings.OIDC_USER_GROUP in group_claim if settings.OIDC_USER_GROUP else True
|
||||||
|
|
||||||
@@ -68,18 +70,18 @@ class OpenIDProvider(AuthProvider[OIDCRequest]):
|
|||||||
return self.get_access_token(user, settings.OIDC_REMEMBER_ME) # type: ignore
|
return self.get_access_token(user, settings.OIDC_REMEMBER_ME) # type: ignore
|
||||||
|
|
||||||
if user:
|
if user:
|
||||||
if user.admin != is_admin:
|
if settings.OIDC_ADMIN_GROUP and user.admin != is_admin:
|
||||||
self._logger.debug(f"[OIDC] {'Setting' if is_admin else 'Removing'} user as admin")
|
self._logger.debug(f"[OIDC] {'Setting' if is_admin else 'Removing'} user as admin")
|
||||||
user.admin = is_admin
|
user.admin = is_admin
|
||||||
repos.users.update(user.id, user)
|
repos.users.update(user.id, user)
|
||||||
return self.get_access_token(user, settings.OIDC_REMEMBER_ME)
|
return self.get_access_token(user, settings.OIDC_REMEMBER_ME)
|
||||||
|
|
||||||
self._logger.info("[OIDC] Found user but their AuthMethod does not match OIDC")
|
self._logger.warning("[OIDC] Found user but their AuthMethod does not match OIDC")
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def get_claims(self, settings: AppSettings) -> JWTClaims | None:
|
def get_claims(self, settings: AppSettings) -> JWTClaims | None:
|
||||||
"""Get the claims from the ID token and check if the required claims are present"""
|
"""Get the claims from the ID token and check if the required claims are present"""
|
||||||
required_claims = {"preferred_username", "name", "email"}
|
required_claims = {"preferred_username", "name", "email", settings.OIDC_USER_CLAIM}
|
||||||
jwks = OpenIDProvider.get_jwks()
|
jwks = OpenIDProvider.get_jwks()
|
||||||
if not jwks:
|
if not jwks:
|
||||||
return None
|
return None
|
||||||
@@ -91,15 +93,18 @@ class OpenIDProvider(AuthProvider[OIDCRequest]):
|
|||||||
self._logger.error(
|
self._logger.error(
|
||||||
f"[OIDC] Unsupported algorithm '{algorithm}'. Unable to decode id token due to mismatched algorithm."
|
f"[OIDC] Unsupported algorithm '{algorithm}'. Unable to decode id token due to mismatched algorithm."
|
||||||
)
|
)
|
||||||
|
return None
|
||||||
|
|
||||||
try:
|
try:
|
||||||
claims.validate()
|
claims.validate()
|
||||||
except ExpiredTokenError as e:
|
except ExpiredTokenError as e:
|
||||||
self._logger.debug(f"[OIDC] {e.error}: {e.description}")
|
self._logger.error(f"[OIDC] {e.error}: {e.description}")
|
||||||
return None
|
return None
|
||||||
|
except Exception as e:
|
||||||
|
self._logger.error("[OIDC] Exception while validating id_token claims", e)
|
||||||
|
|
||||||
if not claims:
|
if not claims:
|
||||||
self._logger.warning("[OIDC] Claims not found")
|
self._logger.error("[OIDC] Claims not found")
|
||||||
return None
|
return None
|
||||||
if not required_claims.issubset(claims.keys()):
|
if not required_claims.issubset(claims.keys()):
|
||||||
self._logger.error(
|
self._logger.error(
|
||||||
@@ -116,20 +121,27 @@ class OpenIDProvider(AuthProvider[OIDCRequest]):
|
|||||||
|
|
||||||
if not (settings.OIDC_READY and settings.OIDC_CONFIGURATION_URL):
|
if not (settings.OIDC_READY and settings.OIDC_CONFIGURATION_URL):
|
||||||
return None
|
return None
|
||||||
configuration = None
|
|
||||||
with requests.get(settings.OIDC_CONFIGURATION_URL, timeout=5) as config_response:
|
session = requests.Session()
|
||||||
|
if settings.OIDC_TLS_CACERTFILE:
|
||||||
|
session.verify = settings.OIDC_TLS_CACERTFILE
|
||||||
|
|
||||||
|
config_response = session.get(settings.OIDC_CONFIGURATION_URL, timeout=5)
|
||||||
config_response.raise_for_status()
|
config_response.raise_for_status()
|
||||||
configuration = config_response.json()
|
configuration = config_response.json()
|
||||||
|
|
||||||
if not configuration:
|
if not configuration:
|
||||||
OpenIDProvider._logger.warning("[OIDC] Unable to fetch configuration from the OIDC_CONFIGURATION_URL")
|
OpenIDProvider._logger.warning("[OIDC] Unable to fetch configuration from the OIDC_CONFIGURATION_URL")
|
||||||
|
session.close()
|
||||||
return None
|
return None
|
||||||
|
|
||||||
jwks_uri = configuration.get("jwks_uri", None)
|
jwks_uri = configuration.get("jwks_uri", None)
|
||||||
if not jwks_uri:
|
if not jwks_uri:
|
||||||
OpenIDProvider._logger.warning("[OIDC] Unable to find the jwks_uri from the OIDC_CONFIGURATION_URL")
|
OpenIDProvider._logger.warning("[OIDC] Unable to find the jwks_uri from the OIDC_CONFIGURATION_URL")
|
||||||
|
session.close()
|
||||||
return None
|
return None
|
||||||
|
|
||||||
with requests.get(jwks_uri, timeout=5) as response:
|
response = session.get(jwks_uri, timeout=5)
|
||||||
response.raise_for_status()
|
response.raise_for_status()
|
||||||
|
session.close()
|
||||||
return JsonWebKey.import_key_set(response.json())
|
return JsonWebKey.import_key_set(response.json())
|
||||||
|
|||||||
@@ -2,8 +2,8 @@ import secrets
|
|||||||
from datetime import datetime, timedelta, timezone
|
from datetime import datetime, timedelta, timezone
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
|
import jwt
|
||||||
from fastapi import Request
|
from fastapi import Request
|
||||||
from jose import jwt
|
|
||||||
from sqlalchemy.orm.session import Session
|
from sqlalchemy.orm.session import Session
|
||||||
|
|
||||||
from mealie.core import root_logger
|
from mealie.core import root_logger
|
||||||
|
|||||||
@@ -192,16 +192,20 @@ class AppSettings(BaseSettings):
|
|||||||
OIDC_REMEMBER_ME: bool = False
|
OIDC_REMEMBER_ME: bool = False
|
||||||
OIDC_SIGNING_ALGORITHM: str = "RS256"
|
OIDC_SIGNING_ALGORITHM: str = "RS256"
|
||||||
OIDC_USER_CLAIM: str = "email"
|
OIDC_USER_CLAIM: str = "email"
|
||||||
|
OIDC_GROUPS_CLAIM: str | None = "groups"
|
||||||
|
OIDC_TLS_CACERTFILE: str | None = None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def OIDC_READY(self) -> bool:
|
def OIDC_READY(self) -> bool:
|
||||||
"""Validates OIDC settings are all set"""
|
"""Validates OIDC settings are all set"""
|
||||||
|
|
||||||
required = {self.OIDC_CLIENT_ID, self.OIDC_CONFIGURATION_URL}
|
required = {self.OIDC_CLIENT_ID, self.OIDC_CONFIGURATION_URL, self.OIDC_USER_CLAIM}
|
||||||
not_none = None not in required
|
not_none = None not in required
|
||||||
valid_user_claim = self.OIDC_USER_CLAIM in ["email", "preferred_username"]
|
valid_group_claim = True
|
||||||
|
if (not self.OIDC_USER_GROUP or not self.OIDC_ADMIN_GROUP) and not self.OIDC_GROUPS_CLAIM:
|
||||||
|
valid_group_claim = False
|
||||||
|
|
||||||
return self.OIDC_AUTH_ENABLED and not_none and valid_user_claim
|
return self.OIDC_AUTH_ENABLED and not_none and valid_group_claim
|
||||||
|
|
||||||
# ===============================================
|
# ===============================================
|
||||||
# Testing Config
|
# Testing Config
|
||||||
|
|||||||
@@ -27,10 +27,10 @@ class GUID(TypeDecorator):
|
|||||||
return str(value)
|
return str(value)
|
||||||
else:
|
else:
|
||||||
if not isinstance(value, uuid.UUID):
|
if not isinstance(value, uuid.UUID):
|
||||||
return "%.32x" % uuid.UUID(value).int
|
return f"{uuid.UUID(value).int:032x}"
|
||||||
else:
|
else:
|
||||||
# hexstring
|
# hexstring
|
||||||
return "%.32x" % value.int
|
return f"{value.int:032x}"
|
||||||
|
|
||||||
def load_dialect_impl(self, dialect):
|
def load_dialect_impl(self, dialect):
|
||||||
if dialect.name == "postgresql":
|
if dialect.name == "postgresql":
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ from .group import *
|
|||||||
from .invite_tokens import *
|
from .invite_tokens import *
|
||||||
from .mealplan import *
|
from .mealplan import *
|
||||||
from .preferences import *
|
from .preferences import *
|
||||||
|
from .recipe_action import *
|
||||||
from .report import *
|
from .report import *
|
||||||
from .shopping_list import *
|
from .shopping_list import *
|
||||||
from .webhooks import *
|
from .webhooks import *
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ if TYPE_CHECKING:
|
|||||||
from ..users import User
|
from ..users import User
|
||||||
from .events import GroupEventNotifierModel
|
from .events import GroupEventNotifierModel
|
||||||
from .exports import GroupDataExportsModel
|
from .exports import GroupDataExportsModel
|
||||||
|
from .recipe_action import GroupRecipeAction
|
||||||
from .report import ReportModel
|
from .report import ReportModel
|
||||||
from .shopping_list import ShoppingList
|
from .shopping_list import ShoppingList
|
||||||
|
|
||||||
@@ -64,6 +65,7 @@ class Group(SqlAlchemyBase, BaseMixins):
|
|||||||
GroupMealPlan, order_by="GroupMealPlan.date", **common_args
|
GroupMealPlan, order_by="GroupMealPlan.date", **common_args
|
||||||
)
|
)
|
||||||
webhooks: Mapped[list[GroupWebhooksModel]] = orm.relationship(GroupWebhooksModel, **common_args)
|
webhooks: Mapped[list[GroupWebhooksModel]] = orm.relationship(GroupWebhooksModel, **common_args)
|
||||||
|
recipe_actions: Mapped[list["GroupRecipeAction"]] = orm.relationship("GroupRecipeAction", **common_args)
|
||||||
cookbooks: Mapped[list[CookBook]] = orm.relationship(CookBook, **common_args)
|
cookbooks: Mapped[list[CookBook]] = orm.relationship(CookBook, **common_args)
|
||||||
server_tasks: Mapped[list[ServerTaskModel]] = orm.relationship(ServerTaskModel, **common_args)
|
server_tasks: Mapped[list[ServerTaskModel]] = orm.relationship(ServerTaskModel, **common_args)
|
||||||
data_exports: Mapped[list["GroupDataExportsModel"]] = orm.relationship("GroupDataExportsModel", **common_args)
|
data_exports: Mapped[list["GroupDataExportsModel"]] = orm.relationship("GroupDataExportsModel", **common_args)
|
||||||
@@ -82,6 +84,7 @@ class Group(SqlAlchemyBase, BaseMixins):
|
|||||||
exclude={
|
exclude={
|
||||||
"users",
|
"users",
|
||||||
"webhooks",
|
"webhooks",
|
||||||
|
"recipe_actions",
|
||||||
"shopping_lists",
|
"shopping_lists",
|
||||||
"cookbooks",
|
"cookbooks",
|
||||||
"preferences",
|
"preferences",
|
||||||
|
|||||||
25
mealie/db/models/group/recipe_action.py
Normal file
25
mealie/db/models/group/recipe_action.py
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
|
from sqlalchemy import ForeignKey, String
|
||||||
|
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
||||||
|
|
||||||
|
from .._model_base import BaseMixins, SqlAlchemyBase
|
||||||
|
from .._model_utils import GUID, auto_init
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from group import Group
|
||||||
|
|
||||||
|
|
||||||
|
class GroupRecipeAction(SqlAlchemyBase, BaseMixins):
|
||||||
|
__tablename__ = "recipe_actions"
|
||||||
|
id: Mapped[GUID] = mapped_column(GUID, primary_key=True, default=GUID.generate)
|
||||||
|
group_id: Mapped[GUID] = mapped_column(GUID, ForeignKey("groups.id"), index=True)
|
||||||
|
group: Mapped["Group"] = relationship("Group", back_populates="recipe_actions", single_parent=True)
|
||||||
|
|
||||||
|
action_type: Mapped[str] = mapped_column(String, index=True)
|
||||||
|
title: Mapped[str] = mapped_column(String, index=True)
|
||||||
|
url: Mapped[str] = mapped_column(String)
|
||||||
|
|
||||||
|
@auto_init()
|
||||||
|
def __init__(self, **_) -> None:
|
||||||
|
pass
|
||||||
@@ -3,7 +3,11 @@
|
|||||||
"server-error": "Iets het skeefgeloop"
|
"server-error": "Iets het skeefgeloop"
|
||||||
},
|
},
|
||||||
"recipe": {
|
"recipe": {
|
||||||
"unique-name-error": "Nuwe resepname moet uniek wees"
|
"unique-name-error": "Nuwe resepname moet uniek wees",
|
||||||
|
"recipe-defaults": {
|
||||||
|
"ingredient-note": "1 Cup Flour",
|
||||||
|
"step-text": "Recipe steps as well as other fields in the recipe page support markdown syntax.\n\n**Add a link**\n\n[My Link](https://demo.mealie.io)\n"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"mealplan": {
|
"mealplan": {
|
||||||
"no-recipes-match-your-rules": "Geen resepte voldoen aan jou reëls nie"
|
"no-recipes-match-your-rules": "Geen resepte voldoen aan jou reëls nie"
|
||||||
|
|||||||
@@ -3,7 +3,11 @@
|
|||||||
"server-error": "حدث خطأ غير متوقع"
|
"server-error": "حدث خطأ غير متوقع"
|
||||||
},
|
},
|
||||||
"recipe": {
|
"recipe": {
|
||||||
"unique-name-error": "يجب أن تكون أسماء الوصفات فريدة"
|
"unique-name-error": "يجب أن تكون أسماء الوصفات فريدة",
|
||||||
|
"recipe-defaults": {
|
||||||
|
"ingredient-note": "1 Cup Flour",
|
||||||
|
"step-text": "Recipe steps as well as other fields in the recipe page support markdown syntax.\n\n**Add a link**\n\n[My Link](https://demo.mealie.io)\n"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"mealplan": {
|
"mealplan": {
|
||||||
"no-recipes-match-your-rules": "لا توجد وصفات تتطابق مع المرشحات الخاصة بك"
|
"no-recipes-match-your-rules": "لا توجد وصفات تتطابق مع المرشحات الخاصة بك"
|
||||||
|
|||||||
@@ -3,7 +3,11 @@
|
|||||||
"server-error": "Възникна неочаквана грешка"
|
"server-error": "Възникна неочаквана грешка"
|
||||||
},
|
},
|
||||||
"recipe": {
|
"recipe": {
|
||||||
"unique-name-error": "Името на рецептата трябва да е уникално"
|
"unique-name-error": "Името на рецептата трябва да е уникално",
|
||||||
|
"recipe-defaults": {
|
||||||
|
"ingredient-note": "1 чаша брашно",
|
||||||
|
"step-text": "Стъпките на рецептата, както и други полета в страницата с рецепти поддържат синтаксис за маркиране.\n\n **Добавяне на връзка**\n\n [Моята връзка](https://demo.mealie.io)\n"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"mealplan": {
|
"mealplan": {
|
||||||
"no-recipes-match-your-rules": "Няма рецепти отговарящи на Вашите условия"
|
"no-recipes-match-your-rules": "Няма рецепти отговарящи на Вашите условия"
|
||||||
|
|||||||
@@ -3,7 +3,11 @@
|
|||||||
"server-error": "S'ha produït un error inesperat"
|
"server-error": "S'ha produït un error inesperat"
|
||||||
},
|
},
|
||||||
"recipe": {
|
"recipe": {
|
||||||
"unique-name-error": "El nom de la recepta ha de ser únic"
|
"unique-name-error": "El nom de la recepta ha de ser únic",
|
||||||
|
"recipe-defaults": {
|
||||||
|
"ingredient-note": "1 Cup Flour",
|
||||||
|
"step-text": "Recipe steps as well as other fields in the recipe page support markdown syntax.\n\n**Add a link**\n\n[My Link](https://demo.mealie.io)\n"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"mealplan": {
|
"mealplan": {
|
||||||
"no-recipes-match-your-rules": "Cap recepta coincideix amb les teues regles"
|
"no-recipes-match-your-rules": "Cap recepta coincideix amb les teues regles"
|
||||||
|
|||||||
@@ -3,7 +3,11 @@
|
|||||||
"server-error": "Došlo k nečekané chybě"
|
"server-error": "Došlo k nečekané chybě"
|
||||||
},
|
},
|
||||||
"recipe": {
|
"recipe": {
|
||||||
"unique-name-error": "Názvy receptů musí být jedinečné"
|
"unique-name-error": "Názvy receptů musí být jedinečné",
|
||||||
|
"recipe-defaults": {
|
||||||
|
"ingredient-note": "1 Cup Flour",
|
||||||
|
"step-text": "Recipe steps as well as other fields in the recipe page support markdown syntax.\n\n**Add a link**\n\n[My Link](https://demo.mealie.io)\n"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"mealplan": {
|
"mealplan": {
|
||||||
"no-recipes-match-your-rules": "Žádné recepty neodpovídají vašim pravidlům"
|
"no-recipes-match-your-rules": "Žádné recepty neodpovídají vašim pravidlům"
|
||||||
|
|||||||
@@ -3,7 +3,11 @@
|
|||||||
"server-error": "Der opstod en uventet fejl"
|
"server-error": "Der opstod en uventet fejl"
|
||||||
},
|
},
|
||||||
"recipe": {
|
"recipe": {
|
||||||
"unique-name-error": "Opskriftsnavnet er allerede i brug"
|
"unique-name-error": "Opskriftsnavnet er allerede i brug",
|
||||||
|
"recipe-defaults": {
|
||||||
|
"ingredient-note": "1 Cup Flour",
|
||||||
|
"step-text": "Recipe steps as well as other fields in the recipe page support markdown syntax.\n\n**Add a link**\n\n[My Link](https://demo.mealie.io)\n"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"mealplan": {
|
"mealplan": {
|
||||||
"no-recipes-match-your-rules": "Ingen opskrifter matcher dine regler"
|
"no-recipes-match-your-rules": "Ingen opskrifter matcher dine regler"
|
||||||
|
|||||||
@@ -3,7 +3,11 @@
|
|||||||
"server-error": "Ein unerwarteter Fehler ist aufgetreten"
|
"server-error": "Ein unerwarteter Fehler ist aufgetreten"
|
||||||
},
|
},
|
||||||
"recipe": {
|
"recipe": {
|
||||||
"unique-name-error": "Rezeptnamen müssen einzigartig sein"
|
"unique-name-error": "Rezeptnamen müssen einzigartig sein",
|
||||||
|
"recipe-defaults": {
|
||||||
|
"ingredient-note": "250 g Mehl",
|
||||||
|
"step-text": "Zubereitungs-Schritte und andere Felder der Rezeptseite unterstützen Markdown Syntax.\n\n**Füge einen Link hinzu**\n\n[Mein Link](https://demo.mealie.io)\n"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"mealplan": {
|
"mealplan": {
|
||||||
"no-recipes-match-your-rules": "Keine Rezepte entsprechen deinen Regeln"
|
"no-recipes-match-your-rules": "Keine Rezepte entsprechen deinen Regeln"
|
||||||
@@ -37,7 +41,7 @@
|
|||||||
"day": "Tag|Tage",
|
"day": "Tag|Tage",
|
||||||
"hour": "Stunde|Stunden",
|
"hour": "Stunde|Stunden",
|
||||||
"minute": "Minute|Minuten",
|
"minute": "Minute|Minuten",
|
||||||
"second": "sekunde|sekunden",
|
"second": "Sekunde|Sekunden",
|
||||||
"millisecond": "Millisekunde|Millisekunden",
|
"millisecond": "Millisekunde|Millisekunden",
|
||||||
"microsecond": "Mikrosekunde|Mikrosekunden"
|
"microsecond": "Mikrosekunde|Mikrosekunden"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,11 @@
|
|||||||
"server-error": "An unexpected error occurred"
|
"server-error": "An unexpected error occurred"
|
||||||
},
|
},
|
||||||
"recipe": {
|
"recipe": {
|
||||||
"unique-name-error": "Recipe names must be unique"
|
"unique-name-error": "Recipe names must be unique",
|
||||||
|
"recipe-defaults": {
|
||||||
|
"ingredient-note": "1 Κύπελλο Αλεύρι",
|
||||||
|
"step-text": "Βήματα συνταγής, καθώς και άλλα πεδία στη σύνταξη σήμανσης της σελίδας συνταγής.\n\n**Προσθήκη συνδέσμου**\n\n[Ο σύνδεσμος μου](https://demo.mealie.io)\n"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"mealplan": {
|
"mealplan": {
|
||||||
"no-recipes-match-your-rules": "No recipes match your rules"
|
"no-recipes-match-your-rules": "No recipes match your rules"
|
||||||
|
|||||||
@@ -3,7 +3,11 @@
|
|||||||
"server-error": "An unexpected error occurred"
|
"server-error": "An unexpected error occurred"
|
||||||
},
|
},
|
||||||
"recipe": {
|
"recipe": {
|
||||||
"unique-name-error": "Recipe names must be unique"
|
"unique-name-error": "Recipe names must be unique",
|
||||||
|
"recipe-defaults": {
|
||||||
|
"ingredient-note": "1 Cup Flour",
|
||||||
|
"step-text": "Recipe steps as well as other fields in the recipe page support markdown syntax.\n\n**Add a link**\n\n[My Link](https://demo.mealie.io)\n"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"mealplan": {
|
"mealplan": {
|
||||||
"no-recipes-match-your-rules": "No recipes match your rules"
|
"no-recipes-match-your-rules": "No recipes match your rules"
|
||||||
|
|||||||
@@ -3,7 +3,11 @@
|
|||||||
"server-error": "An unexpected error occurred"
|
"server-error": "An unexpected error occurred"
|
||||||
},
|
},
|
||||||
"recipe": {
|
"recipe": {
|
||||||
"unique-name-error": "Recipe names must be unique"
|
"unique-name-error": "Recipe names must be unique",
|
||||||
|
"recipe-defaults": {
|
||||||
|
"ingredient-note": "1 Cup Flour",
|
||||||
|
"step-text": "Recipe steps as well as other fields in the recipe page support markdown syntax.\n\n**Add a link**\n\n[My Link](https://demo.mealie.io)\n"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"mealplan": {
|
"mealplan": {
|
||||||
"no-recipes-match-your-rules": "No recipes match your rules"
|
"no-recipes-match-your-rules": "No recipes match your rules"
|
||||||
|
|||||||
@@ -3,7 +3,11 @@
|
|||||||
"server-error": "Se ha producido un error inesperado"
|
"server-error": "Se ha producido un error inesperado"
|
||||||
},
|
},
|
||||||
"recipe": {
|
"recipe": {
|
||||||
"unique-name-error": "El nombre de la receta debe ser único"
|
"unique-name-error": "El nombre de la receta debe ser único",
|
||||||
|
"recipe-defaults": {
|
||||||
|
"ingredient-note": "1 Cup Flour",
|
||||||
|
"step-text": "Recipe steps as well as other fields in the recipe page support markdown syntax.\n\n**Add a link**\n\n[My Link](https://demo.mealie.io)\n"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"mealplan": {
|
"mealplan": {
|
||||||
"no-recipes-match-your-rules": "No hay recetas que coincidan con tus reglas"
|
"no-recipes-match-your-rules": "No hay recetas que coincidan con tus reglas"
|
||||||
|
|||||||
@@ -3,7 +3,11 @@
|
|||||||
"server-error": "Tapahtui odottamaton virhe"
|
"server-error": "Tapahtui odottamaton virhe"
|
||||||
},
|
},
|
||||||
"recipe": {
|
"recipe": {
|
||||||
"unique-name-error": "Reseptien nimien täytyy olla yksilöllisiä"
|
"unique-name-error": "Reseptien nimien täytyy olla yksilöllisiä",
|
||||||
|
"recipe-defaults": {
|
||||||
|
"ingredient-note": "1 Cup Flour",
|
||||||
|
"step-text": "Recipe steps as well as other fields in the recipe page support markdown syntax.\n\n**Add a link**\n\n[My Link](https://demo.mealie.io)\n"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"mealplan": {
|
"mealplan": {
|
||||||
"no-recipes-match-your-rules": "Määritysten mukaisia reseptejä ei löytynyt"
|
"no-recipes-match-your-rules": "Määritysten mukaisia reseptejä ei löytynyt"
|
||||||
|
|||||||
@@ -3,7 +3,11 @@
|
|||||||
"server-error": "Une erreur inattendue s'est produite"
|
"server-error": "Une erreur inattendue s'est produite"
|
||||||
},
|
},
|
||||||
"recipe": {
|
"recipe": {
|
||||||
"unique-name-error": "Les noms de recette doivent être uniques"
|
"unique-name-error": "Les noms de recette doivent être uniques",
|
||||||
|
"recipe-defaults": {
|
||||||
|
"ingredient-note": "1 tasse de Farine",
|
||||||
|
"step-text": "Les étapes de la recette ainsi que les autres champs de la page de recette supportent la syntaxe markdown.\n\n**Ajouter un lien**\n\n[Mon lien](https://demo.mealie.io)\n"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"mealplan": {
|
"mealplan": {
|
||||||
"no-recipes-match-your-rules": "Aucune recette ne correspond à vos règles"
|
"no-recipes-match-your-rules": "Aucune recette ne correspond à vos règles"
|
||||||
@@ -33,12 +37,12 @@
|
|||||||
"generic-deleted": "{name} a été supprimé"
|
"generic-deleted": "{name} a été supprimé"
|
||||||
},
|
},
|
||||||
"datetime": {
|
"datetime": {
|
||||||
"year": "year|years",
|
"year": "année|années",
|
||||||
"day": "day|days",
|
"day": "jour|jours",
|
||||||
"hour": "hour|hours",
|
"hour": "heure|heures",
|
||||||
"minute": "minute|minutes",
|
"minute": "minute|minutes",
|
||||||
"second": "second|seconds",
|
"second": "seconde|secondes",
|
||||||
"millisecond": "millisecond|milliseconds",
|
"millisecond": "milliseconde|millisecondes",
|
||||||
"microsecond": "microsecond|microseconds"
|
"microsecond": "microseconde|microsecondes"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,11 @@
|
|||||||
"server-error": "Une erreur inattendue s’est produite"
|
"server-error": "Une erreur inattendue s’est produite"
|
||||||
},
|
},
|
||||||
"recipe": {
|
"recipe": {
|
||||||
"unique-name-error": "Les noms de recette doivent être uniques"
|
"unique-name-error": "Les noms de recette doivent être uniques",
|
||||||
|
"recipe-defaults": {
|
||||||
|
"ingredient-note": "100 g de farine",
|
||||||
|
"step-text": "Les étapes de la recette ainsi que les autres champs de la page de recette supportent la syntaxe markdown.\n\n**Ajouter un lien**\n\n[Mon lien](https://demo.mealie.io)\n"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"mealplan": {
|
"mealplan": {
|
||||||
"no-recipes-match-your-rules": "Aucune recette ne correspond à vos règles"
|
"no-recipes-match-your-rules": "Aucune recette ne correspond à vos règles"
|
||||||
|
|||||||
@@ -3,7 +3,11 @@
|
|||||||
"server-error": "An unexpected error occurred"
|
"server-error": "An unexpected error occurred"
|
||||||
},
|
},
|
||||||
"recipe": {
|
"recipe": {
|
||||||
"unique-name-error": "Recipe names must be unique"
|
"unique-name-error": "Recipe names must be unique",
|
||||||
|
"recipe-defaults": {
|
||||||
|
"ingredient-note": "1 Cup Flour",
|
||||||
|
"step-text": "Recipe steps as well as other fields in the recipe page support markdown syntax.\n\n**Add a link**\n\n[My Link](https://demo.mealie.io)\n"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"mealplan": {
|
"mealplan": {
|
||||||
"no-recipes-match-your-rules": "No recipes match your rules"
|
"no-recipes-match-your-rules": "No recipes match your rules"
|
||||||
|
|||||||
@@ -3,7 +3,11 @@
|
|||||||
"server-error": "אירעה שגיאה בלתי צפויה"
|
"server-error": "אירעה שגיאה בלתי צפויה"
|
||||||
},
|
},
|
||||||
"recipe": {
|
"recipe": {
|
||||||
"unique-name-error": "שמות מתכונים חייבים להיות יחודיים"
|
"unique-name-error": "שמות מתכונים חייבים להיות יחודיים",
|
||||||
|
"recipe-defaults": {
|
||||||
|
"ingredient-note": "1 Cup Flour",
|
||||||
|
"step-text": "Recipe steps as well as other fields in the recipe page support markdown syntax.\n\n**Add a link**\n\n[My Link](https://demo.mealie.io)\n"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"mealplan": {
|
"mealplan": {
|
||||||
"no-recipes-match-your-rules": "אין מתכון שמתאים לחוקים שלך"
|
"no-recipes-match-your-rules": "אין מתכון שמתאים לחוקים שלך"
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user