add ability to trigger synchronous automation from button action
This commit is contained in:
parent
ac57a849ce
commit
1539bf234b
|
@ -48,7 +48,6 @@
|
|||
}
|
||||
return acc
|
||||
}, {})
|
||||
console.log(plugins)
|
||||
|
||||
const selectAction = action => {
|
||||
actionVal = action
|
||||
|
|
|
@ -184,7 +184,7 @@
|
|||
{#if !isTrigger}
|
||||
<div>
|
||||
<div class="block-options">
|
||||
{#if !loopBlock}
|
||||
{#if block?.canLoop}
|
||||
<ActionButton on:click={() => addLooping()} icon="Reuse">
|
||||
Add Looping
|
||||
</ActionButton>
|
||||
|
|
|
@ -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
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -1,12 +1,15 @@
|
|||
<script>
|
||||
import { Select, Label, Input, Checkbox } from "@budibase/bbui"
|
||||
import { Select, Label, Input, Checkbox, Icon } from "@budibase/bbui"
|
||||
import { automationStore } from "builderStore"
|
||||
import SaveFields from "./SaveFields.svelte"
|
||||
import { TriggerStepID } from "constants/backend/automations"
|
||||
import { AutomationActionStepId } from "../../../../../../../../types/src/documents"
|
||||
|
||||
export let parameters = {}
|
||||
export let bindings = []
|
||||
|
||||
let synchronous = parameters.synchronous
|
||||
|
||||
const AUTOMATION_STATUS = {
|
||||
NEW: "new",
|
||||
EXISTING: "existing",
|
||||
|
@ -16,6 +19,11 @@
|
|||
? AUTOMATION_STATUS.EXISTING
|
||||
: AUTOMATION_STATUS.NEW
|
||||
|
||||
$: {
|
||||
if (automationStatus === AUTOMATION_STATUS.NEW) {
|
||||
synchronous = false
|
||||
}
|
||||
}
|
||||
$: automations = $automationStore.automations
|
||||
.filter(a => a.definition.trigger?.stepId === TriggerStepID.APP)
|
||||
.map(automation => {
|
||||
|
@ -23,10 +31,15 @@
|
|||
automation.definition.trigger.inputs.fields || {}
|
||||
).map(([name, type]) => ({ name, type }))
|
||||
|
||||
let hasCollectBlock = automation.definition.steps.some(
|
||||
step => step.stepId === AutomationActionStepId.COLLECT
|
||||
)
|
||||
|
||||
return {
|
||||
name: automation.name,
|
||||
_id: automation._id,
|
||||
schema,
|
||||
synchronous: hasCollectBlock,
|
||||
}
|
||||
})
|
||||
$: hasAutomations = automations && automations.length > 0
|
||||
|
@ -57,6 +70,15 @@
|
|||
parameters.fields = {}
|
||||
parameters.automationId = automations[0]?._id
|
||||
}
|
||||
|
||||
const onChange = value => {
|
||||
let automationId = value.detail
|
||||
synchronous = automations.find(
|
||||
automation => automation._id === automationId
|
||||
).synchronous
|
||||
parameters.automationId = automationId
|
||||
parameters.synchronous = synchronous
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="root">
|
||||
|
@ -85,6 +107,7 @@
|
|||
|
||||
{#if automationStatus === AUTOMATION_STATUS.EXISTING}
|
||||
<Select
|
||||
on:change={onChange}
|
||||
bind:value={parameters.automationId}
|
||||
placeholder="Choose automation"
|
||||
options={automations}
|
||||
|
@ -98,6 +121,19 @@
|
|||
/>
|
||||
{/if}
|
||||
|
||||
{#if synchronous}
|
||||
<Label small />
|
||||
|
||||
<div class="synchronous-info">
|
||||
<Icon name="Info" />
|
||||
<div>
|
||||
<i
|
||||
>This automation will run synchronously due to the existence of a
|
||||
Collect block</i
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
<Label small />
|
||||
<Checkbox
|
||||
text="Do not display default notification"
|
||||
|
@ -142,6 +178,11 @@
|
|||
align-items: center;
|
||||
}
|
||||
|
||||
.synchronous-info {
|
||||
display: flex;
|
||||
gap: var(--spacing-s);
|
||||
}
|
||||
|
||||
.fields {
|
||||
margin-top: var(--spacing-l);
|
||||
display: grid;
|
||||
|
|
|
@ -57,7 +57,13 @@
|
|||
{
|
||||
"name": "Trigger Automation",
|
||||
"type": "application",
|
||||
"component": "TriggerAutomation"
|
||||
"component": "TriggerAutomation",
|
||||
"context": [
|
||||
{
|
||||
"label": "Automation Result",
|
||||
"value": "result"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Update Field Value",
|
||||
|
|
|
@ -122,15 +122,24 @@ const deleteRowHandler = async action => {
|
|||
}
|
||||
|
||||
const triggerAutomationHandler = async action => {
|
||||
const { fields, notificationOverride } = action.parameters
|
||||
const { fields, notificationOverride, synchronous } = action.parameters
|
||||
if (fields) {
|
||||
try {
|
||||
await API.triggerAutomation({
|
||||
automationId: action.parameters.automationId,
|
||||
fields,
|
||||
})
|
||||
if (!notificationOverride) {
|
||||
notificationStore.actions.success("Automation triggered")
|
||||
if (synchronous) {
|
||||
const result = await API.triggerSynchronousAutomation({
|
||||
automationId: action.parameters.automationId,
|
||||
fields,
|
||||
})
|
||||
console.log(typeof result)
|
||||
return { result }
|
||||
} else {
|
||||
await API.triggerAutomation({
|
||||
automationId: action.parameters.automationId,
|
||||
fields,
|
||||
})
|
||||
if (!notificationOverride) {
|
||||
notificationStore.actions.success("Automation triggered")
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
// Abort next actions
|
||||
|
@ -138,7 +147,6 @@ const triggerAutomationHandler = async action => {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
const navigationHandler = action => {
|
||||
const { url, peek, externalNewTab } = action.parameters
|
||||
routeStore.actions.navigate(url, peek, externalNewTab)
|
||||
|
|
|
@ -11,6 +11,13 @@ export const buildAutomationEndpoints = API => ({
|
|||
})
|
||||
},
|
||||
|
||||
triggerSynchronousAutomation: async ({ automationId, fields }) => {
|
||||
return await API.post({
|
||||
url: `/api/automations/${automationId}/triggerSynchronous`,
|
||||
body: { fields },
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* Tests an automation with data.
|
||||
* @param automationId the ID of the automation to test
|
||||
|
|
|
@ -15,7 +15,12 @@ import { MetadataTypes } from "../../constants"
|
|||
import { setTestFlag, clearTestFlag } from "../../utilities/redis"
|
||||
import { context, cache, events } from "@budibase/backend-core"
|
||||
import { automations } from "@budibase/pro"
|
||||
import { Automation, BBContext } from "@budibase/types"
|
||||
import {
|
||||
Automation,
|
||||
AutomationActionStepId,
|
||||
AutomationResults,
|
||||
BBContext,
|
||||
} from "@budibase/types"
|
||||
import { getActionDefinitions as actionDefs } from "../../automations/actions"
|
||||
|
||||
async function getActionDefinitions() {
|
||||
|
@ -267,6 +272,24 @@ export async function trigger(ctx: BBContext) {
|
|||
}
|
||||
}
|
||||
|
||||
export async function triggerSynchronous(ctx: BBContext) {
|
||||
const db = context.getAppDB()
|
||||
let automation = await db.get(ctx.params.id)
|
||||
const response: AutomationResults = await triggers.externalTrigger(
|
||||
automation,
|
||||
{
|
||||
...ctx.request.body,
|
||||
appId: ctx.appId,
|
||||
},
|
||||
{ getResponses: true }
|
||||
)
|
||||
|
||||
let collectedValue = response.steps.find(
|
||||
step => step.stepId === AutomationActionStepId.COLLECT
|
||||
)
|
||||
ctx.body = collectedValue?.outputs
|
||||
}
|
||||
|
||||
function prepareTestInput(input: any) {
|
||||
// prepare the test parameters
|
||||
if (input.id && input.row) {
|
||||
|
|
|
@ -73,6 +73,17 @@ router
|
|||
),
|
||||
controller.trigger
|
||||
)
|
||||
.post(
|
||||
"/api/automations/:id/triggerSynchronous",
|
||||
appInfoMiddleware({ appType: AppType.PROD }),
|
||||
paramResource("id"),
|
||||
authorized(
|
||||
permissions.PermissionType.AUTOMATION,
|
||||
permissions.PermissionLevel.EXECUTE
|
||||
),
|
||||
controller.triggerSynchronous
|
||||
)
|
||||
|
||||
.post(
|
||||
"/api/automations/:id/test",
|
||||
appInfoMiddleware({ appType: AppType.DEV }),
|
||||
|
|
|
@ -14,6 +14,7 @@ import * as filter from "./steps/filter"
|
|||
import * as delay from "./steps/delay"
|
||||
import * as queryRow from "./steps/queryRows"
|
||||
import * as loop from "./steps/loop"
|
||||
import * as collect from "./steps/collect"
|
||||
import env from "../environment"
|
||||
import {
|
||||
AutomationStepSchema,
|
||||
|
@ -39,6 +40,7 @@ const ACTION_IMPLS: Record<
|
|||
DELAY: delay.run,
|
||||
FILTER: filter.run,
|
||||
QUERY_ROWS: queryRow.run,
|
||||
COLLECT: collect.run,
|
||||
// these used to be lowercase step IDs, maintain for backwards compat
|
||||
discord: discord.run,
|
||||
slack: slack.run,
|
||||
|
@ -59,6 +61,7 @@ export const BUILTIN_ACTION_DEFINITIONS: Record<string, AutomationStepSchema> =
|
|||
FILTER: filter.definition,
|
||||
QUERY_ROWS: queryRow.definition,
|
||||
LOOP: loop.definition,
|
||||
COLLECT: collect.definition,
|
||||
// these used to be lowercase step IDs, maintain for backwards compat
|
||||
discord: discord.definition,
|
||||
slack: slack.definition,
|
||||
|
|
|
@ -56,6 +56,7 @@ export enum AutomationActionStepId {
|
|||
FILTER = "FILTER",
|
||||
QUERY_ROWS = "QUERY_ROWS",
|
||||
LOOP = "LOOP",
|
||||
COLLECT = "COLLECT",
|
||||
// these used to be lowercase step IDs, maintain for backwards compat
|
||||
discord = "discord",
|
||||
slack = "slack",
|
||||
|
@ -120,6 +121,7 @@ export interface AutomationStepSchema {
|
|||
outputs: InputOutputBlock
|
||||
}
|
||||
custom?: boolean
|
||||
canLoop?: boolean
|
||||
}
|
||||
|
||||
export interface AutomationStep extends AutomationStepSchema {
|
||||
|
|
Loading…
Reference in New Issue