1
0
Fork 0
mirror of https://github.com/mealie-recipes/mealie.git synced 2025-07-20 13:49:40 +02:00

fix: Refresh recipe section when clicking card tag chip (#4810)

Co-authored-by: Kuchenpirat <24235032+Kuchenpirat@users.noreply.github.com>
This commit is contained in:
gpotter@gmail.com 2025-01-14 09:18:16 -08:00 committed by GitHub
parent 4b992afc67
commit 203218a3d5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 61 additions and 16 deletions

View file

@ -7,7 +7,7 @@
:elevation="hover ? 12 : 2" :elevation="hover ? 12 : 2"
:to="recipeRoute" :to="recipeRoute"
:min-height="imageHeight + 75" :min-height="imageHeight + 75"
@click="$emit('click')" @click.self="$emit('click')"
> >
<RecipeCardImage <RecipeCardImage
:icon-size="imageHeight" :icon-size="imageHeight"
@ -39,7 +39,7 @@
<RecipeRating class="pb-1" :value="rating" :recipe-id="recipeId" :slug="slug" :small="true" /> <RecipeRating class="pb-1" :value="rating" :recipe-id="recipeId" :slug="slug" :small="true" />
<v-spacer></v-spacer> <v-spacer></v-spacer>
<RecipeChips :truncate="true" :items="tags" :title="false" :limit="2" :small="true" url-prefix="tags" /> <RecipeChips :truncate="true" :items="tags" :title="false" :limit="2" :small="true" url-prefix="tags" v-on="$listeners" />
<!-- If we're not logged-in, no items display, so we hide this menu --> <!-- If we're not logged-in, no items display, so we hide this menu -->
<RecipeContextMenu <RecipeContextMenu

View file

@ -38,7 +38,7 @@
<SafeMarkdown :source="description" /> <SafeMarkdown :source="description" />
</v-list-item-subtitle> </v-list-item-subtitle>
<div class="d-flex flex-wrap justify-start ma-0"> <div class="d-flex flex-wrap justify-start ma-0">
<RecipeChips :truncate="true" :items="tags" :title="false" :limit="2" :small="true" url-prefix="tags" /> <RecipeChips :truncate="true" :items="tags" :title="false" :limit="2" :small="true" url-prefix="tags" v-on="$listeners" />
</div> </div>
<div class="d-flex flex-wrap justify-end align-center"> <div class="d-flex flex-wrap justify-end align-center">
<slot name="actions"> <slot name="actions">

View file

@ -82,6 +82,8 @@
:image="recipe.image" :image="recipe.image"
:tags="recipe.tags" :tags="recipe.tags"
:recipe-id="recipe.id" :recipe-id="recipe.id"
v-on="$listeners"
/> />
</v-lazy> </v-lazy>
</v-col> </v-col>
@ -105,6 +107,8 @@
:image="recipe.image" :image="recipe.image"
:tags="recipe.tags" :tags="recipe.tags"
:recipe-id="recipe.id" :recipe-id="recipe.id"
v-on="$listeners"
/> />
</v-lazy> </v-lazy>
</v-col> </v-col>
@ -296,6 +300,7 @@ export default defineComponent({
}, useAsyncKey()); }, useAsyncKey());
}, 500); }, 500);
function sortRecipes(sortType: string) { function sortRecipes(sortType: string) {
if (state.sortLoading || loading.value) { if (state.sortLoading || loading.value) {
return; return;

View file

@ -9,7 +9,8 @@
color="accent" color="accent"
:small="small" :small="small"
dark dark
:to="`${baseRecipeRoute}?${urlPrefix}=${category.id}`"
@click.prevent="() => $emit('item-selected', category, urlPrefix)"
> >
{{ truncateText(category.name) }} {{ truncateText(category.name) }}
</v-chip> </v-chip>

View file

@ -23,13 +23,13 @@
<a :href="`/g/${groupSlug}/r/${item.slug}`" style="color: inherit; text-decoration: inherit; " @click="$emit('click')">{{ item.name }}</a> <a :href="`/g/${groupSlug}/r/${item.slug}`" style="color: inherit; text-decoration: inherit; " @click="$emit('click')">{{ item.name }}</a>
</template> </template>
<template #item.tags="{ item }"> <template #item.tags="{ item }">
<RecipeChip small :items="item.tags" :is-category="false" url-prefix="tags" /> <RecipeChip small :items="item.tags" :is-category="false" url-prefix="tags" @item-selected="filterItems" />
</template> </template>
<template #item.recipeCategory="{ item }"> <template #item.recipeCategory="{ item }">
<RecipeChip small :items="item.recipeCategory" /> <RecipeChip small :items="item.recipeCategory" @item-selected="filterItems" />
</template> </template>
<template #item.tools="{ item }"> <template #item.tools="{ item }">
<RecipeChip small :items="item.tools" url-prefix="tools" /> <RecipeChip small :items="item.tools" url-prefix="tools" @item-selected="filterItems" />
</template> </template>
<template #item.userId="{ item }"> <template #item.userId="{ item }">
<v-list-item class="justify-start"> <v-list-item class="justify-start">
@ -48,12 +48,13 @@
</template> </template>
<script lang="ts"> <script lang="ts">
import { computed, defineComponent, onMounted, ref, useContext } from "@nuxtjs/composition-api"; import { computed, defineComponent, onMounted, ref, useContext, useRouter } from "@nuxtjs/composition-api";
import UserAvatar from "../User/UserAvatar.vue"; import UserAvatar from "../User/UserAvatar.vue";
import RecipeChip from "./RecipeChips.vue"; import RecipeChip from "./RecipeChips.vue";
import { Recipe } from "~/lib/api/types/recipe"; import { Recipe, RecipeCategory, RecipeTool } from "~/lib/api/types/recipe";
import { useUserApi } from "~/composables/api"; import { useUserApi } from "~/composables/api";
import { UserSummary } from "~/lib/api/types/user"; import { UserSummary } from "~/lib/api/types/user";
import { RecipeTag } from "~/lib/api/types/household";
const INPUT_EVENT = "input"; const INPUT_EVENT = "input";
@ -106,7 +107,7 @@ export default defineComponent({
setup(props, context) { setup(props, context) {
const { $auth, i18n } = useContext(); const { $auth, i18n } = useContext();
const groupSlug = $auth.user?.groupSlug; const groupSlug = $auth.user?.groupSlug;
const router = useRouter();
function setValue(value: Recipe[]) { function setValue(value: Recipe[]) {
context.emit(INPUT_EVENT, value); context.emit(INPUT_EVENT, value);
} }
@ -167,6 +168,13 @@ export default defineComponent({
} }
} }
function filterItems(item: RecipeTag | RecipeCategory | RecipeTool, itemType: string) {
if (!groupSlug || !item.id) {
return;
}
router.push(`/g/${groupSlug}?${itemType}=${item.id}`);
}
onMounted(() => { onMounted(() => {
refreshMembers(); refreshMembers();
}); });
@ -186,6 +194,7 @@ export default defineComponent({
formatDate, formatDate,
members, members,
getMember, getMember,
filterItems,
}; };
}, },

View file

@ -138,6 +138,7 @@
:title="$tc('general.recipes')" :title="$tc('general.recipes')"
:recipes="recipes" :recipes="recipes"
:query="passedQueryWithSeed" :query="passedQueryWithSeed"
@item-selected="filterItems"
@replaceRecipes="replaceRecipes" @replaceRecipes="replaceRecipes"
@appendRecipes="appendRecipes" @appendRecipes="appendRecipes"
/> />
@ -387,6 +388,19 @@ export default defineComponent({
} }
) )
function filterItems(item: RecipeCategory | RecipeTag | RecipeTool, urlPrefix: string) {
if (urlPrefix === "categories") {
const result = categories.store.value.filter((category) => (category.id as string).includes(item.id as string));
selectedCategories.value = result as NoUndefinedField<RecipeTag>[];
} else if (urlPrefix === "tags") {
const result = tags.store.value.filter((tag) => (tag.id as string).includes(item.id as string));
selectedTags.value = result as NoUndefinedField<RecipeTag>[];
} else if (urlPrefix === "tools") {
const result = tools.store.value.filter((tool) => (tool.id ).includes(item.id || "" ));
selectedTags.value = result as NoUndefinedField<RecipeTag>[];
}
}
async function hydrateSearch() { async function hydrateSearch() {
const query = router.currentRoute.query; const query = router.currentRoute.query;
if (query.auto?.length) { if (query.auto?.length) {
@ -592,6 +606,8 @@ export default defineComponent({
removeRecipe, removeRecipe,
replaceRecipes, replaceRecipes,
passedQueryWithSeed, passedQueryWithSeed,
filterItems,
}; };
}, },
head: {}, head: {},

View file

@ -35,7 +35,7 @@
--> -->
<v-col v-if="!isCookMode || isEditForm" cols="12" sm="12" md="4" lg="4"> <v-col v-if="!isCookMode || isEditForm" cols="12" sm="12" md="4" lg="4">
<RecipePageIngredientToolsView v-if="!isEditForm" :recipe="recipe" :scale="scale" /> <RecipePageIngredientToolsView v-if="!isEditForm" :recipe="recipe" :scale="scale" />
<RecipePageOrganizers v-if="$vuetify.breakpoint.mdAndUp" :recipe="recipe" /> <RecipePageOrganizers v-if="$vuetify.breakpoint.mdAndUp" :recipe="recipe" @item-selected="chipClicked" />
</v-col> </v-col>
<v-divider v-if="$vuetify.breakpoint.mdAndUp && !isCookMode" class="my-divider" :vertical="true" /> <v-divider v-if="$vuetify.breakpoint.mdAndUp && !isCookMode" class="my-divider" :vertical="true" />
@ -166,7 +166,7 @@ import {
usePageUser, usePageUser,
} from "~/composables/recipe-page/shared-state"; } from "~/composables/recipe-page/shared-state";
import { NoUndefinedField } from "~/lib/api/types/non-generated"; import { NoUndefinedField } from "~/lib/api/types/non-generated";
import { Recipe } from "~/lib/api/types/recipe"; import { Recipe, RecipeCategory, RecipeTag, RecipeTool } from "~/lib/api/types/recipe";
import { useRouteQuery } from "~/composables/use-router"; import { useRouteQuery } from "~/composables/use-router";
import { useUserApi } from "~/composables/api"; import { useUserApi } from "~/composables/api";
import { uuid4, deepCopy } from "~/composables/use-utils"; import { uuid4, deepCopy } from "~/composables/use-utils";
@ -329,6 +329,17 @@ export default defineComponent({
*/ */
const { user } = usePageUser(); const { user } = usePageUser();
/** =============================================================
* RecipeChip Clicked
*/
function chipClicked(item: RecipeTag | RecipeCategory | RecipeTool, itemType: string) {
if (!item.id) {
return;
}
router.push(`/g/${groupSlug.value}?${itemType}=${item.id}`);
}
return { return {
user, user,
isOwnGroup, isOwnGroup,
@ -350,7 +361,8 @@ export default defineComponent({
deleteRecipe, deleteRecipe,
addStep, addStep,
hasLinkedIngredients, hasLinkedIngredients,
notLinkedIngredients notLinkedIngredients,
chipClicked,
}; };
}, },
head: {}, head: {},

View file

@ -14,7 +14,7 @@
:show-add="true" :show-add="true"
selector-type="categories" selector-type="categories"
/> />
<RecipeChips v-else :items="recipe.recipeCategory" /> <RecipeChips v-else :items="recipe.recipeCategory" v-on="$listeners" />
</v-card-text> </v-card-text>
</v-card> </v-card>
@ -32,7 +32,7 @@
:show-add="true" :show-add="true"
selector-type="tags" selector-type="tags"
/> />
<RecipeChips v-else :items="recipe.tags" url-prefix="tags" /> <RecipeChips v-else :items="recipe.tags" url-prefix="tags" v-on="$listeners" />
</v-card-text> </v-card-text>
</v-card> </v-card>
@ -41,7 +41,7 @@
<v-card-title class="py-2"> {{ $t('tool.required-tools') }} </v-card-title> <v-card-title class="py-2"> {{ $t('tool.required-tools') }} </v-card-title>
<v-divider class="mx-2" /> <v-divider class="mx-2" />
<v-card-text class="pt-0"> <v-card-text class="pt-0">
<RecipeOrganizerSelector v-model="recipe.tools" selector-type="tools" /> <RecipeOrganizerSelector v-model="recipe.tools" selector-type="tools" v-on="$listeners" />
</v-card-text> </v-card-text>
</v-card> </v-card>
@ -82,6 +82,8 @@ export default defineComponent({
const { user } = usePageUser(); const { user } = usePageUser();
const { isEditForm } = usePageState(props.recipe.slug); const { isEditForm } = usePageState(props.recipe.slug);
return { return {
isEditForm, isEditForm,
user, user,