refactor contribution list, stay open after adding contribution message

This commit is contained in:
einhornimmond 2025-05-10 19:06:43 +02:00
parent 9b1e162042
commit 2cabeb87bb
14 changed files with 309 additions and 244 deletions

View File

@ -1,13 +1,15 @@
import { Contribution as dbContribution } from '@entity/Contribution'
import { User as DbUser } from '@entity/User'
import { ContributionMessage as dbContributionMessage } from '@entity/ContributionMessage'
import { Decimal } from 'decimal.js-light'
import { Field, Int, ObjectType } from 'type-graphql'
import { ContributionMessage } from './ContributionMessage'
import { User } from './User'
@ObjectType()
export class Contribution {
constructor(contribution: dbContribution, user?: DbUser | null) {
constructor(contribution: dbContribution) {
const user = contribution.user
this.id = contribution.id
this.firstName = user?.firstName ?? null
this.lastName = user?.lastName ?? null
@ -18,7 +20,7 @@ export class Contribution {
this.confirmedBy = contribution.confirmedBy
this.contributionDate = contribution.contributionDate
this.status = contribution.contributionStatus
this.messagesCount = contribution.messages ? contribution.messages.length : 0
this.messagesCount = contribution.messages?.length ?? 0
this.deniedAt = contribution.deniedAt
this.deniedBy = contribution.deniedBy
this.deletedAt = contribution.deletedAt
@ -28,9 +30,12 @@ export class Contribution {
this.moderatorId = contribution.moderatorId
this.userId = contribution.userId
this.resubmissionAt = contribution.resubmissionAt
if (user) {
this.user = new User(user)
}
this.user = user ? new User(user) : null
this.messages = contribution.messages
? contribution.messages.map(
(message: dbContributionMessage) => new ContributionMessage(message),
)
: null
}
@Field(() => Int)
@ -87,6 +92,9 @@ export class Contribution {
@Field(() => Int)
messagesCount: number
@Field(() => [ContributionMessage], { nullable: true })
messages: ContributionMessage[] | null
@Field(() => String)
status: string

View File

@ -1,18 +1,18 @@
import { ContributionMessage as DbContributionMessage } from '@entity/ContributionMessage'
import { User } from '@entity/User'
import { Field, Int, ObjectType } from 'type-graphql'
@ObjectType()
export class ContributionMessage {
constructor(contributionMessage: DbContributionMessage, user: User) {
constructor(contributionMessage: DbContributionMessage) {
const user = contributionMessage.user
this.id = contributionMessage.id
this.message = contributionMessage.message
this.createdAt = contributionMessage.createdAt
this.updatedAt = contributionMessage.updatedAt
this.type = contributionMessage.type
this.userFirstName = user.firstName
this.userLastName = user.lastName
this.userId = user.id
this.userFirstName = user?.firstName ?? null
this.userLastName = user?.lastName ?? null
this.userId = user?.id ?? null
this.isModerator = contributionMessage.isModerator
}

View File

@ -75,7 +75,7 @@ export class ContributionMessageResolver {
{ id: contributionId } as DbContribution,
finalContributionMessage,
)
return new ContributionMessage(finalContributionMessage, user)
return new ContributionMessage(finalContributionMessage)
}
@Authorized([RIGHTS.LIST_ALL_CONTRIBUTION_MESSAGES])
@ -87,16 +87,12 @@ export class ContributionMessageResolver {
): Promise<ContributionMessageListResult> {
const [contributionMessages, count] = await findContributionMessages({
contributionId,
currentPage,
pageSize,
order,
pagination: { currentPage, pageSize, order },
})
return {
count,
messages: contributionMessages.map(
(message) => new ContributionMessage(message, message.user),
),
messages: contributionMessages.map((message) => new ContributionMessage(message)),
}
}
@ -109,17 +105,13 @@ export class ContributionMessageResolver {
): Promise<ContributionMessageListResult> {
const [contributionMessages, count] = await findContributionMessages({
contributionId,
currentPage,
pageSize,
order,
pagination: { currentPage, pageSize, order },
showModeratorType: true,
})
return {
count,
messages: contributionMessages.map(
(message) => new ContributionMessage(message, message.user),
),
messages: contributionMessages.map((message) => new ContributionMessage(message)),
}
}
@ -194,6 +186,6 @@ export class ContributionMessageResolver {
finalContribution,
finalContributionMessage,
)
return new ContributionMessage(finalContributionMessage, moderator)
return new ContributionMessage(finalContributionMessage)
}
}

View File

@ -24,7 +24,6 @@ import { AdminUpdateContributionArgs } from '@arg/AdminUpdateContributionArgs'
import { ContributionArgs } from '@arg/ContributionArgs'
import { Paginated } from '@arg/Paginated'
import { SearchContributionsFilterArgs } from '@arg/SearchContributionsFilterArgs'
import { ContributionMessageType } from '@enum/ContributionMessageType'
import { ContributionStatus } from '@enum/ContributionStatus'
import { ContributionType } from '@enum/ContributionType'
import { TransactionTypeId } from '@enum/TransactionTypeId'
@ -60,11 +59,15 @@ import { TRANSACTIONS_LOCK } from '@/util/TRANSACTIONS_LOCK'
import { calculateDecay } from '@/util/decay'
import { fullName } from '@/util/utilities'
import { ContributionMessage } from '@model/ContributionMessage'
import { ContributionMessageType } from '../enum/ContributionMessageType'
import { findContribution } from './util/contributions'
import { getOpenCreations, getUserCreation, validateContribution } from './util/creations'
import { extractGraphQLFields, extractGraphQLFieldsForSelect } from './util/extractGraphQLFields'
import { findContributionMessages } from './util/findContributionMessages'
import { findContributions } from './util/findContributions'
import { getLastTransaction } from './util/getLastTransaction'
import { loadAllContributions, loadUserContributions } from './util/loadContributions'
import { sendTransactionsToDltConnector } from './util/sendTransactionsToDltConnector'
@Resolver(() => Contribution)
@ -143,46 +146,59 @@ export class ContributionResolver {
@Ctx() context: Context,
@Args()
paginated: Paginated,
@Arg('statusFilter', () => [ContributionStatus], { nullable: true })
statusFilter?: ContributionStatus[] | null,
): Promise<ContributionListResult> {
const user = getUser(context)
const filter = new SearchContributionsFilterArgs()
filter.statusFilter = statusFilter
filter.userId = user.id
const [dbContributions, count] = await findContributions(paginated, filter, true, {
messages: true,
})
const [dbContributions, count] = await loadUserContributions(user.id, paginated)
// show contributions in progress first
const inProgressContributions = dbContributions.filter(
(contribution) => contribution.contributionStatus === ContributionStatus.IN_PROGRESS,
)
const notInProgressContributions = dbContributions.filter(
(contribution) => contribution.contributionStatus !== ContributionStatus.IN_PROGRESS,
)
return new ContributionListResult(
count,
dbContributions.map((contribution) => {
// filter out moderator messages for this call
[...inProgressContributions, ...notInProgressContributions].map((contribution) => {
// we currently expect not much contribution messages for needing pagination
// but if we get more than expected, we should get warned
if ((contribution.messages?.length || 0) > 10) {
logger.warn('more contribution messages as expected, consider pagination', {
contributionId: contribution.id,
expected: 10,
actual: contribution.messages?.length || 0,
})
}
contribution.messages = contribution.messages?.filter(
(m) => (m.type as ContributionMessageType) !== ContributionMessageType.MODERATOR,
(message) => message.type !== ContributionMessageType.MODERATOR,
)
return new Contribution(contribution, user)
return new Contribution(contribution)
}),
)
}
@Authorized([RIGHTS.LIST_CONTRIBUTIONS])
@Query(() => Int)
async countContributionsInProgress(@Ctx() context: Context): Promise<number> {
const user = getUser(context)
const count = await DbContribution.count({
where: { userId: user.id, contributionStatus: ContributionStatus.IN_PROGRESS },
})
return count
}
@Authorized([RIGHTS.LIST_ALL_CONTRIBUTIONS])
@Query(() => ContributionListResult)
async listAllContributions(
@Args()
paginated: Paginated,
@Arg('statusFilter', () => [ContributionStatus], { nullable: true })
statusFilter?: ContributionStatus[] | null,
): Promise<ContributionListResult> {
const filter = new SearchContributionsFilterArgs()
filter.statusFilter = statusFilter
const [dbContributions, count] = await findContributions(paginated, filter, false, {
user: true,
})
const [dbContributions, count] = await loadAllContributions(paginated)
return new ContributionListResult(
count,
dbContributions.map((contribution) => new Contribution(contribution, contribution.user)),
dbContributions.map((contribution) => new Contribution(contribution)),
)
}
@ -370,7 +386,7 @@ export class ContributionResolver {
return new ContributionListResult(
count,
dbContributions.map((contribution) => new Contribution(contribution, contribution.user)),
dbContributions.map((contribution) => new Contribution(contribution)),
)
}
@ -627,4 +643,30 @@ export class ContributionResolver {
}
return new User(user)
}
@Authorized([RIGHTS.LIST_ALL_CONTRIBUTION_MESSAGES])
@FieldResolver(() => [ContributionMessage], { nullable: true })
async messages(
@Root() contribution: Contribution,
@Arg('pagination', () => Paginated) pagination: Paginated,
): Promise<ContributionMessage[] | null> {
if (contribution.messagesCount === 0) {
return null
}
const [contributionMessages] = await findContributionMessages({
contributionId: contribution.id,
pagination,
})
// we currently expect not much contribution messages for needing pagination
// but if we get more than expected, we should get warned
if (contributionMessages.length > pagination.pageSize) {
logger.warn('more contribution messages as expected, consider pagination', {
contributionId: contribution.id,
expected: pagination.pageSize,
actual: contributionMessages.length,
})
}
return contributionMessages.map((message) => new ContributionMessage(message))
}
}

View File

@ -1,28 +1,26 @@
import { In } from '@dbTools/typeorm'
import { ContributionMessage as DbContributionMessage } from '@entity/ContributionMessage'
import { Paginated } from '@arg/Paginated'
import { ContributionMessageType } from '@enum/ContributionMessageType'
import { Order } from '@enum/Order'
interface FindContributionMessagesOptions {
contributionId: number
pageSize: number
currentPage: number
order: Order
pagination: Paginated
showModeratorType?: boolean
}
export const findContributionMessages = async (
options: FindContributionMessagesOptions,
): Promise<[DbContributionMessage[], number]> => {
const { contributionId, pageSize, currentPage, order, showModeratorType } = options
const { contributionId, pagination, showModeratorType } = options
const messageTypes = [ContributionMessageType.DIALOG, ContributionMessageType.HISTORY]
if (showModeratorType) {
messageTypes.push(ContributionMessageType.MODERATOR)
}
const { currentPage, pageSize, order } = pagination
return DbContributionMessage.findAndCount({
where: {
contributionId,

View File

@ -0,0 +1,41 @@
import { Paginated } from '@arg/Paginated'
import { FindManyOptions } from '@dbTools/typeorm'
import { Contribution as DbContribution } from '@entity/Contribution'
function buildBaseOptions(paginated: Paginated): FindManyOptions<DbContribution> {
const { order, currentPage, pageSize } = paginated
return {
order: { createdAt: order, id: order },
skip: (currentPage - 1) * pageSize,
take: pageSize,
}
}
/*
* Load user contributions with messages
* @param userId if userId is set, load all contributions of the user, with messages
* @param paginated pagination, see {@link Paginated}
*/
export const loadUserContributions = async (
userId: number,
paginated: Paginated,
): Promise<[DbContribution[], number]> => {
return DbContribution.findAndCount({
where: { userId },
relations: { messages: { user: true } },
...buildBaseOptions(paginated),
})
}
/*
* Load all contributions
* @param paginated pagination, see {@link Paginated}
*/
export const loadAllContributions = async (
paginated: Paginated,
): Promise<[DbContribution[], number]> => {
return DbContribution.findAndCount({
relations: { user: true },
...buildBaseOptions(paginated),
})
}

View File

@ -5,10 +5,10 @@
<BForm @submit.prevent="onSubmit" @reset="onReset">
<BFormTextarea
id="textarea"
:model-value="form.text"
:model-value="formText"
:placeholder="$t('form.memo')"
:rows="3"
@update:model-value="form.text = $event"
@update:model-value="formText = $event"
/>
<BRow class="mt-4 mb-4">
<BCol>
@ -39,35 +39,37 @@ const props = defineProps({
},
})
const emit = defineEmits(['get-list-contribution-messages', 'update-status'])
const emit = defineEmits([
'get-list-contribution-messages',
'update-status',
'add-contribution-message',
])
const { t } = useI18n()
const { toastSuccess, toastError } = useAppToast()
const { mutate: createContributionMessageMutation } = useMutation(createContributionMessage)
const form = ref({
text: '',
})
const formText = ref('')
const isSubmitting = ref(false)
const disabled = computed(() => {
return form.value.text === '' || isSubmitting.value
return formText.value === '' || isSubmitting.value
})
async function onSubmit() {
isSubmitting.value = true
try {
await createContributionMessageMutation({
const result = await createContributionMessageMutation({
contributionId: props.contributionId,
message: form.value.text,
message: formText.value,
})
emit('get-list-contribution-messages', false)
// emit('get-list-contribution-messages', false)
formText.value = ''
emit('update-status', props.contributionId)
form.value.text = ''
emit('add-contribution-message', result.data.createContributionMessage)
toastSuccess(t('message.reply'))
} catch (error) {
toastError(error.message)
@ -77,6 +79,6 @@ async function onSubmit() {
}
function onReset() {
form.value.text = ''
formText.value = ''
}
</script>

View File

@ -10,7 +10,6 @@
v-if="['PENDING', 'IN_PROGRESS'].includes(status)"
:contribution-id="contributionId"
v-bind="$attrs"
@update-status="updateStatus"
/>
</div>
@ -46,11 +45,6 @@ export default {
required: true,
},
},
methods: {
updateStatus(id) {
this.$emit('update-status', id)
},
},
}
</script>
<style scoped>

View File

@ -1,27 +1,16 @@
<template>
<div class="contribution-list">
<div v-if="items.length === 0 && !loading.value">
{{ emptyText }}
</div>
<div v-else class="contribution-list">
<div v-for="item in items" :key="item.id + 'a'" class="mb-3">
<contribution-list-item
v-if="item.status === 'IN_PROGRESS'"
v-bind="item"
:contribution-id="item.id"
:all-contribution="allContribution"
@close-all-open-collapse="$emit('close-all-open-collapse')"
@update-contribution-form="updateContributionForm"
@delete-contribution="deleteContribution"
@update-status="updateStatus"
/>
</div>
<div v-for="item2 in items" :key="item2.id" class="mb-3">
<contribution-list-item
v-if="item2.status !== 'IN_PROGRESS'"
v-bind="item2"
:contribution-id="item2.id"
:all-contribution="allContribution"
@close-all-open-collapse="$emit('close-all-open-collapse')"
@update-contribution-form="updateContributionForm"
@delete-contribution="deleteContribution"
@update-status="updateStatus"
/>
</div>
<BPagination
@ -39,59 +28,58 @@
</div>
</template>
<script setup>
import { ref, computed, watch } from 'vue'
import { ref, computed, watch, watchEffect, onMounted } from 'vue'
import ContributionListItem from '@/components/Contributions/ContributionListItem.vue'
import { listContributions, listAllContributions } from '@/graphql/contributions.graphql'
import { useQuery } from '@vue/apollo-composable'
import { PAGE_SIZE } from '@/constants'
const props = defineProps({
items: {
type: Array,
required: true,
},
contributionCount: {
type: Number,
required: true,
},
showPagination: {
type: Boolean,
required: true,
},
pageSize: {
type: Number,
default: 25,
},
allContribution: {
type: Boolean,
required: false,
default: false,
},
emptyText: {
type: String,
required: false,
default: '',
},
})
const emit = defineEmits([
'close-all-open-collapse',
'update-list-contributions',
'update-contribution-form',
'delete-contribution',
'update-status',
])
const currentPage = ref(1)
const messages = ref([])
const contributionListResult = computed(() => {
return props.allContribution
? result.value?.listAllContributions
: result.value?.listContributions
})
const contributionCount = computed(() => {
return contributionListResult.value?.contributionCount || 0
})
const items = computed(() => {
return contributionListResult.value?.contributionList || []
})
const isPaginationVisible = computed(() => {
return props.showPagination && props.pageSize < props.contributionCount
return PAGE_SIZE < contributionCount.value
})
watch(currentPage, () => {
updateListContributions()
})
const updateListContributions = () => {
emit('update-list-contributions', {
const { result, loading } = useQuery(
props.allContribution ? listAllContributions : listContributions,
() => ({
currentPage: currentPage.value,
pageSize: props.pageSize,
})
window.scrollTo(0, 0)
}
pageSize: PAGE_SIZE,
}),
{ fetchPolicy: 'cache-and-network' },
)
const updateContributionForm = (item) => {
emit('update-contribution-form', item)
@ -100,8 +88,4 @@ const updateContributionForm = (item) => {
const deleteContribution = (item) => {
emit('delete-contribution', item)
}
const updateStatus = (id) => {
emit('update-status', id)
}
</script>

View File

@ -2,7 +2,7 @@
<div>
<div
class="contribution-list-item bg-white app-box-shadow gradido-border-radius pt-3 px-3"
:class="status === 'IN_PROGRESS' && !allContribution ? 'pulse border border-205' : ''"
:class="localStatus === 'IN_PROGRESS' && !allContribution ? 'pulse border border-205' : ''"
>
<BRow>
<BCol cols="3" lg="2" md="2">
@ -39,7 +39,7 @@
{{ $t('moderatorChangedMemo') }}
</div>
<div
v-if="status === 'IN_PROGRESS' && !allContribution"
v-if="localStatus === 'IN_PROGRESS' && !allContribution"
class="text-danger pointer hover-font-bold"
@click="visible = !visible"
>
@ -50,11 +50,11 @@
<div class="small">
{{ $t('creation') }} {{ $t('(') }}{{ hours }} {{ $t('h') }}{{ $t(')') }}
</div>
<div v-if="status === 'DENIED' && allContribution" class="fw-bold">
<div v-if="localStatus === 'DENIED' && allContribution" class="fw-bold">
<variant-icon icon="x-circle" variant="danger" />
{{ $t('contribution.alert.denied') }}
</div>
<div v-if="status === 'DELETED'" class="small">
<div v-if="localStatus === 'DELETED'" class="small">
{{ $t('contribution.deleted') }}
</div>
<div v-else class="fw-bold">{{ $filters.GDD(amount) }}</div>
@ -66,12 +66,16 @@
</BCol>
</BRow>
<BRow
v-if="(!['CONFIRMED', 'DELETED'].includes(status) && !allContribution) || messagesCount > 0"
v-if="
(!['CONFIRMED', 'DELETED'].includes(localStatus) && !allContribution) || messagesCount > 0
"
class="p-2"
>
<BCol cols="3" class="me-auto text-center">
<div
v-if="!['CONFIRMED', 'DELETED'].includes(status) && !allContribution && !moderatorId"
v-if="
!['CONFIRMED', 'DELETED'].includes(localStatus) && !allContribution && !moderatorId
"
class="test-delete-contribution pointer me-3"
@click="deleteContribution({ id })"
>
@ -82,7 +86,9 @@
</BCol>
<BCol cols="3" class="text-center">
<div
v-if="!['CONFIRMED', 'DELETED'].includes(status) && !allContribution && !moderatorId"
v-if="
!['CONFIRMED', 'DELETED'].includes(localStatus) && !allContribution && !moderatorId
"
class="test-edit-contribution pointer me-3"
@click="
$emit('update-contribution-form', {
@ -104,14 +110,15 @@
</div>
</BCol>
</BRow>
<BCollapse :id="collapseId" :model-value="visible">
<BCollapse :model-value="visible">
<contribution-messages-list
:messages="messagesGet"
:status="status"
:status="localStatus"
:contribution-id="contributionId"
@get-list-contribution-messages="getListContributionMessages"
@update-status="updateStatus"
@close-all-open-collapse="visible = false"
@add-contribution-message="addContributionMessage"
/>
</BCollapse>
<div class="pb-3"></div>
@ -140,6 +147,10 @@ const props = defineProps({
memo: {
type: String,
},
messages: {
type: Array,
required: false,
},
firstName: {
type: String,
required: false,
@ -208,6 +219,16 @@ const { t } = useI18n()
const messagesGet = ref([])
const visible = ref(false)
const localStatus = ref(props.status)
watch(
() => props.messages,
() => {
messagesGet.value = props.messages
},
// parent is loading messages already
{ immediate: false },
)
const variant = computed(() => {
if (props.deletedAt) return 'danger'
@ -266,6 +287,10 @@ function getListContributionMessages(closeCollapse = true) {
}
}
function addContributionMessage(message) {
messagesGet.value.push(message)
}
onResult((resultValue) => {
if (resultValue.data) {
messagesGet.value.length = 0
@ -279,11 +304,11 @@ onError((err) => {
toastError(err.message)
})
function updateStatus(id) {
emit('update-status', id)
const updateStatus = (id) => {
localStatus.value = 'PENDING'
}
const emit = defineEmits(['delete-contribution', 'close-all-open-collapse', 'update-status'])
const emit = defineEmits(['delete-contribution', 'close-all-open-collapse'])
</script>
<style lang="scss" scoped>

View File

@ -1 +1,2 @@
export const GDD_PER_HOUR = 20
export const PAGE_SIZE = 25

View File

@ -0,0 +1,59 @@
fragment contributionFields on Contribution {
id
amount
memo
createdAt
contributionDate
confirmedAt
confirmedBy
status
messagesCount
deniedAt
deniedBy
updatedBy
updatedAt
}
fragment contributionMessageFields on ContributionMessage {
id
message
createdAt
updatedAt
type
userFirstName
userLastName
userId
}
query listContributions ($currentPage: Int = 1, $pageSize: Int = 25, $order: Order = DESC) {
listContributions(currentPage: $currentPage, pageSize: $pageSize, order: $order) {
contributionCount
contributionList {
...contributionFields
deletedAt
moderatorId
messages(pagination: { currentPage: 1, pageSize: 10, order: DESC }) {
...contributionMessageFields
}
}
}
}
query countContributionsInProgress {
countContributionsInProgress
}
query listAllContributions ($currentPage: Int = 1, $pageSize: Int = 25, $order: Order = DESC) {
listAllContributions(currentPage: $currentPage, pageSize: $pageSize, order: $order) {
contributionCount
contributionList {
firstName
lastName
...contributionFields
}
}
}

View File

@ -188,18 +188,8 @@ export const listContributionLinks = gql`
`
export const listContributions = gql`
query (
$currentPage: Int = 1
$pageSize: Int = 25
$order: Order = DESC
$statusFilter: [ContributionStatus!]
) {
listContributions(
currentPage: $currentPage
pageSize: $pageSize
order: $order
statusFilter: $statusFilter
) {
query ($currentPage: Int = 1, $pageSize: Int = 25, $order: Order = DESC) {
listContributions(currentPage: $currentPage, pageSize: $pageSize, order: $order) {
contributionCount
contributionList {
id

View File

@ -2,7 +2,7 @@
<div class="community-page">
<div>
<BTabs :model-value="tabIndex" no-nav-style borderless align="center">
<BTab no-body>
<BTab no-body lazy>
<open-creations-amount
:minimal-date="minimalDate"
:max-gdd-last-month="maxForMonths[0]"
@ -18,39 +18,18 @@
@update-contribution="handleUpdateContribution"
/>
</BTab>
<BTab no-body>
<div v-if="items.length === 0">
{{ $t('contribution.noContributions.myContributions') }}
</div>
<div v-else>
<contribution-list
:items="items"
:contribution-count="contributionCount"
:show-pagination="true"
:page-size="pageSize"
@close-all-open-collapse="closeAllOpenCollapse"
@update-list-contributions="handleUpdateListContributions"
@update-contribution-form="handleUpdateContributionForm"
@delete-contribution="handleDeleteContribution"
@update-status="updateStatus"
/>
</div>
<BTab no-body lazy>
<contribution-list
:empty-text="$t('contribution.noContributions.myContributions')"
@update-contribution-form="handleUpdateContributionForm"
@delete-contribution="handleDeleteContribution"
/>
</BTab>
<BTab no-body>
<div v-if="itemsAll.length === 0">
{{ $t('contribution.noContributions.allContributions') }}
</div>
<div v-else>
<contribution-list
:items="itemsAll"
:contribution-count="contributionCountAll"
:show-pagination="true"
:page-size="pageSizeAll"
:all-contribution="true"
@update-list-contributions="handleUpdateListAllContributions"
@update-contribution-form="handleUpdateContributionForm"
/>
</div>
<BTab no-body lazy>
<contribution-list
:empty-text="$t('contribution.noContributions.allContributions')"
:all-contribution="true"
/>
</BTab>
</BTabs>
</div>
@ -65,7 +44,8 @@ import OpenCreationsAmount from '@/components/Contributions/OpenCreationsAmount'
import ContributionForm from '@/components/Contributions/ContributionForm'
import ContributionList from '@/components/Contributions/ContributionList'
import { createContribution, updateContribution, deleteContribution } from '@/graphql/mutations'
import { listContributions, listAllContributions, openCreations } from '@/graphql/queries'
import { openCreations } from '@/graphql/queries'
import { countContributionsInProgress } from '@/graphql/contributions.graphql'
import { useAppToast } from '@/composables/useToast'
import { useI18n } from 'vue-i18n'
import { GDD_PER_HOUR } from '../constants'
@ -130,51 +110,30 @@ const { onResult: onOpenCreationsResult, refetch: refetchOpenCreations } = useQu
fetchPolicy: 'network-only',
},
)
const { onResult: onListAllContributionsResult, refetch: refetchAllContributions } = useQuery(
listAllContributions,
() => ({
currentPage: currentPageAll.value,
pageSize: pageSizeAll.value,
}),
{ fetchPolicy: 'no-cache' },
)
const { onResult: onListContributionsResult, refetch: refetchContributions } = useQuery(
listContributions,
() => ({
currentPage: currentPage.value,
pageSize: pageSize.value,
}),
{ fetchPolicy: 'network-only' },
)
const { mutate: createContributionMutation } = useMutation(createContribution)
const { mutate: updateContributionMutation } = useMutation(updateContribution)
const { mutate: deleteContributionMutation } = useMutation(deleteContribution)
const { onResult: handleInProgressContributionFound } = useQuery(
countContributionsInProgress,
{},
{
fetchPolicy: 'network-only',
},
)
onOpenCreationsResult(({ data }) => {
if (data) {
openCreationsData.value = data.openCreations
}
})
onListAllContributionsResult(({ data }) => {
// jump to my contributions if in progress contribution found
handleInProgressContributionFound(({ data }) => {
if (data) {
contributionCountAll.value = data.listAllContributions.contributionCount
itemsAll.value.length = 0
data.listAllContributions.contributionList.forEach((entry) => {
itemsAll.value.push(entry)
})
}
})
onListContributionsResult(({ data }) => {
if (data) {
contributionCount.value = data.listContributions.contributionCount
items.value.length = 0
data.listContributions.contributionList.forEach((entry) => {
items.value.push({ ...entry })
})
if (items.value.find((item) => item.status === 'IN_PROGRESS')) {
const count = data.countContributionsInProgress
if (count > 0) {
tabIndex.value = 1
if (route.params.tab !== 'contributions') {
router.push({ params: { tab: 'contributions' } })
@ -187,19 +146,11 @@ onListContributionsResult(({ data }) => {
const updateTabIndex = () => {
const index = COMMUNITY_TABS.indexOf(route.params.tab)
tabIndex.value = index > -1 ? index : 0
closeAllOpenCollapse()
}
const closeAllOpenCollapse = () => {
document.querySelectorAll('.collapse.show').forEach((el) => {
el.classList.remove('show')
})
}
const refetchData = () => {
refetchAllContributions()
refetchContributions()
refetchOpenCreations()
handleInProgressContributionFound()
}
const handleSaveContribution = async (data) => {
@ -243,21 +194,6 @@ const handleDeleteContribution = async (data) => {
}
}
const handleUpdateListAllContributions = (pagination) => {
currentPageAll.value = pagination.currentPage
pageSizeAll.value = pagination.pageSize
refetchAllContributions({
currentPage: currentPage.value,
pageSize: pageSize.value,
})
}
const handleUpdateListContributions = (pagination) => {
currentPage.value = pagination.currentPage
pageSize.value = pagination.pageSize
refetchContributions()
}
const handleUpdateContributionForm = (item) => {
form.value = {
id: item.id,
@ -272,13 +208,6 @@ const handleUpdateContributionForm = (item) => {
router.push({ params: { tab: 'contribute' } })
}
const updateStatus = (id) => {
const item = items.value.find((item) => item.id === id)
if (item) {
item.status = 'PENDING'
}
}
watch(() => route.params.tab, updateTabIndex)
onMounted(updateTabIndex)