diff --git a/raiden-dapp/src/views/QuickPayRoute.vue b/raiden-dapp/src/views/QuickPayRoute.vue index 086d4a60d2..540bfca22b 100644 --- a/raiden-dapp/src/views/QuickPayRoute.vue +++ b/raiden-dapp/src/views/QuickPayRoute.vue @@ -33,11 +33,13 @@ class="quick-pay__action__component" :transfer-token-amount="tokenAmount" :payment-identifier="paymentIdentifier" - :show-progress-in-dialog="showActionProgressInDialog" :dialog-title="actionDialogTitle" + :completion-delay-timeout="1500" + show-progress-in-dialog @started="setActionInProgress" @completed="redirect" @failed="handleActionError" + @dialogClosed="redirect" > - + @@ -66,7 +68,7 @@ - + @@ -129,10 +131,11 @@ export default class QuickPayRoute extends Mixins(NavigationMixin) { | typeof ChannelOpenAndTransferAction | typeof ChannelDepositAndTransferAction = TransferAction; actionInProgress = false; - error: Error | null = null; + actionFailed = false; + error: Error | null = null; // Note that action errors are not set here. get tokenAddress(): string { - return getAddress(this.$route.query.token); + return getAddress(this.$route.query.tokenAddress); } get token(): Token | null { @@ -140,7 +143,7 @@ export default class QuickPayRoute extends Mixins(NavigationMixin) { } get targetAddress(): string { - return getAddress(this.$route.query.target); + return getAddress(this.$route.query.targetAddress); } get tokenAmount(): BigNumber | undefined { @@ -171,7 +174,7 @@ export default class QuickPayRoute extends Mixins(NavigationMixin) { } get paymentIdentifier(): BigNumber | undefined { - return getPaymentId(this.$route.query.paymentId); + return getPaymentId(this.$route.query.identifier); } get redirectionTarget(): string { @@ -179,8 +182,8 @@ export default class QuickPayRoute extends Mixins(NavigationMixin) { } get redirectionUrl(): string { - let url = `${this.redirectionTarget}?paymentId=${this.paymentIdentifier}`; - url += this.error ? '&failed=true' : `&payerAddress=${this.$raiden.getAccount()}`; + let url = `${this.redirectionTarget}?identifier=${this.paymentIdentifier}`; + url += this.actionFailed ? '&failed=true' : `&payerAddress=${this.$raiden.getAccount()}`; return url; } @@ -193,6 +196,10 @@ export default class QuickPayRoute extends Mixins(NavigationMixin) { ); } + get errorVisible(): boolean { + return this.error != null && !this.actionInProgress && !this.actionFailed; + } + get directChannelWithTarget(): RaidenChannel | undefined { const channels = this.getChannels(this.tokenAddress); return channels.filter( @@ -216,48 +223,50 @@ export default class QuickPayRoute extends Mixins(NavigationMixin) { } get actionHeader(): string { - return this.actionComponent === TransferAction - ? '' // Empty on purpose. No header for this case. - : this.actionComponent === ChannelDepositAndTransferAction - ? (this.$t('quick-pay.action-titles.channel-deposit') as string) - : this.actionComponent === ChannelOpenAndTransferAction - ? (this.$t('quick-pay.action-titles.channel-open') as string) - : ''; - } - - get showActionProgressInDialog(): boolean { - return this.actionComponent !== TransferAction; + switch (this.actionComponent) { + case TransferAction: + return ''; // Empty on purpose. No header for this case. + case ChannelDepositAndTransferAction: + return this.$t('quick-pay.action-titles.channel-deposit') as string; + case ChannelOpenAndTransferAction: + return this.$t('quick-pay.action-titles.channel-open') as string; + default: + return ''; // Necessary for TypeScript + } } get actionDialogTitle(): string { - return this.actionComponent === TransferAction - ? '' // Empty on purpose. No title for this case. - : this.actionComponent === ChannelDepositAndTransferAction - ? (this.$t('quick-pay.action-titles.channel-deposit-and-transfer') as string) - : this.actionComponent === ChannelOpenAndTransferAction - ? (this.$t('quick-pay.action-titles.channel-open-and-transfer') as string) - : ''; + switch (this.actionComponent) { + case TransferAction: + return ''; // Empty on purpose. No title for this case. + case ChannelDepositAndTransferAction: + return this.$t('quick-pay.action-titles.channel-deposit-and-transfer') as string; + case ChannelOpenAndTransferAction: + return this.$t('quick-pay.action-titles.channel-open-and-transfer') as string; + default: + return ''; // Necessary for TypeScript + } } get actionMessagePath(): string { - return this.actionComponent === TransferAction - ? 'quick-pay.action-messages.transfer' - : this.actionComponent === ChannelDepositAndTransferAction - ? 'quick-pay.action-messages.channel-deposit-and-transfer' - : this.actionComponent === ChannelOpenAndTransferAction - ? 'quick-pay.action-messages.channel-open-and-transfer' - : ''; + switch (this.actionComponent) { + case TransferAction: + return 'quick-pay.action-messages.transfer'; + case ChannelDepositAndTransferAction: + return 'quick-pay.action-messages.channel-deposit-and-transfer'; + case ChannelOpenAndTransferAction: + return 'quick-pay.action-messages.channel-open-and-transfer'; + default: + return ''; // Necessary for TypeScript + } } @Watch('$route.query', { immediate: true }) onRouteQueryChanged(): void { - if (this.actionInProgress) { - return; - } - if (this.anyRequiredQueryParameterInvalid) { this.error = new Error(this.$t('quick-pay.invalid-parameter-error') as string); } else { + this.error = null; this.decideOnActionComponent(); } } @@ -290,7 +299,7 @@ export default class QuickPayRoute extends Mixins(NavigationMixin) { if (isRecoverableTransferError(error)) { this.decideToDepositOrOpenChannel(); } else { - this.error = error; + this.actionFailed = true; } } diff --git a/raiden-dapp/tests/unit/components/mixins/action-mixin.spec.ts b/raiden-dapp/tests/unit/components/mixins/action-mixin.spec.ts index f504c22c38..1f3dec3bc8 100644 --- a/raiden-dapp/tests/unit/components/mixins/action-mixin.spec.ts +++ b/raiden-dapp/tests/unit/components/mixins/action-mixin.spec.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ import type { Wrapper } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils'; import flushPromises from 'flush-promises'; diff --git a/raiden-dapp/tests/unit/views/quick-pay-route.spec.ts b/raiden-dapp/tests/unit/views/quick-pay-route.spec.ts index 1ea1799c95..006f775e6d 100644 --- a/raiden-dapp/tests/unit/views/quick-pay-route.spec.ts +++ b/raiden-dapp/tests/unit/views/quick-pay-route.spec.ts @@ -305,17 +305,6 @@ describe('QuickPayRoute.vue', () => { }); describe('action events', () => { - test('hides action message when action starts', async () => { - const wrapper = createWrapper(); - const action = wrapper.get('.quick-pay__action__component'); - expect(wrapper.find('.quick-pay__action__message').exists()).toBeTruthy(); - - action.vm.$emit('started'); - await wrapper.vm.$nextTick(); - - expect(wrapper.find('.quick-pay__action__message').exists()).toBeFalsy(); - }); - describe('redirections', () => { const originalWindowLocation = global.window.location; let windowReplaceSpy: jest.Mock; @@ -403,28 +392,16 @@ describe('QuickPayRoute.vue', () => { }); describe('failed action handling', () => { - test('displays action message again on any error', async () => { - const wrapper = createWrapper(); - const action = wrapper.get('.quick-pay__action__component'); - - const error = new Error('Any transfer error'); - action.vm.$emit('failed', error); - await wrapper.vm.$nextTick(); - - const message = wrapper.find('.quick-pay__action__message'); - expect(message.exists()).toBeTruthy(); - }); - - test('displays error dialog when error is not recoverable', async () => { - const wrapper = createWrapper(); - const action = wrapper.get('.quick-pay__action__component'); + test('remains same action when error is not recoverable', async () => { + const wrapper = createWrapper(optionsForStraightTransfer); + const firstAction = wrapper.getComponent(TransferAction); const error = new Error('The requested target is offline.'); - action.vm.$emit('failed', error); + firstAction.vm.$emit('failed', error); await wrapper.vm.$nextTick(); - const errorDialog = wrapper.findComponent(ErrorDialog); - expect(errorDialog.exists()).toBeTruthy(); + const secondAction = wrapper.get('.quick-pay__action__component'); + expect(secondAction.vm).toEqual(firstAction.vm); }); describe('can recover from no valid routes found error', () => {