mirror of
https://github.com/mealie-recipes/mealie.git
synced 2025-07-24 15:49:42 +02:00
feat: Migrate to Nuxt 3 framework (#5184)
Co-authored-by: Michael Genson <71845777+michael-genson@users.noreply.github.com> Co-authored-by: Kuchenpirat <24235032+Kuchenpirat@users.noreply.github.com>
This commit is contained in:
parent
89ab7fac25
commit
c24d532608
403 changed files with 23959 additions and 19557 deletions
|
@ -1,81 +1,121 @@
|
|||
<template>
|
||||
<div :style="`height: ${height}`">
|
||||
<div :style="`height: ${height}px;`">
|
||||
<v-expand-transition>
|
||||
<v-card
|
||||
:ripple="false"
|
||||
:class="isFlat ? 'mx-auto flat' : 'mx-auto'"
|
||||
:style="{ cursor }"
|
||||
hover
|
||||
:to="$listeners.selected ? undefined : recipeRoute"
|
||||
height="100%"
|
||||
:to="$attrs.selected ? undefined : recipeRoute"
|
||||
@click="$emit('selected')"
|
||||
>
|
||||
<v-img v-if="vertical" class="rounded-sm">
|
||||
<v-img
|
||||
v-if="vertical"
|
||||
class="rounded-sm"
|
||||
cover
|
||||
>
|
||||
<RecipeCardImage
|
||||
:icon-size="100"
|
||||
:height="height"
|
||||
:slug="slug"
|
||||
:recipe-id="recipeId"
|
||||
small
|
||||
size="small"
|
||||
:image-version="image"
|
||||
:height="height"
|
||||
/>
|
||||
</v-img>
|
||||
<v-list-item three-line :class="vertical ? 'px-2' : 'px-0'">
|
||||
<slot v-if="!vertical" name="avatar">
|
||||
<v-list-item-avatar tile :height="height" width="125" class="v-mobile-img rounded-sm my-0">
|
||||
<v-list-item
|
||||
lines="two"
|
||||
class="py-0"
|
||||
:class="vertical ? 'px-2' : 'px-0'"
|
||||
item-props
|
||||
height="100%"
|
||||
density="compact"
|
||||
>
|
||||
<template #prepend>
|
||||
<slot
|
||||
v-if="!vertical"
|
||||
name="avatar"
|
||||
>
|
||||
<RecipeCardImage
|
||||
:icon-size="100"
|
||||
:height="height"
|
||||
:slug="slug"
|
||||
:recipe-id="recipeId"
|
||||
:image-version="image"
|
||||
size="small"
|
||||
width="125"
|
||||
:height="height"
|
||||
/>
|
||||
</slot>
|
||||
</template>
|
||||
<div class="pl-4 d-flex flex-column justify-space-between align-stretch pr-2">
|
||||
<v-list-item-title class="mt-3 mb-1 text-top text-truncate w-100">
|
||||
{{ name }}
|
||||
</v-list-item-title>
|
||||
<v-list-item-subtitle class="ma-0 text-top">
|
||||
<SafeMarkdown v-if="description" :source="description" />
|
||||
<p v-else>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
</p>
|
||||
</v-list-item-subtitle>
|
||||
<div
|
||||
class="d-flex flex-nowrap justify-start ma-0 pt-2 pb-0"
|
||||
style="overflow-x: hidden; overflow-y: hidden; white-space: nowrap;"
|
||||
>
|
||||
<RecipeChips
|
||||
:truncate="true"
|
||||
:items="tags"
|
||||
:title="false"
|
||||
:limit="2"
|
||||
small
|
||||
url-prefix="tags"
|
||||
v-bind="$attrs"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<slot name="actions">
|
||||
<v-card-actions class="w-100 my-0 px-1 py-0">
|
||||
<RecipeFavoriteBadge
|
||||
v-if="isOwnGroup && showRecipeContent"
|
||||
:recipe-id="recipeId"
|
||||
show-always
|
||||
class="ma-0 pa-0"
|
||||
/>
|
||||
<div v-else class="my-0 px-1 py-0" /> <!-- Empty div to keep the layout consistent -->
|
||||
<RecipeRating
|
||||
v-if="showRecipeContent"
|
||||
:class="[{ 'pb-2': !isOwnGroup }, 'ml-n2']"
|
||||
:value="rating"
|
||||
:recipe-id="recipeId"
|
||||
:slug="slug"
|
||||
small
|
||||
/>
|
||||
</v-list-item-avatar>
|
||||
</slot>
|
||||
<v-list-item-content class="py-0">
|
||||
<v-list-item-title class="mt-1 mb-1 text-top">{{ name }}</v-list-item-title>
|
||||
<v-list-item-subtitle class="ma-0 text-top">
|
||||
<SafeMarkdown :source="description" />
|
||||
</v-list-item-subtitle>
|
||||
<div class="d-flex flex-wrap justify-start ma-0">
|
||||
<RecipeChips :truncate="true" :items="tags" :title="false" :limit="2" :small="true" url-prefix="tags" v-on="$listeners" />
|
||||
</div>
|
||||
<div class="d-flex flex-wrap justify-end align-center">
|
||||
<slot name="actions">
|
||||
<RecipeFavoriteBadge v-if="isOwnGroup && showRecipeContent" :recipe-id="recipeId" show-always />
|
||||
<RecipeRating
|
||||
v-if="showRecipeContent"
|
||||
:class="isOwnGroup ? 'ml-auto' : 'ml-auto pb-2'"
|
||||
:value="rating"
|
||||
:recipe-id="recipeId"
|
||||
:slug="slug"
|
||||
:small="true"
|
||||
/>
|
||||
<v-spacer></v-spacer>
|
||||
|
||||
<!-- If we're not logged-in, no items display, so we hide this menu -->
|
||||
<!-- We also add padding to the v-rating above to compensate -->
|
||||
<RecipeContextMenu
|
||||
v-if="isOwnGroup && showRecipeContent"
|
||||
:slug="slug"
|
||||
:menu-icon="$globals.icons.dotsHorizontal"
|
||||
:name="name"
|
||||
:recipe-id="recipeId"
|
||||
:use-items="{
|
||||
delete: false,
|
||||
edit: false,
|
||||
download: true,
|
||||
mealplanner: true,
|
||||
shoppingList: true,
|
||||
print: false,
|
||||
printPreferences: false,
|
||||
share: true,
|
||||
}"
|
||||
@deleted="$emit('delete', slug)"
|
||||
/>
|
||||
</slot>
|
||||
</div>
|
||||
</v-list-item-content>
|
||||
<!-- If we're not logged-in, no items display, so we hide this menu -->
|
||||
<!-- We also add padding to the v-rating above to compensate -->
|
||||
<RecipeContextMenu
|
||||
v-if="isOwnGroup && showRecipeContent"
|
||||
:slug="slug"
|
||||
:menu-icon="$globals.icons.dotsHorizontal"
|
||||
:name="name"
|
||||
:recipe-id="recipeId"
|
||||
class="ml-auto"
|
||||
:use-items="{
|
||||
delete: false,
|
||||
edit: false,
|
||||
download: true,
|
||||
mealplanner: true,
|
||||
shoppingList: true,
|
||||
print: false,
|
||||
printPreferences: false,
|
||||
share: true,
|
||||
}"
|
||||
@deleted="$emit('delete', slug)"
|
||||
/>
|
||||
</v-card-actions>
|
||||
</slot>
|
||||
</v-list-item>
|
||||
<slot />
|
||||
</v-card>
|
||||
|
@ -84,7 +124,6 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { computed, defineComponent, useContext, useRoute } from "@nuxtjs/composition-api";
|
||||
import RecipeFavoriteBadge from "./RecipeFavoriteBadge.vue";
|
||||
import RecipeContextMenu from "./RecipeContextMenu.vue";
|
||||
import RecipeCardImage from "./RecipeCardImage.vue";
|
||||
|
@ -92,7 +131,7 @@ import RecipeRating from "./RecipeRating.vue";
|
|||
import RecipeChips from "./RecipeChips.vue";
|
||||
import { useLoggedInState } from "~/composables/use-logged-in-state";
|
||||
|
||||
export default defineComponent({
|
||||
export default defineNuxtComponent({
|
||||
components: {
|
||||
RecipeFavoriteBadge,
|
||||
RecipeContextMenu,
|
||||
|
@ -139,27 +178,23 @@ export default defineComponent({
|
|||
default: false,
|
||||
},
|
||||
height: {
|
||||
type: [Number, String],
|
||||
type: [Number],
|
||||
default: 150,
|
||||
},
|
||||
imageHeight: {
|
||||
type: [Number, String],
|
||||
default: "fill-height",
|
||||
},
|
||||
},
|
||||
emits: ["selected", "delete"],
|
||||
setup(props) {
|
||||
const { $auth } = useContext();
|
||||
const $auth = useMealieAuth();
|
||||
const { isOwnGroup } = useLoggedInState();
|
||||
|
||||
const route = useRoute();
|
||||
const groupSlug = computed(() => route.value.params.groupSlug || $auth.user?.groupSlug || "");
|
||||
const groupSlug = computed(() => route.params.groupSlug || $auth.user.value?.groupSlug || "");
|
||||
const showRecipeContent = computed(() => props.recipeId && props.slug);
|
||||
const recipeRoute = computed<string>(() => {
|
||||
return showRecipeContent.value ? `/g/${groupSlug.value}/r/${props.slug}` : "";
|
||||
});
|
||||
const cursor = computed(() => showRecipeContent.value ? "pointer" : "auto");
|
||||
|
||||
|
||||
return {
|
||||
isOwnGroup,
|
||||
recipeRoute,
|
||||
|
@ -170,7 +205,10 @@ export default defineComponent({
|
|||
});
|
||||
</script>
|
||||
|
||||
<style>
|
||||
<style scoped>
|
||||
:deep(.v-list-item__prepend) {
|
||||
height: 100%;
|
||||
}
|
||||
.v-mobile-img {
|
||||
padding-top: 0;
|
||||
padding-bottom: 0;
|
||||
|
@ -198,8 +236,9 @@ export default defineComponent({
|
|||
align-self: start !important;
|
||||
}
|
||||
|
||||
.flat, .theme--dark .flat {
|
||||
box-shadow: none!important;
|
||||
background-color: transparent!important;
|
||||
.flat,
|
||||
.theme--dark .flat {
|
||||
box-shadow: none !important;
|
||||
background-color: transparent !important;
|
||||
}
|
||||
</style>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue