Allow to edit accounts
Signed-off-by: Knut Ahlers <knut@ahlers.me>
This commit is contained in:
parent
7886365acc
commit
ed3f281092
3 changed files with 211 additions and 5 deletions
153
frontend/components/accountEditor.vue
Normal file
153
frontend/components/accountEditor.vue
Normal file
|
@ -0,0 +1,153 @@
|
||||||
|
<template>
|
||||||
|
<div
|
||||||
|
id="editAccountModal"
|
||||||
|
ref="editAccountModal"
|
||||||
|
class="modal fade"
|
||||||
|
tabindex="-1"
|
||||||
|
aria-labelledby="editAccountModalLabel"
|
||||||
|
aria-hidden="true"
|
||||||
|
>
|
||||||
|
<div class="modal-dialog modal-sm">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h1
|
||||||
|
id="editAccountModalLabel"
|
||||||
|
class="modal-title fs-5"
|
||||||
|
>
|
||||||
|
Edit Account
|
||||||
|
</h1>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="btn-close"
|
||||||
|
data-bs-dismiss="modal"
|
||||||
|
aria-label="Close"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<div class="mb-3">
|
||||||
|
<label
|
||||||
|
for="editAccountModalName"
|
||||||
|
class="form-label"
|
||||||
|
>Name</label>
|
||||||
|
<input
|
||||||
|
id="editAccountModalName"
|
||||||
|
v-model="form.name"
|
||||||
|
class="form-control"
|
||||||
|
type="text"
|
||||||
|
@keypress.enter="updateAccount"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-3">
|
||||||
|
<div class="form-check">
|
||||||
|
<input
|
||||||
|
id="editAccountModalHidden"
|
||||||
|
v-model="form.hidden"
|
||||||
|
class="form-check-input"
|
||||||
|
type="checkbox"
|
||||||
|
:disabled="form.balance !== 0"
|
||||||
|
>
|
||||||
|
<label
|
||||||
|
for="editAccountModalHidden"
|
||||||
|
class="form-check-label"
|
||||||
|
>Hide account</label>
|
||||||
|
</div>
|
||||||
|
<div class="form-text">
|
||||||
|
Note: You cannot un-hide the account using UI, you need to unhide it via API.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="btn btn-primary"
|
||||||
|
@click="updateAccount"
|
||||||
|
>
|
||||||
|
<i class="fas fa-fw fa-pencil mr-1" />
|
||||||
|
Update
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { Modal } from 'bootstrap'
|
||||||
|
import { responseToJSON } from '../helpers'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
form: {
|
||||||
|
balance: 0,
|
||||||
|
hidden: false,
|
||||||
|
name: '',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
emits: ['editClosed', 'editComplete'],
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
updateAccount() {
|
||||||
|
if (!this.account) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const update = new URLSearchParams()
|
||||||
|
|
||||||
|
if (this.form.name !== this.account.name) {
|
||||||
|
update.set('name', this.form.name)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.form.hidden !== this.account.hidden) {
|
||||||
|
update.set('hidden', String(this.form.hidden))
|
||||||
|
}
|
||||||
|
|
||||||
|
if (update.toString().length === 0) {
|
||||||
|
// No updates, why are we here?
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
return fetch(`/api/accounts/${this.account.id}?${update.toString()}`, {
|
||||||
|
method: 'PATCH',
|
||||||
|
})
|
||||||
|
.then(responseToJSON)
|
||||||
|
.then(() => this.$emit('editComplete'))
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
mounted() {
|
||||||
|
this.$refs.editAccountModal
|
||||||
|
.addEventListener('hidden.bs.modal', () => this.$emit('editClosed'))
|
||||||
|
},
|
||||||
|
|
||||||
|
name: 'AccountingAppAccountEditor',
|
||||||
|
|
||||||
|
props: {
|
||||||
|
account: {
|
||||||
|
default: () => ({}),
|
||||||
|
required: false,
|
||||||
|
type: Object,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
watch: {
|
||||||
|
account(to) {
|
||||||
|
if (!to) {
|
||||||
|
Modal.getOrCreateInstance(this.$refs.editAccountModal).hide()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
this.form = {
|
||||||
|
balance: to.balance,
|
||||||
|
hidden: to.hidden,
|
||||||
|
name: to.name,
|
||||||
|
}
|
||||||
|
|
||||||
|
Modal.getOrCreateInstance(this.$refs.editAccountModal).show()
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
|
@ -2,8 +2,17 @@
|
||||||
<div>
|
<div>
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col d-flex fs-3 align-items-center text-semibold">
|
<div
|
||||||
{{ accountIdToName[accountId] }}
|
class="col d-flex fs-3 align-items-center text-semibold"
|
||||||
|
>
|
||||||
|
<a
|
||||||
|
class="text-white text-decoration-none"
|
||||||
|
href="#"
|
||||||
|
title="Click to Edit"
|
||||||
|
@click.prevent="editedAccId = accountId"
|
||||||
|
>
|
||||||
|
{{ accountIdToName[accountId] }}
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="col d-flex align-items-center justify-content-end">
|
<div class="col d-flex align-items-center justify-content-end">
|
||||||
<range-selector
|
<range-selector
|
||||||
|
@ -306,6 +315,12 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<account-editor
|
||||||
|
:account="editedAcc"
|
||||||
|
@editClosed="editedAccId = null"
|
||||||
|
@editComplete="$emit('update-accounts'); editedAccId = null"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -313,12 +328,13 @@
|
||||||
/* eslint-disable sort-imports */
|
/* eslint-disable sort-imports */
|
||||||
import { Modal } from 'bootstrap'
|
import { Modal } from 'bootstrap'
|
||||||
|
|
||||||
|
import accountEditor from './accountEditor.vue'
|
||||||
import { formatNumber } from '../helpers'
|
import { formatNumber } from '../helpers'
|
||||||
import rangeSelector from './rangeSelector.vue'
|
import rangeSelector from './rangeSelector.vue'
|
||||||
import txEditor from './txEditor.vue'
|
import txEditor from './txEditor.vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: { rangeSelector, txEditor },
|
components: { accountEditor, rangeSelector, txEditor },
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
account() {
|
account() {
|
||||||
|
@ -345,6 +361,13 @@ export default {
|
||||||
return cats
|
return cats
|
||||||
},
|
},
|
||||||
|
|
||||||
|
editedAcc() {
|
||||||
|
if (!this.editedAccId) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
return this.accounts.filter(acc => acc.id === this.editedAccId)[0] || null
|
||||||
|
},
|
||||||
|
|
||||||
selectedTx() {
|
selectedTx() {
|
||||||
return Object.entries(this.selectedTxRaw)
|
return Object.entries(this.selectedTxRaw)
|
||||||
.filter(e => e[1])
|
.filter(e => e[1])
|
||||||
|
@ -392,6 +415,7 @@ export default {
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
editedAccId: null,
|
||||||
editedTxId: null,
|
editedTxId: null,
|
||||||
|
|
||||||
modals: {
|
modals: {
|
||||||
|
@ -410,6 +434,8 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
emits: ['update-accounts'],
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
deleteSelected() {
|
deleteSelected() {
|
||||||
const actions = []
|
const actions = []
|
||||||
|
|
|
@ -49,7 +49,16 @@
|
||||||
v-for="cat in categories"
|
v-for="cat in categories"
|
||||||
:key="cat.id"
|
:key="cat.id"
|
||||||
>
|
>
|
||||||
<td>{{ cat.name }}</td>
|
<td>
|
||||||
|
<a
|
||||||
|
class="text-white text-decoration-none"
|
||||||
|
href="#"
|
||||||
|
title="Click to Edit"
|
||||||
|
@click.prevent="editedAccId = cat.id"
|
||||||
|
>
|
||||||
|
{{ cat.name }}
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
<td :class="{'text-end': true, 'text-danger': (allocatedByCategory[cat.id] || 0) < 0}">
|
<td :class="{'text-end': true, 'text-danger': (allocatedByCategory[cat.id] || 0) < 0}">
|
||||||
{{ formatNumber(allocatedByCategory[cat.id] || 0) }} €
|
{{ formatNumber(allocatedByCategory[cat.id] || 0) }} €
|
||||||
</td>
|
</td>
|
||||||
|
@ -170,6 +179,12 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<account-editor
|
||||||
|
:account="editedAcc"
|
||||||
|
@editClosed="editedAccId = null"
|
||||||
|
@editComplete="$emit('update-accounts'); editedAccId = null"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -177,12 +192,13 @@
|
||||||
/* eslint-disable sort-imports */
|
/* eslint-disable sort-imports */
|
||||||
import { Modal } from 'bootstrap'
|
import { Modal } from 'bootstrap'
|
||||||
|
|
||||||
|
import accountEditor from './accountEditor.vue'
|
||||||
import { formatNumber } from '../helpers'
|
import { formatNumber } from '../helpers'
|
||||||
import rangeSelector from './rangeSelector.vue'
|
import rangeSelector from './rangeSelector.vue'
|
||||||
import { unallocatedMoneyAcc } from '../constants'
|
import { unallocatedMoneyAcc } from '../constants'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: { rangeSelector },
|
components: { accountEditor, rangeSelector },
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
activityByCategory() {
|
activityByCategory() {
|
||||||
|
@ -211,6 +227,13 @@ export default {
|
||||||
return accounts
|
return accounts
|
||||||
},
|
},
|
||||||
|
|
||||||
|
editedAcc() {
|
||||||
|
if (!this.editedAccId) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
return this.accounts.filter(acc => acc.id === this.editedAccId)[0] || null
|
||||||
|
},
|
||||||
|
|
||||||
transferModalValid() {
|
transferModalValid() {
|
||||||
if (!this.modals.createTransfer.from || !this.modals.createTransfer.to) {
|
if (!this.modals.createTransfer.from || !this.modals.createTransfer.to) {
|
||||||
return false
|
return false
|
||||||
|
@ -254,6 +277,8 @@ export default {
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
editedAccId: null,
|
||||||
|
|
||||||
modals: {
|
modals: {
|
||||||
createTransfer: {
|
createTransfer: {
|
||||||
amount: 0,
|
amount: 0,
|
||||||
|
@ -267,6 +292,8 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
emits: ['update-accounts'],
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
fetchTransactions() {
|
fetchTransactions() {
|
||||||
const since = this.timeRange.start.toISOString()
|
const since = this.timeRange.start.toISOString()
|
||||||
|
|
Loading…
Reference in a new issue