Merge branch 'master' into 2594-filter-query-all-contributions

This commit is contained in:
Hannes Heine 2023-01-26 10:21:14 +01:00 committed by GitHub
commit 1fac86def0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 279 additions and 212 deletions

View File

@ -39,7 +39,7 @@ module.exports = {
{
src: './src',
extensions: ['.js', '.vue'],
ignores: [],
ignores: ['/overlay/'],
enableFix: false,
},
],

View File

@ -1,7 +1,7 @@
<template>
<div class="component-overlay">
<b-jumbotron class="bg-light p-4">
<template #header>{{ $t('overlay.confirm.title') }}</template>
<template #header><slot name="title" /></template>
<template #lead>
<b-row class="mt-4">
@ -31,26 +31,18 @@
</template>
<hr class="my-4" />
<p>{{ $t('overlay.confirm.text') }}</p>
<p>
{{ $t('overlay.confirm.question') }}
</p>
<slot name="text" />
<slot name="question" />
<b-container>
<b-row>
<b-col>
<b-button size="md" variant="danger" class="m-3" @click="$emit('overlay-cancel')">
{{ $t('overlay.confirm.cancel') }}
<b-button size="md" variant="info" class="m-3" @click="$emit('overlay-cancel')">
{{ $t('overlay.cancel') }}
</b-button>
</b-col>
<b-col class="text-right">
<b-button
size="md"
variant="success"
class="m-3 text-right"
@click="$emit('confirm-creation', item)"
>
{{ $t('overlay.confirm.yes') }}
</b-button>
<slot name="submit-btn" />
</b-col>
</b-row>
</b-container>

View File

@ -5,7 +5,7 @@
<b-button
variant="danger"
size="md"
@click="$emit('remove-creation', row.item)"
@click="$emit('show-overlay', row.item, 'delete')"
class="mr-2"
>
<b-icon icon="trash" variant="light"></b-icon>
@ -37,30 +37,30 @@
</b-button>
</div>
</template>
<template #cell(deny)="row">
<div v-if="$store.state.moderator.id !== row.item.userId">
<b-button
variant="warning"
size="md"
@click="$emit('show-overlay', row.item, 'deny')"
class="mr-2"
>
<b-icon icon="x" variant="light"></b-icon>
</b-button>
</div>
</template>
<template #cell(confirm)="row">
<div v-if="$store.state.moderator.id !== row.item.userId">
<b-button
variant="success"
size="md"
@click="$emit('show-overlay', row.item)"
@click="$emit('show-overlay', row.item, 'confirm')"
class="mr-2"
>
<b-icon icon="check" scale="2" variant=""></b-icon>
</b-button>
</div>
</template>
<template #cell(deny)="row">
<div v-if="$store.state.moderator.id !== row.item.userId">
<b-button
variant="danger"
size="md"
@click="$emit('deny-creation', row.item)"
class="mr-2"
>
<b-icon icon="x" variant="light"></b-icon>
</b-button>
</div>
</template>
<template #row-details="row">
<row-details
:row="row"

View File

