First try with an overview page for the balance
This commit is contained in:
		
							parent
							
								
									502c40329c
								
							
						
					
					
						commit
						d396940071
					
				|  | @ -1,71 +1,140 @@ | ||||||
| <template> | <template> | ||||||
|   <div> |   <q-page padding> | ||||||
|     <q-page padding> |     <q-card> | ||||||
|       <q-card> |       <q-card-section class="text-center"> | ||||||
|         <q-card-section> |         <div class="text-h4">Aktueller Stand</div> | ||||||
|           <q-table :data="rows" row-key="userid" :columns="columns" /> |         <div style="font-size: 2em">{{ balance.toFixed(2) }} €</div> | ||||||
|         </q-card-section> |       </q-card-section> | ||||||
|       </q-card> |       <q-separator /> | ||||||
|     </q-page> |       <q-card-section> | ||||||
|   </div> |         <q-table | ||||||
|  |           title="Buchungen" | ||||||
|  |           :data="data" | ||||||
|  |           :columns="columns" | ||||||
|  |           row-key="id" | ||||||
|  |           :pagination.sync="pagination" | ||||||
|  |           :loading="loading" | ||||||
|  |           @request="onRequest" | ||||||
|  |           binary-state-sort | ||||||
|  |         /> | ||||||
|  |       </q-card-section> | ||||||
|  |     </q-card> | ||||||
|  |   </q-page> | ||||||
| </template> | </template> | ||||||
| 
 | 
 | ||||||
| <script lang="ts"> | <script lang="ts"> | ||||||
| // TODO: Load all users / balances | import { computed, defineComponent, onMounted, ref } from '@vue/composition-api'; | ||||||
| 
 |  | ||||||
| // TODO: Fill usefull data |  | ||||||
| 
 |  | ||||||
| import { computed, defineComponent } from '@vue/composition-api'; |  | ||||||
| import { StateInterfaceBalance } from '../store/balance'; | import { StateInterfaceBalance } from '../store/balance'; | ||||||
| import { Store } from 'vuex'; | import { Store } from 'vuex'; | ||||||
|  | import { formatDateTime } from 'src/utils/datetime'; | ||||||
|  | 
 | ||||||
