diff --git a/frontend/src/components/Admin/General/CreatePageDialog.vue b/frontend/src/components/Admin/General/CreatePageDialog.vue index 6094f1fe7..2754e58d0 100644 --- a/frontend/src/components/Admin/General/CreatePageDialog.vue +++ b/frontend/src/components/Admin/General/CreatePageDialog.vue @@ -17,7 +17,7 @@

- Custom Pages + {{$t('settings.custom-pages')}} - Create + {{$t('general.create')}}

@@ -41,11 +41,11 @@ - Delete + {{$t('general.delete')}} - Edit + {{$t('general.edit')}} @@ -55,7 +55,7 @@ - Save + {{$t('general.save')}} @@ -76,8 +76,8 @@ export default { customPages: [], newPageData: { create: true, - title: "New Page", - buttonText: "Create", + title: this.$t('settings.new-page'), + buttonText: this.$t('general.create'), data: { name: "", categories: [], @@ -86,8 +86,8 @@ export default { }, editPageData: { create: false, - title: "Edit Page", - buttonText: "Update", + title: this.$t('settings.edit-page'), + buttonText: this.$t('general.update'), data: {}, }, }; diff --git a/frontend/src/components/FormHelpers/CategoryTagSelector.vue b/frontend/src/components/FormHelpers/CategoryTagSelector.vue index 4abdffe1f..c31f0a017 100644 --- a/frontend/src/components/FormHelpers/CategoryTagSelector.vue +++ b/frontend/src/components/FormHelpers/CategoryTagSelector.vue @@ -90,7 +90,7 @@ export default { computed: { inputLabel() { if (!this.showLabel) return null; - return this.tagSelector ? "Tags" : "Categories"; + return this.tagSelector ? this.$t('recipe.tags') : this.$t('recipe.categories'); }, activeItems() { let ItemObjects = []; diff --git a/frontend/src/components/Recipe/RecipeViewer/Ingredients.vue b/frontend/src/components/Recipe/RecipeViewer/Ingredients.vue index 036a3516a..1a29c14f5 100644 --- a/frontend/src/components/Recipe/RecipeViewer/Ingredients.vue +++ b/frontend/src/components/Recipe/RecipeViewer/Ingredients.vue @@ -12,6 +12,7 @@ v-model="ingredient.checked" class="pt-0 my-auto py-auto" color="secondary" + :readonly="true" > diff --git a/frontend/src/components/UI/CardSection.vue b/frontend/src/components/UI/CardSection.vue index 9ad3230a2..5d70e1d4d 100644 --- a/frontend/src/components/UI/CardSection.vue +++ b/frontend/src/components/UI/CardSection.vue @@ -5,7 +5,7 @@ - + {{ title.toUpperCase() }} diff --git a/frontend/src/components/UI/CategorySidebar.vue b/frontend/src/components/UI/CategorySidebar.vue index 58373847b..9103417db 100644 --- a/frontend/src/components/UI/CategorySidebar.vue +++ b/frontend/src/components/UI/CategorySidebar.vue @@ -54,22 +54,11 @@ export default { { icon: "mdi-magnify", to: "/search", - title: "search", + title: this.$t('search.search'), }, ], }; }, - computed: { - allCategories() { - return this.$store.getters.getCategories; - }, - }, - watch: { - allCategories() { - this.buildSidebar(); - }, - showSidebar() {}, - }, mounted() { this.buildSidebar(); this.mobile = this.viewScale(); @@ -81,14 +70,27 @@ export default { this.links = []; this.links.push(...this.baseLinks); const pages = await api.siteSettings.getPages(); - pages.sort((a, b) => a.position - b.position); - pages.forEach(async element => { - this.links.push({ - title: element.name, - to: `/pages/${element.slug}`, - icon: "mdi-tag", + if(pages.length > 0) { + pages.sort((a, b) => a.position - b.position); + pages.forEach(async element => { + this.links.push({ + title: element.name, + to: `/pages/${element.slug}`, + icon: "mdi-tag", + }); }); - }); + } + else { + const categories = await api.categories.getAll(); + categories.forEach(async element => { + this.links.push({ + title: element.name, + to: `/recipes/category/${element.slug}`, + icon: "mdi-tag", + }); + }); + } + }, viewScale() { switch (this.$vuetify.breakpoint.name) { diff --git a/frontend/src/locales/messages/de.json b/frontend/src/locales/messages/de.json index ab3219cd8..9cf70f5b1 100644 --- a/frontend/src/locales/messages/de.json +++ b/frontend/src/locales/messages/de.json @@ -93,7 +93,7 @@ "groups": "Gruppen", "could-not-validate-credentials": "Anmeldeinformationen konnten nicht validiert werden", "login": "Anmeldung", - "groups-can-only-be-set-by-administrators": "Groups can only be set by administrators", + "groups-can-only-be-set-by-administrators": "Gruppen können nur durch einen Administrator gesetzt werden", "upload-photo": "Foto hochladen", "reset-password": "Passwort zurücksetzen", "current-password": "Aktuelles Passwort", diff --git a/frontend/src/locales/messages/en.json b/frontend/src/locales/messages/en.json index 99704da96..9a63052c5 100644 --- a/frontend/src/locales/messages/en.json +++ b/frontend/src/locales/messages/en.json @@ -55,7 +55,8 @@ "wednesday": "Wednesday", "thursday": "Thursday", "friday": "Friday", - "saturday": "Saturday" + "saturday": "Saturday", + "about": "About" }, "page": { "home-page": "Home Page", @@ -152,7 +153,16 @@ "delete-confirmation": "Are you sure you want to delete this recipe?" }, "search": { - "search-mealie": "Search Mealie" + "search-mealie": "Search Mealie", + "search-placeholder": "Search...", + "max-results": "Max Results", + "category-filter": "Category Filter", + "tag-filter": "Tag Filter", + "include": "Include", + "exclude": "Exclude", + "and": "And", + "or": "Or", + "search": "Search" }, "settings": { "general-settings": "General Settings", @@ -224,7 +234,11 @@ "migrations": "Migrations", "profile": "Profile", "locale-settings": "Locale settings", - "first-day-of-week": "First day of the week" + "first-day-of-week": "First day of the week", + "custom-pages": "Custom Pages", + "new-page": "New Page", + "edit-page": "Edit Page", + "page-name": "Page Name" }, "migration": { "recipe-migration": "Recipe Migration", diff --git a/frontend/src/locales/messages/fr.json b/frontend/src/locales/messages/fr.json index 8f68effc2..883a2eaa8 100644 --- a/frontend/src/locales/messages/fr.json +++ b/frontend/src/locales/messages/fr.json @@ -53,7 +53,10 @@ "sunday": "Dimanche", "thursday": "Jeudi", "tuesday": "Mardi", - "wednesday": "Mercredi" + "wednesday": "Mercredi", + "groups": "Groupes", + "users": "Utilisateurs", + "about": "À propos" }, "page": { "home-page": "Accueil", @@ -127,7 +130,7 @@ "categories": "Catégories", "tags": "Tags", "instructions": "Instructions", - "step-index": "Etape: {step}", + "step-index": "Étape : {step}", "recipe-name": "Nom de la recette", "servings": "Portions", "ingredient": "Ingrédient", @@ -150,7 +153,16 @@ "delete-confirmation": "Êtes-vous sûr(e) de vouloir supprimer cette recette ?" }, "search": { - "search-mealie": "Rechercher dans Mealie" + "search-mealie": "Rechercher dans Mealie", + "search-placeholder": "Rechercher...", + "and": "Et", + "category-filter": "Filtre par catégories", + "exclude": "Exclure", + "include": "Inclure", + "max-results": "Résultats max", + "or": "Ou", + "tag-filter": "Filtre par tags", + "search": "Rechercher" }, "settings": { "general-settings": "Paramètres généraux", @@ -192,7 +204,7 @@ }, "webhooks": { "meal-planner-webhooks": "Webhooks du planificateur de repas", - "the-urls-listed-below-will-recieve-webhooks-containing-the-recipe-data-for-the-meal-plan-on-its-scheduled-day-currently-webhooks-will-execute-at": "Les liens dans cette liste recevront les webhooks contenant les recettes pour le plan de menu du jour défini. Actuellement, les webhooks s'executeront à { time }", + "the-urls-listed-below-will-recieve-webhooks-containing-the-recipe-data-for-the-meal-plan-on-its-scheduled-day-currently-webhooks-will-execute-at": "Les liens dans cette liste recevront les webhooks contenant les recettes pour le plan de menu du jour défini. Actuellement, les webhooks s'exécuteront à", "test-webhooks": "Tester les webhooks", "webhook-url": "Lien du webhook" }, @@ -222,7 +234,11 @@ "profile": "Profil", "site-settings": "Paramètres site", "locale-settings": "Paramètres de langue", - "first-day-of-week": "Premier jour de la semaine" + "first-day-of-week": "Premier jour de la semaine", + "custom-pages": "Pages personnalisées", + "edit-page": "Modifier la page", + "new-page": "Nouvelle page", + "page-name": "Nom de la page" }, "migration": { "recipe-migration": "Migrer les recettes", diff --git a/frontend/src/main.js b/frontend/src/main.js index 45c9381a9..c4917605e 100644 --- a/frontend/src/main.js +++ b/frontend/src/main.js @@ -18,6 +18,20 @@ const router = new VueRouter({ mode: process.env.NODE_ENV === "production" ? "history" : "hash", }); +const DEFAULT_TITLE = 'Mealie'; +const TITLE_SEPARATOR = '🍴'; +const TITLE_SUFFIX = " " + TITLE_SEPARATOR + " " + DEFAULT_TITLE; +router.afterEach( (to) => { + Vue.nextTick( async () => { + if(typeof to.meta.title === 'function' ) { + const title = await to.meta.title(to); + document.title = title + TITLE_SUFFIX; + } else { + document.title = to.meta.title ? to.meta.title + TITLE_SUFFIX : DEFAULT_TITLE; + } + }); +}); + const vueApp = new Vue({ vuetify, store, diff --git a/frontend/src/pages/SearchPage/FilterSelector.vue b/frontend/src/pages/SearchPage/FilterSelector.vue index c46649e51..72574edb6 100644 --- a/frontend/src/pages/SearchPage/FilterSelector.vue +++ b/frontend/src/pages/SearchPage/FilterSelector.vue @@ -10,11 +10,11 @@ mandatory > - Include + {{$t('search.include')}} - Exclude + {{$t('search.exclude')}} @@ -28,10 +28,10 @@ mandatory > - And + {{$t('search.and')}} - Or + {{$t('search.or')}} diff --git a/frontend/src/pages/SearchPage/index.vue b/frontend/src/pages/SearchPage/index.vue index 697f21de0..4ead25d03 100644 --- a/frontend/src/pages/SearchPage/index.vue +++ b/frontend/src/pages/SearchPage/index.vue @@ -8,7 +8,7 @@ v-model="searchString" outlined color="primary accent-3" - placeholder="Placeholder" + :placeholder="$t('search.search-placeholder')" append-icon="mdi-magnify" > @@ -16,7 +16,7 @@ -

Category Filter

+

{{$t('search.category-filter')}}

-

Tag Filter

+

{{$t('search.tag-filter')}}

{ + const recipe = await api.recipes.requestDetails(route.params.recipe); + return recipe.name; + }, + } + }, { path: "/new/", component: NewRecipe }, - { path: "/meal-plan/planner", component: Planner }, - { path: "/meal-plan/this-week", component: ThisWeek }, + { + path: "/meal-plan/planner", + component: Planner, + meta: { + title: i18n.t('meal-plan.meal-planner'), + } + }, + { + path: "/meal-plan/this-week", + component: ThisWeek, + meta: { + title: i18n.t('meal-plan.dinner-this-week'), + } + + }, Admin, { path: "/meal-plan/today", diff --git a/mealie/services/scraper/cleaner.py b/mealie/services/scraper/cleaner.py index bb3f7375b..0129f68f8 100644 --- a/mealie/services/scraper/cleaner.py +++ b/mealie/services/scraper/cleaner.py @@ -26,9 +26,9 @@ class Cleaner: recipe_data["description"] = Cleaner.html(recipe_data.get("description", "")) # Times - recipe_data["prepTime"] = Cleaner.time(recipe_data.get("prepTime", None)) - recipe_data["performTime"] = Cleaner.time(recipe_data.get("performTime", None)) - recipe_data["totalTime"] = Cleaner.time(recipe_data.get("totalTime", None)) + recipe_data["prepTime"] = Cleaner.time(recipe_data.get("prepTime")) + recipe_data["performTime"] = Cleaner.time(recipe_data.get("performTime")) + recipe_data["totalTime"] = Cleaner.time(recipe_data.get("totalTime")) recipe_data["recipeCategory"] = Cleaner.category(recipe_data.get("recipeCategory", [])) recipe_data["recipeYield"] = Cleaner.yield_amount(recipe_data.get("recipeYield")) @@ -70,6 +70,9 @@ class Cleaner: if not instructions: return [] + if isinstance(instructions[0], list): + instructions = instructions[0] + # One long string split by (possibly multiple) new lines if isinstance(instructions, str): return [{"text": Cleaner._instruction(line)} for line in instructions.splitlines() if line]