[pinia] Some work on balance store

This commit is contained in:
Ferdinand Thiessen 2021-02-03 13:35:31 +01:00
parent 544d58889b
commit 0922d468d9
6 changed files with 43 additions and 233 deletions

View File

@ -95,7 +95,6 @@ function combineMainLinks(
): FG_Plugin.PluginMainLink[] { ): FG_Plugin.PluginMainLink[] {
const targetPluginMainLink: FG_Plugin.PluginMainLink | undefined = target.find( const targetPluginMainLink: FG_Plugin.PluginMainLink | undefined = target.find(
(targetPluginMainLink: FG_Plugin.PluginMainLink) => { (targetPluginMainLink: FG_Plugin.PluginMainLink) => {
console.log(targetPluginMainLink.title, source.title);
return targetPluginMainLink.title == source.title; return targetPluginMainLink.title == source.title;
} }
); );
@ -173,7 +172,6 @@ function loadPlugin(
loadedPlugins.mainLinks = combineMainLinks(loadedPlugins.mainLinks, route); loadedPlugins.mainLinks = combineMainLinks(loadedPlugins.mainLinks, route);
}); });
loadedPlugins.shortcuts = loadShortCuts(loadedPlugins.shortcuts, plugin.mainRoutes); loadedPlugins.shortcuts = loadShortCuts(loadedPlugins.shortcuts, plugin.mainRoutes);
console.log(loadedPlugins);
} }
if (plugin.outRoutes) { if (plugin.outRoutes) {
loadedPlugins.routes = combineRoutes(loadedPlugins.routes, plugin.outRoutes); loadedPlugins.routes = combineRoutes(loadedPlugins.routes, plugin.outRoutes);
@ -208,7 +206,7 @@ async function getBackend(): Promise<Backend | null> {
const response: AxiosResponse<Backend> = await api.get('/'); const response: AxiosResponse<Backend> = await api.get('/');
backend = response.data; backend = response.data;
} catch (e) { } catch (e) {
console.log(e); console.warn(e);
return null; return null;
} finally { } finally {
return backend; return backend;
@ -241,7 +239,6 @@ export default boot(({ router, app, store }) => {
// check dependencies // check dependencies
backendPromise backendPromise
.then((backend) => { .then((backend) => {
console.log(backend);
if (backend) { if (backend) {
plugins.forEach((plugin: FG_Plugin.Plugin) => { plugins.forEach((plugin: FG_Plugin.Plugin) => {
plugin.requiredModules.forEach((requiredModule: string) => { plugin.requiredModules.forEach((requiredModule: string) => {

View File

@ -89,12 +89,10 @@ export default defineComponent({
}); });
}); });
const transactions = computed(() => { const transactions = computed(() => {
const a = (<FG.Transaction[]>balanceGetters.transactions()) return (<FG.Transaction[]>balanceGetters.transactions())
.filter((t) => t.original_id == undefined) .filter((t) => t.original_id == undefined)
.filter((t) => t.time > new Date(now.getFullYear(), now.getMonth(), now.getDate())) .filter((t) => t.time > new Date(now.getFullYear(), now.getMonth(), now.getDate()))
.sort((a, b) => (a.time >= b.time ? -1 : 1)); .sort((a, b) => (a.time >= b.time ? -1 : 1));
console.log(a);
return a;
}); });
const canAdd = () => const canAdd = () =>

View File

@ -1,17 +1,13 @@
import { Module } from 'vuex';
import routes from './routes'; import routes from './routes';
import { FG_Plugin } from 'src/plugins'; import { FG_Plugin } from 'src/plugins';
import { defineAsyncComponent } from 'vue'; import { defineAsyncComponent } from 'vue';
import { StateInterface } from 'src/store';
import balance, { BalanceInterface } from './store/balance';
const plugin: FG_Plugin.Plugin = { const plugin: FG_Plugin.Plugin = {
name: 'Balance', name: 'Balance',
mainRoutes: routes, mainRoutes: routes,
requiredModules: ['User'], requiredModules: ['User'],
requiredBackendModules: ['balance'], requiredBackendModules: ['balance'],
version: '0.0.1', version: '0.0.2',
store: new Map<string, Module<BalanceInterface, StateInterface>>([['balance', balance]]),
widgets: [ widgets: [
{ {
priority: 0, priority: 0,

View File

@ -1,7 +1,7 @@
import { Module, MutationTree, ActionTree, GetterTree } from 'vuex'; import { defineStore } from 'pinia';
import { StateInterface, useMainStore } from 'src/store';
import { api } from 'src/boot/axios'; import { api } from 'src/boot/axios';
import { AxiosResponse } from 'axios'; import { AxiosResponse } from 'axios';
import { useMainStore } from 'src/store';
interface BalanceResponse { interface BalanceResponse {
balance: number; balance: number;
@ -18,228 +18,49 @@ export interface TransactionsResponse {
count?: number; count?: number;
} }
export interface UserBalance extends BalanceResponse {
limit: number | null;
}
export interface BalanceInterface {
balances: Map<string, UserBalance>;
shortcuts: Array<number>;
transactions: Array<FG.Transaction>;
loading: number;
}
export interface StateInterfaceBalance {
balance: BalanceInterface;
}
const state: BalanceInterface = {
balances: new Map<string, UserBalance>(),
shortcuts: [],
transactions: [],
loading: 0,
};
function fixTransaction(t: FG.Transaction) { function fixTransaction(t: FG.Transaction) {
t.time = new Date(t.time); t.time = new Date(t.time);
} }
const mutations: MutationTree<BalanceInterface> = { export const balanceStore = defineStore({
setBalance(state, data: { userid: string; balance: BalanceResponse }) { id: 'balance',
state.balances.set(
data.userid,
Object.assign({ limit: state.balances.get(data.userid)?.limit || null }, data.balance)
);
},
changeBalance(state, data: { userid: string; amount: number }) {
const user = <UserBalance>state.balances.get(data.userid);
if (data.amount < 0) user.debit += data.amount;
else user.credit += data.amount;
user.balance += data.amount;
},
setLimit(state, data: { userid: string; limit: number | null }) {
if (state.balances.has(data.userid))
(<UserBalance>state.balances.get(data.userid)).limit = data.limit;
else state.balances.set(data.userid, { balance: 0, debit: 0, credit: 0, limit: data.limit });
},
setLoading(state, data = true) {
if (data) state.loading += 1;
else state.loading -= 1;
},
setShortcuts(state, data: Array<number>) {
state.shortcuts.splice(0, state.shortcuts.length, ...data);
},
addTransaction(state, data: FG.Transaction) {
state.transactions.push(data);
},
addTransactions(state, data: [FG.Transaction]) {
data.forEach((transaction) => {
if (!state.transactions.find((t) => t.id == transaction.id)) {
state.transactions.push(transaction);
}
});
state.transactions.sort((a, b) => (a.time <= b.time ? -1 : 1));
},
reverseTransaction(state, data: { transaction: FG.Transaction; reversal: FG.Transaction }) {
const idx = state.transactions.findIndex((value) => value.id === data.transaction.id);
data.transaction.reversal_id = data.reversal.id;
if (idx > -1) state.transactions[idx] = data.transaction;
else state.transactions.push(data.transaction);
},
};
const actions: ActionTree<BalanceInterface, StateInterface> = { state: () => ({
//const actions: ActionTree<BalanceInterface, any> = { balances: [] as BalancesResponse[],
addShortcut({ commit, state }, shortcut) { shortcuts: [] as number[],
const sc = [...state.shortcuts, shortcut]; }),
getters: {
balance() {
const mainStore = useMainStore();
return this.balances.find((v) => v.userid === mainStore.user?.userid);
},
},
actions: {
async createShortcut(shortcut: number) {
const mainStore = useMainStore();
const sc = [...this.shortcuts, shortcut];
sc.sort(); sc.sort();
const mainStore = useMainStore(); await api.put(`/users/${mainStore.currentUser.userid}/balance/shortcuts`, sc);
const user = mainStore.currentUser; this.shortcuts = sc;
return api.put(`/users/${user.userid}/balance/shortcuts`, sc).then(() => {
commit('setShortcuts', sc);
});
}, },
removeShortcut({ commit, state }, shortcut) {
const sc = state.shortcuts.filter((value: number) => value != shortcut); async removeShortcut(shortcut: number) {
const mainStore = useMainStore(); const mainStore = useMainStore();
const user = mainStore.currentUser; const sc = this.shortcuts.filter((value: number) => value !== shortcut);
return api.put(`/users/${user.userid}/balance/shortcuts`, sc).then(() => { await api.put(`/users/${mainStore.currentUser.userid}/balance/shortcuts`, sc);
commit('setShortcuts', sc); this.shortcuts = sc;
});
}, },
getShortcuts({ commit, state }, force = false) {
if (force || state.shortcuts.length == 0) { async getShortcuts(force = false) {
if (force || this.shortcuts.length == 0) {
const mainStore = useMainStore(); const mainStore = useMainStore();
commit('setLoading'); const { data } = await api.get<number[]>(
const user = mainStore.currentUser; `/users/${mainStore.currentUser.userid}/balance/shortcuts`
return api );
.get(`/users/${user.userid}/balance/shortcuts`) this.shortcuts = data;
.then(({ data }: AxiosResponse<BalanceResponse>) => {
commit('setShortcuts', data);
return data;
})
.finally(() => commit('setLoading', false));
} }
}, },
getBalance({ commit }, user: FG.User | undefined = undefined) {
commit('setLoading');
const mainStore = useMainStore();
if (!user) user = mainStore.currentUser;
return api
.get(`/users/${user.userid}/balance`)
.then(({ data }: AxiosResponse<BalanceResponse>) => {
commit('setBalance', { userid: user?.userid, balance: data });
return data;
})
.finally(() => commit('setLoading', false));
}, },
getBalances() { });
return api.get('/balance').then(({ data }: AxiosResponse<Array<BalancesResponse>>) => {
return data;
});
},
getTransactions(
{ commit },
payload: {
userid?: string;
filter?: {
limit?: number;
offset?: number;
from?: Date;
to?: Date;
showReversals?: boolean;
showCancelled?: boolean;
};
}
) {
commit('setLoading');
const mainStore = useMainStore();
if (!payload.userid) payload.userid = mainStore.currentUser.userid;
if (!payload.filter) payload.filter = { limit: 10 };
return api
.get(`/users/${payload.userid}/balance/transactions`, { params: payload.filter || {} })
.then(({ data }: AxiosResponse<TransactionsResponse>) => {
data.transactions.forEach((t) => fixTransaction(t));
commit('addTransactions', data.transactions);
return data;
})
.finally(() => commit('setLoading', false));
},
getLimit({ commit }) {
const mainStore = useMainStore();
commit('setLoading');
api
/* eslint-disable-next-line @typescript-eslint/restrict-template-expressions */
.get(`/users/${mainStore.currentUser.userid}/balance/limit`)
.then(({ data }) => {
console.log(data);
})
.catch((err) => {
console.warn(err);
})
.finally(() => commit('setLoading', false));
},
revert({ dispatch, commit }, transaction: FG.Transaction) {
return api
.delete(`/balance/${transaction.id}`)
.then(({ data }: AxiosResponse<FG.Transaction>) => {
fixTransaction(data);
commit('reverseTransaction', { transaction: transaction, reversal: data });
dispatch('getBalance').catch((err) => console.warn(err));
});
},
changeBalance({ dispatch, commit }, data: { amount: number; user: string; sender?: string }) {
commit('setLoading');
return api
.put(`/users/${data.user}/balance`, data)
.then((response: AxiosResponse<FG.Transaction>) => {
const mainStore = useMainStore();
const transaction = response.data;
fixTransaction(transaction);
if (
data.user == mainStore.currentUser.userid ||
data.sender === mainStore.currentUser.userid
)
commit('addTransaction', transaction);
commit(state.balances.has(data.user) ? 'changeBalance' : 'setBalance', {
userid: data.user,
amount: data.amount,
});
if (data.sender)
commit(state.balances.has(data.sender) ? 'changeBalance' : 'setBalance', {
userid: data.sender,
amount: -1 * data.amount,
});
return transaction;
})
.catch((err) => {
console.debug(err);
// Maybe Balance changed
void dispatch('getTransactions', {});
return dispatch('getBalance', data.sender ? data.sender : data.user);
})
.finally(() => commit('setLoading', false));
},
};
const getters: GetterTree<BalanceInterface, StateInterface> = {
balances: ({ balances }) => {
return balances;
},
shortcuts: ({ shortcuts }) => {
return shortcuts;
},
transactions: ({ transactions }) => {
return transactions;
},
};
const balance: Module<BalanceInterface, StateInterface> = {
namespaced: true,
state,
mutations,
actions,
getters,
};
export default balance;

View File

@ -99,12 +99,10 @@ export default defineComponent({
if (role.value) { if (role.value) {
if (role.value.id === -1) if (role.value.id === -1)
void userStore.newRole(role.value).then((createdRole: FG.Role) => { void userStore.newRole(role.value).then((createdRole: FG.Role) => {
console.log(createdRole);
role.value = createdRole; role.value = createdRole;
}); });
else { else {
if (newRoleName.value !== '') role.value.name = newRoleName.value; if (newRoleName.value !== '') role.value.name = newRoleName.value;
console.log(role.value);
void userStore.updateRole(role.value); void userStore.updateRole(role.value);
} }
} }

View File

@ -20,7 +20,7 @@
<script lang="ts"> <script lang="ts">
import { defineComponent, onBeforeMount, ref } from 'vue'; import { defineComponent, onBeforeMount, ref } from 'vue';
import Session from '../components/settings/Sessions.vue'; import Session from '../components/settings/Session.vue';
import MainUserSettings from '../components/settings/MainUserSettings.vue'; import MainUserSettings from '../components/settings/MainUserSettings.vue';
import { useMainStore } from 'src/store'; import { useMainStore } from 'src/store';
import { useSessionStore } from '../store'; import { useSessionStore } from '../store';