From 2c3fa81227b862a7a5ba0b7cfcdedc671591edde Mon Sep 17 00:00:00 2001 From: sephrat <34862846+sephrat@users.noreply.github.com> Date: Wed, 14 Apr 2021 17:11:55 +0200 Subject: [PATCH 1/7] Display categories in sidebar if no pages set (#292) Fixes #291 --- .../src/components/UI/CategorySidebar.vue | 38 ++++++++++--------- 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/frontend/src/components/UI/CategorySidebar.vue b/frontend/src/components/UI/CategorySidebar.vue index 58373847b..7fd349579 100644 --- a/frontend/src/components/UI/CategorySidebar.vue +++ b/frontend/src/components/UI/CategorySidebar.vue @@ -59,17 +59,6 @@ export default { ], }; }, - 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) { From f3ea467e20a8d1c7cce4801e169d848f99c9b902 Mon Sep 17 00:00:00 2001 From: sephrat <34862846+sephrat@users.noreply.github.com> Date: Wed, 14 Apr 2021 17:12:22 +0200 Subject: [PATCH 2/7] Enrich page title with context (#296) - Static pages have their own titles - The name of the recipe is displayed when viewing it --- .../src/components/UI/CategorySidebar.vue | 2 +- frontend/src/locales/messages/en.json | 6 ++- frontend/src/locales/messages/fr.json | 6 ++- frontend/src/main.js | 14 +++++++ frontend/src/routes/admin.js | 25 +++++++++++++ frontend/src/routes/index.js | 37 +++++++++++++++++-- 6 files changed, 81 insertions(+), 9 deletions(-) diff --git a/frontend/src/components/UI/CategorySidebar.vue b/frontend/src/components/UI/CategorySidebar.vue index 7fd349579..9103417db 100644 --- a/frontend/src/components/UI/CategorySidebar.vue +++ b/frontend/src/components/UI/CategorySidebar.vue @@ -54,7 +54,7 @@ export default { { icon: "mdi-magnify", to: "/search", - title: "search", + title: this.$t('search.search'), }, ], }; diff --git a/frontend/src/locales/messages/en.json b/frontend/src/locales/messages/en.json index 3bd654f27..36835625e 100644 --- a/frontend/src/locales/messages/en.json +++ b/frontend/src/locales/messages/en.json @@ -48,7 +48,8 @@ "apply": "Apply", "current-parenthesis": "(Current)", "users": "Users", - "groups": "Groups" + "groups": "Groups", + "about": "About" }, "page": { "home-page": "Home Page", @@ -145,7 +146,8 @@ "delete-confirmation": "Are you sure you want to delete this recipe?" }, "search": { - "search-mealie": "Search Mealie" + "search-mealie": "Search Mealie", + "search": "Search" }, "settings": { "general-settings": "General Settings", diff --git a/frontend/src/locales/messages/fr.json b/frontend/src/locales/messages/fr.json index a92e4d9af..4e56fefcf 100644 --- a/frontend/src/locales/messages/fr.json +++ b/frontend/src/locales/messages/fr.json @@ -46,7 +46,8 @@ "token": "Jeton", "field-required": "Champ obligatoire", "apply": "Appliquer", - "current-parenthesis": "(Actuel)" + "current-parenthesis": "(Actuel)", + "about": "À propos" }, "page": { "home-page": "Accueil", @@ -143,7 +144,8 @@ "delete-confirmation": "Êtes-vous sûr(e) de vouloir supprimer cette recette ?" }, "search": { - "search-mealie": "Rechercher dans Mealie" + "search-mealie": "Rechercher dans Mealie", + "search": "Rechercher" }, "settings": { "general-settings": "Paramètres généraux", 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/routes/admin.js b/frontend/src/routes/admin.js index e52927db2..cb990f26a 100644 --- a/frontend/src/routes/admin.js +++ b/frontend/src/routes/admin.js @@ -8,6 +8,7 @@ import ManageUsers from "@/pages/Admin/ManageUsers"; import Settings from "@/pages/Admin/Settings"; import About from "@/pages/Admin/About"; import { store } from "../store"; +import i18n from '@/i18n.js'; export default { path: "/admin", @@ -25,35 +26,59 @@ export default { { path: "profile", component: Profile, + meta: { + title: i18n.t('settings.profile'), + }, }, { path: "backups", component: Backup, + meta: { + title: i18n.t('settings.backup-and-exports'), + }, }, { path: "themes", component: Theme, + meta: { + title: i18n.t('general.themes'), + }, }, { path: "meal-planner", component: MealPlanner, + meta: { + title: i18n.t('meal-plan.meal-planner'), + }, }, { path: "migrations", component: Migration, + meta: { + title: i18n.t('settings.migrations'), + }, }, { path: "manage-users", component: ManageUsers, + meta: { + title: i18n.t('settings.manage-users'), + }, }, { path: "settings", component: Settings, + meta: { + title: i18n.t('settings.site-settings'), + }, }, { path: "about", component: About, + meta: { + title: i18n.t('general.about'), + }, }, ], }; diff --git a/frontend/src/routes/index.js b/frontend/src/routes/index.js index af58a187d..f17df9907 100644 --- a/frontend/src/routes/index.js +++ b/frontend/src/routes/index.js @@ -15,6 +15,7 @@ import ThisWeek from "@/pages/MealPlan/ThisWeek"; import { api } from "@/api"; import Admin from "./admin"; import { store } from "../store"; +import i18n from '@/i18n.js'; export const routes = [ { path: "/", name: "home", component: HomePage }, @@ -31,15 +32,43 @@ export const routes = [ { path: "/sign-up", redirect: "/" }, { path: "/sign-up/:token", component: SignUpPage }, { path: "/debug", component: Debug }, - { path: "/search", component: SearchPage }, + { + path: "/search", + component: SearchPage, + meta: { + title: i18n.t('search.search'), + }, + }, { path: "/recipes/all", component: AllRecipes }, { path: "/pages/:customPage", component: CustomPage }, { path: "/recipes/tag/:tag", component: TagPage }, { path: "/recipes/category/:category", component: CategoryPage }, - { path: "/recipe/:recipe", component: ViewRecipe }, + { + path: "/recipe/:recipe", + component: ViewRecipe, + meta: { + title: async route => { + 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", From a4ed9fc87029f39561cdaeff8f105683c6e2e233 Mon Sep 17 00:00:00 2001 From: JonasSchubert Date: Wed, 14 Apr 2021 17:12:59 +0200 Subject: [PATCH 3/7] fix: translates phrase for locale de (#298) Co-authored-by: Jonas Schubert --- frontend/src/locales/messages/de.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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", From 2e339ee9967cc7b234375e57a41e66571da84fb1 Mon Sep 17 00:00:00 2001 From: sephrat <34862846+sephrat@users.noreply.github.com> Date: Wed, 14 Apr 2021 17:14:21 +0200 Subject: [PATCH 4/7] Fix ingredient checkbox click (#305) Fixes #304 v-list-item already flips the checkbox --- frontend/src/components/Recipe/RecipeViewer/Ingredients.vue | 1 + 1 file changed, 1 insertion(+) 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" > From 4b09497c3d73fe810617e2bdd94b438b2a13134b Mon Sep 17 00:00:00 2001 From: sephrat <34862846+sephrat@users.noreply.github.com> Date: Wed, 14 Apr 2021 18:06:54 +0200 Subject: [PATCH 5/7] Localize custom pages and search page (#299) * Localize custom pages and search page * Fix FR translation for step --- .../Admin/General/CreatePageDialog.vue | 2 +- .../Admin/General/CustomPageCreator.vue | 18 ++++++++--------- .../FormHelpers/CategoryTagSelector.vue | 2 +- frontend/src/locales/messages/en.json | 14 ++++++++++++- frontend/src/locales/messages/fr.json | 20 ++++++++++++++++--- .../src/pages/SearchPage/FilterSelector.vue | 8 ++++---- frontend/src/pages/SearchPage/index.vue | 8 ++++---- 7 files changed, 49 insertions(+), 23 deletions(-) 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/locales/messages/en.json b/frontend/src/locales/messages/en.json index 36835625e..4bf311d2a 100644 --- a/frontend/src/locales/messages/en.json +++ b/frontend/src/locales/messages/en.json @@ -147,6 +147,14 @@ }, "search": { "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": { @@ -217,7 +225,11 @@ "site-settings": "Site Settings", "manage-users": "Manage Users", "migrations": "Migrations", - "profile": "Profile" + "profile": "Profile", + "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 4e56fefcf..bfeba824c 100644 --- a/frontend/src/locales/messages/fr.json +++ b/frontend/src/locales/messages/fr.json @@ -47,6 +47,8 @@ "field-required": "Champ obligatoire", "apply": "Appliquer", "current-parenthesis": "(Actuel)", + "groups": "Groupes", + "users": "Utilisateurs", "about": "À propos" }, "page": { @@ -121,7 +123,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", @@ -145,6 +147,14 @@ }, "search": { "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": { @@ -187,7 +197,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" }, @@ -215,7 +225,11 @@ "manage-users": "Utilisateurs", "migrations": "Migrations", "profile": "Profil", - "site-settings": "Paramètres site" + "site-settings": "Paramètres site", + "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/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')}}

Date: Fri, 16 Apr 2021 21:15:11 -0800 Subject: [PATCH 6/7] fixes #306 --- mealie/services/scraper/cleaner.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) 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] From 335807637afb8b82f426c024c79c789e7b16814e Mon Sep 17 00:00:00 2001 From: hay-kot Date: Fri, 16 Apr 2021 21:15:57 -0800 Subject: [PATCH 7/7] fixes #297 --- frontend/src/components/UI/CardSection.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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() }}