reload book recipes when adding filter
This commit is contained in:
@ -650,7 +650,7 @@ class CustomFilterSerializer(SpacedModelSerializer, WritableNestedModelSerialize
|
|||||||
|
|
||||||
class RecipeBookSerializer(SpacedModelSerializer, WritableNestedModelSerializer):
|
class RecipeBookSerializer(SpacedModelSerializer, WritableNestedModelSerializer):
|
||||||
shared = UserNameSerializer(many=True)
|
shared = UserNameSerializer(many=True)
|
||||||
filter = CustomFilterSerializer(required=False)
|
filter = CustomFilterSerializer(allow_null=True, required=False)
|
||||||
|
|
||||||
def create(self, validated_data):
|
def create(self, validated_data):
|
||||||
validated_data['created_by'] = self.context['request'].user
|
validated_data['created_by'] = self.context['request'].user
|
||||||
|
@ -44,7 +44,14 @@
|
|||||||
|
|
||||||
<loading-spinner v-if="current_book === book.id && loading"></loading-spinner>
|
<loading-spinner v-if="current_book === book.id && loading"></loading-spinner>
|
||||||
<transition name="slide-fade">
|
<transition name="slide-fade">
|
||||||
<cookbook-slider :recipes="recipes" :book="book" :key="`slider_${book.id}`" v-if="current_book === book.id && !loading" v-on:refresh="refreshData"></cookbook-slider>
|
<cookbook-slider
|
||||||
|
:recipes="recipes"
|
||||||
|
:book="book"
|
||||||
|
:key="`slider_${book.id}`"
|
||||||
|
v-if="current_book === book.id && !loading"
|
||||||
|
v-on:refresh="refreshData"
|
||||||
|
@reload="openBook(current_book, true)"
|
||||||
|
></cookbook-slider>
|
||||||
</transition>
|
</transition>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -95,8 +102,8 @@ export default {
|
|||||||
this.cookbooks = result.data
|
this.cookbooks = result.data
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
openBook: function (book) {
|
openBook: function (book, keepopen = false) {
|
||||||
if (book === this.current_book) {
|
if (book === this.current_book && !keepopen) {
|
||||||
this.current_book = undefined
|
this.current_book = undefined
|
||||||
this.recipes = []
|
this.recipes = []
|
||||||
return
|
return
|
||||||
@ -111,18 +118,7 @@ export default {
|
|||||||
|
|
||||||
apiClient.listRecipeBookEntrys({ query: { book: book } }).then((result) => {
|
apiClient.listRecipeBookEntrys({ query: { book: book } }).then((result) => {
|
||||||
this.recipes = result.data
|
this.recipes = result.data
|
||||||
if (book_contents.filter) {
|
if (book_contents.filter) this.appendRecipeFilter(1, book_contents)
|
||||||
var promises = []
|
|
||||||
var page = 1
|
|
||||||
this.appendRecipeFilter(page, book_contents).then((count) => {
|
|
||||||
while (count.total > 0) {
|
|
||||||
page++
|
|
||||||
promises.push(this.appendRecipeFilter(page, book_contents))
|
|
||||||
count.total = count.total - count.page
|
|
||||||
}
|
|
||||||
Promise.all(promises).then()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
this.loading = false
|
this.loading = false
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
@ -142,7 +138,7 @@ export default {
|
|||||||
},
|
},
|
||||||
appendRecipeFilter: function (page, book) {
|
appendRecipeFilter: function (page, book) {
|
||||||
let params = { page: page, options: { query: { filter: book.filter.id } } }
|
let params = { page: page, options: { query: { filter: book.filter.id } } }
|
||||||
return this.genericAPI(this.Models.RECIPE, this.Actions.LIST, params).then((results) => {
|
this.genericAPI(this.Models.RECIPE, this.Actions.LIST, params).then((results) => {
|
||||||
let recipes = results.data.results.map((x) => {
|
let recipes = results.data.results.map((x) => {
|
||||||
return {
|
return {
|
||||||
id: (Math.random() * 1999) ^ 1999,
|
id: (Math.random() * 1999) ^ 1999,
|
||||||
@ -152,8 +148,11 @@ export default {
|
|||||||
recipe_content: x,
|
recipe_content: x,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
this.recipes.push(...recipes)
|
this.recipes.push(...recipes)
|
||||||
return { total: results.data.count - results.data.results.length, page: results.data.results.length }
|
if (results.data.next) {
|
||||||
|
this.appendRecipeFilter(page + 1, book)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -100,6 +100,7 @@ export default {
|
|||||||
this.editing = false
|
this.editing = false
|
||||||
this.saveData()
|
this.saveData()
|
||||||
this.$emit("editing", false)
|
this.$emit("editing", false)
|
||||||
|
this.$emit("reload")
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
updateEmoji: function (item, value) {
|
updateEmoji: function (item, value) {
|
||||||
@ -109,6 +110,7 @@ export default {
|
|||||||
},
|
},
|
||||||
saveData: function () {
|
saveData: function () {
|
||||||
let apiClient = new ApiApiFactory()
|
let apiClient = new ApiApiFactory()
|
||||||
|
console.log(this.book_copy)
|
||||||
|
|
||||||
apiClient
|
apiClient
|
||||||
.updateRecipeBook(this.book_copy.id, this.book_copy)
|
.updateRecipeBook(this.book_copy.id, this.book_copy)
|
||||||
|
@ -1,235 +1,223 @@
|
|||||||
<template>
|
<template>
|
||||||
<div v-bind:class="{ bounceright: bounce_right, bounceleft: bounce_left }">
|
<div v-bind:class="{ bounceright: bounce_right, bounceleft: bounce_left }">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col col-md-12 text-center pt-2 pb-4">
|
<div class="col col-md-12 text-center pt-2 pb-4">
|
||||||
<b-pagination pills
|
<b-pagination pills v-model="current_page" :total-rows="page_count_pagination" :per-page="per_page_count" @change="pageChange" first-text="📖" align="fill"> </b-pagination>
|
||||||
v-model="current_page"
|
</div>
|
||||||
:total-rows="page_count_pagination"
|
</div>
|
||||||
:per-page="per_page_count"
|
<div class="row" v-touch:swipe.left="swipeLeft" v-touch:swipe.right="swipeRight">
|
||||||
@change="pageChange"
|
<div class="col-md-1" @click="swipeRight" style="cursor: pointer"></div>
|
||||||
first-text="📖"
|
<div class="col-md-5">
|
||||||
align="fill">
|
<transition name="flip" mode="out-in">
|
||||||
|
<cookbook-edit-card :book="book" v-if="current_page === 1" v-on:editing="cookbook_editing = $event" v-on:refresh="$emit('refresh')" @reload="$emit('reload')"></cookbook-edit-card>
|
||||||
</b-pagination>
|
</transition>
|
||||||
</div>
|
<transition name="flip" mode="out-in">
|
||||||
|
<recipe-card :recipe="display_recipes[0].recipe_content" v-if="current_page > 1" :key="display_recipes[0].recipe"></recipe-card>
|
||||||
|
</transition>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-5">
|
||||||
|
<transition name="flip" mode="out-in">
|
||||||
|
<cookbook-toc :recipes="recipes" v-if="current_page === 1" v-on:switchRecipe="switchRecipe($event)"></cookbook-toc>
|
||||||
|
</transition>
|
||||||
|
<transition name="flip" mode="out-in">
|
||||||
|
<recipe-card :recipe="display_recipes[1].recipe_content" v-if="current_page > 1 && display_recipes.length === 2" :key="display_recipes[1].recipe"></recipe-card>
|
||||||
|
</transition>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-1" @click="swipeLeft" style="cursor: pointer"></div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row" v-touch:swipe.left="swipeLeft" v-touch:swipe.right="swipeRight">
|
|
||||||
<div class="col-md-1" @click="swipeRight" style="cursor: pointer;">
|
|
||||||
</div>
|
|
||||||
<div class="col-md-5">
|
|
||||||
<transition name="flip" mode="out-in">
|
|
||||||
<cookbook-edit-card :book="book" v-if="current_page === 1"
|
|
||||||
v-on:editing="cookbook_editing = $event"
|
|
||||||
v-on:refresh="$emit('refresh')"></cookbook-edit-card>
|
|
||||||
</transition>
|
|
||||||
<transition name="flip" mode="out-in">
|
|
||||||
<recipe-card :recipe="display_recipes[0].recipe_content"
|
|
||||||
v-if="current_page > 1" :key="display_recipes[0].recipe"></recipe-card>
|
|
||||||
</transition>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-5">
|
|
||||||
<transition name="flip" mode="out-in">
|
|
||||||
<cookbook-toc :recipes="recipes" v-if="current_page === 1"
|
|
||||||
v-on:switchRecipe="switchRecipe($event)"></cookbook-toc>
|
|
||||||
</transition>
|
|
||||||
<transition name="flip" mode="out-in">
|
|
||||||
<recipe-card :recipe="display_recipes[1].recipe_content"
|
|
||||||
v-if="current_page > 1 && display_recipes.length === 2"
|
|
||||||
:key="display_recipes[1].recipe"></recipe-card>
|
|
||||||
</transition>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-1" @click="swipeLeft" style="cursor: pointer;">
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import RecipeCard from "./RecipeCard"
|
||||||
import RecipeCard from "./RecipeCard";
|
import CookbookEditCard from "./CookbookEditCard"
|
||||||
import CookbookEditCard from "./CookbookEditCard";
|
import CookbookToc from "./CookbookToc"
|
||||||
import CookbookToc from "./CookbookToc";
|
|
||||||
import Vue2TouchEvents from "vue2-touch-events"
|
import Vue2TouchEvents from "vue2-touch-events"
|
||||||
import Vue from "vue";
|
import Vue from "vue"
|
||||||
import {ApiApiFactory} from "../utils/openapi/api";
|
import { ApiApiFactory } from "../utils/openapi/api"
|
||||||
|
|
||||||
Vue.use(Vue2TouchEvents)
|
Vue.use(Vue2TouchEvents)
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "CookbookSlider.vue",
|
name: "CookbookSlider.vue",
|
||||||
components: {CookbookToc, CookbookEditCard, RecipeCard},
|
components: { CookbookToc, CookbookEditCard, RecipeCard },
|
||||||
props: {
|
props: {
|
||||||
recipes: Array,
|
recipes: Array,
|
||||||
book: Object
|
book: Object,
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
page_count_pagination: function () {
|
|
||||||
return this.recipes.length + 2
|
|
||||||
},
|
},
|
||||||
page_count: function () {
|
computed: {
|
||||||
return Math.ceil(this.page_count_pagination / this.per_page_count)
|
page_count_pagination: function () {
|
||||||
}
|
return this.recipes.length + 2
|
||||||
},
|
},
|
||||||
data() {
|
page_count: function () {
|
||||||
return {
|
return Math.ceil(this.page_count_pagination / this.per_page_count)
|
||||||
display_recipes: [],
|
},
|
||||||
current_page: 1,
|
|
||||||
per_page_count: 2,
|
|
||||||
bounce_left: false,
|
|
||||||
bounce_right: false,
|
|
||||||
cookbook_editing: false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
pageChange: function (page) {
|
|
||||||
this.current_page = page
|
|
||||||
this.display_recipes = this.recipes.slice(((this.current_page - 1) - 1) * 2, (this.current_page - 1) * 2)
|
|
||||||
this.loadRecipeDetails(page)
|
|
||||||
},
|
},
|
||||||
loadRecipeDetails: function (page) {
|
data() {
|
||||||
this.display_recipes.forEach((recipe, index) => {
|
return {
|
||||||
let apiClient = new ApiApiFactory()
|
display_recipes: [],
|
||||||
|
current_page: 1,
|
||||||
|
per_page_count: 2,
|
||||||
|
bounce_left: false,
|
||||||
|
bounce_right: false,
|
||||||
|
cookbook_editing: false,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
pageChange: function (page) {
|
||||||
|
this.current_page = page
|
||||||
|
this.display_recipes = this.recipes.slice((this.current_page - 1 - 1) * 2, (this.current_page - 1) * 2)
|
||||||
|
this.loadRecipeDetails(page)
|
||||||
|
},
|
||||||
|
loadRecipeDetails: function (page) {
|
||||||
|
this.display_recipes.forEach((recipe, index) => {
|
||||||
|
let apiClient = new ApiApiFactory()
|
||||||
|
|
||||||
apiClient.retrieveRecipe(recipe.recipe).then(result => {
|
apiClient.retrieveRecipe(recipe.recipe).then((result) => {
|
||||||
let new_entry = Object.assign({}, recipe);
|
let new_entry = Object.assign({}, recipe)
|
||||||
new_entry.recipe_content = result.data
|
new_entry.recipe_content = result.data
|
||||||
this.$set(this.display_recipes, index, new_entry)
|
this.$set(this.display_recipes, index, new_entry)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
},
|
||||||
|
swipeLeft: function () {
|
||||||
|
if (this.cookbook_editing) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (this.current_page < this.page_count) {
|
||||||
|
this.pageChange(this.current_page + 1)
|
||||||
|
} else {
|
||||||
|
this.bounce_left = true
|
||||||
|
setTimeout(() => (this.bounce_left = false), 500)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
swipeRight: function () {
|
||||||
|
if (this.cookbook_editing) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (this.current_page > 1) {
|
||||||
|
this.pageChange(this.current_page - 1)
|
||||||
|
} else {
|
||||||
|
this.bounce_right = true
|
||||||
|
setTimeout(() => (this.bounce_right = false), 500)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
switchRecipe: function (index) {
|
||||||
|
this.pageChange(Math.ceil((index + 1) / this.per_page_count) + 1)
|
||||||
|
},
|
||||||
},
|
},
|
||||||
swipeLeft: function () {
|
directives: {
|
||||||
if (this.cookbook_editing) {
|
hover: {
|
||||||
return
|
inserted: function (el) {
|
||||||
}
|
el.addEventListener("mouseenter", () => {
|
||||||
if (this.current_page < this.page_count) {
|
el.classList.add("shadow")
|
||||||
this.pageChange(this.current_page + 1)
|
})
|
||||||
} else {
|
el.addEventListener("mouseleave", () => {
|
||||||
this.bounce_left = true
|
el.classList.remove("shadow")
|
||||||
setTimeout(() => this.bounce_left = false, 500);
|
})
|
||||||
}
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
swipeRight: function () {
|
|
||||||
if (this.cookbook_editing) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (this.current_page > 1) {
|
|
||||||
this.pageChange(this.current_page - 1)
|
|
||||||
} else {
|
|
||||||
this.bounce_right = true
|
|
||||||
setTimeout(() => this.bounce_right = false, 500);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
switchRecipe: function (index) {
|
|
||||||
this.pageChange(Math.ceil((index + 1) / this.per_page_count) + 1)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
directives: {
|
|
||||||
hover: {
|
|
||||||
inserted: function (el) {
|
|
||||||
el.addEventListener('mouseenter', () => {
|
|
||||||
el.classList.add("shadow")
|
|
||||||
});
|
|
||||||
el.addEventListener('mouseleave', () => {
|
|
||||||
el.classList.remove("shadow")
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.flip-enter-active {
|
.flip-enter-active {
|
||||||
-webkit-animation-name: bounceUp;
|
-webkit-animation-name: bounceUp;
|
||||||
animation-name: bounceUp;
|
animation-name: bounceUp;
|
||||||
-webkit-animation-duration: .5s;
|
-webkit-animation-duration: 0.5s;
|
||||||
animation-duration: .5s;
|
animation-duration: 0.5s;
|
||||||
-webkit-animation-fill-mode: both;
|
-webkit-animation-fill-mode: both;
|
||||||
animation-fill-mode: both;
|
animation-fill-mode: both;
|
||||||
-webkit-animation-timing-function: linear;
|
-webkit-animation-timing-function: linear;
|
||||||
animation-timing-function: linear;
|
animation-timing-function: linear;
|
||||||
animation-iteration-count: infinite;
|
animation-iteration-count: infinite;
|
||||||
-webkit-animation-iteration-count: infinite;
|
-webkit-animation-iteration-count: infinite;
|
||||||
}
|
}
|
||||||
|
|
||||||
.bounceleft {
|
.bounceleft {
|
||||||
-webkit-animation-name: bounceLeft;
|
-webkit-animation-name: bounceLeft;
|
||||||
animation-name: bounceLeft;
|
animation-name: bounceLeft;
|
||||||
-webkit-animation-duration: .5s;
|
-webkit-animation-duration: 0.5s;
|
||||||
animation-duration: .5s;
|
animation-duration: 0.5s;
|
||||||
-webkit-animation-fill-mode: both;
|
-webkit-animation-fill-mode: both;
|
||||||
animation-fill-mode: both;
|
animation-fill-mode: both;
|
||||||
-webkit-animation-timing-function: linear;
|
-webkit-animation-timing-function: linear;
|
||||||
animation-timing-function: linear;
|
animation-timing-function: linear;
|
||||||
animation-iteration-count: 1;
|
animation-iteration-count: 1;
|
||||||
-webkit-animation-iteration-count: 1;
|
-webkit-animation-iteration-count: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.bounceright {
|
.bounceright {
|
||||||
-webkit-animation-name: bounceRight;
|
-webkit-animation-name: bounceRight;
|
||||||
animation-name: bounceRight;
|
animation-name: bounceRight;
|
||||||
-webkit-animation-duration: .5s;
|
-webkit-animation-duration: 0.5s;
|
||||||
animation-duration: .5s;
|
animation-duration: 0.5s;
|
||||||
-webkit-animation-fill-mode: both;
|
-webkit-animation-fill-mode: both;
|
||||||
animation-fill-mode: both;
|
animation-fill-mode: both;
|
||||||
-webkit-animation-timing-function: linear;
|
-webkit-animation-timing-function: linear;
|
||||||
animation-timing-function: linear;
|
animation-timing-function: linear;
|
||||||
animation-iteration-count: 1;
|
animation-iteration-count: 1;
|
||||||
-webkit-animation-iteration-count: 1;
|
-webkit-animation-iteration-count: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@-webkit-keyframes bounceUp {
|
@-webkit-keyframes bounceUp {
|
||||||
0%, 100% {
|
0%,
|
||||||
-webkit-transform: translateY(0);
|
100% {
|
||||||
}
|
-webkit-transform: translateY(0);
|
||||||
50% {
|
}
|
||||||
-webkit-transform: translateY(-7px);
|
50% {
|
||||||
}
|
-webkit-transform: translateY(-7px);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes bounceUp {
|
@keyframes bounceUp {
|
||||||
0%, 100% {
|
0%,
|
||||||
transform: translateY(0);
|
100% {
|
||||||
}
|
transform: translateY(0);
|
||||||
50% {
|
}
|
||||||
transform: translateY(-7px);
|
50% {
|
||||||
}
|
transform: translateY(-7px);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@-webkit-keyframes bounceLeft {
|
@-webkit-keyframes bounceLeft {
|
||||||
0%, 100% {
|
0%,
|
||||||
-webkit-transform: translateY(0);
|
100% {
|
||||||
}
|
-webkit-transform: translateY(0);
|
||||||
50% {
|
}
|
||||||
-webkit-transform: translateX(-10px);
|
50% {
|
||||||
}
|
-webkit-transform: translateX(-10px);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes bounceLeft {
|
@keyframes bounceLeft {
|
||||||
0%, 100% {
|
0%,
|
||||||
transform: translateY(0);
|
100% {
|
||||||
}
|
transform: translateY(0);
|
||||||
50% {
|
}
|
||||||
transform: translateX(-10px);
|
50% {
|
||||||
}
|
transform: translateX(-10px);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@-webkit-keyframes bounceRight {
|
@-webkit-keyframes bounceRight {
|
||||||
0%, 100% {
|
0%,
|
||||||
-webkit-transform: translateY(0);
|
100% {
|
||||||
}
|
-webkit-transform: translateY(0);
|
||||||
50% {
|
}
|
||||||
-webkit-transform: translateX(10px);
|
50% {
|
||||||
}
|
-webkit-transform: translateX(10px);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes bounceRight {
|
@keyframes bounceRight {
|
||||||
0%, 100% {
|
0%,
|
||||||
transform: translateY(0);
|
100% {
|
||||||
}
|
transform: translateY(0);
|
||||||
50% {
|
}
|
||||||
transform: translateX(10px);
|
50% {
|
||||||
}
|
transform: translateX(10px);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
Reference in New Issue
Block a user