From 9b66b309695939c09254ef8b4502506e23f0f671 Mon Sep 17 00:00:00 2001 From: Peter Clement Date: Tue, 9 May 2023 12:04:16 +0100 Subject: [PATCH 01/35] add property to denote if step can be looped --- packages/server/src/automations/steps/bash.ts | 1 + packages/server/src/automations/steps/createRow.ts | 1 + packages/server/src/automations/steps/delay.ts | 1 + packages/server/src/automations/steps/deleteRow.ts | 1 + packages/server/src/automations/steps/discord.ts | 1 + packages/server/src/automations/steps/executeQuery.ts | 1 + packages/server/src/automations/steps/executeScript.ts | 1 + packages/server/src/automations/steps/filter.ts | 1 + packages/server/src/automations/steps/integromat.ts | 1 + packages/server/src/automations/steps/loop.ts | 2 ++ packages/server/src/automations/steps/outgoingWebhook.ts | 1 + packages/server/src/automations/steps/queryRows.ts | 1 + packages/server/src/automations/steps/sendSmtpEmail.ts | 1 + packages/server/src/automations/steps/serverLog.ts | 1 + packages/server/src/automations/steps/slack.ts | 1 + packages/server/src/automations/steps/updateRow.ts | 1 + packages/server/src/automations/steps/zapier.ts | 1 + 17 files changed, 18 insertions(+) diff --git a/packages/server/src/automations/steps/bash.ts b/packages/server/src/automations/steps/bash.ts index 820d0329db..de1f43a907 100644 --- a/packages/server/src/automations/steps/bash.ts +++ b/packages/server/src/automations/steps/bash.ts @@ -18,6 +18,7 @@ export const definition: AutomationStepSchema = { description: "Run a bash script", type: AutomationStepType.ACTION, internal: true, + canLoop: true, stepId: AutomationActionStepId.EXECUTE_BASH, inputs: {}, schema: { diff --git a/packages/server/src/automations/steps/createRow.ts b/packages/server/src/automations/steps/createRow.ts index dac929f1ee..027012338b 100644 --- a/packages/server/src/automations/steps/createRow.ts +++ b/packages/server/src/automations/steps/createRow.ts @@ -17,6 +17,7 @@ export const definition: AutomationStepSchema = { description: "Add a row to your database", type: AutomationStepType.ACTION, internal: true, + canLoop: true, stepId: AutomationActionStepId.CREATE_ROW, inputs: {}, schema: { diff --git a/packages/server/src/automations/steps/delay.ts b/packages/server/src/automations/steps/delay.ts index 9cf578805c..736e392821 100644 --- a/packages/server/src/automations/steps/delay.ts +++ b/packages/server/src/automations/steps/delay.ts @@ -14,6 +14,7 @@ export const definition: AutomationStepSchema = { description: "Delay the automation until an amount of time has passed", stepId: AutomationActionStepId.DELAY, internal: true, + canLoop: false, inputs: {}, schema: { inputs: { diff --git a/packages/server/src/automations/steps/deleteRow.ts b/packages/server/src/automations/steps/deleteRow.ts index 86c7703491..6b830a3eab 100644 --- a/packages/server/src/automations/steps/deleteRow.ts +++ b/packages/server/src/automations/steps/deleteRow.ts @@ -18,6 +18,7 @@ export const definition: AutomationStepSchema = { type: AutomationStepType.ACTION, stepId: AutomationActionStepId.DELETE_ROW, internal: true, + canLoop: true, inputs: {}, schema: { inputs: { diff --git a/packages/server/src/automations/steps/discord.ts b/packages/server/src/automations/steps/discord.ts index c46220c3b2..165f1a6d04 100644 --- a/packages/server/src/automations/steps/discord.ts +++ b/packages/server/src/automations/steps/discord.ts @@ -19,6 +19,7 @@ export const definition: AutomationStepSchema = { stepId: AutomationActionStepId.discord, type: AutomationStepType.ACTION, internal: false, + canLoop: true, inputs: {}, schema: { inputs: { diff --git a/packages/server/src/automations/steps/executeQuery.ts b/packages/server/src/automations/steps/executeQuery.ts index 4969400552..b63d894f5c 100644 --- a/packages/server/src/automations/steps/executeQuery.ts +++ b/packages/server/src/automations/steps/executeQuery.ts @@ -18,6 +18,7 @@ export const definition: AutomationStepSchema = { type: AutomationStepType.ACTION, stepId: AutomationActionStepId.EXECUTE_QUERY, internal: true, + canLoop: true, inputs: {}, schema: { inputs: { diff --git a/packages/server/src/automations/steps/executeScript.ts b/packages/server/src/automations/steps/executeScript.ts index 9bd0eaed18..d0bb500cf1 100644 --- a/packages/server/src/automations/steps/executeScript.ts +++ b/packages/server/src/automations/steps/executeScript.ts @@ -19,6 +19,7 @@ export const definition: AutomationStepSchema = { internal: true, stepId: AutomationActionStepId.EXECUTE_SCRIPT, inputs: {}, + canLoop: true, schema: { inputs: { properties: { diff --git a/packages/server/src/automations/steps/filter.ts b/packages/server/src/automations/steps/filter.ts index c7ab4210ec..f457492fc3 100644 --- a/packages/server/src/automations/steps/filter.ts +++ b/packages/server/src/automations/steps/filter.ts @@ -28,6 +28,7 @@ export const definition: AutomationStepSchema = { "Conditionally halt automations which do not meet certain conditions", type: AutomationStepType.LOGIC, internal: true, + canLoop: false, stepId: AutomationActionStepId.FILTER, inputs: { condition: FilterConditions.EQUAL, diff --git a/packages/server/src/automations/steps/integromat.ts b/packages/server/src/automations/steps/integromat.ts index d7c78a6dd8..45d659d0c7 100644 --- a/packages/server/src/automations/steps/integromat.ts +++ b/packages/server/src/automations/steps/integromat.ts @@ -17,6 +17,7 @@ export const definition: AutomationStepSchema = { stepId: AutomationActionStepId.integromat, type: AutomationStepType.ACTION, internal: false, + canLoop: true, inputs: {}, schema: { inputs: { diff --git a/packages/server/src/automations/steps/loop.ts b/packages/server/src/automations/steps/loop.ts index fdbec83f2e..f646492ee7 100644 --- a/packages/server/src/automations/steps/loop.ts +++ b/packages/server/src/automations/steps/loop.ts @@ -13,6 +13,8 @@ export const definition: AutomationStepSchema = { description: "Loop", stepId: AutomationActionStepId.LOOP, internal: true, + canLoop: false, + inputs: {}, schema: { inputs: { diff --git a/packages/server/src/automations/steps/outgoingWebhook.ts b/packages/server/src/automations/steps/outgoingWebhook.ts index f174935195..acdf60d869 100644 --- a/packages/server/src/automations/steps/outgoingWebhook.ts +++ b/packages/server/src/automations/steps/outgoingWebhook.ts @@ -32,6 +32,7 @@ export const definition: AutomationStepSchema = { description: "Send a request of specified method to a URL", type: AutomationStepType.ACTION, internal: true, + canLoop: true, stepId: AutomationActionStepId.OUTGOING_WEBHOOK, inputs: { requestMethod: "POST", diff --git a/packages/server/src/automations/steps/queryRows.ts b/packages/server/src/automations/steps/queryRows.ts index 1d7e8a419e..f3ab298e55 100644 --- a/packages/server/src/automations/steps/queryRows.ts +++ b/packages/server/src/automations/steps/queryRows.ts @@ -42,6 +42,7 @@ export const definition: AutomationStepSchema = { type: AutomationStepType.ACTION, stepId: AutomationActionStepId.QUERY_ROWS, internal: true, + canLoop: true, inputs: {}, schema: { inputs: { diff --git a/packages/server/src/automations/steps/sendSmtpEmail.ts b/packages/server/src/automations/steps/sendSmtpEmail.ts index c4af9aeaa9..fc88ee721b 100644 --- a/packages/server/src/automations/steps/sendSmtpEmail.ts +++ b/packages/server/src/automations/steps/sendSmtpEmail.ts @@ -15,6 +15,7 @@ export const definition: AutomationStepSchema = { name: "Send Email (SMTP)", type: AutomationStepType.ACTION, internal: true, + canLoop: true, stepId: AutomationActionStepId.SEND_EMAIL_SMTP, inputs: {}, schema: { diff --git a/packages/server/src/automations/steps/serverLog.ts b/packages/server/src/automations/steps/serverLog.ts index 382f7d4efc..241d71a220 100644 --- a/packages/server/src/automations/steps/serverLog.ts +++ b/packages/server/src/automations/steps/serverLog.ts @@ -19,6 +19,7 @@ export const definition: AutomationStepSchema = { description: "Logs the given text to the server (using console.log)", type: AutomationStepType.ACTION, internal: true, + canLoop: true, stepId: AutomationActionStepId.SERVER_LOG, inputs: { text: "", diff --git a/packages/server/src/automations/steps/slack.ts b/packages/server/src/automations/steps/slack.ts index 21ee6ed742..ec08f60e5a 100644 --- a/packages/server/src/automations/steps/slack.ts +++ b/packages/server/src/automations/steps/slack.ts @@ -16,6 +16,7 @@ export const definition: AutomationStepSchema = { stepId: AutomationActionStepId.slack, type: AutomationStepType.ACTION, internal: false, + canLoop: true, inputs: {}, schema: { inputs: { diff --git a/packages/server/src/automations/steps/updateRow.ts b/packages/server/src/automations/steps/updateRow.ts index 96ab1d1642..4b3457961b 100644 --- a/packages/server/src/automations/steps/updateRow.ts +++ b/packages/server/src/automations/steps/updateRow.ts @@ -17,6 +17,7 @@ export const definition: AutomationStepSchema = { description: "Update a row in your database", type: AutomationStepType.ACTION, internal: true, + canLoop: true, stepId: AutomationActionStepId.UPDATE_ROW, inputs: {}, schema: { diff --git a/packages/server/src/automations/steps/zapier.ts b/packages/server/src/automations/steps/zapier.ts index 75a21deaae..dcb3947f1d 100644 --- a/packages/server/src/automations/steps/zapier.ts +++ b/packages/server/src/automations/steps/zapier.ts @@ -13,6 +13,7 @@ export const definition: AutomationStepSchema = { stepId: AutomationActionStepId.zapier, type: AutomationStepType.ACTION, internal: false, + canLoop: true, description: "Trigger a Zapier Zap via webhooks", tagline: "Trigger a Zapier Zap", icon: "ri-flashlight-line", From ac57a849ce23fd8c389aa04b424378755cac1f4e Mon Sep 17 00:00:00 2001 From: Peter Clement Date: Tue, 9 May 2023 12:04:32 +0100 Subject: [PATCH 02/35] add collect bloc definition --- .../server/src/automations/steps/collect.ts | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 packages/server/src/automations/steps/collect.ts diff --git a/packages/server/src/automations/steps/collect.ts b/packages/server/src/automations/steps/collect.ts new file mode 100644 index 0000000000..1083c2a216 --- /dev/null +++ b/packages/server/src/automations/steps/collect.ts @@ -0,0 +1,53 @@ +import { + AutomationActionStepId, + AutomationStepSchema, + AutomationStepInput, + AutomationStepType, + AutomationIOType, +} from "@budibase/types" + +export const definition: AutomationStepSchema = { + name: "Collect Data", + tagline: "Collect data to be sent to design", + icon: "Collection", + description: + "Collects specified data so it can be provided to the design section", + type: AutomationStepType.ACTION, + internal: true, + canLoop: false, + stepId: AutomationActionStepId.COLLECT, + inputs: { + text: "", + }, + schema: { + inputs: { + properties: { + collection: { + type: AutomationIOType.STRING, + title: "What to Collect", + }, + }, + required: ["text"], + }, + outputs: { + properties: { + success: { + type: AutomationIOType.BOOLEAN, + description: "Whether the action was successful", + }, + value: { + type: AutomationIOType.STRING, + description: "Collected data", + }, + }, + required: ["success", "value"], + }, + }, +} + +export async function run({ inputs }: AutomationStepInput) { + return { + success: true, + value: inputs.collection, + } +} From 1539bf234be9ff42c5882c4fb11149c2ccb0c8ca Mon Sep 17 00:00:00 2001 From: Peter Clement Date: Tue, 9 May 2023 12:10:20 +0100 Subject: [PATCH 03/35] add ability to trigger synchronous automation from button action --- .../FlowChart/ActionModal.svelte | 1 - .../FlowChart/FlowItem.svelte | 2 +- .../ButtonActionDrawer.svelte | 30 +++++++++++-- .../actions/TriggerAutomation.svelte | 43 ++++++++++++++++++- .../controls/ButtonActionEditor/manifest.json | 8 +++- packages/client/src/utils/buttonActions.js | 24 +++++++---- packages/frontend-core/src/api/automations.js | 7 +++ .../server/src/api/controllers/automation.ts | 25 ++++++++++- packages/server/src/api/routes/automation.ts | 11 +++++ packages/server/src/automations/actions.ts | 3 ++ .../types/src/documents/app/automation.ts | 2 + 11 files changed, 139 insertions(+), 17 deletions(-) diff --git a/packages/builder/src/components/automation/AutomationBuilder/FlowChart/ActionModal.svelte b/packages/builder/src/components/automation/AutomationBuilder/FlowChart/ActionModal.svelte index 3a85c7ed56..73394f5b90 100644 --- a/packages/builder/src/components/automation/AutomationBuilder/FlowChart/ActionModal.svelte +++ b/packages/builder/src/components/automation/AutomationBuilder/FlowChart/ActionModal.svelte @@ -48,7 +48,6 @@ } return acc }, {}) - console.log(plugins) const selectAction = action => { actionVal = action diff --git a/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowItem.svelte b/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowItem.svelte index 7484a60502..9730c03ef3 100644 --- a/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowItem.svelte +++ b/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowItem.svelte @@ -184,7 +184,7 @@ {#if !isTrigger}
- {#if !loopBlock} + {#if block?.canLoop} addLooping()} icon="Reuse"> Add Looping diff --git a/packages/builder/src/components/design/settings/controls/ButtonActionEditor/ButtonActionDrawer.svelte b/packages/builder/src/components/design/settings/controls/ButtonActionEditor/ButtonActionDrawer.svelte index 8f2c286261..3228c1402d 100644 --- a/packages/builder/src/components/design/settings/controls/ButtonActionEditor/ButtonActionDrawer.svelte +++ b/packages/builder/src/components/design/settings/controls/ButtonActionEditor/ButtonActionDrawer.svelte @@ -126,8 +126,7 @@ } const getAllBindings = (bindings, eventContextBindings, actions) => { - let allBindings = eventContextBindings.concat(bindings) - + let allBindings = [] if (!actions) { return [] } @@ -145,14 +144,37 @@ .forEach(action => { // Check we have a binding for this action, and generate one if not const stateBinding = makeStateBinding(action.parameters.key) - const hasKey = allBindings.some(binding => { + const hasKey = bindings.some(binding => { return binding.runtimeBinding === stateBinding.runtimeBinding }) if (!hasKey) { - allBindings.push(stateBinding) + bindings.push(stateBinding) } }) + // Get which indexes are asynchronous automations as we want to filter them out from the bindings + const asynchronousAutomationIndexes = actions + .map((action, index) => { + if ( + action[EVENT_TYPE_KEY] === "Trigger Automation" && + !action.parameters?.synchronous + ) { + return index + } + }) + .filter(index => index !== undefined) + + // Based on the above, filter out the asynchronous automations from the bindings + if (asynchronousAutomationIndexes) { + allBindings = eventContextBindings + .filter((binding, index) => { + return !asynchronousAutomationIndexes.includes(index) + }) + .concat(bindings) + } else { + allBindings = eventContextBindings.concat(bindings) + } + return allBindings } diff --git a/packages/builder/src/components/design/settings/controls/ButtonActionEditor/actions/TriggerAutomation.svelte b/packages/builder/src/components/design/settings/controls/ButtonActionEditor/actions/TriggerAutomation.svelte index a2ffb144c0..aa617ab9a3 100644 --- a/packages/builder/src/components/design/settings/controls/ButtonActionEditor/actions/TriggerAutomation.svelte +++ b/packages/builder/src/components/design/settings/controls/ButtonActionEditor/actions/TriggerAutomation.svelte @@ -1,12 +1,15 @@
@@ -85,6 +107,7 @@ {#if automationStatus === AUTOMATION_STATUS.EXISTING} +
{/if}
diff --git a/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowItem.svelte b/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowItem.svelte index 99cbab52af..9ff57a764b 100644 --- a/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowItem.svelte +++ b/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowItem.svelte @@ -31,6 +31,9 @@ let showLooping = false let role + $: collectBlockExists = $selectedAutomation.definition.steps.some( + step => step.stepId === ActionStepID.COLLECT + ) $: automationId = $selectedAutomation?._id $: showBindingPicker = block.stepId === ActionStepID.CREATE_ROW || @@ -224,21 +227,28 @@
{/if} - - - - - - - - -
- actionModal.show()} hoverable name="AddCircle" size="S" /> -{#if isTrigger ? totalBlocks > 1 : blockIdx !== totalBlocks - 2} +{#if !collectBlockExists || !lastStep}
+ actionModal.show()} + hoverable + name="AddCircle" + size="S" + /> + {#if isTrigger ? totalBlocks > 1 : blockIdx !== totalBlocks - 2} +
+ {/if} {/if} + + + + + + + +