Merge pull request #12724 from Budibase/feat/trigger-binding-suggesti

Trigger binding suggestions from  trigger fields.
This commit is contained in:
Peter Clement 2024-01-17 09:58:29 +00:00 committed by GitHub
commit be273e1558
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 123 additions and 61 deletions

View File

@ -52,7 +52,6 @@
export let testData export let testData
export let schemaProperties export let schemaProperties
export let isTestModal = false export let isTestModal = false
let webhookModal let webhookModal
let drawer let drawer
let fillWidth = true let fillWidth = true
@ -102,7 +101,6 @@
} }
} }
} }
const onChange = Utils.sequential(async (e, key) => { const onChange = Utils.sequential(async (e, key) => {
// We need to cache the schema as part of the definition because it is // We need to cache the schema as part of the definition because it is
// used in the server to detect relationships. It would be far better to // used in the server to detect relationships. It would be far better to
@ -146,6 +144,7 @@
if (!block || !automation) { if (!block || !automation) {
return [] return []
} }
// Find previous steps to the selected one // Find previous steps to the selected one
let allSteps = [...automation.steps] let allSteps = [...automation.steps]
@ -157,22 +156,96 @@
// Extract all outputs from all previous steps as available bindingsx§x // Extract all outputs from all previous steps as available bindingsx§x
let bindings = [] let bindings = []
let loopBlockCount = 0 let loopBlockCount = 0
const addBinding = (name, value, icon, idx, isLoopBlock, bindingName) => {
const runtimeBinding = determineRuntimeBinding(name, idx, isLoopBlock)
const categoryName = determineCategoryName(idx, isLoopBlock, bindingName)
bindings.push(
createBindingObject(
name,
value,
icon,
idx,
loopBlockCount,
isLoopBlock,
runtimeBinding,
categoryName,
bindingName
)
)
}
const determineRuntimeBinding = (name, idx, isLoopBlock) => {
let runtimeName
/* Begin special cases for generating custom schemas based on triggers */
if (idx === 0 && automation.trigger?.event === "app:trigger") {
return `trigger.fields.${name}`
}
if (
(idx === 0 && automation.trigger?.event === "row:update") ||
automation.trigger?.event === "row:save"
) {
if (name !== "id" && name !== "revision") return `trigger.row.${name}`
}
/* End special cases for generating custom schemas based on triggers */
if (isLoopBlock) {
runtimeName = `loop.${name}`
} else if (block.name.startsWith("JS")) {
runtimeName = `steps[${idx - loopBlockCount}].${name}`
} else {
runtimeName = `steps.${idx - loopBlockCount}.${name}`
}
return idx === 0 ? `trigger.${name}` : runtimeName
}
const determineCategoryName = (idx, isLoopBlock, bindingName) => {
if (idx === 0) return "Trigger outputs"
if (isLoopBlock) return "Loop Outputs"
return bindingName
? `${bindingName} outputs`
: `Step ${idx - loopBlockCount} outputs`
}
const createBindingObject = (
name,
value,
icon,
idx,
loopBlockCount,
isLoopBlock,
runtimeBinding,
categoryName,
bindingName
) => {
return {
readableBinding: bindingName
? `${bindingName}.${name}`
: runtimeBinding,
runtimeBinding,
type: value.type,
description: value.description,
icon,
category: categoryName,
display: {
type: value.type,
name,
rank: isLoopBlock ? idx + 1 : idx - loopBlockCount,
},
}
}
for (let idx = 0; idx < blockIdx; idx++) { for (let idx = 0; idx < blockIdx; idx++) {
let wasLoopBlock = allSteps[idx - 1]?.stepId === ActionStepID.LOOP let wasLoopBlock = allSteps[idx - 1]?.stepId === ActionStepID.LOOP
let isLoopBlock = let isLoopBlock =
allSteps[idx]?.stepId === ActionStepID.LOOP && allSteps[idx]?.stepId === ActionStepID.LOOP &&
allSteps.find(x => x.blockToLoop === block.id) allSteps.some(x => x.blockToLoop === block.id)
let schema = cloneDeep(allSteps[idx]?.schema?.outputs?.properties) ?? {}
let bindingName =
automation.stepNames?.[allSteps[idx - loopBlockCount].id]
// If the previous block was a loop block, decrement the index so the following
// steps are in the correct order
if (wasLoopBlock) {
loopBlockCount++
continue
}
let schema = allSteps[idx]?.schema?.outputs?.properties ?? {}
// If its a Loop Block, we need to add this custom schema
if (isLoopBlock) { if (isLoopBlock) {
schema = { schema = {
currentItem: { currentItem: {
@ -181,54 +254,45 @@
}, },
} }
} }
const outputs = Object.entries(schema)
let bindingIcon = "" if (idx === 0 && automation.trigger?.event === "app:trigger") {
let bindingRank = 0 schema = Object.fromEntries(
if (idx === 0) { Object.keys(automation.trigger.inputs.fields || []).map(key => [
bindingIcon = automation.trigger.icon key,
} else if (isLoopBlock) { { type: automation.trigger.inputs.fields[key] },
bindingIcon = "Reuse" ])
bindingRank = idx + 1 )
} else {
bindingIcon = allSteps[idx].icon
bindingRank = idx - loopBlockCount
} }
let bindingName = if (
automation.stepNames?.[allSteps[idx - loopBlockCount].id] (idx === 0 && automation.trigger.event === "row:update") ||
bindings = bindings.concat( (idx === 0 && automation.trigger.event === "row:save")
outputs.map(([name, value]) => { ) {
let runtimeName = isLoopBlock let table = $tables.list.find(
? `loop.${name}` table => table._id === automation.trigger.inputs.tableId
: block.name.startsWith("JS") )
? `steps[${idx - loopBlockCount}].${name}` // We want to generate our own schema for the bindings from the table schema itself
: `steps.${idx - loopBlockCount}.${name}` for (const key in table?.schema) {
const runtime = idx === 0 ? `trigger.${name}` : runtimeName schema[key] = {
type: table.schema[key].type,
let categoryName
if (idx === 0) {
categoryName = "Trigger outputs"
} else if (isLoopBlock) {
categoryName = "Loop Outputs"
} else if (bindingName) {
categoryName = `${bindingName} outputs`
} else {
categoryName = `Step ${idx - loopBlockCount} outputs`
} }
}
// remove the original binding
delete schema.row
}
let icon =
idx === 0
? automation.trigger.icon
: isLoopBlock
? "Reuse"
: allSteps[idx].icon
return { if (wasLoopBlock) {
readableBinding: bindingName ? `${bindingName}.${name}` : runtime, loopBlockCount++
runtimeBinding: runtime, continue
type: value.type, }
description: value.description,
icon: bindingIcon, Object.entries(schema).forEach(([name, value]) =>
category: categoryName, addBinding(name, value, icon, idx, isLoopBlock, bindingName)
display: {
type: value.type,
name: name,
rank: bindingRank,
},
}
})
) )
} }
@ -246,10 +310,8 @@
}) })
) )
} }
return bindings return bindings
} }
function lookForFilters(properties) { function lookForFilters(properties) {
if (!properties) { if (!properties) {
return [] return []

@ -1 +1 @@
Subproject commit 6f5e2d9a6ee671c5d987462ceb4156e2c3276a2f Subproject commit 9d80daaa5b79da68730d6c5f497f629c47a78ef8