new meal plan widget
This commit is contained in:
parent
0dc6bed7ad
commit
961578385d
@ -90,7 +90,7 @@
|
|||||||
<b-form-group v-if="ui.show_meal_plan"
|
<b-form-group v-if="ui.show_meal_plan"
|
||||||
v-bind:label="$t('Meal_Plan_Days')"
|
v-bind:label="$t('Meal_Plan_Days')"
|
||||||
label-for="popover-input-5" label-cols="8" class="mb-1">
|
label-for="popover-input-5" label-cols="8" class="mb-1">
|
||||||
<b-form-input type="number" v-model="ui.meal_plan_days"
|
<b-form-input type="number" v-model.number="ui.meal_plan_days"
|
||||||
id="popover-input-5" size="sm"
|
id="popover-input-5" size="sm"
|
||||||
class="mt-1"></b-form-input>
|
class="mt-1"></b-form-input>
|
||||||
</b-form-group>
|
</b-form-group>
|
||||||
@ -830,34 +830,37 @@
|
|||||||
|
|
||||||
<template v-if="!searchFiltered() && ui.show_meal_plan">
|
<template v-if="!searchFiltered() && ui.show_meal_plan">
|
||||||
<hr/>
|
<hr/>
|
||||||
<div class="row" >
|
<div class="row">
|
||||||
|
|
||||||
<div class="col col-md-12">
|
<div class="col col-md-12">
|
||||||
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); column-gap: 0.5rem;row-gap: 1rem; grid-auto-rows: max-content; ">
|
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); column-gap: 0.5rem;row-gap: 1rem; grid-auto-rows: max-content; ">
|
||||||
<b-list-group v-for="day in meal_plan_grid" v-bind:key="day.day">
|
<div v-for="day in meal_plan_grid" v-bind:key="day.day">
|
||||||
<b-list-group-item>
|
<b-list-group v-if="day.plan_entries.length > 0 || !isMobile">
|
||||||
<div class="d-flex flex-row align-items-center">
|
<b-list-group-item>
|
||||||
<div>
|
<div class="d-flex flex-row align-items-center">
|
||||||
<h4>{{ day.date_label }}</h4>
|
<div>
|
||||||
|
<h4>{{ day.date_label }}</h4>
|
||||||
|
</div>
|
||||||
|
<div class="flex-grow-1 text-right">
|
||||||
|
<!--<b-button class=""><i class="fa fa-plus"></i></b-button>--> <!-- TODO need to rewrite meal plan edit modal to use store -->
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex-grow-1 text-right">
|
|
||||||
<b-button class=""><i class="fa fa-plus"></i></b-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</b-list-group-item>
|
</b-list-group-item>
|
||||||
<b-list-group-item v-for="plan in day.plan_entries" v-bind:key="plan.id">
|
<b-list-group-item v-for="plan in day.plan_entries" v-bind:key="plan.id">
|
||||||
<div class="d-flex flex-row align-items-center">
|
<div class="d-flex flex-row align-items-center">
|
||||||
<div>
|
<div>
|
||||||
<b-img style="height: 50px; width: 50px; object-fit: cover" :src="plan.recipe.image" rounded="circle"></b-img>
|
<b-img style="height: 50px; width: 50px; object-fit: cover" :src="plan.recipe.image" rounded="circle"></b-img>
|
||||||
|
</div>
|
||||||
|
<div class="flex-grow-1 ml-2" style="text-overflow: ellipsis; overflow-wrap: anywhere;">
|
||||||
|
<span class="two-row-text"><a :href="resolveDjangoUrl('view_recipe', plan.recipe.id)">{{ plan.recipe.name }}</a></span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex-grow-1 ml-2">
|
</b-list-group-item>
|
||||||
<span class="two-row-text">{{ plan.recipe.name }}</span>
|
|
||||||
</div>
|
</b-list-group>
|
||||||
</div>
|
</div>
|
||||||
</b-list-group-item>
|
|
||||||
|
|
||||||
</b-list-group>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -872,17 +875,18 @@
|
|||||||
<div class="col col-md-12">
|
<div class="col col-md-12">
|
||||||
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); column-gap: 0.5rem;row-gap: 1rem; grid-auto-rows: max-content; ">
|
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); column-gap: 0.5rem;row-gap: 1rem; grid-auto-rows: max-content; ">
|
||||||
|
|
||||||
<template v-if="!searchFiltered()">
|
<!-- TODO remove once new meal plan view has proven to be good -->
|
||||||
<recipe-card
|
<!-- <template v-if="!searchFiltered()">-->
|
||||||
v-bind:key="`mp_${m.id}`"
|
<!-- <recipe-card-->
|
||||||
v-for="m in meal_plans"
|
<!-- v-bind:key="`mp_${m.id}`"-->
|
||||||
:recipe="m.recipe"
|
<!-- v-for="m in meal_plans"-->
|
||||||
:meal_plan="m"
|
<!-- :recipe="m.recipe"-->
|
||||||
:use_plural="use_plural"
|
<!-- :meal_plan="m"-->
|
||||||
:footer_text="m.meal_type_name"
|
<!-- :use_plural="use_plural"-->
|
||||||
footer_icon="far fa-calendar-alt"
|
<!-- :footer_text="m.meal_type_name"-->
|
||||||
></recipe-card>
|
<!-- footer_icon="far fa-calendar-alt"-->
|
||||||
</template>
|
<!-- ></recipe-card>-->
|
||||||
|
<!-- </template>-->
|
||||||
|
|
||||||
<recipe-card v-for="r in recipes" v-bind:key="r.id" :recipe="r"
|
<recipe-card v-for="r in recipes" v-bind:key="r.id" :recipe="r"
|
||||||
:footer_text="isRecentOrNew(r)[0]"
|
:footer_text="isRecentOrNew(r)[0]"
|
||||||
@ -957,6 +961,7 @@ import RecipeCard from "@/components/RecipeCard"
|
|||||||
import GenericMultiselect from "@/components/GenericMultiselect"
|
import GenericMultiselect from "@/components/GenericMultiselect"
|
||||||
import RecipeSwitcher from "@/components/Buttons/RecipeSwitcher"
|
import RecipeSwitcher from "@/components/Buttons/RecipeSwitcher"
|
||||||
import {ApiApiFactory} from "@/utils/openapi/api"
|
import {ApiApiFactory} from "@/utils/openapi/api"
|
||||||
|
import {useMealPlanStore} from "@/stores/MealPlanStore";
|
||||||
|
|
||||||
Vue.use(VueCookies)
|
Vue.use(VueCookies)
|
||||||
Vue.use(BootstrapVue)
|
Vue.use(BootstrapVue)
|
||||||
@ -975,6 +980,7 @@ export default {
|
|||||||
recipes_loading: true,
|
recipes_loading: true,
|
||||||
facets: {Books: [], Foods: [], Keywords: []},
|
facets: {Books: [], Foods: [], Keywords: []},
|
||||||
meal_plans: [],
|
meal_plans: [],
|
||||||
|
meal_plan_store: null,
|
||||||
last_viewed_recipes: [],
|
last_viewed_recipes: [],
|
||||||
sortMenu: false,
|
sortMenu: false,
|
||||||
use_plural: false,
|
use_plural: false,
|
||||||
@ -1060,9 +1066,9 @@ export default {
|
|||||||
computed: {
|
computed: {
|
||||||
meal_plan_grid: function () {
|
meal_plan_grid: function () {
|
||||||
let grid = []
|
let grid = []
|
||||||
for (const x of Array(5).keys()) {
|
for (const x of Array(this.ui.meal_plan_days).keys()) {
|
||||||
let moment_date = moment().add(x, "d")
|
let moment_date = moment().add(x, "d")
|
||||||
grid.push({date: moment_date, date_label: moment_date.format('DD.MM'), plan_entries: this.meal_plans.filter((m) => moment(m.date).isSame(moment_date, 'day'))})
|
grid.push({date: moment_date, date_label: moment_date.format('DD.MM'), plan_entries: this.meal_plan_store.plans.filter((m) => moment(m.date).isSame(moment_date, 'day'))})
|
||||||
}
|
}
|
||||||
|
|
||||||
return grid
|
return grid
|
||||||
@ -1169,6 +1175,9 @@ export default {
|
|||||||
})
|
})
|
||||||
return sort_order
|
return sort_order
|
||||||
},
|
},
|
||||||
|
isMobile: function () { //TODO move to central helper
|
||||||
|
return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
|
||||||
@ -1306,21 +1315,26 @@ export default {
|
|||||||
return [...new Map(data.map((item) => [key(item), item])).values()]
|
return [...new Map(data.map((item) => [key(item), item])).values()]
|
||||||
},
|
},
|
||||||
loadMealPlan: function () {
|
loadMealPlan: function () {
|
||||||
if (this.ui.show_meal_plan) {
|
console.log('loadMealpLan')
|
||||||
let params = {
|
this.meal_plan_store = useMealPlanStore()
|
||||||
options: {
|
this.meal_plan_store.refreshFromAPI(moment().format("YYYY-MM-DD"), moment().add(this.ui.meal_plan_days, "days").format("YYYY-MM-DD"))
|
||||||
query: {
|
|
||||||
from_date: moment().format("YYYY-MM-DD"),
|
|
||||||
to_date: moment().add(this.ui.meal_plan_days, "days").format("YYYY-MM-DD"),
|
// if (this.ui.show_meal_plan) {
|
||||||
},
|
// let params = {
|
||||||
},
|
// options: {
|
||||||
}
|
// query: {
|
||||||
this.genericAPI(this.Models.MEAL_PLAN, this.Actions.LIST, params).then((result) => {
|
// from_date: moment().format("YYYY-MM-DD"),
|
||||||
this.meal_plans = result.data
|
// to_date: moment().add(this.ui.meal_plan_days, "days").format("YYYY-MM-DD"),
|
||||||
})
|
// },
|
||||||
} else {
|
// },
|
||||||
this.meal_plans = []
|
// }
|
||||||
}
|
// this.genericAPI(this.Models.MEAL_PLAN, this.Actions.LIST, params).then((result) => {
|
||||||
|
// this.meal_plans = result.data
|
||||||
|
// })
|
||||||
|
// } else {
|
||||||
|
// this.meal_plans = []
|
||||||
|
// }
|
||||||
},
|
},
|
||||||
genericSelectChanged: function (obj) {
|
genericSelectChanged: function (obj) {
|
||||||
if (obj.var.includes("::")) {
|
if (obj.var.includes("::")) {
|
||||||
|
@ -106,6 +106,7 @@ import ShoppingModal from "@/components/Modals/ShoppingModal"
|
|||||||
import moment from "moment"
|
import moment from "moment"
|
||||||
import Vue from "vue"
|
import Vue from "vue"
|
||||||
import {ApiApiFactory} from "@/utils/openapi/api"
|
import {ApiApiFactory} from "@/utils/openapi/api"
|
||||||
|
import {useMealPlanStore} from "@/stores/MealPlanStore";
|
||||||
|
|
||||||
Vue.prototype.moment = moment
|
Vue.prototype.moment = moment
|
||||||
|
|
||||||
@ -191,6 +192,7 @@ export default {
|
|||||||
apiClient
|
apiClient
|
||||||
.createMealPlan(entry)
|
.createMealPlan(entry)
|
||||||
.then((result) => {
|
.then((result) => {
|
||||||
|
useMealPlanStore().plans.push(result.data)
|
||||||
this.$bvModal.hide(`modal-meal-plan_${this.modal_id}`)
|
this.$bvModal.hide(`modal-meal-plan_${this.modal_id}`)
|
||||||
if (reviewshopping) {
|
if (reviewshopping) {
|
||||||
this.mealplan = result.data.id
|
this.mealplan = result.data.id
|
||||||
|
40
vue/src/stores/MealPlanStore.js
Normal file
40
vue/src/stores/MealPlanStore.js
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
import {defineStore} from 'pinia'
|
||||||
|
import {ApiApiFactory} from "@/utils/openapi/api";
|
||||||
|
import moment from "moment/moment";
|
||||||
|
|
||||||
|
|
||||||
|
const _STORE_ID = 'meal_plan_store'
|
||||||
|
|
||||||
|
/*
|
||||||
|
* test store to play around with pinia and see if it can work for my usecases
|
||||||
|
* dont trust that all mealplans are in store as there is no cache validation logic, its just a shared data holder
|
||||||
|
* */
|
||||||
|
export const useMealPlanStore = defineStore(_STORE_ID, {
|
||||||
|
state: () => ({
|
||||||
|
plans: [] //TODO convert to dict and add translation functions for easy editing
|
||||||
|
}),
|
||||||
|
getters: {
|
||||||
|
plan_list() {
|
||||||
|
let plan_list = []
|
||||||
|
for (let key in this.plans) {
|
||||||
|
plan_list.push(this.plans[key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
actions: {
|
||||||
|
refreshFromAPI(from_date, to_date) {
|
||||||
|
let options = {
|
||||||
|
query: {
|
||||||
|
from_date: from_date,
|
||||||
|
to_date: to_date,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
let apiClient = new ApiApiFactory()
|
||||||
|
|
||||||
|
apiClient.listMealPlans(options).then(r => {
|
||||||
|
this.plans = r.data
|
||||||
|
})
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
Loading…
Reference in New Issue
Block a user