First step from vuex to pinia

This commit is contained in:
2022-02-09 23:08:36 +00:00
parent 2137460187
commit 2d0737a10c
8 changed files with 147 additions and 86 deletions

View File

@ -21,7 +21,22 @@ export default defineComponent({
}
},
beforeCreate () {
this.$store.commit("initializeStore");
const store = localStorage.getItem("store");
if (!store)
return;
const restoredState = JSON.parse(store);
if (!restoredState)
return;
state.Session = restoredState.Session;
state.CurrentBudgetID = restoredState.CurrentBudgetID;
state.ShowMenu = restoredState.ShowMenu;
state.ExpandMenu = restoredState.ExpandMenu;
for (const budget of restoredState.Budgets || []) {
state.Budgets.set(budget[0], budget[1]);
}
}
})
</script>

View File

@ -2,12 +2,12 @@ import { createApp } from 'vue'
import App from './App.vue'
import './index.css'
import router from './router'
import { store, key } from './store'
import { createPinia } from 'pinia'
import { SET_CURRENT_ACCOUNT, SET_CURRENT_BUDGET } from './store/action-types'
const app = createApp(App)
app.use(router)
app.use(store, key)
app.use(createPinia())
app.mount('#app')
router.beforeEach(async (to, from, next) => {

View File

@ -3,98 +3,21 @@ import { createStore, Store, createLogger } from 'vuex'
import { LOGIN_SUCCESS, LOGOUT, TITLE } from './mutation-types'
import { FETCH_ACCOUNT, FETCH_BUDGET, GET, REGISTER, IMPORT_YNAB, LOGIN, NEW_BUDGET, POST, SET_CURRENT_ACCOUNT, SET_CURRENT_BUDGET } from './action-types'
import { budgetStore } from './budget'
export interface State {
Session: {
Token?: string
User?: string
},
ShowMenu?: boolean,
ExpandMenu?: boolean,
Budgets: Map<string, Budget>,
CurrentBudgetID?: string,
}
export interface Budget {
ID: string
Name: string
AvailableBalance: number
}
import { Budget, useSessionStore } from '../stores/session'
export const key: InjectionKey<Store<State>> = Symbol()
export const store = createStore<State>({
state: {
Session: {
Token: undefined,
User: undefined
},
ShowMenu: undefined,
Budgets: new Map<string, Budget>(),
CurrentBudgetID: undefined,
},
mutations: {
deleteBudget(state: State, budgetid: string) {
state.Budgets.delete(budgetid)
},
toggleMenu(state) {
state.ShowMenu = !state.ShowMenu;
},
toggleMenuSize(state) {
state.ExpandMenu = !state.ExpandMenu;
},
initializeStore(state) {
const store = localStorage.getItem("store");
if (!store)
return;
const restoredState = JSON.parse(store);
if (!restoredState)
return;
state.Session = restoredState.Session;
state.CurrentBudgetID = restoredState.CurrentBudgetID;
state.ShowMenu = restoredState.ShowMenu;
state.ExpandMenu = restoredState.ExpandMenu;
for (const budget of restoredState.Budgets || []) {
state.Budgets.set(budget[0], budget[1]);
}
},
[TITLE](state, title) {
document.title = "Budgeteer - " + title;
},
[LOGIN_SUCCESS](state, result) {
state.Session = {
User: result.User,
Token: result.Token
};
for (const budget of result.Budgets) {
state.Budgets.set(budget.ID, budget)
}
},
addBudget(state, budget) {
state.Budgets.set(budget.ID, budget);
},
[LOGOUT](state) {
state.Session = { Token: undefined, User: undefined };
state.Budgets.clear();
},
setCurrentBudgetID(state, budgetid) {
state.CurrentBudgetID = budgetid;
},
},
actions: {
[LOGIN]({ state, commit }, login) {
return fetch("/api/v1/user/login", { method: "POST", body: JSON.stringify(login) })
.then(x => x.json())
.then(x => commit(LOGIN_SUCCESS, x))
},
[REGISTER]({ state, commit }, login) {
return fetch("/api/v1/user/register", { method: "POST", body: JSON.stringify(login) })
.then(x => x.json())
.then(x => commit(LOGIN_SUCCESS, x))
},
[IMPORT_YNAB]({ getters, dispatch }, formData) {
return dispatch("POST", { path: "/budget/" + getters.CurrentBudget.ID + "/import/ynab", body: formData });
},
@ -137,9 +60,6 @@ export const store = createStore<State>({
},
},
getters: {
Budgets(state) {
return state.Budgets.values();
},
AuthHeaders(state) {
return {
'Authorization': 'Bearer ' + state.Session.Token
@ -171,9 +91,10 @@ export const store = createStore<State>({
})
store.subscribe((mutation, state) => {
const sessionStore = useSessionStore();
let persistedState = {
Session: state.Session,
Budgets: [...state.Budgets],
Session: sessionStore,
// Accounts: [...state.Accounts],
CurrentBudgetID: state.CurrentBudgetID,
//CurrentAccountID: state.CurrentAccountID,

16
web/src/stores/budgets.ts Normal file
View File

@ -0,0 +1,16 @@
import { defineStore } from "pinia";
interface State {
CurrentBudgetID: string | null,
}
export const useBudgetsStore = defineStore('budget', {
state: (): State => ({
CurrentBudgetID: null
}),
actions: {
setCurrentBudgetID(budgetid : string) {
this.CurrentBudgetID = budgetid;
},
}
})

69
web/src/stores/session.ts Normal file
View File

@ -0,0 +1,69 @@
import { defineStore } from 'pinia'
interface State {
Token: string | null
User: string | null
Budgets: Map<string, Budget>,
}
export interface Budget {
ID: string
Name: string
AvailableBalance: number
}
export const useSessionStore = defineStore('session', {
// convert to a function
state: (): State => ({
Token: null,
User: null,
Budgets: new Map<string, Budget>(),
}),
getters: {
Budgets(): IterableIterator<Budget> {
return this.Budgets.values();
},
/*// must define return type because of using `this`
fullUserDetails (state): FullUserDetails {
// import from other stores
const authPreferencesStore = useAuthPreferencesStore()
const authEmailStore = useAuthEmailStore()
return {
...state,
// other getters now on `this`
fullName: this.fullName,
...authPreferencesStore.$state,
...authEmailStore.details
}
// alternative if other modules are still in Vuex
// return {
// ...state,
// fullName: this.fullName,
// ...vuexStore.state.auth.preferences,
// ...vuexStore.getters['auth/email'].details
// }
}*/
},
actions: {
loginSuccess(x : any) {
this.User = x.User;
this.Token = x.Token;
this.Budgets = x.Budgets;
},
login(login: any) {
return fetch("/api/v1/user/login", { method: "POST", body: JSON.stringify(login) })
.then(x => x.json())
.then(x => this.loginSuccess(x));
},
register(login : any) {
return fetch("/api/v1/user/register", { method: "POST", body: JSON.stringify(login) })
.then(x => x.json())
.then(x => this.loginSuccess(x))
},
// easily reset state using `$reset`
logout() {
this.$reset()
}
}
})

View File

@ -0,0 +1,21 @@
import { defineStore } from "pinia";
interface State {
ShowMenu?: boolean,
ExpandMenu?: boolean,
}
export const useSettingsStore = defineStore('settings', {
state: (): State => ({
ShowMenu: undefined,
ExpandMenu: false,
}),
actions: {
toggleMenu() {
this.ShowMenu = !this.ShowMenu;
},
toggleMenuSize() {
this.ExpandMenu = !this.ExpandMenu;
},
}
});