mirror of
https://github.com/mealie-recipes/mealie.git
synced 2025-08-05 13:35:23 +02:00
feat(lang): more localization(#2219)
* feat(lang): localize some views * fix: typo * fix: Localization broke bug report generation * feat(lang): localize recipe page instructions
This commit is contained in:
parent
6b63c751b1
commit
9fd1ba6e46
29 changed files with 362 additions and 226 deletions
|
@ -135,7 +135,7 @@
|
|||
<BaseButton create @click="createDialog = true" />
|
||||
<BaseButton @click="mergeDialog = true">
|
||||
<template #icon> {{ $globals.icons.foods }} </template>
|
||||
Combine
|
||||
{{ $t('data-pages.combine') }}
|
||||
</BaseButton>
|
||||
</template>
|
||||
<template #item.label="{ item }">
|
||||
|
@ -146,7 +146,7 @@
|
|||
<template #button-bottom>
|
||||
<BaseButton @click="seedDialog = true">
|
||||
<template #icon> {{ $globals.icons.database }} </template>
|
||||
Seed
|
||||
{{ $t('data-pages.seed') }}
|
||||
</BaseButton>
|
||||
</template>
|
||||
</CrudTable>
|
||||
|
|
|
@ -61,7 +61,7 @@
|
|||
<RecipeSettingsSwitches v-model="recipeSettings" />
|
||||
</div>
|
||||
<p class="text-center mb-0">
|
||||
<i>{{ $t('data-pages.recipes.selected-length-recipe-s-settings-will-be-updated', [selected.length]) }}</i>
|
||||
<i>{{ $tc('data-pages.recipes.selected-length-recipe-s-settings-will-be-updated', selected.length) }}</i>
|
||||
</p>
|
||||
</v-card-text>
|
||||
</BaseDialog>
|
||||
|
|
|
@ -133,7 +133,7 @@
|
|||
|
||||
<BaseButton @click="mergeDialog = true">
|
||||
<template #icon> {{ $globals.icons.units }} </template>
|
||||
Combine
|
||||
{{ $t('data-pages.combine') }}
|
||||
</BaseButton>
|
||||
</template>
|
||||
<template #item.useAbbreviation="{ item }">
|
||||
|
@ -149,7 +149,7 @@
|
|||
<template #button-bottom>
|
||||
<BaseButton @click="seedDialog = true">
|
||||
<template #icon> {{ $globals.icons.database }} </template>
|
||||
Seed
|
||||
{{ $t('data-pages.seed') }}
|
||||
</BaseButton>
|
||||
</template>
|
||||
</CrudTable>
|
||||
|
|
|
@ -26,8 +26,8 @@
|
|||
|
||||
<div class="d-flex align-center justify-space-between mb-2">
|
||||
<v-tabs>
|
||||
<v-tab to="/group/mealplan/planner/view">Meal Planner</v-tab>
|
||||
<v-tab to="/group/mealplan/planner/edit">Edit</v-tab>
|
||||
<v-tab to="/group/mealplan/planner/view">{{ $t('meal-plan.meal-planner') }}</v-tab>
|
||||
<v-tab to="/group/mealplan/planner/edit">{{ $t('general.edit') }}</v-tab>
|
||||
</v-tabs>
|
||||
<ButtonLink :icon="$globals.icons.calendar" to="/group/mealplan/settings" :text="$tc('general.settings')" />
|
||||
</div>
|
||||
|
|
|
@ -137,7 +137,7 @@
|
|||
<v-icon left>
|
||||
{{ $globals.icons.tags }}
|
||||
</v-icon>
|
||||
{{ mealplan.entryType }}
|
||||
{{ getEntryTypeText(mealplan.entryType) }}
|
||||
</v-chip>
|
||||
</template>
|
||||
<v-list>
|
||||
|
@ -167,7 +167,7 @@
|
|||
children: [
|
||||
{
|
||||
icon: $globals.icons.diceMultiple,
|
||||
text: 'Breakfast',
|
||||
text: $tc('meal-plan.breakfast'),
|
||||
event: 'randomBreakfast',
|
||||
},
|
||||
{
|
||||
|
@ -212,7 +212,7 @@ import { SortableEvent } from "sortablejs";
|
|||
import draggable from "vuedraggable";
|
||||
import { watchDebounced } from "@vueuse/core";
|
||||
import { MealsByDate } from "./types";
|
||||
import { useMealplans, planTypeOptions } from "~/composables/use-group-mealplan";
|
||||
import { useMealplans, usePlanTypeOptions, getEntryTypeText } from "~/composables/use-group-mealplan";
|
||||
import RecipeCardImage from "~/components/Domain/Recipe/RecipeCardImage.vue";
|
||||
import { PlanEntryType } from "~/lib/api/types/meal-plan";
|
||||
import { useUserApi } from "~/composables/api";
|
||||
|
@ -333,10 +333,13 @@ export default defineComponent({
|
|||
|
||||
const search = useRecipeSearch(api);
|
||||
|
||||
const planTypeOptions = usePlanTypeOptions();
|
||||
|
||||
return {
|
||||
state,
|
||||
onMoveCallback,
|
||||
planTypeOptions,
|
||||
getEntryTypeText,
|
||||
|
||||
// Dialog
|
||||
dialog,
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { computed, defineComponent } from "@nuxtjs/composition-api";
|
||||
import { computed, defineComponent, useContext } from "@nuxtjs/composition-api";
|
||||
import { MealsByDate } from "./types";
|
||||
import { ReadPlanEntry } from "~/lib/api/types/meal-plan";
|
||||
import RecipeCardMobile from "~/components/Domain/Recipe/RecipeCardMobile.vue";
|
||||
|
@ -65,15 +65,17 @@ export default defineComponent({
|
|||
sections: DaySection[];
|
||||
};
|
||||
|
||||
const { i18n } = useContext();
|
||||
|
||||
const plan = computed<Days[]>(() => {
|
||||
return props.mealplans.reduce((acc, day) => {
|
||||
const out: Days = {
|
||||
date: day.date,
|
||||
sections: [
|
||||
{ title: "Breakfast", meals: [] },
|
||||
{ title: "Lunch", meals: [] },
|
||||
{ title: "Dinner", meals: [] },
|
||||
{ title: "Side", meals: [] },
|
||||
{ title: i18n.tc("meal-plan.breakfast"), meals: [] },
|
||||
{ title: i18n.tc("meal-plan.lunch"), meals: [] },
|
||||
{ title: i18n.tc("meal-plan.dinner"), meals: [] },
|
||||
{ title: i18n.tc("meal-plan.side"), meals: [] },
|
||||
],
|
||||
};
|
||||
|
||||
|
|
|
@ -9,14 +9,13 @@
|
|||
:src="require('~/static/svgs/manage-data-migrations.svg')"
|
||||
></v-img>
|
||||
</template>
|
||||
<template #title> Recipe Data Migrations</template>
|
||||
Recipes can be migrated from another supported application to Mealie. This is a great way to get started with
|
||||
Mealie.
|
||||
<template #title> {{ $t('migration.recipe-data-migrations') }}</template>
|
||||
{{ $t('migration.recipe-data-migrations-explanation') }}
|
||||
</BasePageTitle>
|
||||
<v-container>
|
||||
<BaseCardSectionTitle :title="$i18n.tc('migration.new-migration')"> </BaseCardSectionTitle>
|
||||
<v-card outlined :loading="loading">
|
||||
<v-card-title> Choose Migration Type </v-card-title>
|
||||
<v-card-title> {{ $t('migration.choose-migration-type') }} </v-card-title>
|
||||
<v-card-text v-if="content" class="pb-0">
|
||||
<div class="mb-2">
|
||||
<BaseOverflowButton v-model="migrationType" mode="model" :items="items" />
|
||||
|
@ -29,7 +28,7 @@
|
|||
</v-treeview>
|
||||
</v-card-text>
|
||||
|
||||
<v-card-title class="mt-0"> Upload File </v-card-title>
|
||||
<v-card-title class="mt-0"> {{ $t('general.upload-file') }} </v-card-title>
|
||||
<v-card-text>
|
||||
<AppButtonUpload
|
||||
accept=".zip"
|
||||
|
@ -45,7 +44,11 @@
|
|||
<v-card-text>
|
||||
<v-checkbox v-model="addMigrationTag">
|
||||
<template #label>
|
||||
Tag all recipes with <b class="mx-1"> {{ migrationType }} </b> tag
|
||||
<i18n path="migration.tag-all-recipes">
|
||||
<template #tag-name>
|
||||
<b class="mx-1"> {{ migrationType }} </b>
|
||||
</template>
|
||||
</i18n>
|
||||
</template>
|
||||
</v-checkbox>
|
||||
</v-card-text>
|
||||
|
@ -128,7 +131,7 @@ export default defineComponent({
|
|||
children: [
|
||||
{
|
||||
id: 2,
|
||||
name: "Recipe 1",
|
||||
name: i18n.t("migration.recipe-1"),
|
||||
icon: $globals.icons.folderOutline,
|
||||
children: [
|
||||
{ id: 3, name: "recipe.json", icon: $globals.icons.codeJson },
|
||||
|
@ -138,7 +141,7 @@ export default defineComponent({
|
|||
},
|
||||
{
|
||||
id: 6,
|
||||
name: "Recipe 2",
|
||||
name: i18n.t("migration.recipe-2"),
|
||||
icon: $globals.icons.folderOutline,
|
||||
children: [
|
||||
{ id: 7, name: "recipe.json", icon: $globals.icons.codeJson },
|
||||
|
@ -160,7 +163,7 @@ export default defineComponent({
|
|||
children: [
|
||||
{
|
||||
id: 2,
|
||||
name: "Recipe 1",
|
||||
name: i18n.t("migration.recipe-1"),
|
||||
icon: $globals.icons.folderOutline,
|
||||
children: [
|
||||
{ id: 3, name: "recipe.json", icon: $globals.icons.codeJson },
|
||||
|
@ -170,7 +173,7 @@ export default defineComponent({
|
|||
},
|
||||
{
|
||||
id: 6,
|
||||
name: "Recipe 2",
|
||||
name: i18n.t("migration.recipe-2"),
|
||||
icon: $globals.icons.folderOutline,
|
||||
children: [
|
||||
{ id: 7, name: "recipe.json", icon: $globals.icons.codeJson },
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
{{ $t("general.confirm-delete-generic") }}
|
||||
</v-card-text>
|
||||
</BaseDialog>
|
||||
<BaseDialog v-model="createDialog" title="New Notification" @submit="createNewNotifier">
|
||||
<BaseDialog v-model="createDialog" :title="$t('events.new-notification')" @submit="createNewNotifier">
|
||||
<v-card-text>
|
||||
<v-text-field v-model="createNotifierData.name" :label="$t('general.name')"></v-text-field>
|
||||
<v-text-field v-model="createNotifierData.appriseUrl" :label="$t('events.apprise-url')"></v-text-field>
|
||||
|
@ -22,7 +22,7 @@
|
|||
<template #header>
|
||||
<v-img max-height="125" max-width="125" :src="require('~/static/svgs/manage-notifiers.svg')"></v-img>
|
||||
</template>
|
||||
<template #title> Event Notifiers </template>
|
||||
<template #title> {{ $t("events.event-notifiers") }} </template>
|
||||
{{ $t("events.new-notification-form-description") }}
|
||||
|
||||
<div class="mt-3 d-flex justify-space-around">
|
||||
|
@ -51,12 +51,15 @@
|
|||
</template>
|
||||
</v-expansion-panel-header>
|
||||
<v-expansion-panel-content>
|
||||
<v-text-field v-model="notifiers[index].name" label="Name"></v-text-field>
|
||||
<v-text-field v-model="notifiers[index].appriseUrl" label="Apprise URL (skipped if blank)"></v-text-field>
|
||||
<v-checkbox v-model="notifiers[index].enabled" label="Enable Notifier" dense></v-checkbox>
|
||||
<v-text-field v-model="notifiers[index].name" :label="$t('general.name')"></v-text-field>
|
||||
<v-text-field
|
||||
v-model="notifiers[index].appriseUrl"
|
||||
:label="$t('events.apprise-url-skipped-if-blank')"
|
||||
></v-text-field>
|
||||
<v-checkbox v-model="notifiers[index].enabled" :label="$t('events.enable-notifier')" dense></v-checkbox>
|
||||
|
||||
<v-divider></v-divider>
|
||||
<p class="pt-4">What events should this notifier subscribe to?</p>
|
||||
<p class="pt-4">{{ $t("events.what-events") }}</p>
|
||||
<div class="notifier-options">
|
||||
<section v-for="sec in optionsSections" :key="sec.id">
|
||||
<h4>
|
||||
|
@ -196,27 +199,27 @@ export default defineComponent({
|
|||
},
|
||||
{
|
||||
id: 2,
|
||||
text: "User Events",
|
||||
text: i18n.tc("events.user-events"),
|
||||
options: [
|
||||
{
|
||||
text: "When a new user joins your group",
|
||||
text: i18n.tc("events.when-a-new-user-joins-your-group"),
|
||||
key: "userSignup",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
text: "Mealplan Events",
|
||||
text: i18n.tc("events.mealplan-events"),
|
||||
options: [
|
||||
{
|
||||
text: "When a user in your group creates a new mealplan",
|
||||
text: i18n.tc("events.when-a-user-in-your-group-creates-a-new-mealplan"),
|
||||
key: "mealplanEntryCreated",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
text: "Shopping List Events",
|
||||
text: i18n.tc("events.shopping-list-events"),
|
||||
options: [
|
||||
{
|
||||
text: i18n.t("general.create") as string,
|
||||
|
@ -234,7 +237,7 @@ export default defineComponent({
|
|||
},
|
||||
{
|
||||
id: 5,
|
||||
text: "Cookbook Events",
|
||||
text: i18n.tc("events.cookbook-events"),
|
||||
options: [
|
||||
{
|
||||
text: i18n.t("general.create") as string,
|
||||
|
@ -252,7 +255,7 @@ export default defineComponent({
|
|||
},
|
||||
{
|
||||
id: 6,
|
||||
text: "Tag Events",
|
||||
text: i18n.tc("events.tag-events"),
|
||||
options: [
|
||||
{
|
||||
text: i18n.t("general.create") as string,
|
||||
|
@ -270,7 +273,7 @@ export default defineComponent({
|
|||
},
|
||||
{
|
||||
id: 7,
|
||||
text: "Category Events",
|
||||
text: i18n.tc("events.category-events"),
|
||||
options: [
|
||||
{
|
||||
text: i18n.t("general.create") as string,
|
||||
|
@ -300,8 +303,10 @@ export default defineComponent({
|
|||
createNewNotifier,
|
||||
};
|
||||
},
|
||||
head: {
|
||||
title: "Notifiers",
|
||||
head() {
|
||||
return {
|
||||
title: this.$t("profile.notifiers"),
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
|
|
@ -4,12 +4,9 @@
|
|||
<template #header>
|
||||
<v-img max-height="125" max-width="125" :src="require('~/static/svgs/manage-webhooks.svg')"></v-img>
|
||||
</template>
|
||||
<template #title> Webhooks </template>
|
||||
<template #title> {{ $t('settings.webhooks.webhooks') }} </template>
|
||||
<v-card-text class="pb-0">
|
||||
The webhooks defined below will be executed when a meal is defined for the day. At the scheduled time the
|
||||
webhooks will be sent with the data from the recipe that is scheduled for the day. Note that webhook execution
|
||||
is not exact. The webhooks are executed on a 5 minutes interval so the webhooks will be executed within 5 +/-
|
||||
minutes of the scheduled.
|
||||
{{ $t('settings.webhooks.description') }}
|
||||
</v-card-text>
|
||||
</BasePageTitle>
|
||||
|
||||
|
@ -23,7 +20,7 @@
|
|||
<v-icon large left :color="webhook.enabled ? 'info' : null">
|
||||
{{ $globals.icons.webhook }}
|
||||
</v-icon>
|
||||
{{ webhook.name }} - {{ timeDisplay(timeUTCToLocal(webhook.scheduledTime)) }}
|
||||
{{ webhook.name }} - {{ $d(timeUTC(webhook.scheduledTime), "time") }}
|
||||
</div>
|
||||
<template #actions>
|
||||
<v-btn small icon class="ml-2">
|
||||
|
@ -48,28 +45,18 @@
|
|||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from "@nuxtjs/composition-api";
|
||||
import { useGroupWebhooks, timeLocalToUTC, timeUTCToLocal } from "~/composables/use-group-webhooks";
|
||||
import { useGroupWebhooks, timeUTC } from "~/composables/use-group-webhooks";
|
||||
import GroupWebhookEditor from "~/components/Domain/Group/GroupWebhookEditor.vue";
|
||||
|
||||
export default defineComponent({
|
||||
components: { GroupWebhookEditor },
|
||||
setup() {
|
||||
const { actions, webhooks } = useGroupWebhooks();
|
||||
function timeDisplay(time: string): string {
|
||||
// returns the time in the format HH:MM AM/PM
|
||||
const [hours, minutes] = time.split(":");
|
||||
const ampm = Number(hours) < 12 ? "AM" : "PM";
|
||||
const hour = Number(hours) % 12 || 12;
|
||||
const minute = minutes.padStart(2, "0");
|
||||
return `${hour}:${minute} ${ampm}`;
|
||||
}
|
||||
|
||||
return {
|
||||
webhooks,
|
||||
actions,
|
||||
timeLocalToUTC,
|
||||
timeUTCToLocal,
|
||||
timeDisplay,
|
||||
timeUTC
|
||||
};
|
||||
},
|
||||
head() {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue