From 7f63ca04a0ec484dd28f7a8e6ae1817a8b36f70c Mon Sep 17 00:00:00 2001 From: PeterSmallenbroek Date: Wed, 5 Feb 2025 16:36:01 +0100 Subject: [PATCH] Feat: retry transfer in activity log --- e2e/portalicious/pages/PaymentsPage.ts | 2 +- interfaces/Portalicious/eslint.config.js | 2 +- .../retry-transfers-dialog.component.html | 2 +- .../retry-transfers-dialog.component.ts | 35 +------ .../project-payment/project-payment.page.html | 2 +- .../project-payment/project-payment.page.ts | 25 ++++- .../table-cell-overview.component.html | 51 +++++++++++ .../table-cell-overview.component.ts | 91 ++++++++++++------- .../project-registration-activity-log.page.ts | 2 +- .../Portalicious/src/locale/messages.xlf | 5 +- 10 files changed, 143 insertions(+), 74 deletions(-) create mode 100644 interfaces/Portalicious/src/app/pages/project-registration-activity-log/components/table-cell-overview/table-cell-overview.component.html rename interfaces/Portalicious/src/app/pages/project-registration-activity-log/components/{ => table-cell-overview}/table-cell-overview.component.ts (68%) diff --git a/e2e/portalicious/pages/PaymentsPage.ts b/e2e/portalicious/pages/PaymentsPage.ts index 934c13697e..8d32527106 100644 --- a/e2e/portalicious/pages/PaymentsPage.ts +++ b/e2e/portalicious/pages/PaymentsPage.ts @@ -53,7 +53,7 @@ class PaymentsPage extends BasePage { }); this.paymentAmount = this.page.getByTestId('metric-tile-component'); this.retryFailedTransfersButton = this.page.getByRole('button', { - name: 'Retry failed transfers', + name: 'Retry failed transfer(s)', }); this.popupRetryTransferButton = this.page.getByRole('button', { name: 'Retry transfers', diff --git a/interfaces/Portalicious/eslint.config.js b/interfaces/Portalicious/eslint.config.js index e17bb0e156..4490a51cca 100644 --- a/interfaces/Portalicious/eslint.config.js +++ b/interfaces/Portalicious/eslint.config.js @@ -69,7 +69,7 @@ module.exports = tseslint.config( ], '@angular-eslint/component-max-inline-declarations': [ 'error', - { template: 30 }, + { template: 10 }, ], '@angular-eslint/no-async-lifecycle-method': ['error'], '@angular-eslint/no-conflicting-lifecycle': ['error'], diff --git a/interfaces/Portalicious/src/app/pages/project-payment/components/retry-transfers-dialog/retry-transfers-dialog.component.html b/interfaces/Portalicious/src/app/pages/project-payment/components/retry-transfers-dialog/retry-transfers-dialog.component.html index e1814ae976..af5e944a72 100644 --- a/interfaces/Portalicious/src/app/pages/project-payment/components/retry-transfers-dialog/retry-transfers-dialog.component.html +++ b/interfaces/Portalicious/src/app/pages/project-payment/components/retry-transfers-dialog/retry-transfers-dialog.component.html @@ -1,6 +1,6 @@ ([]); @@ -55,37 +52,7 @@ export class RetryTransfersDialogComponent { }, })); - public retryFailedTransfers({ - table, - triggeredFromContextMenu, - contextMenuItem, - }: { - table: QueryTableComponent; - triggeredFromContextMenu: boolean; - contextMenuItem?: PaymentMetricDetails; - }) { - const actionData = table.getActionData({ - triggeredFromContextMenu, - contextMenuItem, - fieldForFilter: 'referenceId', - noSelectionToastMessage: $localize`:@@no-registrations-selected:Select one or more registrations and try again.`, - }); - - if (!actionData) { - return; - } - - const selection = actionData.selection; - - if (!Array.isArray(selection) || selection.length === 0) { - this.toastService.showGenericError(); // Should never happen - return; - } - - const referenceIds = selection.map( - (transaction) => transaction.referenceId, - ); - + public retryFailedTransfers({ referenceIds }: { referenceIds: string[] }) { this.referenceIdsForRetryTransfers.set(referenceIds); this.retryTransfersConfirmationDialog().askForConfirmation(); } diff --git a/interfaces/Portalicious/src/app/pages/project-payment/project-payment.page.html b/interfaces/Portalicious/src/app/pages/project-payment/project-payment.page.html index 6e6abc5530..be83cd329a 100644 --- a/interfaces/Portalicious/src/app/pages/project-payment/project-payment.page.html +++ b/interfaces/Portalicious/src/app/pages/project-payment/project-payment.page.html @@ -119,7 +119,7 @@

> @if (canRetryTransfers()) { transaction.referenceId, + ); + + this.retryTransfersDialog().retryFailedTransfers({ + referenceIds, }); } } diff --git a/interfaces/Portalicious/src/app/pages/project-registration-activity-log/components/table-cell-overview/table-cell-overview.component.html b/interfaces/Portalicious/src/app/pages/project-registration-activity-log/components/table-cell-overview/table-cell-overview.component.html new file mode 100644 index 0000000000..c997cc6d7e --- /dev/null +++ b/interfaces/Portalicious/src/app/pages/project-registration-activity-log/components/table-cell-overview/table-cell-overview.component.html @@ -0,0 +1,51 @@ +
+ @if (!!overview()) { + {{ overview() }} + } + +
+ @if (chipData()) { + + } + + @if (canRetryTransfer()) { + + } +
+ + @let dialogData = voucherDialogData(); + @if (dialogData) { + + } +
+ +@let payment = paymentId(); +@if (payment) { + +} diff --git a/interfaces/Portalicious/src/app/pages/project-registration-activity-log/components/table-cell-overview.component.ts b/interfaces/Portalicious/src/app/pages/project-registration-activity-log/components/table-cell-overview/table-cell-overview.component.ts similarity index 68% rename from interfaces/Portalicious/src/app/pages/project-registration-activity-log/components/table-cell-overview.component.ts rename to interfaces/Portalicious/src/app/pages/project-registration-activity-log/components/table-cell-overview/table-cell-overview.component.ts index d3683037bc..776ac9fe72 100644 --- a/interfaces/Portalicious/src/app/pages/project-registration-activity-log/components/table-cell-overview.component.ts +++ b/interfaces/Portalicious/src/app/pages/project-registration-activity-log/components/table-cell-overview/table-cell-overview.component.ts @@ -6,14 +6,18 @@ import { inject, input, LOCALE_ID, + viewChild, } from '@angular/core'; import { injectQuery } from '@tanstack/angular-query-experimental'; +import { ButtonModule } from 'primeng/button'; import { ChipModule } from 'primeng/chip'; import { ActivityTypeEnum } from '@121-service/src/activities/enum/activity-type.enum'; import { FinancialServiceProviders } from '@121-service/src/financial-service-providers/enum/financial-service-provider-name.enum'; +import { TransactionStatusEnum } from '@121-service/src/payments/transactions/enums/transaction-status.enum'; import { GenericRegistrationAttributes } from '@121-service/src/registration/enum/registration-attribute.enum'; +import { PermissionEnum } from '@121-service/src/user/enum/permission.enum'; import { ColoredChipComponent } from '~/components/colored-chip/colored-chip.component'; import { @@ -25,8 +29,10 @@ import { TableCellComponent } from '~/components/query-table/components/table-ce import { MESSAGE_CONTENT_TYPE_LABELS } from '~/domains/message/message.helper'; import { REGISTRATION_STATUS_LABELS } from '~/domains/registration/registration.helper'; import { Activity } from '~/domains/registration/registration.model'; +import { RetryTransfersDialogComponent } from '~/pages/project-payment/components/retry-transfers-dialog/retry-transfers-dialog.component'; import { ActivityLogVoucherDialogComponent } from '~/pages/project-registration-activity-log/components/activity-log-voucher-dialog/activity-log-voucher-dialog.component'; import { ActivityLogTableCellContext } from '~/pages/project-registration-activity-log/project-registration-activity-log.page'; +import { AuthService } from '~/services/auth.service'; import { RegistrationAttributeService } from '~/services/registration-attribute.service'; import { Locale } from '~/utils/locale'; @@ -37,38 +43,10 @@ import { Locale } from '~/utils/locale'; ColoredChipComponent, ActivityLogVoucherDialogComponent, NgClass, + ButtonModule, + RetryTransfersDialogComponent, ], - template: ` -
- @if (!!overview()) { - {{ overview() }} - } - - @if (chipData()) { -
- -
- } - - @let dialogData = voucherDialogData(); - @if (dialogData) { - - } -
- `, + templateUrl: './table-cell-overview.component.html', styles: ``, changeDetection: ChangeDetectionStrategy.OnPush, }) @@ -79,7 +57,11 @@ export class TableCellOverviewComponent readonly context = input.required(); locale = inject(LOCALE_ID); + readonly retryTransfersDialog = + viewChild.required('retryTransfersDialog'); + readonly registrationAttributeService = inject(RegistrationAttributeService); + readonly authService = inject(AuthService); readonly registrationAttributes = injectQuery( this.registrationAttributeService.getRegistrationAttributes(this.context), @@ -99,6 +81,14 @@ export class TableCellOverviewComponent return undefined; }); + readonly paymentId = computed(() => { + const item = this.value(); + if (item.type === ActivityTypeEnum.Transaction) { + return item.attributes.payment.toString(); + } + return undefined; + }); + readonly overview = computed(() => { const item = this.value(); switch (item.type) { @@ -125,6 +115,27 @@ export class TableCellOverviewComponent } }); + readonly canRetryTransfer = computed(() => { + const item = this.value(); + if ( + !this.authService.hasAllPermissions({ + projectId: this.context().projectId(), + requiredPermissions: [ + PermissionEnum.PaymentREAD, + PermissionEnum.PaymentCREATE, + PermissionEnum.PaymentTransactionREAD, + ], + }) + ) { + return false; + } + + if (item.type !== ActivityTypeEnum.Transaction) { + return false; + } + return item.attributes.status === TransactionStatusEnum.error; + }); + readonly voucherDialogData = computed(() => { const item = this.value(); const referenceId = this.context().referenceId; @@ -148,4 +159,22 @@ export class TableCellOverviewComponent voucherReferenceId: referenceId, }; }); + + retryTransfer() { + // TODO AB#33349: Not sure if this still needs to be checked + // if (this.paymentStatus.data()?.inProgress) { + // this.toastService.showToast({ + // severity: 'warn', + // detail: $localize`A payment is currently in progress. Please wait until it has finished.`, + // }); + // return; + // } + const referenceId = this.context().referenceId; + if (referenceId) { + const referenceIds = [referenceId]; + this.retryTransfersDialog().retryFailedTransfers({ + referenceIds, + }); + } + } } diff --git a/interfaces/Portalicious/src/app/pages/project-registration-activity-log/project-registration-activity-log.page.ts b/interfaces/Portalicious/src/app/pages/project-registration-activity-log/project-registration-activity-log.page.ts index 4b05b37e5f..9881c59cff 100644 --- a/interfaces/Portalicious/src/app/pages/project-registration-activity-log/project-registration-activity-log.page.ts +++ b/interfaces/Portalicious/src/app/pages/project-registration-activity-log/project-registration-activity-log.page.ts @@ -23,7 +23,7 @@ import { ACTIVITY_LOG_ITEM_TYPE_LABELS } from '~/domains/registration/registrati import { Activity } from '~/domains/registration/registration.model'; import { ActivityLogExpandedRowComponent } from '~/pages/project-registration-activity-log/components/activity-log-expanded-row/activity-log-expanded-row.component'; import { TableCellActivityComponent } from '~/pages/project-registration-activity-log/components/table-cell-activity.component'; -import { TableCellOverviewComponent } from '~/pages/project-registration-activity-log/components/table-cell-overview.component'; +import { TableCellOverviewComponent } from '~/pages/project-registration-activity-log/components/table-cell-overview/table-cell-overview.component'; export interface ActivityLogTableCellContext { projectId: Signal; diff --git a/interfaces/Portalicious/src/locale/messages.xlf b/interfaces/Portalicious/src/locale/messages.xlf index 7077bb8d4e..c678f58571 100644 --- a/interfaces/Portalicious/src/locale/messages.xlf +++ b/interfaces/Portalicious/src/locale/messages.xlf @@ -1175,7 +1175,7 @@ You are about to retry payment(s). The transfer status will change to Pending until received by the registration. - Retry failed transfers + Retry failed transfer(s) Payment report @@ -1533,6 +1533,9 @@ Inclusion score generated by the answers of the Kobo form. + + Retry transfer +