Remove vuex

This commit is contained in:
2022-02-10 15:49:21 +00:00
parent 8b0e368d58
commit c693625e34
21 changed files with 322 additions and 351 deletions

28
web/src/stores/api.ts Normal file
View File

@ -0,0 +1,28 @@
import { defineStore } from "pinia";
import { useSessionStore } from "./session";
export const useAPI = defineStore("api", {
actions: {
GET(path : string) {
const sessionStore = useSessionStore();
return fetch("/api/v1" + path, {
headers: sessionStore.AuthHeaders,
})
},
POST(path : string, body : FormData | string | null) {
const sessionStore = useSessionStore();
return fetch("/api/v1" + path, {
method: "POST",
headers: sessionStore.AuthHeaders,
body: body,
})
},
DELETE(path : string) {
const sessionStore = useSessionStore();
return fetch("/api/v1" + path, {
method: "DELETE",
headers: sessionStore.AuthHeaders,
})
},
}
});

View File

@ -0,0 +1,111 @@
import { defineStore } from "pinia"
import { FETCH_ACCOUNT } from "../store/action-types";
import { useAPI } from "./api";
import { useSessionStore } from "./session";
interface State {
Accounts: Map<string, Account>,
CurrentAccountID: string | null,
Categories: Map<string, Category>,
Months: Map<number, Map<number, Map<string, Category>>>,
Transactions: [],
Assignments: []
}
export interface Account {
ID: string
Name: string
OnBudget: boolean
Balance: Number
}
export interface Category {
ID: string
Group: string
Name: string
AvailableLastMonth: number
Assigned: number
Activity: number
Available: number
}
export const useAccountStore = defineStore("budget/account", {
state: (): State => ({
Accounts: new Map<string, Account>(),
CurrentAccountID: null,
Months: new Map<number, Map<number, Map<string, Category>>>(),
Categories: new Map<string, Category>(),
Transactions: [],
Assignments: []
}),
getters: {
AccountsList(state) {
return state.Accounts.values();
},
Categories: (state) => (year : number, month : number) => {
const yearMap = state.Months.get(year);
return yearMap?.get(month)?.values();
},
CurrentAccount(state) : Account | undefined {
if (state.CurrentAccountID == null)
return undefined;
return state.Accounts.get(state.CurrentAccountID);
},
OnBudgetAccounts(state) {
return Array.from(state.Accounts.values()).filter(x => x.OnBudget);
},
OnBudgetAccountsBalance(state) : Number {
return this.OnBudgetAccounts.reduce((prev, curr) => prev + Number(curr.Balance), 0);
},
OffBudgetAccounts(state) {
return Array.from(state.Accounts.values()).filter(x => !x.OnBudget);
},
OffBudgetAccountsBalance(state) : Number {
return this.OffBudgetAccounts.reduce((prev, curr) => prev + Number(curr.Balance), 0);
},
Transactions(state) {
return (state.Transactions || []);
}
},
actions: {
async SetCurrentAccount(budgetid : string, accountid : string) {
if (budgetid == null)
return
this.CurrentAccountID = accountid;
if (this.CurrentAccount == undefined)
return
useSessionStore().setTitle(this.CurrentAccount.Name);
await this.FetchAccount(accountid);
},
async FetchAccount(accountid : string) {
const api = useAPI();
const result = await api.GET("/api/v1/account/" + accountid + "/transactions");
const response = await result.json();
this.Transactions = response.Transactions;
},
async FetchMonthBudget(budgetid : string, month : number, year : number) {
const api = useAPI();
const result = await api.GET("/budget/" + budgetid + "/" + year + "/" + month);
const response = await result.json();
this.addCategoriesForMonth(year, month, response.Categories);
},
addCategoriesForMonth(year : number, month : number, categories : Category[]) : void {
const yearMap = this.Months.get(year) || new Map<number, Map<string, Category>>();
this.Months.set(year, yearMap);
const monthMap = yearMap.get(month) || new Map<string, Category>();
yearMap.set(month, monthMap);
for (const category of categories){
monthMap.set(category.ID, category);
}
},
logout() {
this.$reset()
},
}
})

View File

@ -1,5 +1,6 @@
import { defineStore } from "pinia";
import { useAPI } from "./api";
import { useAccountStore } from "./budget-account";
import { Budget, useSessionStore } from "./session";
interface State {
@ -8,35 +9,29 @@ interface State {
export const useBudgetsStore = defineStore('budget', {
state: (): State => ({
CurrentBudgetID: null
CurrentBudgetID: null,
}),
actions: {
setCurrentBudgetID(budgetid : string) {
this.CurrentBudgetID = budgetid;
},
},
getters: {
CurrentBudget() : Budget | undefined {
CurrentBudget(): Budget | undefined {
if (this.CurrentBudgetID == null)
return undefined;
const sessionStore = useSessionStore();
return sessionStore.Budgets.get(this.CurrentBudgetID);
},
CurrentBudgetName() : string {
CurrentBudgetName(state): string {
return this.CurrentBudget?.Name ?? "";
},
CurrentBudgetID() : string | undefined {
return this.CurrentBudgetID;
},
ImportYNAB(formData) {
},
actions: {
ImportYNAB(formData: FormData) {
const api = useAPI();
return api.POST(
"/budget/" + this.CurrentBudgetID + "/import/ynab",
formData
"/budget/" + this.CurrentBudgetID + "/import/ynab",
formData,
);
},
async NewBudget(budgetName) {
async NewBudget(budgetName: string): Promise<void> {
const api = useAPI();
const result = await api.POST(
"/budget/new",
@ -47,13 +42,24 @@ export const useBudgetsStore = defineStore('budget', {
const sessionStore = useSessionStore();
sessionStore.Budgets.set(response.ID, response);
},
async SetCurrentBudget(budgetid : string) {
async SetCurrentBudget(budgetid: string): Promise<void> {
this.CurrentBudgetID = budgetid;
if (budgetid == null)
return
await dispatch(FETCH_BUDGET, budgetid)
await this.FetchBudget(budgetid);
},
async FetchBudget(budgetid: string) {
const api = useAPI();
const result = await api.GET("/budget/" + budgetid);
const response = await result.json();
for (const account of response.Accounts || []) {
useAccountStore().Accounts.set(account.ID, account);
}
for (const category of response.Categories || []) {
useAccountStore().Categories.set(category.ID, category);
}
},
}
})

View File

@ -20,35 +20,9 @@ export const useSessionStore = defineStore('session', {
Budgets: new Map<string, Budget>(),
}),
getters: {
Budgets(): IterableIterator<Budget> {
return this.Budgets.values();
},
AuthHeaders(): HeadersInit {
return {
'Authorization': 'Bearer ' + this.Token
}
},
/*// 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
// }
}*/
BudgetsList: (state) => state.Budgets.values(),
AuthHeaders: (state) => ({'Authorization': 'Bearer ' + state.Token}),
LoggedIn: (state) => state.Token != null,
},
actions: {
setTitle(title : string) {