properly reactive meal plan store with dict

This commit is contained in:
vabene1111 2023-02-18 19:13:32 +01:00
parent 9167261714
commit 83947e31aa
3 changed files with 74 additions and 34 deletions

View File

@ -797,7 +797,8 @@
<div class="col-12 col-xl-10 col-lg-10 offset-xl-1 offset-lg-1">
<div style="overflow-x:visible; overflow-y: hidden;white-space: nowrap;">
<b-dropdown id="sortby" :text="sortByLabel" variant="outline-primary" size="sm" style="overflow-y: visible; overflow-x: visible; position: static"
<b-dropdown id="sortby" :text="sortByLabel" variant="outline-primary" size="sm"
style="overflow-y: visible; overflow-x: visible; position: static"
class="shadow-none" toggle-class="text-decoration-none">
<div v-for="o in sortOptions" :key="o.id">
<b-dropdown-item
@ -833,7 +834,8 @@
<div class="row">
<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; ">
<div v-for="day in meal_plan_grid" v-bind:key="day.day">
<b-list-group v-if="day.plan_entries.length > 0 || !isMobile">
<b-list-group-item>
@ -842,7 +844,8 @@
<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 -->
<!--<b-button class=""><i class="fa fa-plus"></i></b-button>-->
<!-- TODO need to rewrite meal plan edit modal to use store -->
</div>
</div>
@ -850,10 +853,15 @@
<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>
<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 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>
</b-list-group-item>
@ -873,7 +881,8 @@
<div v-if="recipes.length > 0" class="mt-4">
<div class="row">
<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; ">
<!-- TODO remove once new meal plan view has proven to be good -->
<!-- <template v-if="!searchFiltered()">-->
@ -899,7 +908,8 @@
<div class="row" style="margin-top: 2vh" v-if="!random_search">
<div class="col col-md-12">
<b-pagination v-model="search.pagination_page" :total-rows="pagination_count" first-number last-number size="lg"
<b-pagination v-model="search.pagination_page" :total-rows="pagination_count" first-number
last-number size="lg"
:per-page="ui.page_size" @change="pageChange" align="center"></b-pagination>
</div>
</div>
@ -1069,11 +1079,16 @@ export default {
computed: {
meal_plan_grid: function () {
let grid = []
if (this.meal_plan_store !== null && this.meal_plan_store.plan_list.length > 0) {
for (const x of Array(this.ui.meal_plan_days).keys()) {
let moment_date = moment().add(x, "d")
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'))})
grid.push({
date: moment_date,
date_label: moment_date.format('DD.MM'),
plan_entries: this.meal_plan_store.plan_list.filter((m) => moment(m.date).isSame(moment_date, 'day'))
})
}
}
return grid
},
locale: function () {

View File

@ -1,28 +1,31 @@
import {defineStore} from 'pinia'
import {ApiApiFactory} from "@/utils/openapi/api";
import moment from "moment/moment";
const _STORE_ID = 'meal_plan_store'
import Vue from "vue"
/*
* 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
plans: {},
currently_updating: null,
}),
getters: {
plan_list() {
plan_list: function () {
let plan_list = []
for (let key in this.plans) {
plan_list.push(this.plans[key]);
}
return plan_list
}
},
actions: {
refreshFromAPI(from_date, to_date) {
if (this.currently_updating !== [from_date, to_date]) {
this.currently_updating = [from_date, to_date] // certainly no perfect check but better than nothing
let options = {
query: {
from_date: from_date,
@ -31,10 +34,14 @@ export const useMealPlanStore = defineStore(_STORE_ID, {
}
let apiClient = new ApiApiFactory()
apiClient.listMealPlans(options).then(r => {
this.plans = r.data
r.data.forEach((p) => {
Vue.set(this.plans, p.id, p)
})
this.currently_updating = null
})
}
},
},
})

View File

@ -2430,6 +2430,16 @@
optionalDependencies:
prettier "^1.18.2 || ^2.0.0"
"@vue/composition-api@1.7.1":
version "1.7.1"
resolved "https://registry.yarnpkg.com/@vue/composition-api/-/composition-api-1.7.1.tgz#aa6831be5a12817d93e89e247460c310dd7a3a32"
integrity sha512-xDWoEtxGXhH9Ku3ROYX/rzhcpt4v31hpPU5zF3UeVC/qxA3dChmqU8zvTUYoKh3j7rzpNsoFOwqsWG7XPMlaFA==
"@vue/devtools-api@^6.4.5":
version "6.5.0"
resolved "https://registry.yarnpkg.com/@vue/devtools-api/-/devtools-api-6.5.0.tgz#98b99425edee70b4c992692628fa1ea2c1e57d07"
integrity sha512-o9KfBeaBmCKl10usN4crU53fYtC1r7jJwdGKjPT24t348rHxgfpZ0xL3Xm/gLUYnc0oTp8LAmrxOeLyu6tbk2Q==
"@vue/eslint-config-typescript@^10.0.0":
version "10.0.0"
resolved "https://registry.yarnpkg.com/@vue/eslint-config-typescript/-/eslint-config-typescript-10.0.0.tgz#3b63c8cf276962cb89414857581b9b424acf2820"
@ -8642,6 +8652,14 @@ pify@^4.0.1:
resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231"
integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==
pinia@^2.0.30:
version "2.0.30"
resolved "https://registry.yarnpkg.com/pinia/-/pinia-2.0.30.tgz#b18a581dad6821ed5fbebfaf631229480ea9d2d9"
integrity sha512-q6DUmxWwe/mQgg+55QQjykpKC+aGeGdaJV3niminl19V08dE+LRTvSEuqi6/NLSGCKHI49KGL6tMNEOssFiMyA==
dependencies:
"@vue/devtools-api" "^6.4.5"
vue-demi "*"
pinkie-promise@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa"
@ -11140,6 +11158,11 @@ vue-cookies@^1.8.2:
resolved "https://registry.yarnpkg.com/vue-cookies/-/vue-cookies-1.8.2.tgz#39515fa09ebb585a50ac86c0e182a6b9307dc6ad"
integrity sha512-+NfoC5l+7ybuVwpnqsf52qndnoYMjEb4EFhX4/j9RzzQP00dNzuJELsWuW2p8omNUzNlSgWGVyyWoOeJr347tw==
vue-demi@*:
version "0.13.11"
resolved "https://registry.yarnpkg.com/vue-demi/-/vue-demi-0.13.11.tgz#7d90369bdae8974d87b1973564ad390182410d99"
integrity sha512-IR8HoEEGM65YY3ZJYAjMlKygDQn25D5ajNFNoKh9RSDMQtlzCxtfQjdQgv9jjK+m3377SsJXY8ysq8kLCZL25A==
vue-eslint-parser@^8.0.0, vue-eslint-parser@^8.0.1:
version "8.3.0"
resolved "https://registry.yarnpkg.com/vue-eslint-parser/-/vue-eslint-parser-8.3.0.tgz#5d31129a1b3dd89c0069ca0a1c88f970c360bd0d"
@ -11260,11 +11283,6 @@ vuedraggable@^2.24.3:
dependencies:
sortablejs "1.10.2"
vuex@^3.6.0:
version "3.6.2"
resolved "https://registry.yarnpkg.com/vuex/-/vuex-3.6.2.tgz#236bc086a870c3ae79946f107f16de59d5895e71"
integrity sha512-ETW44IqCgBpVomy520DT5jf8n0zoCac+sxWnn+hMe/CzaSejb/eVw2YToiXYX+Ex/AuHHia28vWTq4goAexFbw==
watch-size@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/watch-size/-/watch-size-2.0.0.tgz#096ee28d0365bd7ea03d9c8bf1f2f50a73be1474"
@ -11587,7 +11605,7 @@ word-wrap@^1.2.3:
resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c"
integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==
workbox-background-sync@6.5.4:
workbox-background-sync@6.5.4, workbox-background-sync@^6.5.4:
version "6.5.4"
resolved "https://registry.yarnpkg.com/workbox-background-sync/-/workbox-background-sync-6.5.4.tgz#3141afba3cc8aa2ae14c24d0f6811374ba8ff6a9"
integrity sha512-0r4INQZMyPky/lj4Ou98qxcThrETucOde+7mRGJl13MPJugQNKeZQOdIJe/1AchOP23cTqHcN/YVpD6r8E6I8g==
@ -11894,7 +11912,7 @@ workbox-webpack-plugin@^6.5.4:
webpack-sources "^1.4.3"
workbox-build "6.5.4"
workbox-window@6.5.4:
workbox-window@6.5.4, workbox-window@^6.5.4:
version "6.5.4"
resolved "https://registry.yarnpkg.com/workbox-window/-/workbox-window-6.5.4.tgz#d991bc0a94dff3c2dbb6b84558cff155ca878e91"
integrity sha512-HnLZJDwYBE+hpG25AQBO8RUWBJRaCsI9ksQJEp3aCOFCaG5kqaToAYXFRAHxzRluM2cQbGzdQF5rjKPWPA1fug==