| export default defineComponent({ | export default defineComponent({ | ||||||
|   // name: 'PageName' |   // name: 'PageName' | ||||||
|   setup(_, { root }) { |   setup(_, { root }) { | ||||||
|     const store = <Store<StateInterfaceBalance>>root.$store; |     const store = <Store<StateInterfaceBalance>>root.$store; | ||||||
| 
 | 
 | ||||||
|     const rows = []; |     onMounted(() => { | ||||||
|  |       void store.dispatch('balance/getBalance'); | ||||||
|  |       onRequest({ | ||||||
|  |         pagination: pagination.value, | ||||||
|  |         filter: undefined | ||||||
|  |       }); | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     const data = ref<FG.Transaction[]>([]); | ||||||
|  |     const loading = ref(false); | ||||||
|  |     const pagination = ref({ | ||||||
|  |       sortBy: 'desc', | ||||||
|  |       descending: false, | ||||||
|  |       page: 1, | ||||||
|  |       rowsPerPage: 3, | ||||||
|  |       rowsNumber: 10 | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     interface PaginationInterface { | ||||||
|  |       sortBy: string; | ||||||
|  |       descending: boolean; | ||||||
|  |       page: number; | ||||||
|  |       rowsPerPage: number; | ||||||
|  |       rowsNumber: number; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function onRequest(props: { pagination: PaginationInterface; filter?: string }) { | ||||||
|  |       const { page, rowsPerPage, sortBy, descending } = props.pagination; | ||||||
|  |       const filter = props.filter; | ||||||
|  | 
 | ||||||
|  |       loading.value = true; | ||||||
|  | 
 | ||||||
|  |       void store.dispatch('balance/getTransactionsCount', filter).then((value: number) => { | ||||||
|  |         pagination.value.rowsNumber = value; | ||||||
|  | 
 | ||||||
|  |         // get all rows if "All" (0) is selected | ||||||
|  |         const fetchCount = rowsPerPage === 0 ? pagination.value.rowsNumber : rowsPerPage; | ||||||
|  |         // calculate starting row of data | ||||||
|  |         const startRow = (page - 1) * rowsPerPage; | ||||||
|  | 
 | ||||||
|  |         // fetch data from "server" | ||||||
|  |         store | ||||||
|  |           .dispatch('balance/getTransactions', { | ||||||
|  |             filter: { row: startRow, limit: fetchCount } | ||||||
|  |           }) | ||||||
|  |           .then((gotTransactions: FG.Transaction[]) => { | ||||||
|  |             // clear out existing data and add new | ||||||
|  |             data.value.splice(0, data.value.length, ...gotTransactions); | ||||||
|  |             // don't forget to update local pagination object | ||||||
|  |             pagination.value.page = page; | ||||||
|  |             pagination.value.rowsPerPage = rowsPerPage; | ||||||
|  |             pagination.value.sortBy = sortBy; | ||||||
|  |             pagination.value.descending = descending; | ||||||
|  |           }) | ||||||
|  |           .finally(() => (loading.value = false)); | ||||||
|  |       }); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     const balance = computed( | ||||||
|  |       () => | ||||||
|  |         store.state.balance.balances.get((<FG.User>store.state.user.currentUser).userid)?.balance || | ||||||
|  |         NaN | ||||||
|  |     ); | ||||||
| 
 | 
 | ||||||
|     const columns = [ |     const columns = [ | ||||||
|       { |       { | ||||||
|         name: 'userid', |         name: 'time', | ||||||
|         label: 'Datum', |         label: 'Datum', | ||||||
|         field: 'userid', |         field: 'time', | ||||||
|         required: true, |         required: true, | ||||||
|         align: 'left', |         sortable: true, | ||||||
|         sortable: true |         format: (val: Date) => formatDateTime(new Date(val), true, true, true) | ||||||
|       }, |       }, | ||||||
|       { |       { | ||||||
|         name: 'balance', |         name: 'text', | ||||||
|         label: 'Text', |         label: 'Text', | ||||||
|         field: 'balance', |         format: (_: undefined, row: FG.Transaction) => { | ||||||
|         format: (val: number) => val.toFixed(2) |           if (row.sender_id == null) return 'Gutschrift'; | ||||||
|  |           else { | ||||||
|  |             if (row.receiver_id == null) return 'Angeschrieben'; | ||||||
|  |             else { | ||||||
|  |               if (row.receiver_id === store.state.user.currentUser?.userid) return 'Bekommen von X'; | ||||||
|  |               else return 'Gesendet an X'; | ||||||
|  |             } | ||||||
|  |           } | ||||||
|  |         } | ||||||
|       }, |       }, | ||||||
|       { |       { | ||||||
|         name: 'limit', |         name: 'amount', | ||||||
|         label: 'Betrag', |         label: 'Betrag', | ||||||
|         field: 'limit', |         field: 'amount', | ||||||
|         format: (val: number) => (val === null ? 'keins' : val) |         format: (val: number) => `${val.toFixed(2)}€` | ||||||
|       }, |       }, | ||||||
|       { |       { | ||||||
|         name: 'limit', |         name: 'author_id', | ||||||
|         label: 'Benutzer', |         label: 'Benutzer', | ||||||
|         field: 'limit', |         field: 'author_id', | ||||||
|         format: (val: number) => (val === null ? 'keins' : val) |         format: (val: string) => store.state.user.users.filter(x => x.userid == val)[0].display_name | ||||||
|       }, |  | ||||||
|       { |  | ||||||
|         name: 'limit', |  | ||||||
|         label: 'Storniert', |  | ||||||
|         field: 'limit', |  | ||||||
|         format: (val: number) => (val === null ? 'keins' : val) |  | ||||||
|       }, |  | ||||||
|       { |  | ||||||
|         name: 'limit', |  | ||||||
|         label: 'Löschen', |  | ||||||
|         field: 'limit', |  | ||||||
|         format: (val: number) => (val === null ? 'keins' : val) |  | ||||||
|       } |       } | ||||||
|     ]; |     ]; | ||||||
|     return { rows, columns }; | 
 | ||||||
|  |     return { data, pagination, onRequest, loading, balance, columns }; | ||||||
|   } |   } | ||||||
| }); | }); | ||||||
| </script> | </script> | ||||||
|  |  | ||||||
|  | @ -69,7 +69,7 @@ const mutations: MutationTree<BalanceInterface> = { | ||||||
|   }, |   }, | ||||||
|   reverseTransaction(state, data: { transaction: FG.Transaction; reversal: FG.Transaction }) { |   reverseTransaction(state, data: { transaction: FG.Transaction; reversal: FG.Transaction }) { | ||||||
|     const idx = state.transactions.findIndex(value => value.id === data.transaction.id); |     const idx = state.transactions.findIndex(value => value.id === data.transaction.id); | ||||||
|     data.transaction.reversal = data.reversal; |     data.transaction.reversal_id = data.reversal.id; | ||||||
|     if (idx > -1) state.transactions[idx] = data.transaction; |     if (idx > -1) state.transactions[idx] = data.transaction; | ||||||
|     else state.transactions.push(data.transaction); |     else state.transactions.push(data.transaction); | ||||||
|   } |   } | ||||||
|  | @ -78,7 +78,7 @@ const mutations: MutationTree<BalanceInterface> = { | ||||||
| const actions: ActionTree<BalanceInterface, StateInterface> = { | const actions: ActionTree<BalanceInterface, StateInterface> = { | ||||||
|   addShortcut({ commit, state, rootState }, shortcut) { |   addShortcut({ commit, state, rootState }, shortcut) { | ||||||
|     const sc = [...state.shortcuts, shortcut]; |     const sc = [...state.shortcuts, shortcut]; | ||||||
|     sc.sort().reverse(); |     sc.sort(); | ||||||
| 
 | 
 | ||||||
|     const user = <FG.User>rootState.user.currentUser; |     const user = <FG.User>rootState.user.currentUser; | ||||||
|     return axios.put(`/users/${user.userid}/balance/shortcuts`, sc).then(() => { |     return axios.put(`/users/${user.userid}/balance/shortcuts`, sc).then(() => { | ||||||
|  | @ -136,6 +136,15 @@ const actions: ActionTree<BalanceInterface, StateInterface> = { | ||||||
|       }) |       }) | ||||||
|       .finally(() => commit('setLoading', false)); |       .finally(() => commit('setLoading', false)); | ||||||
|   }, |   }, | ||||||
|  |   getTransactionsCount( | ||||||
|  |     { state }, | ||||||
|  |     payload: { | ||||||
|  |       userid?: string; | ||||||
|  |       filter?: { limit?: number; offset?: number; from?: Date; to?: Date }; | ||||||
|  |     } | ||||||
|  |   ) { | ||||||
|  |     return Promise.resolve(3); | ||||||
|  |   }, | ||||||
|   getLimit({ rootState, commit }) { |   getLimit({ rootState, commit }) { | ||||||
|     commit('setLoading'); |     commit('setLoading'); | ||||||
|     axios |     axios | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue