diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index d7aff56f3..383735507 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -448,7 +448,7 @@ jobs:
report_name: Coverage Admin Interface
type: lcov
result_path: ./coverage/lcov.info
- min_coverage: 91
+ min_coverage: 93
token: ${{ github.token }}
##############################################################################
diff --git a/admin/src/App.vue b/admin/src/App.vue
index 40460eda4..bcaab2ef9 100644
--- a/admin/src/App.vue
+++ b/admin/src/App.vue
@@ -13,3 +13,11 @@ export default {
components: { defaultLayout },
}
+
diff --git a/admin/src/components/UserTable.spec.js b/admin/src/components/UserTable.spec.js
index 982b65a81..d900b126d 100644
--- a/admin/src/components/UserTable.spec.js
+++ b/admin/src/components/UserTable.spec.js
@@ -11,22 +11,36 @@ describe('UserTable', () => {
const defaultItemsUser = [
{
- email: 'bibi@bloxberg.de',
+ userId: 1,
firstName: 'Bibi',
lastName: 'Bloxberg',
- creation: [1000, 1000, 1000],
+ email: 'bibi@bloxberg.de',
+ creation: [200, 400, 600],
+ emailChecked: true,
},
{
- email: 'bibi@bloxberg.de',
- firstName: 'Bibi',
- lastName: 'Bloxberg',
+ userId: 2,
+ firstName: 'Benjamin',
+ lastName: 'Blümchen',
+ email: 'benjamin@bluemchen.de',
creation: [1000, 1000, 1000],
+ emailChecked: true,
},
{
- email: 'bibi@bloxberg.de',
- firstName: 'Bibi',
- lastName: 'Bloxberg',
+ userId: 3,
+ firstName: 'Peter',
+ lastName: 'Lustig',
+ email: 'peter@lustig.de',
+ creation: [0, 0, 0],
+ emailChecked: true,
+ },
+ {
+ userId: 4,
+ firstName: 'New',
+ lastName: 'User',
+ email: 'new@user.ch',
creation: [1000, 1000, 1000],
+ emailChecked: false,
},
]
@@ -107,7 +121,7 @@ describe('UserTable', () => {
const mocks = {
$t: jest.fn((t) => t),
- $d: jest.fn((d) => d),
+ $d: jest.fn((d) => String(d)),
$apollo: {
query: apolloQueryMock,
},
@@ -122,7 +136,7 @@ describe('UserTable', () => {
describe('mount', () => {
describe('type PageUserSearch', () => {
- beforeEach(() => {
+ beforeEach(async () => {
wrapper = Wrapper(propsDataPageUserSearch)
})
@@ -175,12 +189,12 @@ describe('UserTable', () => {
})
describe('content', () => {
- it('has 3 rows', () => {
- expect(wrapper.findAll('tbody tr').length).toBe(3)
+ it('has 4 rows', () => {
+ expect(wrapper.findAll('tbody tr')).toHaveLength(4)
})
it('has 7 columns', () => {
- expect(wrapper.findAll('tr:nth-child(1) > td').length).toBe(7)
+ expect(wrapper.findAll('tr:nth-child(1) > td')).toHaveLength(7)
})
it('find button on fifth column', () => {
@@ -189,6 +203,110 @@ describe('UserTable', () => {
).toBeTruthy()
})
})
+
+ describe('row toggling', () => {
+ describe('user with email not activated', () => {
+ it('has no details button', () => {
+ expect(
+ wrapper.findAll('tbody > tr').at(3).findAll('td').at(4).find('button').exists(),
+ ).toBeFalsy()
+ })
+
+ it('has a red confirmed button with envelope item', () => {
+ const row = wrapper.findAll('tbody > tr').at(3)
+ expect(row.findAll('td').at(5).find('button').exists()).toBeTruthy()
+ expect(row.findAll('td').at(5).find('button').classes('btn-danger')).toBeTruthy()
+ expect(row.findAll('td').at(5).find('svg').classes('bi-envelope')).toBeTruthy()
+ })
+
+ describe('click on envelope', () => {
+ beforeEach(async () => {
+ await wrapper
+ .findAll('tbody > tr')
+ .at(3)
+ .findAll('td')
+ .at(5)
+ .find('button')
+ .trigger('click')
+ })
+
+ it('opens the details', async () => {
+ expect(wrapper.findAll('tbody > tr')).toHaveLength(6)
+ expect(wrapper.findAll('tbody > tr').at(5).find('input').element.value).toBe(
+ 'new@user.ch',
+ )
+ expect(wrapper.findAll('tbody > tr').at(5).text()).toContain(
+ 'unregister_mail.text_false',
+ )
+ // HACK: for some reason we need to close the row details after this test
+ await wrapper
+ .findAll('tbody > tr')
+ .at(3)
+ .findAll('td')
+ .at(5)
+ .find('button')
+ .trigger('click')
+ })
+
+ describe('click on envelope again', () => {
+ beforeEach(async () => {
+ await wrapper
+ .findAll('tbody > tr')
+ .at(3)
+ .findAll('td')
+ .at(5)
+ .find('button')
+ .trigger('click')
+ })
+
+ it('closes the details', () => {
+ expect(wrapper.findAll('tbody > tr')).toHaveLength(4)
+ })
+ })
+
+ describe('click on close details', () => {
+ beforeEach(async () => {
+ await wrapper.findAll('tbody > tr').at(5).findAll('button').at(1).trigger('click')
+ })
+
+ it('closes the details', () => {
+ expect(wrapper.findAll('tbody > tr')).toHaveLength(4)
+ })
+ })
+ })
+ })
+
+ describe('different details', () => {
+ it.skip('shows the creation formular for second user', async () => {
+ await wrapper
+ .findAll('tbody > tr')
+ .at(1)
+ .findAll('td')
+ .at(4)
+ .find('button')
+ .trigger('click')
+ expect(wrapper.findAll('tbody > tr')).toHaveLength(6)
+ expect(
+ wrapper
+ .findAll('tbody > tr')
+ .at(3)
+ .find('div.component-creation-formular')
+ .exists(),
+ ).toBeTruthy()
+ })
+
+ it.skip('shows the transactions for third user', async () => {
+ await wrapper
+ .findAll('tbody > tr')
+ .at(4)
+ .findAll('td')
+ .at(6)
+ .find('button')
+ .trigger('click')
+ expect(wrapper.findAll('tbody > tr')).toHaveLength(6)
+ })
+ })
+ })
})
})
diff --git a/admin/src/components/UserTable.vue b/admin/src/components/UserTable.vue
index 0fa72f573..e518ac6d1 100644
--- a/admin/src/components/UserTable.vue
+++ b/admin/src/components/UserTable.vue
@@ -133,7 +133,7 @@
variant="danger"
v-show="type === 'UserListMassCreation' || type === 'PageCreationConfirm'"
size="md"
- @click="overlayShow('remove', row.item)"
+ @click="bookmarkRemove(row.item)"
class="mr-2"
>
@@ -242,13 +242,6 @@ export default {
this.overlayBookmarkType = bookmarkType
this.overlayItem = item
- if (bookmarkType === 'remove') {
- this.overlayText.header = this.$t('overlay.remove.title')
- this.overlayText.text1 = this.$t('overlay.remove.text')
- this.overlayText.text2 = this.$t('overlay.remove.question')
- this.overlayText.button_ok = this.$t('overlay.remove.yes')
- this.overlayText.button_cancel = this.$t('overlay.remove.no')
- }
if (bookmarkType === 'confirm') {
this.overlayText.header = this.$t('overlay.confirm.title')
this.overlayText.text1 = this.$t('overlay.confirm.text')
@@ -258,9 +251,6 @@ export default {
}
},
overlayOK(bookmarkType, item) {
- if (bookmarkType === 'remove') {
- this.bookmarkRemove(item)
- }
if (bookmarkType === 'confirm') {
this.$emit('confirm-creation', item)
}
diff --git a/admin/src/locales/de.json b/admin/src/locales/de.json
index 7585ee122..327cfd302 100644
--- a/admin/src/locales/de.json
+++ b/admin/src/locales/de.json
@@ -54,6 +54,7 @@
}
},
"remove": "Entfernen",
+ "remove_all": "alle Nutzer entfernen",
"transaction": "Transaktion",
"transactionlist": {
"amount": "Betrag",
diff --git a/admin/src/locales/en.json b/admin/src/locales/en.json
index 2680a1c00..3f12f10a8 100644
--- a/admin/src/locales/en.json
+++ b/admin/src/locales/en.json
@@ -54,6 +54,7 @@
}
},
"remove": "Remove",
+ "remove_all": "Remove all users",
"transaction": "Transaction",
"transactionlist": {
"amount": "Amount",
diff --git a/admin/src/pages/Creation.spec.js b/admin/src/pages/Creation.spec.js
index e06e43607..81d556e9b 100644
--- a/admin/src/pages/Creation.spec.js
+++ b/admin/src/pages/Creation.spec.js
@@ -154,55 +154,16 @@ describe('Creation', () => {
},
])
})
- })
- describe('remove item', () => {
- beforeEach(async () => {
- await wrapper
- .findAll('table')
- .at(0)
- .findAll('tbody > tr')
- .at(1)
- .find('button')
- .trigger('click')
- await wrapper
- .findAll('table')
- .at(1)
- .findAll('tbody > tr')
- .at(0)
- .find('button')
- .trigger('click')
- })
-
- it('opens a dialog', () => {
- expect(wrapper.findAll('#overlay').at(1).isVisible()).toBeTruthy()
- })
-
- describe('cancel remove item', () => {
+ describe('remove item', () => {
beforeEach(async () => {
- await wrapper.findAll('#overlay').at(1).findAll('button').at(0).trigger('click')
- })
-
- it('closes the dialog', () => {
- expect(wrapper.findAll('#overlay').at(1).isVisible()).toBeFalsy()
- })
-
- it('has one item in left table', () => {
- expect(wrapper.findAll('table').at(0).findAll('tbody > tr')).toHaveLength(1)
- })
-
- it('has one item in right table', () => {
- expect(wrapper.findAll('table').at(1).findAll('tbody > tr')).toHaveLength(1)
- })
- })
-
- describe('confirm remove item', () => {
- beforeEach(async () => {
- await wrapper.findAll('#overlay').at(1).findAll('button').at(1).trigger('click')
- })
-
- it('closes the dialog', () => {
- expect(wrapper.findAll('#overlay').at(1).isVisible()).toBeFalsy()
+ await wrapper
+ .findAll('table')
+ .at(1)
+ .findAll('tbody > tr')
+ .at(0)
+ .find('button')
+ .trigger('click')
})
it('has two items in left table', () => {
@@ -223,32 +184,24 @@ describe('Creation', () => {
expect(storeCommitMock).toBeCalledWith('setUserSelectedInMassCreation', [])
})
})
- })
- // this can only happen after API call in CreationForm
- describe('remove all bookmarks', () => {
- beforeEach(async () => {
- await wrapper
- .findAll('table')
- .at(0)
- .findAll('tbody > tr')
- .at(1)
- .find('button')
- .trigger('click')
- jest.clearAllMocks()
- wrapper.findComponent({ name: 'CreationFormular' }).vm.$emit('remove-all-bookmark')
- })
+ describe('remove all bookmarks', () => {
+ beforeEach(async () => {
+ jest.clearAllMocks()
+ await wrapper.find('button.btn-light').trigger('click')
+ })
- it('has no items in right table', () => {
- expect(wrapper.findAll('table').at(1).findAll('tbody > tr')).toHaveLength(0)
- })
+ it('has no items in right table', () => {
+ expect(wrapper.findAll('table').at(1).findAll('tbody > tr')).toHaveLength(0)
+ })
- it('commits empty array to userSelectedInMassCreation', () => {
- expect(storeCommitMock).toBeCalledWith('setUserSelectedInMassCreation', [])
- })
+ it('commits empty array to userSelectedInMassCreation', () => {
+ expect(storeCommitMock).toBeCalledWith('setUserSelectedInMassCreation', [])
+ })
- it('calls searchUsers', () => {
- expect(apolloQueryMock).toBeCalled()
+ it('calls searchUsers', () => {
+ expect(apolloQueryMock).toBeCalled()
+ })
})
})
@@ -288,17 +241,38 @@ describe('Creation', () => {
jest.clearAllMocks()
})
- it('calls API when criteria changes', async () => {
- await wrapper.setData({ criteria: 'XX' })
- expect(apolloQueryMock).toBeCalledWith(
- expect.objectContaining({
- variables: {
- searchText: 'XX',
- currentPage: 1,
- pageSize: 25,
- },
- }),
- )
+ describe('search criteria', () => {
+ beforeEach(async () => {
+ await wrapper.setData({ criteria: 'XX' })
+ })
+
+ it('calls API when criteria changes', async () => {
+ expect(apolloQueryMock).toBeCalledWith(
+ expect.objectContaining({
+ variables: {
+ searchText: 'XX',
+ currentPage: 1,
+ pageSize: 25,
+ },
+ }),
+ )
+ })
+
+ describe('reset search criteria', () => {
+ it('calls the API', async () => {
+ jest.clearAllMocks()
+ await wrapper.find('.test-click-clear-criteria').trigger('click')
+ expect(apolloQueryMock).toBeCalledWith(
+ expect.objectContaining({
+ variables: {
+ searchText: '',
+ currentPage: 1,
+ pageSize: 25,
+ },
+ }),
+ )
+ })
+ })
})
it('calls API when currentPage changes', async () => {
diff --git a/admin/src/pages/Creation.vue b/admin/src/pages/Creation.vue
index 6da762a15..64efab997 100644
--- a/admin/src/pages/Creation.vue
+++ b/admin/src/pages/Creation.vue
@@ -3,12 +3,20 @@
-
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+ {{ $t('remove_all') }}
+
+
+
+
{{ $t('multiple_creation_text') }}
@@ -41,7 +57,7 @@
type="massCreation"
:creation="creation"
:items="itemsMassCreation"
- @remove-all-bookmark="removeAllBookmark"
+ @remove-all-bookmark="removeAllBookmarks"
/>
@@ -123,7 +139,7 @@ export default {
)
this.$store.commit('setUserSelectedInMassCreation', this.itemsMassCreation)
},
- removeAllBookmark() {
+ removeAllBookmarks() {
this.itemsMassCreation = []
this.$store.commit('setUserSelectedInMassCreation', [])
this.getUsers()
diff --git a/admin/src/pages/CreationConfirm.spec.js b/admin/src/pages/CreationConfirm.spec.js
index 5768e1078..2520fd37b 100644
--- a/admin/src/pages/CreationConfirm.spec.js
+++ b/admin/src/pages/CreationConfirm.spec.js
@@ -78,6 +78,7 @@ describe('CreationConfirm', () => {
it('commits resetOpenCreations to store', () => {
expect(storeCommitMock).toBeCalledWith('resetOpenCreations')
})
+
it('commits setOpenCreations to store', () => {
expect(storeCommitMock).toBeCalledWith('setOpenCreations', 2)
})
@@ -85,7 +86,7 @@ describe('CreationConfirm', () => {
describe('remove creation with success', () => {
beforeEach(async () => {
- await wrapper.findComponent({ name: 'UserTable' }).vm.$emit('remove-creation', { id: 1 })
+ await wrapper.findAll('tr').at(1).findAll('button').at(0).trigger('click')
})
it('calls the deletePendingCreation mutation', () => {
@@ -107,7 +108,7 @@ describe('CreationConfirm', () => {
describe('remove creation with error', () => {
beforeEach(async () => {
apolloMutateMock.mockRejectedValue({ message: 'Ouchhh!' })
- await wrapper.findComponent({ name: 'UserTable' }).vm.$emit('remove-creation', { id: 1 })
+ await wrapper.findAll('tr').at(1).findAll('button').at(0).trigger('click')
})
it('toasts an error message', () => {
@@ -118,22 +119,52 @@ describe('CreationConfirm', () => {
describe('confirm creation with success', () => {
beforeEach(async () => {
apolloMutateMock.mockResolvedValue({})
- await wrapper.findComponent({ name: 'UserTable' }).vm.$emit('confirm-creation', { id: 2 })
+ await wrapper.findAll('tr').at(2).findAll('button').at(2).trigger('click')
})
- it('calls the confirmPendingCreation mutation', () => {
- expect(apolloMutateMock).toBeCalledWith({
- mutation: confirmPendingCreation,
- variables: { id: 2 },
+ describe('overlay', () => {
+ it('opens the overlay', () => {
+ expect(wrapper.find('#overlay').isVisible()).toBeTruthy()
})
- })
- it('commits openCreationsMinus to store', () => {
- expect(storeCommitMock).toBeCalledWith('openCreationsMinus', 1)
- })
+ describe('cancel confirmation', () => {
+ beforeEach(async () => {
+ await wrapper.find('#overlay').findAll('button').at(0).trigger('click')
+ })
- it('toasts a success message', () => {
- expect(toastedSuccessMock).toBeCalledWith('creation_form.toasted_created')
+ it('closes the overlay', () => {
+ expect(wrapper.find('#overlay').isVisible()).toBeFalsy()
+ })
+
+ it('still has 2 items in the table', () => {
+ expect(wrapper.findAll('tbody > tr')).toHaveLength(2)
+ })
+ })
+
+ describe('confirm creation', () => {
+ beforeEach(async () => {
+ await wrapper.find('#overlay').findAll('button').at(1).trigger('click')
+ })
+
+ it('calls the confirmPendingCreation mutation', () => {
+ expect(apolloMutateMock).toBeCalledWith({
+ mutation: confirmPendingCreation,
+ variables: { id: 2 },
+ })
+ })
+
+ it('commits openCreationsMinus to store', () => {
+ expect(storeCommitMock).toBeCalledWith('openCreationsMinus', 1)
+ })
+
+ it('toasts a success message', () => {
+ expect(toastedSuccessMock).toBeCalledWith('creation_form.toasted_created')
+ })
+
+ it('has 1 item left in the table', () => {
+ expect(wrapper.findAll('tbody > tr')).toHaveLength(1)
+ })
+ })
})
})
diff --git a/admin/src/pages/UserSearch.spec.js b/admin/src/pages/UserSearch.spec.js
index 64783e82e..fe7bde0cc 100644
--- a/admin/src/pages/UserSearch.spec.js
+++ b/admin/src/pages/UserSearch.spec.js
@@ -88,100 +88,6 @@ describe('UserSearch', () => {
)
})
- describe('row toggling', () => {
- it('has 4 users in the table', () => {
- expect(wrapper.findAll('tbody > tr')).toHaveLength(4)
- })
-
- describe('user with email not activated', () => {
- it('has no details button', () => {
- expect(
- wrapper.findAll('tbody > tr').at(3).findAll('td').at(4).find('button').exists(),
- ).toBeFalsy()
- })
-
- it('has a red confirmed button with envelope item', () => {
- const row = wrapper.findAll('tbody > tr').at(3)
- expect(row.findAll('td').at(5).find('button').exists()).toBeTruthy()
- expect(row.findAll('td').at(5).find('button').classes('btn-danger')).toBeTruthy()
- expect(row.findAll('td').at(5).find('svg').classes('bi-envelope')).toBeTruthy()
- })
-
- describe('click on envelope', () => {
- it('opens the details', async () => {
- await wrapper
- .findAll('tbody > tr')
- .at(3)
- .findAll('td')
- .at(5)
- .find('button')
- .trigger('click')
- expect(wrapper.findAll('tbody > tr')).toHaveLength(6)
- expect(wrapper.findAll('tbody > tr').at(5).find('input').element.value).toBe(
- 'new@user.ch',
- )
- expect(wrapper.findAll('tbody > tr').at(5).text()).toContain(
- 'unregister_mail.text_false',
- )
- })
-
- describe('click on envelope again', () => {
- it('closes the details', async () => {
- await wrapper
- .findAll('tbody > tr')
- .at(3)
- .findAll('td')
- .at(5)
- .find('button')
- .trigger('click')
- expect(wrapper.findAll('tbody > tr')).toHaveLength(4)
- })
- })
-
- describe('click on close details', () => {
- it('closes the details', async () => {
- await wrapper
- .findAll('tbody > tr')
- .at(3)
- .findAll('td')
- .at(5)
- .find('button')
- .trigger('click')
- await wrapper.findAll('tbody > tr').at(5).findAll('button').at(1).trigger('click')
- expect(wrapper.findAll('tbody > tr')).toHaveLength(4)
- })
- })
- })
- })
-
- describe('different details', () => {
- it.skip('shows the creation formular for second user', async () => {
- await wrapper
- .findAll('tbody > tr')
- .at(1)
- .findAll('td')
- .at(4)
- .find('button')
- .trigger('click')
- expect(wrapper.findAll('tbody > tr')).toHaveLength(6)
- expect(
- wrapper.findAll('tbody > tr').at(3).find('div.component-creation-formular').exists(),
- ).toBeTruthy()
- })
-
- it.skip('shows the transactions for third user', async () => {
- await wrapper
- .findAll('tbody > tr')
- .at(4)
- .findAll('td')
- .at(6)
- .find('button')
- .trigger('click')
- expect(wrapper.findAll('tbody > tr')).toHaveLength(6)
- })
- })
- })
-
describe('unconfirmed emails', () => {
beforeEach(async () => {
await wrapper.find('button.btn-block').trigger('click')
@@ -237,6 +143,23 @@ describe('UserSearch', () => {
}),
)
})
+
+ describe('reset the search field', () => {
+ it('calls the API with empty criteria', async () => {
+ jest.clearAllMocks()
+ await wrapper.find('.test-click-clear-criteria').trigger('click')
+ expect(apolloQueryMock).toBeCalledWith(
+ expect.objectContaining({
+ variables: {
+ searchText: '',
+ currentPage: 1,
+ pageSize: 25,
+ notActivated: false,
+ },
+ }),
+ )
+ })
+ })
})
describe('apollo returns error', () => {
diff --git a/admin/src/pages/UserSearch.vue b/admin/src/pages/UserSearch.vue
index eca0189a0..28e1a7774 100644
--- a/admin/src/pages/UserSearch.vue
+++ b/admin/src/pages/UserSearch.vue
@@ -7,12 +7,21 @@
-
+
+
+
+
+
+
+
+
+
+
{
}
const propsData = {
- balance: 100.0,
+ balance: 0.0,
}
const Wrapper = () => {
@@ -37,7 +37,44 @@ describe('GddSend', () => {
expect(wrapper.find('div.transaction-form').exists()).toBeTruthy()
})
+ describe('transaction form disable because balance 0,0 GDD', () => {
+ it('has a disabled input field of type email', () => {
+ expect(wrapper.find('#input-group-1').find('input').attributes('disabled')).toBe('disabled')
+ })
+ it('has a disabled input field for amount', () => {
+ expect(wrapper.find('#input-2').find('input').attributes('disabled')).toBe('disabled')
+ })
+ it('has a disabled textarea field ', () => {
+ expect(wrapper.find('#input-3').find('textarea').attributes('disabled')).toBe('disabled')
+ })
+ it('has a message indicating that there are no GDDs to send ', () => {
+ expect(wrapper.find('.text-danger').text()).toBe('form.no_gdd_available')
+ })
+ it('has no reset button and no submit button ', () => {
+ expect(wrapper.find('.test-buttons').exists()).toBeFalsy()
+ })
+ })
+
describe('transaction form', () => {
+ beforeEach(() => {
+ wrapper.setProps({ balance: 100.0 })
+ })
+ describe('transaction form show because balance 100,0 GDD', () => {
+ it('has no warning message ', () => {
+ expect(wrapper.find('.text-danger').exists()).toBeFalsy()
+ })
+ it('has a reset button', () => {
+ expect(wrapper.find('.test-buttons').findAll('button').at(0).attributes('type')).toBe(
+ 'reset',
+ )
+ })
+ it('has a submit button', () => {
+ expect(wrapper.find('.test-buttons').findAll('button').at(1).attributes('type')).toBe(
+ 'submit',
+ )
+ })
+ })
+
describe('email field', () => {
it('has an input field of type email', () => {
expect(wrapper.find('#input-group-1').find('input').attributes('type')).toBe('email')
diff --git a/frontend/src/views/Pages/SendOverview/GddSend/TransactionForm.vue b/frontend/src/views/Pages/SendOverview/GddSend/TransactionForm.vue
index 364f54ac7..0f5650543 100644
--- a/frontend/src/views/Pages/SendOverview/GddSend/TransactionForm.vue
+++ b/frontend/src/views/Pages/SendOverview/GddSend/TransactionForm.vue
@@ -41,6 +41,7 @@
placeholder="E-Mail"
style="font-size: large"
class="pl-3"
+ :disabled="isBalanceDisabled"
>
@@ -76,6 +77,7 @@
:placeholder="$n(0.01)"
style="font-size: large"
class="pl-3"
+ :disabled="isBalanceDisabled"
>
@@ -105,6 +107,7 @@
v-model="form.memo"
class="pl-3"
style="font-size: large"
+ :disabled="isBalanceDisabled"
>
@@ -114,7 +117,10 @@
-
+
+ {{ $t('form.no_gdd_available') }}
+
+
{{ $t('form.reset') }}
@@ -192,6 +198,11 @@ export default {
this.form.email = this.form.email.trim()
},
},
+ computed: {
+ isBalanceDisabled() {
+ return this.balance <= 0 ? 'disabled' : false
+ },
+ },
}