mirror of
https://github.com/IT4Change/gradido.git
synced 2026-02-06 09:56:05 +00:00
473 lines
13 KiB
Vue
473 lines
13 KiB
Vue
<!-- eslint-disable @intlify/vue-i18n/no-dynamic-keys -->
|
|
<template>
|
|
<div class="creation-confirm">
|
|
<user-query v-model="query" class="mb-2 mt-2" :placeholder="$t('user_memo_search')" />
|
|
<p class="mb-2">
|
|
<input v-model="noHashtag" type="checkbox" class="noHashtag" />
|
|
<span v-b-tooltip="$t('no_hashtag_tooltip')" class="ms-2">{{ $t('no_hashtag') }}</span>
|
|
</p>
|
|
<p v-if="showResubmissionCheckbox" class="mb-4">
|
|
<input v-model="hideResubmissionModel" type="checkbox" class="hideResubmission" />
|
|
<span v-b-tooltip="$t('hide_resubmission_tooltip')" class="ms-2">
|
|
{{ $t('hide_resubmission') }}
|
|
</span>
|
|
</p>
|
|
<div>
|
|
<BTabs v-model="tabIndex" content-class="mt-3" fill>
|
|
<BTab active :title-link-attributes="{ 'data-test': 'open' }">
|
|
<template #title>
|
|
<IBiBellFill style="color: #0d6efd" />
|
|
{{ $t('contributions.open') }}
|
|
<BBadge v-if="$store.state.openCreations > 0" variant="danger">
|
|
{{ $store.state.openCreations }}
|
|
</BBadge>
|
|
</template>
|
|
</BTab>
|
|
<BTab :title-link-attributes="{ 'data-test': 'confirmed' }">
|
|
<template #title>
|
|
<IBiCheck style="color: #198754" />
|
|
{{ $t('contributions.confirms') }}
|
|
</template>
|
|
</BTab>
|
|
<BTab :title-link-attributes="{ 'data-test': 'denied' }">
|
|
<template #title>
|
|
<IBiXCircle style="color: #ffc107" />
|
|
{{ $t('contributions.denied') }}
|
|
</template>
|
|
</BTab>
|
|
<BTab :title-link-attributes="{ 'data-test': 'deleted' }">
|
|
<template #title>
|
|
<IBiTrash style="color: #dc3545" />
|
|
{{ $t('contributions.deleted') }}
|
|
</template>
|
|
</BTab>
|
|
<BTab :title-link-attributes="{ 'data-test': 'all' }">
|
|
<template #title>
|
|
<IBiList />
|
|
{{ $t('contributions.all') }}
|
|
</template>
|
|
</BTab>
|
|
</BTabs>
|
|
</div>
|
|
<open-creations-table
|
|
class="mt-4"
|
|
:items="items"
|
|
:fields="fields"
|
|
:hide-resubmission="hideResubmission"
|
|
@show-overlay="showOverlay"
|
|
@update-status="updateStatus"
|
|
@reload-contribution="reloadContribution"
|
|
@update-contributions="refetch"
|
|
@search-for-email="query = $event"
|
|
/>
|
|
|
|
<BPagination
|
|
v-model="currentPage"
|
|
pills
|
|
size="lg"
|
|
:per-page="pageSize"
|
|
:total-rows="rows"
|
|
align="center"
|
|
:hide-ellipsis="true"
|
|
/>
|
|
|
|
<div v-if="overlay" id="overlay" @dblclick="overlay = false">
|
|
<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>
|
|
<BButton size="md" :variant="overlayIcon" class="m-3 text-end" @click="overlayEvent">
|
|
{{ $t(overlayBtnText) }}
|
|
</BButton>
|
|
</template>
|
|
</Overlay>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { ref, computed, watch } from 'vue'
|
|
import { useQuery, useMutation } from '@vue/apollo-composable'
|
|
import { useStore } from 'vuex'
|
|
import { useI18n } from 'vue-i18n'
|
|
|
|
import Overlay from '../components/Overlay'
|
|
import OpenCreationsTable from '../components/Tables/OpenCreationsTable'
|
|
import UserQuery from '../components/UserQuery'
|
|
import { adminListContributions } from '../graphql/adminListContributions'
|
|
import { adminDeleteContribution } from '../graphql/adminDeleteContribution'
|
|
import { confirmContribution } from '../graphql/confirmContribution'
|
|
import { denyContribution } from '../graphql/denyContribution'
|
|
import { getContribution } from '../graphql/getContribution'
|
|
import { useAppToast } from '@/composables/useToast'
|
|
|
|
const FILTER_TAB_MAP = [
|
|
['IN_PROGRESS', 'PENDING'],
|
|
['CONFIRMED'],
|
|
['DENIED'],
|
|
['DELETED'],
|
|
['IN_PROGRESS', 'PENDING', 'CONFIRMED', 'DENIED', 'DELETED'],
|
|
]
|
|
|
|
const store = useStore()
|
|
const { t, d } = useI18n()
|
|
const { toastError, toastSuccess } = useAppToast()
|
|
|
|
const tabIndex = ref(0)
|
|
const items = ref([])
|
|
const overlay = ref(false)
|
|
const item = ref({})
|
|
const variant = ref('confirm')
|
|
const rows = ref(0)
|
|
const currentPage = ref(1)
|
|
const pageSize = ref(25)
|
|
const query = ref('')
|
|
const noHashtag = ref(null)
|
|
const hideResubmissionModel = ref(true)
|
|
|
|
const fields = computed(
|
|
() =>
|
|
[
|
|
// open contributions
|
|
[
|
|
{ key: 'bookmark', label: t('delete') },
|
|
{ key: 'deny', label: t('deny') },
|
|
{ key: 'firstName', label: t('firstname') },
|
|
{ key: 'lastName', label: t('lastname') },
|
|
{
|
|
key: 'amount',
|
|
label: t('creation'),
|
|
formatter: (value) => value + ' GDD',
|
|
},
|
|
{ key: 'memo', label: t('text'), class: 'text-break' },
|
|
{
|
|
key: 'contributionDate',
|
|
label: t('created'),
|
|
formatter: (value) => formatDateOrDash(value),
|
|
},
|
|
{ key: 'moderatorId', label: t('moderator.moderator') },
|
|
{ key: 'editCreation', label: t('details') },
|
|
{ key: 'confirm', label: t('save') },
|
|
],
|
|
// confirmed contributions
|
|
[
|
|
{ key: 'firstName', label: t('firstname') },
|
|
{ key: 'lastName', label: t('lastname') },
|
|
{
|
|
key: 'amount',
|
|
label: t('creation'),
|
|
formatter: (value) => value + ' GDD',
|
|
},
|
|
{ key: 'memo', label: t('text'), class: 'text-break' },
|
|
{
|
|
key: 'contributionDate',
|
|
label: t('created'),
|
|
formatter: (value) => formatDateOrDash(value),
|
|
},
|
|
{
|
|
key: 'createdAt',
|
|
label: t('createdAt'),
|
|
formatter: (value) => formatDateOrDash(value),
|
|
},
|
|
{
|
|
key: 'confirmedAt',
|
|
label: t('contributions.confirms'),
|
|
formatter: (value) => formatDateOrDash(value),
|
|
},
|
|
{ key: 'confirmedBy', label: t('moderator.moderator') },
|
|
{ key: 'chatCreation', label: t('details') },
|
|
],
|
|
// denied contributions
|
|
[
|
|
{ key: 'firstName', label: t('firstname') },
|
|
{ key: 'lastName', label: t('lastname') },
|
|
{
|
|
key: 'amount',
|
|
label: t('creation'),
|
|
formatter: (value) => value + ' GDD',
|
|
},
|
|
{ key: 'memo', label: t('text'), class: 'text-break' },
|
|
{
|
|
key: 'contributionDate',
|
|
label: t('created'),
|
|
formatter: (value) => formatDateOrDash(value),
|
|
},
|
|
{
|
|
key: 'createdAt',
|
|
label: t('createdAt'),
|
|
formatter: (value) => formatDateOrDash(value),
|
|
},
|
|
{
|
|
key: 'deniedAt',
|
|
label: t('contributions.denied'),
|
|
formatter: (value) => formatDateOrDash(value),
|
|
},
|
|
{ key: 'deniedBy', label: t('moderator.moderator') },
|
|
{ key: 'chatCreation', label: t('details') },
|
|
],
|
|
// deleted contributions
|
|
[
|
|
{ key: 'firstName', label: t('firstname') },
|
|
{ key: 'lastName', label: t('lastname') },
|
|
{
|
|
key: 'amount',
|
|
label: t('creation'),
|
|
formatter: (value) => value + ' GDD',
|
|
},
|
|
{ key: 'memo', label: t('text'), class: 'text-break' },
|
|
{
|
|
key: 'contributionDate',
|
|
label: t('created'),
|
|
formatter: (value) => formatDateOrDash(value),
|
|
},
|
|
{
|
|
key: 'createdAt',
|
|
label: t('createdAt'),
|
|
formatter: (value) => formatDateOrDash(value),
|
|
},
|
|
{
|
|
key: 'deletedAt',
|
|
label: t('contributions.deleted'),
|
|
formatter: (value) => formatDateOrDash(value),
|
|
},
|
|
{ key: 'deletedBy', label: t('moderator.moderator') },
|
|
{ key: 'chatCreation', label: t('details') },
|
|
],
|
|
// all contributions
|
|
[
|
|
{ key: 'status', label: t('status') },
|
|
{ key: 'firstName', label: t('firstname') },
|
|
{ key: 'lastName', label: t('lastname') },
|
|
{
|
|
key: 'amount',
|
|
label: t('creation'),
|
|
formatter: (value) => value + ' GDD',
|
|
},
|
|
{ key: 'memo', label: t('text'), class: 'text-break' },
|
|
{
|
|
key: 'contributionDate',
|
|
label: t('created'),
|
|
formatter: (value) => formatDateOrDash(value),
|
|
},
|
|
{
|
|
key: 'createdAt',
|
|
label: t('createdAt'),
|
|
formatter: (value) => formatDateOrDash(value),
|
|
},
|
|
{
|
|
key: 'confirmedAt',
|
|
label: t('contributions.confirms'),
|
|
formatter: (value) => formatDateOrDash(value),
|
|
},
|
|
{ key: 'confirmedBy', label: t('moderator.moderator') },
|
|
{ key: 'chatCreation', label: t('details') },
|
|
],
|
|
][tabIndex.value],
|
|
)
|
|
|
|
const statusFilter = computed(() => [...FILTER_TAB_MAP[tabIndex.value]])
|
|
|
|
const overlayTitle = computed(() => `overlay.${variant.value}.title`)
|
|
const overlayText = computed(() => `overlay.${variant.value}.text`)
|
|
const overlayQuestion = computed(() => `overlay.${variant.value}.question`)
|
|
const overlayBtnText = computed(() => `overlay.${variant.value}.yes`)
|
|
const overlayEvent = computed(() => {
|
|
switch (variant.value) {
|
|
case 'confirm':
|
|
return confirmCreation
|
|
case 'deny':
|
|
return denyCreation
|
|
case 'delete':
|
|
return deleteCreation
|
|
default:
|
|
return null
|
|
}
|
|
})
|
|
const overlayIcon = computed(() => {
|
|
switch (variant.value) {
|
|
case 'confirm':
|
|
return 'success'
|
|
case 'deny':
|
|
return 'warning'
|
|
case 'delete':
|
|
return 'danger'
|
|
default:
|
|
return 'info'
|
|
}
|
|
})
|
|
const showResubmissionCheckbox = computed(() => tabIndex.value === 0)
|
|
const hideResubmission = computed(() =>
|
|
showResubmissionCheckbox.value ? hideResubmissionModel.value : false,
|
|
)
|
|
|
|
watch(tabIndex, () => {
|
|
currentPage.value = 1
|
|
items.value = []
|
|
})
|
|
|
|
const { onResult, onError, result, refetch } = useQuery(
|
|
adminListContributions,
|
|
{
|
|
currentPage: currentPage.value,
|
|
pageSize: pageSize.value,
|
|
statusFilter: statusFilter.value,
|
|
query: query.value,
|
|
noHashtag: noHashtag.value,
|
|
hideResubmission: hideResubmission.value,
|
|
},
|
|
{
|
|
fetchPolicy: 'no-cache',
|
|
},
|
|
)
|
|
|
|
watch([statusFilter, query, noHashtag, hideResubmission, currentPage], () => {
|
|
refetch({
|
|
currentPage: currentPage.value,
|
|
pageSize: pageSize.value,
|
|
statusFilter: statusFilter.value,
|
|
query: query.value,
|
|
noHashtag: noHashtag.value,
|
|
hideResubmission: hideResubmission.value,
|
|
})
|
|
})
|
|
|
|
onError((error) => {
|
|
toastError(error.message)
|
|
})
|
|
|
|
onResult(() => {
|
|
rows.value = result.value.adminListContributions.contributionCount
|
|
items.value = result.value.adminListContributions.contributionList
|
|
if (statusFilter.value.toString() === FILTER_TAB_MAP[0].toString()) {
|
|
store.commit('setOpenCreations', result.value.adminListContributions.contributionCount)
|
|
}
|
|
})
|
|
|
|
const {
|
|
mutate: deleteMutation,
|
|
onDone: onDeleteDone,
|
|
onError: onDeleteError,
|
|
} = useMutation(adminDeleteContribution)
|
|
|
|
onDeleteDone(() => {
|
|
overlay.value = false
|
|
updatePendingCreations(item.value.id)
|
|
toastSuccess(t('creation_form.toasted_delete'))
|
|
})
|
|
|
|
onDeleteError((error) => {
|
|
overlay.value = false
|
|
toastError(error.message)
|
|
})
|
|
|
|
const {
|
|
mutate: denyMutation,
|
|
onDone: onDenayDone,
|
|
onError: onDenayError,
|
|
} = useMutation(denyContribution)
|
|
|
|
onDenayDone(() => {
|
|
overlay.value = false
|
|
updatePendingCreations(item.value.id)
|
|
toastSuccess(t('creation_form.toasted_denied'))
|
|
})
|
|
|
|
onDenayError((error) => {
|
|
overlay.value = false
|
|
toastError(error.message)
|
|
})
|
|
|
|
const {
|
|
mutate: confirmMutation,
|
|
onDone: onConfirmationDone,
|
|
onError: onConfirmationError,
|
|
} = useMutation(confirmContribution)
|
|
|
|
onConfirmationDone(() => {
|
|
overlay.value = false
|
|
updatePendingCreations(item.value.id)
|
|
toastSuccess(t('creation_form.toasted_created'))
|
|
})
|
|
|
|
onConfirmationError((error) => {
|
|
overlay.value = false
|
|
toastError(error.message)
|
|
})
|
|
|
|
const reloadContribution = (id) => {
|
|
useQuery(getContribution, { id })
|
|
.onResult((result) => {
|
|
const contribution = result.data.contribution
|
|
const index = items.value.findIndex((obj) => obj.id === contribution.id)
|
|
items.value[index] = contribution
|
|
})
|
|
.onError((error) => {
|
|
overlay.value = false
|
|
toastError(error.message)
|
|
})
|
|
}
|
|
|
|
const deleteCreation = () => {
|
|
deleteMutation({
|
|
id: item.value.id,
|
|
})
|
|
}
|
|
|
|
const denyCreation = () => {
|
|
denyMutation({
|
|
id: item.value.id,
|
|
})
|
|
}
|
|
|
|
const confirmCreation = () => {
|
|
confirmMutation({
|
|
id: item.value.id,
|
|
})
|
|
}
|
|
|
|
const updatePendingCreations = (id) => {
|
|
items.value = items.value.filter((obj) => obj.id !== id)
|
|
store.commit('openCreationsMinus', 1)
|
|
}
|
|
|
|
const showOverlay = (selectedItem, selectedVariant) => {
|
|
overlay.value = true
|
|
item.value = selectedItem
|
|
variant.value = selectedVariant
|
|
}
|
|
|
|
const updateStatus = (id) => {
|
|
const target = items.value.find((obj) => obj.id === id)
|
|
if (target) {
|
|
target.messagesCount++
|
|
target.status = 'IN_PROGRESS'
|
|
}
|
|
}
|
|
|
|
const formatDateOrDash = (value) => {
|
|
return value ? d(new Date(value), 'short') : '—'
|
|
}
|
|
</script>
|
|
|
|
<style>
|
|
#overlay {
|
|
position: fixed;
|
|
display: flex;
|
|
align-items: center;
|
|
width: 100%;
|
|
height: 100%;
|
|
inset: 0;
|
|
padding-left: 5%;
|
|
background-color: rgb(12 11 11 / 78.1%);
|
|
z-index: 1000000;
|
|
cursor: pointer;
|
|
}
|
|
</style>
|