From 92f6cbfba36d1238e5b981c018b2a5365aabfe9c Mon Sep 17 00:00:00 2001 From: Csaba Tuncsik Date: Tue, 9 Apr 2024 10:25:12 +0200 Subject: [PATCH] fix(editor): Fix displaying logic of execution retry button (#9061) --- .../src/components/ExecutionsList.vue | 10 +-- .../ExecutionsView/ExecutionCard.vue | 7 +- .../ExecutionsView/ExecutionPreview.vue | 5 +- .../__tests__/ExecutionCard.test.ts | 77 +++++++++++++++++++ .../editor-ui/src/mixins/executionsHelpers.ts | 7 ++ 5 files changed, 94 insertions(+), 12 deletions(-) create mode 100644 packages/editor-ui/src/components/ExecutionsView/__tests__/ExecutionCard.test.ts diff --git a/packages/editor-ui/src/components/ExecutionsList.vue b/packages/editor-ui/src/components/ExecutionsList.vue index bf431044d33d5..5f89a8c5bfc07 100644 --- a/packages/editor-ui/src/components/ExecutionsList.vue +++ b/packages/editor-ui/src/components/ExecutionsList.vue @@ -894,15 +894,6 @@ export default defineComponent({ this.showError(error, this.i18n.baseText('executionsList.showError.stopExecution.title')); } }, - isExecutionRetriable(execution: ExecutionSummary): boolean { - return ( - execution.stoppedAt !== undefined && - !execution.finished && - execution.retryOf === undefined && - execution.retrySuccessId === undefined && - !execution.waitTill - ); - }, async deleteExecution(execution: ExecutionSummary) { this.isDataLoading = true; try { @@ -1160,6 +1151,7 @@ export default defineComponent({ background: var(--execution-card-border-waiting); } + &.canceled td:first-child::before, &.unknown td:first-child::before { background: var(--execution-card-border-unknown); } diff --git a/packages/editor-ui/src/components/ExecutionsView/ExecutionCard.vue b/packages/editor-ui/src/components/ExecutionsView/ExecutionCard.vue index eee8c47172f61..232169ae9ffca 100644 --- a/packages/editor-ui/src/components/ExecutionsView/ExecutionCard.vue +++ b/packages/editor-ui/src/components/ExecutionsView/ExecutionCard.vue @@ -59,7 +59,7 @@
import { defineComponent } from 'vue'; -import type { ExecutionSummary } from '@/Interface'; +import type { ExecutionSummary } from 'n8n-workflow'; import type { IExecutionUIData } from '@/mixins/executionsHelpers'; import { executionHelpers } from '@/mixins/executionsHelpers'; import { VIEWS } from '@/constants'; @@ -133,6 +133,9 @@ export default defineComponent({ isActive(): boolean { return this.execution.id === this.$route.params.executionId; }, + isRetriable(): boolean { + return this.isExecutionRetriable(this.execution); + }, }, methods: { onRetryMenuItemSelect(action: string): void { diff --git a/packages/editor-ui/src/components/ExecutionsView/ExecutionPreview.vue b/packages/editor-ui/src/components/ExecutionsView/ExecutionPreview.vue index e8a63a9f308bb..6c1c7beecbdb1 100644 --- a/packages/editor-ui/src/components/ExecutionsView/ExecutionPreview.vue +++ b/packages/editor-ui/src/components/ExecutionsView/ExecutionPreview.vue @@ -96,7 +96,7 @@ { diff --git a/packages/editor-ui/src/components/ExecutionsView/__tests__/ExecutionCard.test.ts b/packages/editor-ui/src/components/ExecutionsView/__tests__/ExecutionCard.test.ts new file mode 100644 index 0000000000000..65e6ec5b16e20 --- /dev/null +++ b/packages/editor-ui/src/components/ExecutionsView/__tests__/ExecutionCard.test.ts @@ -0,0 +1,77 @@ +import { createComponentRenderer } from '@/__tests__/render'; +import ExecutionCard from '@/components/ExecutionsView/ExecutionCard.vue'; +import { createPinia, setActivePinia } from 'pinia'; + +const renderComponent = createComponentRenderer(ExecutionCard, { + global: { + stubs: { + 'router-link': { + template: '
', + }, + }, + mocks: { + $route: { + params: {}, + }, + }, + }, +}); + +describe('ExecutionCard', () => { + beforeEach(() => { + setActivePinia(createPinia()); + }); + + test.each([ + [ + { + id: '1', + mode: 'manual', + status: 'success', + retryOf: null, + retrySuccessId: null, + }, + false, + ], + [ + { + id: '2', + mode: 'manual', + status: 'error', + retryOf: null, + retrySuccessId: null, + }, + true, + ], + [ + { + id: '3', + mode: 'manual', + status: 'error', + retryOf: '2', + retrySuccessId: null, + }, + false, + ], + [ + { + id: '4', + mode: 'manual', + status: 'error', + retryOf: null, + retrySuccessId: '3', + }, + false, + ], + ])('with execution %j retry button visibility is %s', (execution, shouldRenderRetryBtn) => { + const { queryByTestId } = renderComponent({ + props: { + execution, + }, + }); + + expect(!!queryByTestId('retry-execution-button') && shouldRenderRetryBtn).toBe( + shouldRenderRetryBtn, + ); + }); +}); diff --git a/packages/editor-ui/src/mixins/executionsHelpers.ts b/packages/editor-ui/src/mixins/executionsHelpers.ts index 507b625b9f989..0db11d3ea81b0 100644 --- a/packages/editor-ui/src/mixins/executionsHelpers.ts +++ b/packages/editor-ui/src/mixins/executionsHelpers.ts @@ -74,5 +74,12 @@ export const executionHelpers = defineComponent({ const { date, time } = convertToDisplayDate(fullDate); return locale.baseText('executionsList.started', { interpolate: { time, date } }); }, + isExecutionRetriable(execution: ExecutionSummary): boolean { + return ( + ['crashed', 'error'].includes(execution.status ?? '') && + !execution.retryOf && + !execution.retrySuccessId + ); + }, }, });