Remove vuex
This commit is contained in:
28
web/src/stores/api.ts
Normal file
28
web/src/stores/api.ts
Normal 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,
|
||||
})
|
||||
},
|
||||
}
|
||||
});
|
111
web/src/stores/budget-account.ts
Normal file
111
web/src/stores/budget-account.ts
Normal 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()
|
||||
},
|
||||
}
|
||||
|
||||
})
|
@ -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);
|
||||
}
|
||||
},
|
||||
}
|
||||
})
|
@ -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) {
|
||||
|
Reference in New Issue
Block a user