From ac4872d06d6d483fdc4ab0bd70532884e3a5a5f6 Mon Sep 17 00:00:00 2001 From: einhornimmond Date: Thu, 8 May 2025 10:02:10 +0200 Subject: [PATCH 01/36] keep message display open after answear --- .../components/Contributions/ContributionListItem.vue | 9 --------- 1 file changed, 9 deletions(-) diff --git a/frontend/src/components/Contributions/ContributionListItem.vue b/frontend/src/components/Contributions/ContributionListItem.vue index 2b0e2b0a1..72678c081 100644 --- a/frontend/src/components/Contributions/ContributionListItem.vue +++ b/frontend/src/components/Contributions/ContributionListItem.vue @@ -278,15 +278,6 @@ onError((err) => { toastError(err.message) }) -watch( - () => visible.value, - () => { - if (visible.value) { - getListContributionMessages() - } - }, -) - function updateStatus(id) { emit('update-status', id) } From 9b1e162042e78ea2f8f710a4e6c11f0440b5f732 Mon Sep 17 00:00:00 2001 From: einhornimmond Date: Fri, 9 May 2025 09:49:07 +0200 Subject: [PATCH 02/36] fix: prevent layout jump during collapse animation --- .../ContributionMessages/ContributionMessagesList.vue | 4 ++-- .../src/components/Contributions/ContributionListItem.vue | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/frontend/src/components/ContributionMessages/ContributionMessagesList.vue b/frontend/src/components/ContributionMessages/ContributionMessagesList.vue index b7f97daff..56b7fea8b 100644 --- a/frontend/src/components/ContributionMessages/ContributionMessagesList.vue +++ b/frontend/src/components/ContributionMessages/ContributionMessagesList.vue @@ -14,8 +14,8 @@ /> -
- +
+ {{ $t('form.close') }} diff --git a/frontend/src/components/Contributions/ContributionListItem.vue b/frontend/src/components/Contributions/ContributionListItem.vue index 72678c081..7aa50812a 100644 --- a/frontend/src/components/Contributions/ContributionListItem.vue +++ b/frontend/src/components/Contributions/ContributionListItem.vue @@ -104,16 +104,17 @@
-
- + +
From 2cabeb87bbe79a97a66756157d10115a1bdb15d9 Mon Sep 17 00:00:00 2001 From: einhornimmond Date: Sat, 10 May 2025 19:06:43 +0200 Subject: [PATCH 03/36] refactor contribution list, stay open after adding contribution message --- backend/src/graphql/model/Contribution.ts | 20 ++- .../src/graphql/model/ContributionMessage.ts | 10 +- .../resolver/ContributionMessageResolver.ts | 20 +-- .../graphql/resolver/ContributionResolver.ts | 86 +++++++++--- .../resolver/util/findContributionMessages.ts | 10 +- .../resolver/util/loadContributions.ts | 41 ++++++ .../ContributionMessagesFormular.vue | 28 ++-- .../ContributionMessagesList.vue | 6 - .../Contributions/ContributionList.vue | 84 +++++------- .../Contributions/ContributionListItem.vue | 49 +++++-- frontend/src/constants.js | 1 + frontend/src/graphql/contributions.graphql | 59 +++++++++ frontend/src/graphql/queries.js | 14 +- frontend/src/pages/Community.vue | 125 ++++-------------- 14 files changed, 309 insertions(+), 244 deletions(-) create mode 100644 backend/src/graphql/resolver/util/loadContributions.ts create mode 100644 frontend/src/graphql/contributions.graphql diff --git a/backend/src/graphql/model/Contribution.ts b/backend/src/graphql/model/Contribution.ts index 301348ccc..21f47bf2d 100644 --- a/backend/src/graphql/model/Contribution.ts +++ b/backend/src/graphql/model/Contribution.ts @@ -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 diff --git a/backend/src/graphql/model/ContributionMessage.ts b/backend/src/graphql/model/ContributionMessage.ts index 6f70d5024..998717c83 100644 --- a/backend/src/graphql/model/ContributionMessage.ts +++ b/backend/src/graphql/model/ContributionMessage.ts @@ -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 } diff --git a/backend/src/graphql/resolver/ContributionMessageResolver.ts b/backend/src/graphql/resolver/ContributionMessageResolver.ts index 88cd73bc7..3eae0b042 100644 --- a/backend/src/graphql/resolver/ContributionMessageResolver.ts +++ b/backend/src/graphql/resolver/ContributionMessageResolver.ts @@ -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 { 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 { 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) } } diff --git a/backend/src/graphql/resolver/ContributionResolver.ts b/backend/src/graphql/resolver/ContributionResolver.ts index a137b0d79..365c52f5d 100644 --- a/backend/src/graphql/resolver/ContributionResolver.ts +++ b/backend/src/graphql/resolver/ContributionResolver.ts @@ -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 { 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 { + 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 { - 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 { + 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)) + } } diff --git a/backend/src/graphql/resolver/util/findContributionMessages.ts b/backend/src/graphql/resolver/util/findContributionMessages.ts index 460b62b38..9f9209e7c 100644 --- a/backend/src/graphql/resolver/util/findContributionMessages.ts +++ b/backend/src/graphql/resolver/util/findContributionMessages.ts @@ -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, diff --git a/backend/src/graphql/resolver/util/loadContributions.ts b/backend/src/graphql/resolver/util/loadContributions.ts new file mode 100644 index 000000000..18f4a4fe6 --- /dev/null +++ b/backend/src/graphql/resolver/util/loadContributions.ts @@ -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 { + 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), + }) +} diff --git a/frontend/src/components/ContributionMessages/ContributionMessagesFormular.vue b/frontend/src/components/ContributionMessages/ContributionMessagesFormular.vue index 85363665f..634823168 100644 --- a/frontend/src/components/ContributionMessages/ContributionMessagesFormular.vue +++ b/frontend/src/components/ContributionMessages/ContributionMessagesFormular.vue @@ -5,10 +5,10 @@ @@ -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 = '' } diff --git a/frontend/src/components/ContributionMessages/ContributionMessagesList.vue b/frontend/src/components/ContributionMessages/ContributionMessagesList.vue index 56b7fea8b..1406ce744 100644 --- a/frontend/src/components/ContributionMessages/ContributionMessagesList.vue +++ b/frontend/src/components/ContributionMessages/ContributionMessagesList.vue @@ -10,7 +10,6 @@ v-if="['PENDING', 'IN_PROGRESS'].includes(status)" :contribution-id="contributionId" v-bind="$attrs" - @update-status="updateStatus" /> @@ -46,11 +45,6 @@ export default { required: true, }, }, - methods: { - updateStatus(id) { - this.$emit('update-status', id) - }, - }, } diff --git a/frontend/src/components/Contributions/ContributionEdit.vue b/frontend/src/components/Contributions/ContributionEdit.vue index ed2b7c012..4ae5fc8c8 100644 --- a/frontend/src/components/Contributions/ContributionEdit.vue +++ b/frontend/src/components/Contributions/ContributionEdit.vue @@ -4,7 +4,6 @@ :max-gdd-last-month="maxForMonths[0]" :max-gdd-this-month="maxForMonths[1]" @upsert-contribution="handleUpdateContribution" - @reset-form="emit('reset-form')" /> @@ -19,7 +18,7 @@ import { useI18n } from 'vue-i18n' const { toastError, toastSuccess } = useAppToast() const { t } = useI18n() -const emit = defineEmits(['contribution-updated', 'reset-form']) +const emit = defineEmits(['contribution-updated']) const props = defineProps({ modelValue: { type: Object, required: true }, diff --git a/frontend/src/components/Contributions/ContributionForm.vue b/frontend/src/components/Contributions/ContributionForm.vue index 18d28c0f5..b25d858a9 100644 --- a/frontend/src/components/Contributions/ContributionForm.vue +++ b/frontend/src/components/Contributions/ContributionForm.vue @@ -63,7 +63,7 @@ type="reset" variant="secondary" data-test="button-cancel" - @click="emit('reset-form')" + @click="resetForm" > {{ $t('form.cancel') }} @@ -84,7 +84,6 @@ - diff --git a/frontend/src/components/Contributions/ContributionListItem.vue b/frontend/src/components/Contributions/ContributionListItem.vue index e579d6280..be0d2a31b 100644 --- a/frontend/src/components/Contributions/ContributionListItem.vue +++ b/frontend/src/components/Contributions/ContributionListItem.vue @@ -2,26 +2,15 @@
- - + -
- {{ username.username }} - -
{{ $d(new Date(contributionDate), 'short') }}
@@ -31,7 +20,7 @@ {{ $t('moderatorChangedMemo') }}
@@ -42,10 +31,6 @@
{{ $t('creation') }} {{ $t('(') }}{{ hours }} {{ $t('h') }}{{ $t(')') }}
-
- - {{ $t('contribution.alert.denied') }} -
{{ $t('contribution.deleted') }}
@@ -57,17 +42,10 @@
- +
@@ -78,9 +56,7 @@
0" :messages="localMessages" :status="localStatus" - :contribution-id="contributionId" + :contribution-id="id" @close-messages-list="emit('toggle-messages-visible')" @add-contribution-message="addContributionMessage" /> @@ -128,9 +104,9 @@ import ContributionMessagesList from '@/components/ContributionMessages/Contribu import { useAppToast } from '@/composables/useToast' import { useI18n } from 'vue-i18n' import { useMutation } from '@vue/apollo-composable' -import AppAvatar from '@/components/AppAvatar.vue' import { GDD_PER_HOUR } from '../../constants' import { deleteContribution } from '@/graphql/contributions.graphql' +import { useContributionStatus } from '@/composables/useContributionStatus' const props = defineProps({ id: { @@ -147,36 +123,9 @@ const props = defineProps({ required: false, default: () => [], }, - user: { - type: Object, - required: false, - }, - createdAt: { - type: String, - }, contributionDate: { type: String, }, - deletedAt: { - type: String, - required: false, - }, - confirmedBy: { - type: Number, - required: false, - }, - confirmedAt: { - type: String, - required: false, - }, - deniedBy: { - type: Number, - required: false, - }, - deniedAt: { - type: String, - required: false, - }, updatedBy: { type: Number, required: false, @@ -190,15 +139,6 @@ const props = defineProps({ type: Number, required: false, }, - contributionId: { - type: Number, - required: true, - }, - allContribution: { - type: Boolean, - required: false, - default: false, - }, moderatorId: { type: Number, required: false, @@ -213,11 +153,14 @@ const props = defineProps({ const { toastError, toastSuccess } = useAppToast() const { t } = useI18n() +const { getVariant, getIcon } = useContributionStatus() const { mutate: deleteContributionMutation } = useMutation(deleteContribution) const localMessages = ref([]) const localStatus = ref(props.contributionStatus) +const variant = computed(() => getVariant(props.contributionStatus)) +const icon = computed(() => getIcon(props.contributionStatus)) // if parent reload messages, update local messages copy watch( @@ -237,32 +180,6 @@ watch( }, ) -const statusMapping = { - CONFIRMED: { variant: 'success', icon: 'check' }, - DELETED: { variant: 'danger', icon: 'trash' }, - DENIED: { variant: 'warning', icon: 'x-circle' }, - IN_PROGRESS: { variant: '205', icon: 'question' }, - default: { variant: 'primary', icon: 'bell-fill' }, -} - -const variant = computed(() => { - return (statusMapping[localStatus.value] || statusMapping.default).variant -}) - -const icon = computed(() => { - return (statusMapping[localStatus.value] || statusMapping.default).icon -}) - -const username = computed(() => { - if (!props.user) return {} - return { - username: props.user.alias - ? props.user.alias - : `${props.user.firstName} ${props.user.lastName}`, - initials: `${props.user.firstName[0]}${props.user.lastName[0]}`, - } -}) - const hours = computed(() => parseFloat((props.amount / GDD_PER_HOUR).toFixed(2))) async function processDeleteContribution(item) { diff --git a/frontend/src/components/PaginatorRouteParamsPage.vue b/frontend/src/components/PaginatorRouteParamsPage.vue new file mode 100644 index 000000000..1f41cc54a --- /dev/null +++ b/frontend/src/components/PaginatorRouteParamsPage.vue @@ -0,0 +1,54 @@ + + diff --git a/frontend/src/composables/useContributionStatus.js b/frontend/src/composables/useContributionStatus.js new file mode 100644 index 000000000..5ca07f9cc --- /dev/null +++ b/frontend/src/composables/useContributionStatus.js @@ -0,0 +1,22 @@ +export const useContributionStatus = () => { + const statusMapping = { + CONFIRMED: { variant: 'success', icon: 'check' }, + DELETED: { variant: 'danger', icon: 'trash' }, + DENIED: { variant: 'warning', icon: 'x-circle' }, + IN_PROGRESS: { variant: '205', icon: 'question' }, + default: { variant: 'primary', icon: 'bell-fill' }, + } + + const getVariant = (status) => { + return (statusMapping[status] || statusMapping.default).variant + } + + const getIcon = (status) => { + return (statusMapping[status] || statusMapping.default).icon + } + + return { + getVariant, + getIcon, + } +} diff --git a/frontend/src/graphql/contributions.graphql b/frontend/src/graphql/contributions.graphql index c38449fca..0fe4a46f1 100644 --- a/frontend/src/graphql/contributions.graphql +++ b/frontend/src/graphql/contributions.graphql @@ -35,12 +35,17 @@ query listContributions ($pagination: Paginated!, $messagePagination: Paginated! listContributions(pagination: $pagination, messagePagination: $messagePagination) { contributionCount contributionList { - ...contributionFields - deletedAt - moderatorId + id + amount + memo + contributionDate + contributionStatus + messagesCount messages(pagination: $messagePagination) { ...contributionMessageFields } + updatedBy + moderatorId } } } @@ -49,10 +54,14 @@ query listAllContributions ($pagination: Paginated!) { listAllContributions(pagination: $pagination) { contributionCount contributionList { + amount + memo user { ...userFields - } - ...contributionFields + } + contributionDate + updatedBy + contributionStatus } } } diff --git a/frontend/src/pages/Community.vue b/frontend/src/pages/Community.vue index cba744604..86d2a2486 100644 --- a/frontend/src/pages/Community.vue +++ b/frontend/src/pages/Community.vue @@ -11,16 +11,10 @@ - + - +
@@ -28,24 +22,23 @@