release v2.0.0 #4
|
@ -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) => {
|
||||||
|
|
|
@ -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 = () =>
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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];
|
}),
|
||||||
sc.sort();
|
|
||||||
const mainStore = useMainStore();
|
getters: {
|
||||||
const user = mainStore.currentUser;
|
balance() {
|
||||||
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);
|
|
||||||
const mainStore = useMainStore();
|
|
||||||
const user = mainStore.currentUser;
|
|
||||||
return api.put(`/users/${user.userid}/balance/shortcuts`, sc).then(() => {
|
|
||||||
commit('setShortcuts', sc);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
getShortcuts({ commit, state }, force = false) {
|
|
||||||
if (force || state.shortcuts.length == 0) {
|
|
||||||
const mainStore = useMainStore();
|
const mainStore = useMainStore();
|
||||||
commit('setLoading');
|
return this.balances.find((v) => v.userid === mainStore.user?.userid);
|
||||||
const user = mainStore.currentUser;
|
},
|
||||||
return api
|
|
||||||
.get(`/users/${user.userid}/balance/shortcuts`)
|
|
||||||
.then(({ data }: AxiosResponse<BalanceResponse>) => {
|
|
||||||
commit('setShortcuts', data);
|
|
||||||
return data;
|
|
||||||
})
|
|
||||||
.finally(() => commit('setLoading', false));
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
getBalance({ commit }, user: FG.User | undefined = undefined) {
|
|
||||||
commit('setLoading');
|
actions: {
|
||||||
const mainStore = useMainStore();
|
async createShortcut(shortcut: number) {
|
||||||
if (!user) user = mainStore.currentUser;
|
const mainStore = useMainStore();
|
||||||
return api
|
const sc = [...this.shortcuts, shortcut];
|
||||||
.get(`/users/${user.userid}/balance`)
|
sc.sort();
|
||||||
.then(({ data }: AxiosResponse<BalanceResponse>) => {
|
await api.put(`/users/${mainStore.currentUser.userid}/balance/shortcuts`, sc);
|
||||||
commit('setBalance', { userid: user?.userid, balance: data });
|
this.shortcuts = sc;
|
||||||
return data;
|
},
|
||||||
})
|
|
||||||
.finally(() => commit('setLoading', false));
|
async removeShortcut(shortcut: number) {
|
||||||
},
|
const mainStore = useMainStore();
|
||||||
getBalances() {
|
const sc = this.shortcuts.filter((value: number) => value !== shortcut);
|
||||||
return api.get('/balance').then(({ data }: AxiosResponse<Array<BalancesResponse>>) => {
|
await api.put(`/users/${mainStore.currentUser.userid}/balance/shortcuts`, sc);
|
||||||
return data;
|
this.shortcuts = sc;
|
||||||
});
|
},
|
||||||
},
|
|
||||||
getTransactions(
|
async getShortcuts(force = false) {
|
||||||
{ commit },
|
if (force || this.shortcuts.length == 0) {
|
||||||
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 mainStore = useMainStore();
|
||||||
const transaction = response.data;
|
const { data } = await api.get<number[]>(
|
||||||
fixTransaction(transaction);
|
`/users/${mainStore.currentUser.userid}/balance/shortcuts`
|
||||||
if (
|
);
|
||||||
data.user == mainStore.currentUser.userid ||
|
this.shortcuts = data;
|
||||||
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;
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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';
|
||||||
|
|
Loading…
Reference in New Issue