added loading animation to main search page

This commit is contained in:
vabene1111
2022-09-15 20:53:22 +02:00
parent 459be74a7c
commit e06c82297d
2 changed files with 114 additions and 56 deletions

View File

@@ -1115,6 +1115,9 @@ export default {
}, },
}, },
mounted() { mounted() {
this.recipes = Array(this.ui.page_size).fill({loading:true})
this.$nextTick(function () { this.$nextTick(function () {
if (this.$cookies.isKey(UI_COOKIE_NAME)) { if (this.$cookies.isKey(UI_COOKIE_NAME)) {
this.ui = Object.assign({}, this.ui, this.$cookies.get(UI_COOKIE_NAME)) this.ui = Object.assign({}, this.ui, this.$cookies.get(UI_COOKIE_NAME))

View File

@@ -1,15 +1,47 @@
<template> <template>
<div>
<template v-if="recipe && recipe.loading">
<b-card no-body v-hover>
<b-card-img-lazy style="height: 15vh; object-fit: cover" class="" :src="placeholder_image"
v-bind:alt="$t('Recipe_Image')" top></b-card-img-lazy>
<b-card-body class="p-4">
<h6>
<b-skeleton width="95%"></b-skeleton>
</h6>
<b-card-text>
<b-skeleton height="12px" :width="(45 + Math.random() * 45).toString() + '%'"></b-skeleton>
<b-skeleton height="12px" :width="(20 + Math.random() * 25).toString() + '%'"></b-skeleton>
<b-skeleton height="12px" :width="(30 + Math.random() * 35).toString() + '%'"></b-skeleton>
</b-card-text>
</b-card-body>
</b-card>
</template>
<template v-else>
<b-card no-body v-hover v-if="recipe"> <b-card no-body v-hover v-if="recipe">
<a :href="this.recipe.id !== undefined ? resolveDjangoUrl('view_recipe', this.recipe.id) : null"> <a :href="this.recipe.id !== undefined ? resolveDjangoUrl('view_recipe', this.recipe.id) : null">
<b-card-img-lazy style="height: 15vh; object-fit: cover" class="" :src="recipe_image" v-bind:alt="$t('Recipe_Image')" top></b-card-img-lazy> <b-card-img-lazy style="height: 15vh; object-fit: cover" class="" :src="recipe_image"
<div class="card-img-overlay h-100 d-flex flex-column justify-content-right float-right text-right pt-2 pr-1" v-if="show_context_menu"> v-bind:alt="$t('Recipe_Image')" top></b-card-img-lazy>
<div
class="card-img-overlay h-100 d-flex flex-column justify-content-right float-right text-right pt-2 pr-1"
v-if="show_context_menu">
<a> <a>
<recipe-context-menu :recipe="recipe" class="float-right" v-if="recipe !== null"></recipe-context-menu> <recipe-context-menu :recipe="recipe" class="float-right"
v-if="recipe !== null"></recipe-context-menu>
</a> </a>
</div> </div>
<div class="card-img-overlay w-50 d-flex flex-column justify-content-left float-left text-left pt-2" v-if="recipe.working_time !== 0 || recipe.waiting_time !== 0"> <div class="card-img-overlay w-50 d-flex flex-column justify-content-left float-left text-left pt-2"
<b-badge pill variant="light" class="mt-1 font-weight-normal" v-if="recipe.working_time !== 0"><i class="fa fa-clock"></i> {{ working_time }} </b-badge> v-if="recipe.working_time !== 0 || recipe.waiting_time !== 0">
<b-badge pill variant="secondary" class="mt-1 font-weight-normal" v-if="recipe.waiting_time !== 0"><i class="fa fa-pause"></i> {{ waiting_time }} </b-badge> <b-badge pill variant="light" class="mt-1 font-weight-normal" v-if="recipe.working_time !== 0">
<i
class="fa fa-clock"></i> {{ working_time }}
</b-badge>
<b-badge pill variant="secondary" class="mt-1 font-weight-normal"
v-if="recipe.waiting_time !== 0">
<i class="fa fa-pause"></i> {{ waiting_time }}
</b-badge>
</div> </div>
</a> </a>
@@ -34,14 +66,17 @@
</template> </template>
<p class="mt-1"> <p class="mt-1">
<last-cooked :recipe="recipe"></last-cooked> <last-cooked :recipe="recipe"></last-cooked>
<keywords-component :recipe="recipe" style="margin-top: 4px; position: relative; z-index: 3;"></keywords-component> <keywords-component :recipe="recipe"
style="margin-top: 4px; position: relative; z-index: 3;"></keywords-component>
</p> </p>
<transition name="fade" mode="in-out"> <transition name="fade" mode="in-out">
<div class="row mt-3" v-if="show_detail"> <div class="row mt-3" v-if="show_detail">
<div class="col-md-12"> <div class="col-md-12">
<h6 class="card-title"><i class="fas fa-pepper-hot"></i> {{ $t("Ingredients") }}</h6> <h6 class="card-title"><i class="fas fa-pepper-hot"></i> {{ $t("Ingredients") }}
</h6>
<ingredients-card :steps="recipe.steps" :header="false" :detailed="false" :servings="recipe.servings" /> <ingredients-card :steps="recipe.steps" :header="false" :detailed="false"
:servings="recipe.servings"/>
</div> </div>
</div> </div>
</transition> </transition>
@@ -52,10 +87,15 @@
</b-card-text> </b-card-text>
</b-card-body> </b-card-body>
<b-card-footer v-if="footer_text !== undefined"> <i v-bind:class="footer_icon"></i> {{ footer_text }} </b-card-footer> <b-card-footer v-if="footer_text !== undefined"><i v-bind:class="footer_icon"></i> {{ footer_text }}
</b-card-footer>
</b-card> </b-card>
</template> </template>
</div>
</template>
<script> <script>
import RecipeContextMenu from "@/components/RecipeContextMenu" import RecipeContextMenu from "@/components/RecipeContextMenu"
import KeywordsComponent from "@/components/KeywordsComponent" import KeywordsComponent from "@/components/KeywordsComponent"
@@ -71,7 +111,13 @@ Vue.prototype.moment = moment
export default { export default {
name: "RecipeCard", name: "RecipeCard",
mixins: [ResolveUrlMixin], mixins: [ResolveUrlMixin],
components: { LastCooked, RecipeRating, KeywordsComponent, "recipe-context-menu": RecipeContextMenu, IngredientsCard }, components: {
LastCooked,
RecipeRating,
KeywordsComponent,
"recipe-context-menu": RecipeContextMenu,
IngredientsCard
},
props: { props: {
recipe: Object, recipe: Object,
meal_plan: Object, meal_plan: Object,
@@ -80,7 +126,14 @@ export default {
detailed: {type: Boolean, default: true}, detailed: {type: Boolean, default: true},
show_context_menu: {type: Boolean, default: true} show_context_menu: {type: Boolean, default: true}
}, },
mounted() {}, data() {
return {
placeholder_image: window.IMAGE_PLACEHOLDER,
}
},
mounted() {
},
computed: { computed: {
show_detail: function () { show_detail: function () {
return this.recipe?.steps !== undefined && this.detailed return this.recipe?.steps !== undefined && this.detailed
@@ -100,13 +153,13 @@ export default {
} }
}, },
working_time: function () { working_time: function () {
return calculateHourMinuteSplit(this.recipe.working_time)}, return calculateHourMinuteSplit(this.recipe.working_time)
},
waiting_time: function () { waiting_time: function () {
return calculateHourMinuteSplit(this.recipe.waiting_time)}, return calculateHourMinuteSplit(this.recipe.waiting_time)
}, },
methods: {
}, },
methods: {},
directives: { directives: {
hover: { hover: {
inserted: function (el) { inserted: function (el) {
@@ -127,7 +180,9 @@ export default {
.fade-leave-active { .fade-leave-active {
transition: opacity 0.5s; transition: opacity 0.5s;
} }
.fade-enter, .fade-leave-to /* .fade-leave-active below version 2.1.8 */ {
.fade-enter, .fade-leave-to /* .fade-leave-active below version 2.1.8 */
{
opacity: 0; opacity: 0;
} }
</style> </style>