diff --git a/.github/ISSUE_TEMPLATE/recipe-scraper-bug.yaml b/.github/ISSUE_TEMPLATE/recipe-scraper-bug.yaml index 61b877e7b078..2a38b6a4faa3 100644 --- a/.github/ISSUE_TEMPLATE/recipe-scraper-bug.yaml +++ b/.github/ISSUE_TEMPLATE/recipe-scraper-bug.yaml @@ -17,7 +17,7 @@ body: - label: | I have verified that this issue _is not_ related to the underlying library [hhyrsev/recipe-scrapers](https://github.com/hhursev/recipe-scrapers) by **1)** checking - the [debugger](https://demo.mealie.io/recipe/create/debug) and data is returned, **2)** + the [debugger](https://demo.mealie.io/g/home/r/create/debug) and data is returned, **2)** verifying that there _are_ errors in the log related to application level code, or **3)** verified that the site provides recipe data, or is otherwise supported by [hhyrsev/recipe-scrapers](https://github.com/hhursev/recipe-scrapers) diff --git a/docs/docs/documentation/community-guide/import-recipe-bookmarklet.md b/docs/docs/documentation/community-guide/import-recipe-bookmarklet.md index f0de673df2ef..64326dc1a964 100644 --- a/docs/docs/documentation/community-guide/import-recipe-bookmarklet.md +++ b/docs/docs/documentation/community-guide/import-recipe-bookmarklet.md @@ -15,6 +15,6 @@ var url = document.URL; var mealie = "http://localhost:8080"; var use_keywords= "&use_keywords=1" // Optional - use keywords from recipe - update to "" if you don't want that var edity = "&edit=1" // Optional - keep in edit mode - update to "" if you don't want that -var dest = mealie + "/recipe/create/url?recipe_import_url=" + url + use_keywords + edity; +var dest = mealie + "/r/create/url?recipe_import_url=" + url + use_keywords + edity; window.open(dest, "_blank"); ``` diff --git a/docs/docs/documentation/getting-started/features.md b/docs/docs/documentation/getting-started/features.md index 4c195cc748dc..fb65b1f1f61c 100644 --- a/docs/docs/documentation/getting-started/features.md +++ b/docs/docs/documentation/getting-started/features.md @@ -8,7 +8,7 @@ Mealie offers two main ways to create recipes. You can use the integrated recipe-scraper to create recipes from hundreds of websites, or you can create recipes manually using the recipe editor. -[Creation Demo](https://demo.mealie.io/recipe/create/url){ .md-button .md-button--primary .align-right } +[Creation Demo](https://demo.mealie.io/g/home/r/create/url){ .md-button .md-button--primary .align-right } ### Importing Recipes @@ -34,13 +34,13 @@ Mealie has a robust and flexible recipe organization system with a few different Categories are the overarching organizer for recipes. You can assign as many categories as you'd like to a recipe, but we recommend that you try to limit the categories you assign to a recipe to one or two. This helps keep categories as focused as possible while still allowing you to find recipes that are related to each other. For example, you might assign a recipe to the category **Breakfast**, **Lunch**, **Dinner**, or **Side**. -[Categories Demo](https://demo.mealie.io/recipes/categories){ .md-button .md-button--primary } +[Categories Demo](https://demo.mealie.io/g/home/recipes/categories){ .md-button .md-button--primary } #### Tags Tags, are nearly identical to categories in function but play a secondary role in some cases. As such, we recommend that you use tags freely to help you organize your recipes by more specific topics. For example, if a recipe can be frozen or is a great left-over meal, you could assign the tags **frozen** and **left-over** and easily filter for those at a later time. -[Tags Demo](https://demo.mealie.io/recipes/tags){ .md-button .md-button--primary } +[Tags Demo](https://demo.mealie.io/g/home/recipes/tags){ .md-button .md-button--primary } #### Tools @@ -48,7 +48,7 @@ Tools, are another way that some users like to organize their recipes. If a reci Each of the above organizers can be filtered in searches, and have their own pages where you can view all the recipes that are associated with those organizers. -[Tools Demo](https://demo.mealie.io/recipes/tools){ .md-button .md-button--primary } +[Tools Demo](https://demo.mealie.io/g/home/recipes/tools){ .md-button .md-button--primary } #### Cookbooks @@ -60,7 +60,7 @@ Mealie also has the concept of cookbooks. These can be created inside of a group - Pasta Sides: Recipes that have both the **Side** category and the **Pasta** tag - Dessert Breads: Recipes that have both the **Bread** category and the **Dessert** tag -[Cookbooks Demo](https://demo.mealie.io/group/cookbooks){ .md-button .md-button--primary } +[Cookbooks Demo](https://demo.mealie.io/g/home/cookbooks){ .md-button .md-button--primary } ## Meal Planning diff --git a/frontend/components/Domain/Cookbook/CookbookPage.vue b/frontend/components/Domain/Cookbook/CookbookPage.vue index 2afb33e7722a..3460d82536e6 100644 --- a/frontend/components/Domain/Cookbook/CookbookPage.vue +++ b/frontend/components/Domain/Cookbook/CookbookPage.vue @@ -15,7 +15,6 @@ class="mb-5 mx-1" :recipes="recipes" :query="{ cookbook: slug }" - :group-slug="groupSlug" @sortRecipes="assignSorted" @replaceRecipes="replaceRecipes" @appendRecipes="appendRecipes" @@ -30,24 +29,20 @@ import { useLazyRecipes } from "~/composables/recipes"; import RecipeCardSection from "@/components/Domain/Recipe/RecipeCardSection.vue"; import { useCookbook } from "~/composables/use-group-cookbooks"; + import { useLoggedInState } from "~/composables/use-logged-in-state"; export default defineComponent({ components: { RecipeCardSection }, - props: { - groupSlug: { - type: String, - default: undefined, - } - }, - setup(props) { + setup() { const { $auth } = useContext(); - const loggedIn = computed(() => $auth.loggedIn); - - const { recipes, appendRecipes, assignSorted, removeRecipe, replaceRecipes } = useLazyRecipes(loggedIn.value ? null : props.groupSlug); + const { isOwnGroup } = useLoggedInState(); const route = useRoute(); + const groupSlug = computed(() => route.value.params.groupSlug || $auth.user?.groupSlug || ""); + + const { recipes, appendRecipes, assignSorted, removeRecipe, replaceRecipes } = useLazyRecipes(isOwnGroup.value ? null : groupSlug.value); const slug = route.value.params.slug; - const { getOne } = useCookbook(loggedIn.value ? null : props.groupSlug); + const { getOne } = useCookbook(isOwnGroup.value ? null : groupSlug.value); const tab = ref(null); const book = getOne(slug); diff --git a/frontend/components/Domain/Recipe/RecipeActionMenu.vue b/frontend/components/Domain/Recipe/RecipeActionMenu.vue index 4d576ec462f3..c5b6a72e76cb 100644 --- a/frontend/components/Domain/Recipe/RecipeActionMenu.vue +++ b/frontend/components/Domain/Recipe/RecipeActionMenu.vue @@ -70,7 +70,6 @@ print: true, printPreferences: true, share: loggedIn, - publicUrl: recipe.settings && loggedIn ? recipe.settings.public : false, }" @print="$emit('print')" /> diff --git a/frontend/components/Domain/Recipe/RecipeCard.vue b/frontend/components/Domain/Recipe/RecipeCard.vue index e13bd40d4f21..4499cdb989c6 100644 --- a/frontend/components/Domain/Recipe/RecipeCard.vue +++ b/frontend/components/Domain/Recipe/RecipeCard.vue @@ -34,7 +34,7 @@ - + @@ -42,7 +42,7 @@ @@ -69,12 +68,13 @@ diff --git a/frontend/components/Domain/Recipe/RecipeTimelineItem.vue b/frontend/components/Domain/Recipe/RecipeTimelineItem.vue index 4802cdc22f11..fd460d95d23a 100644 --- a/frontend/components/Domain/Recipe/RecipeTimelineItem.vue +++ b/frontend/components/Domain/Recipe/RecipeTimelineItem.vue @@ -13,7 +13,7 @@ @@ -95,7 +95,7 @@ diff --git a/frontend/components/Layout/LayoutParts/AppHeader.vue b/frontend/components/Layout/LayoutParts/AppHeader.vue index 5af4088d9c09..2c6dab639cc3 100644 --- a/frontend/components/Layout/LayoutParts/AppHeader.vue +++ b/frontend/components/Layout/LayoutParts/AppHeader.vue @@ -35,7 +35,7 @@ {{ $globals.icons.search }} - + {{ $globals.icons.logout }} {{ $vuetify.breakpoint.smAndUp ? $t("user.logout") : "" }} @@ -49,6 +49,7 @@ diff --git a/frontend/layouts/error.vue b/frontend/layouts/error.vue index 6731482f464a..22546b6b40c3 100644 --- a/frontend/layouts/error.vue +++ b/frontend/layouts/error.vue @@ -1,5 +1,5 @@ diff --git a/frontend/lib/api/public/explore/recipes.ts b/frontend/lib/api/public/explore/recipes.ts index 060ada6e03f2..8f6aca367789 100644 --- a/frontend/lib/api/public/explore/recipes.ts +++ b/frontend/lib/api/public/explore/recipes.ts @@ -1,6 +1,8 @@ import { BaseCRUDAPIReadOnly } from "~/lib/api/base/base-clients"; +import { route } from "../../base"; import { Recipe } from "~/lib/api/types/recipe"; -import { ApiRequestInstance } from "~/lib/api/types/non-generated"; +import { ApiRequestInstance, PaginationData } from "~/lib/api/types/non-generated"; +import { RecipeSearchQuery } from "../../user/recipes/recipe"; const prefix = "/api"; @@ -16,4 +18,8 @@ export class PublicRecipeApi extends BaseCRUDAPIReadOnly { constructor(requests: ApiRequestInstance, private readonly groupSlug: string) { super(requests); } + + async search(rsq: RecipeSearchQuery) { + return await this.requests.get>(route(routes.recipesGroupSlug(this.groupSlug), rsq)); + } } diff --git a/frontend/lib/api/types/user.ts b/frontend/lib/api/types/user.ts index 6871dbb83afe..6bba730c5f55 100644 --- a/frontend/lib/api/types/user.ts +++ b/frontend/lib/api/types/user.ts @@ -66,6 +66,7 @@ export interface UserOut { canOrganize?: boolean; id: string; groupId: string; + groupSlug: string; tokens?: LongLiveTokenOut[]; cacheKey: string; } @@ -113,6 +114,7 @@ export interface PrivateUser { canOrganize?: boolean; id: string; groupId: string; + groupSlug: string; tokens?: LongLiveTokenOut[]; cacheKey: string; password: string; diff --git a/frontend/nuxt.config.js b/frontend/nuxt.config.js index 818eddb30b3b..21f8cf5f48b4 100644 --- a/frontend/nuxt.config.js +++ b/frontend/nuxt.config.js @@ -342,7 +342,7 @@ export default { background_color: "#FFFFFF", display: "standalone", share_target: { - action: "/recipe/create/url", + action: "/r/create/url", method: "GET", params: { /* title and url are not currently used in Mealie. If there are issues diff --git a/frontend/package.json b/frontend/package.json index fdb73b48e763..96f0b6aeb40f 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -6,7 +6,7 @@ "dev": "nuxt", "build": "nuxt build", "start": "nuxt start", - "generate": "nuxt generate", + "generate": "nuxt generate --spa", "lint:js": "eslint --ext \".ts,.js,.vue\" --ignore-path .gitignore .", "lint": "yarn lint:js", "test": "vitest", diff --git a/frontend/pages/admin/backups.vue b/frontend/pages/admin/backups.vue index 9237f7739a0d..d8a32bea2d54 100644 --- a/frontend/pages/admin/backups.vue +++ b/frontend/pages/admin/backups.vue @@ -105,13 +105,13 @@ - {{ $t('recipe.looking-for-migrations') }} + {{ $t('recipe.looking-for-migrations') }} diff --git a/frontend/pages/explore/recipes/_groupSlug/_recipeSlug.vue b/frontend/pages/explore/recipes/_groupSlug/_recipeSlug.vue deleted file mode 100644 index 59346c724c07..000000000000 --- a/frontend/pages/explore/recipes/_groupSlug/_recipeSlug.vue +++ /dev/null @@ -1,47 +0,0 @@ - - - diff --git a/frontend/pages/explore/recipes/_groupSlug/index.vue b/frontend/pages/explore/recipes/_groupSlug/index.vue deleted file mode 100644 index 64eca0efea2f..000000000000 --- a/frontend/pages/explore/recipes/_groupSlug/index.vue +++ /dev/null @@ -1,42 +0,0 @@ - - - diff --git a/frontend/pages/cookbooks/_slug.vue b/frontend/pages/g/_groupSlug/cookbooks/_slug.vue similarity index 100% rename from frontend/pages/cookbooks/_slug.vue rename to frontend/pages/g/_groupSlug/cookbooks/_slug.vue diff --git a/frontend/pages/group/cookbooks.vue b/frontend/pages/g/_groupSlug/cookbooks/index.vue similarity index 93% rename from frontend/pages/group/cookbooks.vue rename to frontend/pages/g/_groupSlug/cookbooks/index.vue index cc8c94c2601f..86efb3b1c9dd 100644 --- a/frontend/pages/group/cookbooks.vue +++ b/frontend/pages/g/_groupSlug/cookbooks/index.vue @@ -90,14 +90,22 @@ diff --git a/frontend/pages/g/_groupSlug/r/_slug/index.vue b/frontend/pages/g/_groupSlug/r/_slug/index.vue new file mode 100644 index 000000000000..ffdb262ed40e --- /dev/null +++ b/frontend/pages/g/_groupSlug/r/_slug/index.vue @@ -0,0 +1,59 @@ + + + diff --git a/frontend/pages/recipe/_slug/ingredient-parser.vue b/frontend/pages/g/_groupSlug/r/_slug/ingredient-parser.vue similarity index 97% rename from frontend/pages/recipe/_slug/ingredient-parser.vue rename to frontend/pages/g/_groupSlug/r/_slug/ingredient-parser.vue index 2bc91da8e2e5..358a9a25fc1f 100644 --- a/frontend/pages/recipe/_slug/ingredient-parser.vue +++ b/frontend/pages/g/_groupSlug/r/_slug/ingredient-parser.vue @@ -94,7 +94,7 @@ diff --git a/frontend/pages/login.vue b/frontend/pages/login.vue index 9118e43406a2..546b44720de8 100644 --- a/frontend/pages/login.vue +++ b/frontend/pages/login.vue @@ -103,6 +103,7 @@ diff --git a/frontend/pages/shopping-lists/_id.vue b/frontend/pages/shopping-lists/_id.vue index 4b94f7a68484..8c7dd9f31528 100644 --- a/frontend/pages/shopping-lists/_id.vue +++ b/frontend/pages/shopping-lists/_id.vue @@ -199,7 +199,7 @@
- +
@@ -236,6 +236,7 @@ export default defineComponent({ ShoppingListItemEditor, }, setup() { + const { $auth, i18n } = useContext(); const preferences = useShoppingListPreferences(); const { idle } = useIdle(5 * 60 * 1000) // 5 minutes @@ -247,10 +248,9 @@ export default defineComponent({ const reorderLabelsDialog = ref(false); const route = useRoute(); + const groupSlug = computed(() => route.value.params.groupSlug || $auth.user?.groupSlug || ""); const id = route.value.params.id; - const { i18n } = useContext(); - // =============================================================== // Shopping List Actions @@ -755,6 +755,7 @@ export default defineComponent({ deleteListItem, edit, getLabelColor, + groupSlug, itemsByLabel, listItems, loadingCounter, diff --git a/frontend/pages/shopping-lists/index.vue b/frontend/pages/shopping-lists/index.vue index 85b1e1fd3599..fecbbe4e64a9 100644 --- a/frontend/pages/shopping-lists/index.vue +++ b/frontend/pages/shopping-lists/index.vue @@ -33,19 +33,22 @@
- +
- + \ No newline at end of file + diff --git a/frontend/pages/user/profile/edit.vue b/frontend/pages/user/profile/edit.vue index a590bfe5929a..3eadc87ed1c9 100644 --- a/frontend/pages/user/profile/edit.vue +++ b/frontend/pages/user/profile/edit.vue @@ -108,9 +108,9 @@ :label="$t('profile.show-advanced-description')" @change="updateUser" > - {{ $t('profile.looking-for-privacy-settings') }} + {{ $t('profile.looking-for-privacy-settings') }}
- + {{ $globals.icons.backArrow }} diff --git a/frontend/pages/user/profile/index.vue b/frontend/pages/user/profile/index.vue index 93764d9ab06a..1e5a4331f8ab 100644 --- a/frontend/pages/user/profile/index.vue +++ b/frontend/pages/user/profile/index.vue @@ -16,17 +16,6 @@ {{ $t('profile.get-invite-link') }} - - - {{ $globals.icons.shareVariant }} - - {{ $t('profile.get-public-link') }} -
@@ -114,7 +103,7 @@ @@ -124,7 +113,7 @@ @@ -143,7 +132,7 @@ @@ -152,7 +141,7 @@ @@ -161,7 +150,7 @@ @@ -171,7 +160,7 @@ @@ -182,7 +171,7 @@ @@ -193,7 +182,7 @@ @@ -204,7 +193,7 @@ @@ -218,7 +207,7 @@