basic pinia store
This commit is contained in:
parent
cb363d6321
commit
3af7e98216
@ -13,6 +13,7 @@
|
||||
"@popperjs/core": "^2.11.6",
|
||||
"@riophae/vue-treeselect": "^0.4.0",
|
||||
"@vue/cli": "^5.0.8",
|
||||
"@vue/composition-api": "1.7.1",
|
||||
"axios": "^1.2.0",
|
||||
"babel": "^6.23.0",
|
||||
"babel-core": "^6.26.3",
|
||||
@ -25,6 +26,7 @@
|
||||
"lodash": "^4.17.21",
|
||||
"mavon-editor": "^2.10.4",
|
||||
"moment": "^2.29.4",
|
||||
"pinia": "^2.0.30",
|
||||
"prismjs": "^1.29.0",
|
||||
"string-similarity": "^4.0.4",
|
||||
"vue": "^2.6.14",
|
||||
@ -42,7 +44,6 @@
|
||||
"vue-template-compiler": "2.6.14",
|
||||
"vue2-touch-events": "^3.2.2",
|
||||
"vuedraggable": "^2.24.3",
|
||||
"vuex": "^3.6.0",
|
||||
"workbox-webpack-plugin": "^6.5.4",
|
||||
"workbox-window": "^6.5.4"
|
||||
},
|
||||
|
@ -1,6 +1,7 @@
|
||||
import Vue from 'vue'
|
||||
import App from './RecipeView.vue'
|
||||
import i18n from "@/i18n";
|
||||
import {createPinia, PiniaVuePlugin} from 'pinia'
|
||||
|
||||
Vue.config.productionTip = false
|
||||
|
||||
@ -11,8 +12,11 @@ if (process.env.NODE_ENV === 'development') {
|
||||
}
|
||||
export default __webpack_public_path__ = publicPath // eslint-disable-line
|
||||
|
||||
Vue.use(PiniaVuePlugin)
|
||||
const pinia = createPinia()
|
||||
|
||||
new Vue({
|
||||
pinia,
|
||||
i18n,
|
||||
render: h => h(App),
|
||||
}).$mount('#app')
|
||||
|
@ -16,7 +16,7 @@
|
||||
<small tabindex="-1" class="form-text text-muted" v-if="!missing_recipe">{{ $t("Title") }}</small>
|
||||
</div>
|
||||
<div class="col-6 col-lg-3">
|
||||
<input type="date" id="DateInput" class="form-control" v-model="entryEditing.date" />
|
||||
<input type="date" id="DateInput" class="form-control" v-model="entryEditing.date"/>
|
||||
<small tabindex="-1" class="form-text text-muted">{{ $t("Date") }}</small>
|
||||
</div>
|
||||
</div>
|
||||
@ -75,11 +75,11 @@
|
||||
<small tabindex="-1" class="form-text text-muted">{{ $t("Share") }}</small>
|
||||
</b-form-group>
|
||||
<b-input-group v-if="!autoMealPlan">
|
||||
<b-form-checkbox id="AddToShopping" v-model="mealplan_settings.addshopping" />
|
||||
<b-form-checkbox id="AddToShopping" v-model="mealplan_settings.addshopping"/>
|
||||
<small tabindex="-1" class="form-text text-muted">{{ $t("AddToShopping") }}</small>
|
||||
</b-input-group>
|
||||
<b-input-group v-if="mealplan_settings.addshopping">
|
||||
<b-form-checkbox id="reviewShopping" v-model="mealplan_settings.reviewshopping" />
|
||||
<b-form-checkbox id="reviewShopping" v-model="mealplan_settings.reviewshopping"/>
|
||||
<small tabindex="-1" class="form-text text-muted">{{ $t("review_shopping") }}</small>
|
||||
</b-input-group>
|
||||
</div>
|
||||
@ -89,7 +89,7 @@
|
||||
</div>
|
||||
<div class="row mt-3 mb-3">
|
||||
<div class="col-12">
|
||||
<b-button variant="danger" @click="deleteEntry" v-if="allow_delete">{{ $t("Delete") }} </b-button>
|
||||
<b-button variant="danger" @click="deleteEntry" v-if="allow_delete">{{ $t("Delete") }}</b-button>
|
||||
<b-button class="float-right" variant="primary" @click="editEntry">{{ $t("Save") }}</b-button>
|
||||
</div>
|
||||
</div>
|
||||
@ -103,12 +103,14 @@
|
||||
<script>
|
||||
import Vue from "vue"
|
||||
import VueCookies from "vue-cookies"
|
||||
import { BootstrapVue } from "bootstrap-vue"
|
||||
import {BootstrapVue} from "bootstrap-vue"
|
||||
import GenericMultiselect from "@/components/GenericMultiselect"
|
||||
import { ApiMixin, getUserPreference } from "@/utils/utils"
|
||||
import {ApiMixin, getUserPreference} from "@/utils/utils"
|
||||
|
||||
const { ApiApiFactory } = require("@/utils/openapi/api")
|
||||
const { StandardToasts } = require("@/utils/utils")
|
||||
const {ApiApiFactory} = require("@/utils/openapi/api")
|
||||
const {StandardToasts} = require("@/utils/utils")
|
||||
|
||||
import {useUserPreferenceStore} from "@/stores/UserPreferenceStore";
|
||||
|
||||
Vue.use(BootstrapVue)
|
||||
Vue.use(VueCookies)
|
||||
@ -158,7 +160,8 @@ export default {
|
||||
deep: true,
|
||||
},
|
||||
entryEditing: {
|
||||
handler(newVal) {},
|
||||
handler(newVal) {
|
||||
},
|
||||
deep: true,
|
||||
},
|
||||
mealplan_settings: {
|
||||
@ -172,11 +175,11 @@ export default {
|
||||
},
|
||||
},
|
||||
mounted: function () {
|
||||
|
||||
useUserPreferenceStore().updateIfStaleOrEmpty()
|
||||
},
|
||||
computed: {
|
||||
autoMealPlan: function () {
|
||||
return getUserPreference("mealplan_autoadd_shopping")
|
||||
return useUserPreferenceStore().getStaleData()?.mealplan_autoadd_shopping
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
@ -184,15 +187,13 @@ export default {
|
||||
if (this.$cookies.isKey(MEALPLAN_COOKIE_NAME)) {
|
||||
this.mealplan_settings = Object.assign({}, this.mealplan_settings, this.$cookies.get(MEALPLAN_COOKIE_NAME))
|
||||
}
|
||||
let apiClient = new ApiApiFactory()
|
||||
|
||||
apiClient.listUserPreferences().then((result) => {
|
||||
useUserPreferenceStore().getData().then(userPreference => {
|
||||
if (this.entry.id === -1) {
|
||||
this.entryEditing.shared = result.data[0].plan_share
|
||||
this.entryEditing.shared = userPreference.plan_share
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
editEntry() {
|
||||
this.missing_meal_type = false
|
||||
this.missing_recipe = false
|
||||
@ -207,7 +208,7 @@ export default {
|
||||
}
|
||||
if (!cancel) {
|
||||
this.$bvModal.hide(`edit-modal`)
|
||||
this.$emit("save-entry", { ...this.mealplan_settings, ...this.entryEditing, ...{ addshopping: this.mealplan_settings.addshopping && !this.autoMealPlan } })
|
||||
this.$emit("save-entry", {...this.mealplan_settings, ...this.entryEditing, ...{addshopping: this.mealplan_settings.addshopping && !this.autoMealPlan}})
|
||||
}
|
||||
},
|
||||
deleteEntry() {
|
||||
|
33
vue/src/stores/BaseStorePlugin.js
Normal file
33
vue/src/stores/BaseStorePlugin.js
Normal file
@ -0,0 +1,33 @@
|
||||
|
||||
|
||||
|
||||
https://pinia.vuejs.org/core-concepts/plugins.html#adding-new-state
|
||||
|
||||
|
||||
export function BaseStorePlugin () {
|
||||
return {
|
||||
collection: [],
|
||||
item: {},
|
||||
getCollection: function (url) {
|
||||
api.get(url)
|
||||
.then((response) => {
|
||||
this.collection = response.data;
|
||||
})
|
||||
.catch((error) => {
|
||||
this.handleError(error);
|
||||
});
|
||||
},
|
||||
getItem: function (url) {
|
||||
api.get(url)
|
||||
.then((response) => {
|
||||
this.item = response.data;
|
||||
})
|
||||
.catch((error) => {
|
||||
this.handleError(error);
|
||||
});
|
||||
},
|
||||
handleError: function (error) {
|
||||
window.alert(error);
|
||||
},
|
||||
};
|
||||
}
|
78
vue/src/stores/UserPreferenceStore.js
Normal file
78
vue/src/stores/UserPreferenceStore.js
Normal file
@ -0,0 +1,78 @@
|
||||
import {defineStore} from 'pinia'
|
||||
|
||||
|
||||
import {ApiApiFactory} from "@/utils/openapi/api";
|
||||
|
||||
const _STALE_TIME_IN_MS = 1000 * 30
|
||||
const _STORE_ID = 'user_preference_store'
|
||||
export const useUserPreferenceStore = defineStore(_STORE_ID, {
|
||||
state: () => ({
|
||||
data: null,
|
||||
updated_at: null,
|
||||
}),
|
||||
getters: {
|
||||
|
||||
},
|
||||
actions: {
|
||||
/**
|
||||
* gets data from the store either directly or refreshes from API if data is considered stale
|
||||
* @returns {UserPreference|*|Promise<axios.AxiosResponse<UserPreference>>}
|
||||
*/
|
||||
getData: function () {
|
||||
if (this.isStaleOrEmpty) {
|
||||
return this.refreshFromAPI()
|
||||
} else {
|
||||
return this.data
|
||||
}
|
||||
},
|
||||
/**
|
||||
* get data from store. Does not use API, if store is not initialized returns null.
|
||||
* @returns {null|UserPreference|*}
|
||||
*/
|
||||
getStaleData: function () {
|
||||
return this.data
|
||||
},
|
||||
/**
|
||||
* checks if update timestamp is older than configured stale time interval
|
||||
* @returns {boolean} true if data is considered stale and should be updated
|
||||
*/
|
||||
isStale() {
|
||||
return this.updated_at === null || ((new Date()) - this.updated_at) > _STALE_TIME_IN_MS;
|
||||
},
|
||||
/**
|
||||
* checks if data of store is empty/not initialized
|
||||
* @returns {boolean} true if store is empty
|
||||
*/
|
||||
isEmpty() {
|
||||
return this.data === null
|
||||
},
|
||||
/**
|
||||
* checks if store is empty or data is considered stale, see isStale() and isEmpty()
|
||||
* @returns {boolean}
|
||||
*/
|
||||
isStaleOrEmpty() {
|
||||
return this.isStale() || this.isEmpty()
|
||||
},
|
||||
/**
|
||||
* refreshes store data if isStaleOrEmpty() is true
|
||||
* @returns {Promise<axios.AxiosResponse<UserPreference>>} returns promise with data
|
||||
*/
|
||||
updateIfStaleOrEmpty() {
|
||||
if (this.isStaleOrEmpty) {
|
||||
return this.refreshFromAPI()
|
||||
}
|
||||
},
|
||||
/**
|
||||
* refreshes store data from API
|
||||
* @returns {Promise<axios.AxiosResponse<UserPreference>>} returns promise with data
|
||||
*/
|
||||
refreshFromAPI() {
|
||||
let apiClient = new ApiApiFactory()
|
||||
return apiClient.retrieveUserPreference(localStorage.getItem('USER_ID')).then(r => {
|
||||
this.data = r.data
|
||||
this.updated_at = new Date()
|
||||
return this.data
|
||||
})
|
||||
},
|
||||
},
|
||||
})
|
0
vue/src/stores/root.js
Normal file
0
vue/src/stores/root.js
Normal file
Loading…
Reference in New Issue
Block a user