@ -34,8 +34,6 @@
"creation_form": {
"creation_failed": "Ausstehende Schöpfung für {email} konnte nicht erzeugt werden.",
"creation_for": "Aktives Grundeinkommen für",
"deleteNow": "Möchtest du diesen Beitrag zur Gemeinschaft wirklich löschen?",
"denyNow": "Möchtest du diesen Beitrag zur Gemeinschaft wirklich ablehnen?",
"enter_text": "Text eintragen",
"form": "Schöpfungsformular",
"min_characters": "Mindestens 10 Zeichen eingeben",
@ -113,12 +111,24 @@
"open": "offen",
"open_creations": "Offene Schöpfungen",
"overlay": {
"confirm": {
"cancel": "Abbrechen",
"question": "Willst du diese vorgespeicherte Schöpfung wirklich vollziehen und endgültig speichern?",
"confirm": {
"question": "Willst du diesen Gemeinwohl-Beitrag wirklich bestätigen und gutschreiben?",
"text": "Nach dem Speichern ist der Datensatz nicht mehr änderbar. Bitte überprüfe genau, dass alles stimmt.",
"title": "Gemeinwohl-Beitrag bestätigen!",
"yes": "Ja, Beitrag bestätigen und speichern!"
},
"delete": {
"question": "Willst du diesen Gemeinwohl-Beitrag wirklich endgültig löschen?",
"text": "Nach dem Löschen ist der Datensatz nicht mehr vorhanden.",
"title": "Gemeinwohl-Beitrag löschen!",
"yes": "Ja, Beitrag löschen!"
},
"deny": {
"question": "Willst du diesen Gemeinwohl-Beitrag wirklich ablehnen?",
"text": "Nach dem Speichern ist der Datensatz nicht mehr änderbar und kann auch nicht mehr gelöscht werden. Bitte überprüfe genau, dass alles stimmt.",
"title": "Schöpfung bestätigen!",
"yes": "Ja, Schöpfung bestätigen und speichern!"
"title": "Gemeinwohl-Beitrag ablehnen!",
"yes": "Ja, Beitrag ablehnen und speichern!"
}
},
"redeemed": "eingelöst",

View File

@ -34,8 +34,6 @@
"creation_form": {
"creation_failed": "Could not create pending creation for {email}",
"creation_for": "Active Basic Income for",
"deleteNow": "Do you really want to delete this contribution to the community?",
"denyNow": "Do you really want to reject this contribution to the community?",
"enter_text": "Enter text",
"form": "Creation form",
"min_characters": "Enter at least 10 characters",
@ -113,12 +111,24 @@
"open": "open",
"open_creations": "Open creations",
"overlay": {
"confirm": {
"cancel": "Cancel",
"confirm": {
"question": "Do you really want to carry out and finally save this pre-stored creation?",
"text": "After saving, the record can no longer be changed or deleted. Please check carefully that everything is correct.",
"text": "After saving, the record can no longer be changed. Please check carefully that everything is correct.",
"title": "Confirm creation!",
"yes": "Yes, confirm and save creation!"
},
"delete": {
"question": "Do you really want to carry out and finally save this pre-stored creation?",
"text": "After saving, the record can no longer be changed or deleted. Please check carefully that everything is correct.",
"title": "Delete creation!",
"yes": "Yes, delete and save creation!"
},
"deny": {
"question": "Do you really want to carry out and finally save this pre-stored creation?",
"text": "After saving, the record can no longer be changed or deleted. Please check carefully that everything is correct.",
"title": "Reject creation!",
"yes": "Yes, reject and save creation!"
}
},
"redeemed": "redeemed",

View File

@ -139,24 +139,39 @@ describe('CreationConfirm', () => {
})
})
describe('remove creation with success', () => {
let spy
describe('admin confirms deletion', () => {
describe('actions in overlay', () => {
describe('delete creation', () => {
beforeEach(async () => {
spy = jest.spyOn(wrapper.vm.$bvModal, 'msgBoxConfirm')
spy.mockImplementation(() => Promise.resolve('some value'))
await wrapper.findAll('tr').at(1).findAll('button').at(0).trigger('click')
})
it('opens a modal', () => {
expect(spy).toBeCalled()
it('opens the overlay', () => {
expect(wrapper.find('#overlay').isVisible()).toBeTruthy()
})
describe('with success', () => {
describe('cancel deletion', () => {
beforeEach(async () => {
await wrapper.find('#overlay').findAll('button').at(0).trigger('click')
})
it('closes the overlay', async () => {
expect(wrapper.find('#overlay').exists()).toBeFalsy()
})
it('still has 2 items in the table', () => {
expect(wrapper.findAll('tbody > tr')).toHaveLength(2)
})
})
describe('confirm deletion', () => {
beforeEach(async () => {
await wrapper.find('#overlay').findAll('button').at(1).trigger('click')
})
it('calls the adminDeleteContribution mutation', () => {
expect(adminDeleteContributionMock).toBeCalledWith({ id: 1 })
})
it('commits openCreationsMinus to store', () => {
expect(storeCommitMock).toBeCalledWith('openCreationsMinus', 1)
})
@ -164,46 +179,35 @@ describe('CreationConfirm', () => {
it('toasts a success message', () => {
expect(toastSuccessSpy).toBeCalledWith('creation_form.toasted_delete')
})
it('has 1 item left in the table', () => {
expect(wrapper.findAll('tbody > tr')).toHaveLength(1)
})
})
describe('admin cancels deletion', () => {
describe('with error', () => {
beforeEach(async () => {
spy = jest.spyOn(wrapper.vm.$bvModal, 'msgBoxConfirm')
spy.mockImplementation(() => Promise.resolve(false))
await wrapper.findAll('tr').at(1).findAll('button').at(0).trigger('click')
})
it('does not call the adminDeleteContribution mutation', () => {
expect(adminDeleteContributionMock).not.toBeCalled()
})
})
})
describe('remove creation with error', () => {
let spy
beforeEach(async () => {
spy = jest.spyOn(wrapper.vm.$bvModal, 'msgBoxConfirm')
spy.mockImplementation(() => Promise.resolve('some value'))
adminDeleteContributionMock.mockRejectedValue({ message: 'Ouchhh!' })
await wrapper.findAll('tr').at(1).findAll('button').at(0).trigger('click')
await wrapper.find('#overlay').findAll('button').at(1).trigger('click')
})
it('toasts an error message', () => {
expect(toastErrorSpy).toBeCalledWith('Ouchhh!')
})
})
describe('confirm creation with success', () => {
beforeEach(async () => {
await wrapper.findAll('tr').at(2).findAll('button').at(2).trigger('click')
})
})
describe('confirm creation', () => {
beforeEach(async () => {
await wrapper.findAll('tr').at(2).findAll('button').at(3).trigger('click')
})
describe('overlay', () => {
it('opens the overlay', () => {
expect(wrapper.find('#overlay').isVisible()).toBeTruthy()
})
describe('with succes', () => {
describe('cancel confirmation', () => {
beforeEach(async () => {
await wrapper.find('#overlay').findAll('button').at(0).trigger('click')
@ -218,7 +222,7 @@ describe('CreationConfirm', () => {
})
})
describe('confirm creation', () => {
describe('confirm confirmation', () => {
beforeEach(async () => {
await wrapper.find('#overlay').findAll('button').at(1).trigger('click')
})
@ -239,8 +243,9 @@ describe('CreationConfirm', () => {
expect(wrapper.findAll('tbody > tr')).toHaveLength(1)
})
})
})
describe('confirm creation with error', () => {
describe('with error', () => {
beforeEach(async () => {
confirmContributionMock.mockRejectedValue({ message: 'Ouchhh!' })
await wrapper.find('#overlay').findAll('button').at(1).trigger('click')
@ -251,37 +256,37 @@ describe('CreationConfirm', () => {
})
})
})
})
describe('deny creation with error', () => {
let spy
describe('deny creation', () => {
beforeEach(async () => {
spy = jest.spyOn(wrapper.vm.$bvModal, 'msgBoxConfirm')
spy.mockImplementation(() => Promise.resolve('some value'))
await wrapper.findAll('tr').at(1).findAll('button').at(0).trigger('click')
await wrapper.findAll('tr').at(1).findAll('button').at(2).trigger('click')
})
it('toasts an error message', () => {
expect(toastErrorSpy).toBeCalledWith('Ouchhh!')
})
it('opens the overlay', () => {
expect(wrapper.find('#overlay').isVisible()).toBeTruthy()
})
describe('deny creation with success', () => {
let spy
describe('admin confirms deny', () => {
describe('with succes', () => {
describe('cancel deny', () => {
beforeEach(async () => {
spy = jest.spyOn(wrapper.vm.$bvModal, 'msgBoxConfirm')
spy.mockImplementation(() => Promise.resolve('some value'))
await wrapper.findAll('tr').at(1).findAll('button').at(3).trigger('click')
await wrapper.find('#overlay').findAll('button').at(0).trigger('click')
})
it('opens a modal', () => {
expect(spy).toBeCalled()
it('closes the overlay', async () => {
expect(wrapper.find('#overlay').exists()).toBeFalsy()
})
it('calls the adminDeleteContribution mutation', () => {
it('still has 2 items in the table', () => {
expect(wrapper.findAll('tbody > tr')).toHaveLength(2)
})
})
describe('confirm deny', () => {
beforeEach(async () => {
await wrapper.find('#overlay').findAll('button').at(1).trigger('click')
})
it('calls the denyContribution mutation', () => {
expect(adminDenyContributionMock).toBeCalledWith({ id: 1 })
})
@ -292,17 +297,22 @@ describe('CreationConfirm', () => {
it('toasts a success message', () => {
expect(toastSuccessSpy).toBeCalledWith('creation_form.toasted_denied')
})
it('has 1 item left in the table', () => {
expect(wrapper.findAll('tbody > tr')).toHaveLength(1)
})
})
})
describe('admin cancels deny', () => {
describe('with error', () => {
beforeEach(async () => {
spy = jest.spyOn(wrapper.vm.$bvModal, 'msgBoxConfirm')
spy.mockImplementation(() => Promise.resolve(false))
await wrapper.findAll('tr').at(1).findAll('button').at(3).trigger('click')
adminDenyContributionMock.mockRejectedValue({ message: 'Ouchhh!' })
await wrapper.find('#overlay').findAll('button').at(1).trigger('click')
})
it('does not call the adminDeleteContribution mutation', () => {
expect(adminDenyContributionMock).not.toBeCalled()
it('toasts an error message', () => {
expect(toastErrorSpy).toBeCalledWith('Ouchhh!')
})
})
})
})

View File

@ -1,14 +1,33 @@
<!-- eslint-disable @intlify/vue-i18n/no-dynamic-keys -->
<template>
<div class="creation-confirm">
<div v-if="overlay" id="overlay" @dblclick="overlay = false">
<overlay :item="item" @overlay-cancel="overlay = false" @confirm-creation="confirmCreation" />
<overlay :item="item" @overlay-cancel="overlay = false">
<template #title>
{{ $t(overlayTitle) }}
</template>
<template #text>
<p>{{ $t(overlayText) }}</p>
</template>
<template #question>
<p>{{ $t(overlayQuestion) }}</p>
</template>
<template #submit-btn>
<b-button
size="md"
v-bind:variant="overlayIcon"
class="m-3 text-right"
@click="overlayEvent"
>
{{ $t(overlayBtnText) }}
</b-button>
</template>
</overlay>
</div>
<open-creations-table
class="mt-4"
:items="pendingCreations"
:fields="fields"
@deny-creation="denyCreation"
@remove-creation="removeCreation"
@show-overlay="showOverlay"
@update-state="updateState"
@update-contributions="$apollo.queries.PendingContributions.refetch()"
@ -34,46 +53,44 @@ export default {
pendingCreations: [],
overlay: false,
item: {},
variant: 'confirm',
}
},
methods: {
denyCreation(item) {
this.$bvModal.msgBoxConfirm(this.$t('creation_form.denyNow')).then(async (value) => {
if (value) {
await this.$apollo
.mutate({
mutation: denyContribution,
variables: {
id: item.id,
},
})
.then((result) => {
this.updatePendingCreations(item.id)
this.toastSuccess(this.$t('creation_form.toasted_denied'))
})
.catch((error) => {
this.toastError(error.message)
})
}
})
},
removeCreation(item) {
this.$bvModal.msgBoxConfirm(this.$t('creation_form.deleteNow')).then(async (value) => {
if (value)
await this.$apollo
deleteCreation() {
this.$apollo
.mutate({
mutation: adminDeleteContribution,
variables: {
id: item.id,
id: this.item.id,
},
})
.then((result) => {
this.updatePendingCreations(item.id)
this.overlay = false
this.updatePendingCreations(this.item.id)
this.toastSuccess(this.$t('creation_form.toasted_delete'))
})
.catch((error) => {
this.overlay = false
this.toastError(error.message)
})
},
denyCreation() {
this.$apollo
.mutate({
mutation: denyContribution,
variables: {
id: this.item.id,
},
})
.then((result) => {
this.overlay = false
this.updatePendingCreations(this.item.id)
this.toastSuccess(this.$t('creation_form.toasted_denied'))
})
.catch((error) => {
this.overlay = false
this.toastError(error.message)
})
},
confirmCreation() {
@ -98,9 +115,10 @@ export default {
this.pendingCreations = this.pendingCreations.filter((obj) => obj.id !== id)
this.$store.commit('openCreationsMinus', 1)
},
showOverlay(item) {
showOverlay(item, variant) {
this.overlay = true
this.item = item
this.variant = variant
},
updateState(id) {
this.pendingCreations.find((obj) => obj.id === id).messagesCount++
@ -131,10 +149,37 @@ export default {
},
{ key: 'moderator', label: this.$t('moderator') },
{ key: 'editCreation', label: this.$t('edit') },
{ key: 'confirm', label: this.$t('save') },
{ key: 'deny', label: this.$t('deny') },
{ key: 'confirm', label: this.$t('save') },
]
},
overlayTitle() {
return `overlay.${this.variant}.title`
},
overlayText() {
return `overlay.${this.variant}.text`
},
overlayQuestion() {
return `overlay.${this.variant}.question`
},
overlayBtnText() {
return `overlay.${this.variant}.yes`
},
overlayEvent() {
return this[`${this.variant}Creation`]
},
overlayIcon() {
switch (this.variant) {
case 'confirm':
return 'success'
case 'deny':
return 'warning'
case 'delete':
return 'danger'
default:
return 'info'
}
},
},
apollo: {
PendingContributions: {