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:
parent
4b992afc67
commit
203218a3d5
8 changed files with 61 additions and 16 deletions
|
@ -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
|
||||||
|
|
|
@ -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">
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -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: {},
|
||||||
|
|
|
@ -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: {},
|
||||||
|
|
|
@ -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,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue