From 6ccf744557e476cb40515aa06288dee741484d2a Mon Sep 17 00:00:00 2001 From: Peter Clement Date: Mon, 28 Mar 2022 10:01:56 +0100 Subject: [PATCH] update bindings to support looping --- .../builderStore/store/automation/index.js | 1 + .../FlowChart/FlowChart.svelte | 4 +- .../FlowChart/FlowItem.svelte | 28 ++++++---- .../SetupPanel/AutomationBlockSetup.svelte | 6 --- packages/server/src/automations/steps/loop.js | 12 ++++- packages/server/src/threads/automation.js | 51 +++++++++++++++++-- 6 files changed, 78 insertions(+), 24 deletions(-) diff --git a/packages/builder/src/builderStore/store/automation/index.js b/packages/builder/src/builderStore/store/automation/index.js index 84e6033439..7e61b410e4 100644 --- a/packages/builder/src/builderStore/store/automation/index.js +++ b/packages/builder/src/builderStore/store/automation/index.js @@ -98,6 +98,7 @@ const automationActions = store => ({ automationId: automation?._id, testData, }) + console.log(result) store.update(state => { state.selectedAutomation.testResults = result return state diff --git a/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowChart.svelte b/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowChart.svelte index ca04fed8df..505a0b9aca 100644 --- a/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowChart.svelte +++ b/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowChart.svelte @@ -72,7 +72,9 @@ animate:flip={{ duration: 500 }} in:fly|local={{ x: 500, duration: 1500 }} > - + {#if block.stepId !== "LOOP"} + + {/if} {/each} diff --git a/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowItem.svelte b/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowItem.svelte index 5bd250572e..00b2366657 100644 --- a/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowItem.svelte +++ b/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowItem.svelte @@ -34,6 +34,7 @@ $: testResult = $automationStore.selectedAutomation.testResults?.steps.filter( step => (block.id ? step.id === block.id : step.stepId === block.stepId) ) + $: console.log(testResult) $: isTrigger = block.type === "TRIGGER" $: selected = $automationStore.selectedBlock?.id === block.id @@ -51,7 +52,10 @@ block.schema?.inputs?.properties || {} ).every(x => block?.inputs[x]) - $: loopingSelected = !!block.llop + $: loopingSelected = + $automationStore.selectedAutomation?.automation.definition.steps.find( + x => x.blockToLoop === block.id + ) $: showLooping = false async function deleteStep() { try { @@ -77,21 +81,18 @@ ) } - /* async function removeLooping() { loopingSelected = false - const idx = + const loopToDelete = $automationStore.selectedAutomation.automation.definition.steps.findIndex( - x => x.id === block.id + x => x.blockToLoop === block.id ) - delete $automationStore.selectedAutomation.automation.definition.steps[idx] - .loop - + automationStore.actions.deleteAutomationBlock(loopToDelete) await automationStore.actions.save( $automationStore.selectedAutomation?.automation ) - }*/ + } async function addLooping() { loopingSelected = true const loopDefinition = $automationStore.blockDefinitions.ACTION.LOOP @@ -152,18 +153,25 @@ + {#if !showLooping}
+
+
deleteStep()}> + +
+
x.blockToLoop === block.id + )} {webhookModal} - isLoop={true} />
diff --git a/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte b/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte index 19847a5196..2b4be4bb29 100644 --- a/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte +++ b/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte @@ -35,7 +35,6 @@ export let testData export let schemaProperties export let isTestModal = false - export let isLoop = false let webhookModal let drawer let tempFilters = lookForFilters(schemaProperties) || [] @@ -74,11 +73,6 @@ await automationStore.actions.save( $automationStore.selectedAutomation?.automation ) - } else if (isLoop) { - block.loop[key] = e.detail - await automationStore.actions.save( - $automationStore.selectedAutomation?.automation - ) } else { block.inputs[key] = e.detail await automationStore.actions.save( diff --git a/packages/server/src/automations/steps/loop.js b/packages/server/src/automations/steps/loop.js index 48b20ff277..1f53210269 100644 --- a/packages/server/src/automations/steps/loop.js +++ b/packages/server/src/automations/steps/loop.js @@ -11,7 +11,7 @@ exports.definition = { properties: { option: { customType: "loopOption", - title: "Whether it's an array or a string", + title: "Input type", }, binding: { type: "string", @@ -30,10 +30,18 @@ exports.definition = { }, outputs: { properties: { - currentItem: { + items: { customType: "item", description: "the item currently being executed", }, + success: { + type: "boolean", + description: "Whether the message sent successfully", + }, + iterations: { + type: "number", + descriptions: "The amount of times the block ran", + }, }, required: ["success"], }, diff --git a/packages/server/src/threads/automation.js b/packages/server/src/threads/automation.js index 64d68ab66b..666403d595 100644 --- a/packages/server/src/threads/automation.js +++ b/packages/server/src/threads/automation.js @@ -17,6 +17,7 @@ const LOOP_STEP_ID = actions.ACTION_DEFINITIONS.LOOP.stepId const CRON_STEP_ID = triggerDefs.CRON.stepId const STOPPED_STATUS = { success: false, status: "STOPPED" } const { cloneDeep } = require("lodash/fp") +const { loop } = require("svelte/internal") /** * The automation orchestrator is a class responsible for executing automations. @@ -87,6 +88,7 @@ class Orchestrator { let stepCount = 0 let loopStepNumber + let loopSteps = [] for (let step of automation.definition.steps) { stepCount++ if (step.stepId === LOOP_STEP_ID) { @@ -94,10 +96,18 @@ class Orchestrator { loopStepNumber = stepCount continue } + let iterations = loopStep ? loopStep.inputs.binding.split(",").length : 1 - let iterations = loopStep ? loopStep.inputs.iterations : 1 for (let index = 0; index < iterations; index++) { let originalStepInput = cloneDeep(step.inputs) + + /* + if (step.stepId === LOOP_STEP_ID && index >= loopStep.inputs.iterations) { + this.executionOutput.steps[loopStepNumber].outputs.status = "Loop Broken" + break + } + + */ // execution stopped, record state for that if (stopped) { this.updateExecutionOutput(step.id, step.stepId, {}, STOPPED_STATUS) @@ -135,25 +145,56 @@ class Orchestrator { }) continue } - // THE OUTPUTS GET SET IN THE CONSTRUCTOR SO WE NEED TO RESET THEM - - this.updateExecutionOutput(step.id, step.stepId, step.inputs, outputs) + if (loopStep) { + loopSteps.push({ + id: step.id, + stepId: step.stepId, + inputs: step.inputs, + outputs, + }) + } else { + this.updateExecutionOutput( + step.id, + step.stepId, + step.inputs, + outputs + ) + } } catch (err) { console.error(`Automation error - ${step.stepId} - ${err}`) return err } + if (index === iterations - 1) { loopStep = null break } } + if (loopSteps) { + this.executionOutput.steps.splice(loopStepNumber, 0, { + id: step.id, + stepId: step.stepId, + outputs: { + success: true, + outputs: loopSteps, + iterations: iterations, + }, + }) + this._context.steps.splice(loopStepNumber, 0, { + id: step.id, + stepId: step.stepId, + steps: loopSteps, + iterations, + success: true, + }) + loopSteps = null + } } // Increment quota for automation runs if (!env.SELF_HOSTED && !isDevAppID(this._appId)) { await usage.update(usage.Properties.AUTOMATION, 1) } // make that we don't loop the next step if we have already been looping (loop block only has one step) - return this.executionOutput } }