diff --git a/packages/cli/src/scaling/scaling.service.ts b/packages/cli/src/scaling/scaling.service.ts index 6d09ad05fd..8b18f5e4d3 100644 --- a/packages/cli/src/scaling/scaling.service.ts +++ b/packages/cli/src/scaling/scaling.service.ts @@ -305,6 +305,7 @@ export class ScalingService { this.activeExecutions.resolveResponsePromise(msg.executionId, decodedResponse); break; case 'job-finished': + this.activeExecutions.resolveResponsePromise(msg.executionId, {}); this.logger.info(`Execution ${msg.executionId} (job ${jobId}) finished successfully`, { workerId: msg.workerId, executionId: msg.executionId, diff --git a/packages/cli/src/webhooks/__tests__/webhook-helpers.test.ts b/packages/cli/src/webhooks/__tests__/webhook-helpers.test.ts index 39d770bb6f..f57788e0c4 100644 --- a/packages/cli/src/webhooks/__tests__/webhook-helpers.test.ts +++ b/packages/cli/src/webhooks/__tests__/webhook-helpers.test.ts @@ -65,6 +65,24 @@ describe('autoDetectResponseMode', () => { expect(result).toBe('responseNode'); }); + test('should return formPage when start node is FORM_NODE_TYPE and method is POST and there is a following FORM_NODE_TYPE node', () => { + const workflowStartNode = mock({ + type: FORM_NODE_TYPE, + name: 'startNode', + parameters: {}, + }); + workflow.getChildNodes.mockReturnValue(['childNode']); + workflow.nodes.childNode = mock({ + type: FORM_NODE_TYPE, + parameters: { + operation: 'completion', + }, + disabled: false, + }); + const result = autoDetectResponseMode(workflowStartNode, workflow, 'POST'); + expect(result).toBe('formPage'); + }); + test('should return undefined when start node is FORM_NODE_TYPE with no other form child nodes', () => { const workflowStartNode = mock({ type: FORM_NODE_TYPE, diff --git a/packages/cli/src/webhooks/webhook-helpers.ts b/packages/cli/src/webhooks/webhook-helpers.ts index 9cf26ebce2..a168f311a0 100644 --- a/packages/cli/src/webhooks/webhook-helpers.ts +++ b/packages/cli/src/webhooks/webhook-helpers.ts @@ -105,6 +105,7 @@ export function getWorkflowWebhooks( return returnData; } +// eslint-disable-next-line complexity export function autoDetectResponseMode( workflowStartNode: INode, workflow: Workflow, @@ -126,6 +127,21 @@ export function autoDetectResponseMode( } } + // If there are form nodes connected to a current form node we're dealing with a multipage form + // and we need to return the formPage response mode when a second page of the form gets submitted + // to be able to show potential form errors correctly. + if (workflowStartNode.type === FORM_NODE_TYPE && method === 'POST') { + const connectedNodes = workflow.getChildNodes(workflowStartNode.name); + + for (const nodeName of connectedNodes) { + const node = workflow.nodes[nodeName]; + + if (node.type === FORM_NODE_TYPE && !node.disabled) { + return 'formPage'; + } + } + } + if (workflowStartNode.type === WAIT_NODE_TYPE && workflowStartNode.parameters.resume !== 'form') { return undefined; } diff --git a/packages/cli/templates/form-trigger.handlebars b/packages/cli/templates/form-trigger.handlebars index 3b636b41e7..c00da8a1ec 100644 --- a/packages/cli/templates/form-trigger.handlebars +++ b/packages/cli/templates/form-trigger.handlebars @@ -857,9 +857,7 @@ document.querySelector('#submit-btn span').style.display = 'inline-block'; let postUrl = ''; - if (window.location.href.includes('form-waiting')) { - intervalId = setTimeout(checkExecutionStatus, interval); - } else { + if (!window.location.href.includes('form-waiting')) { postUrl = window.location.search; } @@ -880,7 +878,8 @@ if(json?.formWaitingUrl) { formWaitingUrl = json.formWaitingUrl; - intervalId = setTimeout(checkExecutionStatus, interval); + clearTimeout(timeoutId); + timeoutId = setTimeout(checkExecutionStatus, interval); return; } @@ -934,6 +933,12 @@ }) .catch(function (error) { console.error('Error:', error); + }) + .finally(() => { + if (window.location.href.includes('form-waiting')) { + clearTimeout(timeoutId); + timeoutId = setTimeout(checkExecutionStatus, interval); + } }); } });