Refactor the binding generation to ensure types are processed correctly. Rows were being misrepresented as 'Multi Select'
This commit is contained in:
parent
ef2a2b8bd0
commit
a280039dcb
|
@ -1,4 +1,4 @@
|
||||||
import { derived, get, Readable } from "svelte/store"
|
import { derived, get, readable, Readable } from "svelte/store"
|
||||||
import { API } from "@/api"
|
import { API } from "@/api"
|
||||||
import { cloneDeep } from "lodash/fp"
|
import { cloneDeep } from "lodash/fp"
|
||||||
import { generate } from "shortid"
|
import { generate } from "shortid"
|
||||||
|
@ -39,9 +39,10 @@ import {
|
||||||
TriggerTestOutputs,
|
TriggerTestOutputs,
|
||||||
RowActionTriggerOutputs,
|
RowActionTriggerOutputs,
|
||||||
WebhookTriggerOutputs,
|
WebhookTriggerOutputs,
|
||||||
|
AutomationCustomIOType,
|
||||||
} from "@budibase/types"
|
} from "@budibase/types"
|
||||||
import { ActionStepID, TriggerStepID } from "@/constants/backend/automations"
|
import { ActionStepID, TriggerStepID } from "@/constants/backend/automations"
|
||||||
import { FIELDS } from "@/constants/backend"
|
import { FIELDS as COLUMNS } from "@/constants/backend"
|
||||||
import { sdk } from "@budibase/shared-core"
|
import { sdk } from "@budibase/shared-core"
|
||||||
import { rowActions } from "./rowActions"
|
import { rowActions } from "./rowActions"
|
||||||
import { getNewStepName } from "@/helpers/automations/nameHelpers"
|
import { getNewStepName } from "@/helpers/automations/nameHelpers"
|
||||||
|
@ -101,11 +102,7 @@ const automationActions = (store: AutomationStore) => ({
|
||||||
*
|
*
|
||||||
* @returns {Readable<AutomationContext>}
|
* @returns {Readable<AutomationContext>}
|
||||||
*/
|
*/
|
||||||
generateContext: (): Readable<AutomationContext> | undefined => {
|
generateContext: (): Readable<AutomationContext> => {
|
||||||
if (!organisation || !store.selected || !environment || !tables) {
|
|
||||||
console.error("Automations: Required context stores are uninitialised")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
return derived(
|
return derived(
|
||||||
[organisation, store.selected, environment, tables],
|
[organisation, store.selected, environment, tables],
|
||||||
([$organisation, $selectedAutomation, $env, $tables]) => {
|
([$organisation, $selectedAutomation, $env, $tables]) => {
|
||||||
|
@ -653,7 +650,7 @@ const automationActions = (store: AutomationStore) => ({
|
||||||
let bindings: any[] = []
|
let bindings: any[] = []
|
||||||
const addBinding = (
|
const addBinding = (
|
||||||
name: string,
|
name: string,
|
||||||
value: any,
|
schema: any,
|
||||||
icon: string,
|
icon: string,
|
||||||
idx: number,
|
idx: number,
|
||||||
isLoopBlock: boolean,
|
isLoopBlock: boolean,
|
||||||
|
@ -661,6 +658,7 @@ const automationActions = (store: AutomationStore) => ({
|
||||||
bindingName: string
|
bindingName: string
|
||||||
) => {
|
) => {
|
||||||
if (!name) return
|
if (!name) return
|
||||||
|
|
||||||
const runtimeBinding = store.actions.determineRuntimeBinding(
|
const runtimeBinding = store.actions.determineRuntimeBinding(
|
||||||
name,
|
name,
|
||||||
idx,
|
idx,
|
||||||
|
@ -670,6 +668,11 @@ const automationActions = (store: AutomationStore) => ({
|
||||||
pathSteps
|
pathSteps
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Skip binding if its invalid
|
||||||
|
if (!runtimeBinding) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
const readableBinding = store.actions.determineReadableBinding(
|
const readableBinding = store.actions.determineReadableBinding(
|
||||||
name,
|
name,
|
||||||
pathBlock
|
pathBlock
|
||||||
|
@ -681,20 +684,38 @@ const automationActions = (store: AutomationStore) => ({
|
||||||
bindingName,
|
bindingName,
|
||||||
loopBlockCount
|
loopBlockCount
|
||||||
)
|
)
|
||||||
bindings.push(
|
|
||||||
store.actions.createBindingObject(
|
const isStep = !isLoopBlock && idx !== 0
|
||||||
name,
|
const defaultReadable =
|
||||||
value,
|
bindingName && isStep ? `steps.${bindingName}.${name}` : runtimeBinding
|
||||||
icon,
|
|
||||||
idx,
|
// Check if the schema matches any column types.
|
||||||
loopBlockCount,
|
const column = Object.values(COLUMNS).find(
|
||||||
isLoopBlock,
|
col =>
|
||||||
|
col.type === schema.type &&
|
||||||
|
("subtype" in col ? col.subtype === schema.subtype : true)
|
||||||
|
)
|
||||||
|
|
||||||
|
// Automation types and column types can collide e.g. "array"
|
||||||
|
// Exclude where necessary
|
||||||
|
const ignoreColumnType = schema.customType === AutomationCustomIOType.ROWS
|
||||||
|
|
||||||
|
// Shown in the bindable menus
|
||||||
|
const displayType = ignoreColumnType ? schema.type : column?.name
|
||||||
|
|
||||||
|
bindings.push({
|
||||||
|
readableBinding: readableBinding || defaultReadable,
|
||||||
runtimeBinding,
|
runtimeBinding,
|
||||||
categoryName,
|
type: schema.type,
|
||||||
bindingName,
|
description: schema.description,
|
||||||
readableBinding
|
icon,
|
||||||
)
|
category: categoryName,
|
||||||
)
|
display: {
|
||||||
|
type: displayType,
|
||||||
|
name,
|
||||||
|
rank: isLoopBlock ? idx + 1 : idx - loopBlockCount,
|
||||||
|
},
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
let loopBlockCount = 0
|
let loopBlockCount = 0
|
||||||
|
@ -766,6 +787,7 @@ const automationActions = (store: AutomationStore) => ({
|
||||||
console.error("Loop block missing.")
|
console.error("Loop block missing.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Object.entries(schema).forEach(([name, value]) => {
|
Object.entries(schema).forEach(([name, value]) => {
|
||||||
addBinding(
|
addBinding(
|
||||||
name,
|
name,
|
||||||
|
@ -826,7 +848,7 @@ const automationActions = (store: AutomationStore) => ({
|
||||||
currentBlock: AutomationStep | AutomationTrigger | undefined,
|
currentBlock: AutomationStep | AutomationTrigger | undefined,
|
||||||
pathSteps: (AutomationStep | AutomationTrigger)[]
|
pathSteps: (AutomationStep | AutomationTrigger)[]
|
||||||
) => {
|
) => {
|
||||||
let runtimeName: string | null
|
let runtimeName: string
|
||||||
|
|
||||||
// Legacy support for EXECUTE_SCRIPT steps
|
// Legacy support for EXECUTE_SCRIPT steps
|
||||||
const isJSScript =
|
const isJSScript =
|
||||||
|
@ -863,14 +885,14 @@ const automationActions = (store: AutomationStore) => ({
|
||||||
const stepId = pathSteps[idx].id
|
const stepId = pathSteps[idx].id
|
||||||
if (!stepId) {
|
if (!stepId) {
|
||||||
notifications.error("Error generating binding: Step ID not found.")
|
notifications.error("Error generating binding: Step ID not found.")
|
||||||
return null
|
return
|
||||||
}
|
}
|
||||||
runtimeName = `steps["${stepId}"].${name}`
|
runtimeName = `steps["${stepId}"].${name}`
|
||||||
} else {
|
} else {
|
||||||
const stepId = pathSteps[idx].id
|
const stepId = pathSteps[idx].id
|
||||||
if (!stepId) {
|
if (!stepId) {
|
||||||
notifications.error("Error generating binding: Step ID not found.")
|
notifications.error("Error generating binding: Step ID not found.")
|
||||||
return null
|
return
|
||||||
}
|
}
|
||||||
runtimeName = `steps.${stepId}.${name}`
|
runtimeName = `steps.${stepId}.${name}`
|
||||||
}
|
}
|
||||||
|
@ -891,44 +913,6 @@ const automationActions = (store: AutomationStore) => ({
|
||||||
: `Step ${idx - loopBlockCount} outputs`
|
: `Step ${idx - loopBlockCount} outputs`
|
||||||
},
|
},
|
||||||
|
|
||||||
createBindingObject: (
|
|
||||||
name: string,
|
|
||||||
value: any,
|
|
||||||
icon: string,
|
|
||||||
idx: number,
|
|
||||||
loopBlockCount: number,
|
|
||||||
isLoopBlock: boolean,
|
|
||||||
runtimeBinding: string | null,
|
|
||||||
categoryName: string,
|
|
||||||
bindingName?: string,
|
|
||||||
readableBinding?: string
|
|
||||||
) => {
|
|
||||||
const field = Object.values(FIELDS).find(
|
|
||||||
field =>
|
|
||||||
field.type === value.type &&
|
|
||||||
("subtype" in field ? field.subtype === value.subtype : true)
|
|
||||||
)
|
|
||||||
|
|
||||||
const readableBindingDefault =
|
|
||||||
bindingName && !isLoopBlock && idx !== 0
|
|
||||||
? `steps.${bindingName}.${name}`
|
|
||||||
: runtimeBinding
|
|
||||||
|
|
||||||
return {
|
|
||||||
readableBinding: readableBinding || readableBindingDefault,
|
|
||||||
runtimeBinding,
|
|
||||||
type: value.type,
|
|
||||||
description: value.description,
|
|
||||||
icon,
|
|
||||||
category: categoryName,
|
|
||||||
display: {
|
|
||||||
type: field?.name || value.type,
|
|
||||||
name,
|
|
||||||
rank: isLoopBlock ? idx + 1 : idx - loopBlockCount,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
processBlockInputs: async (
|
processBlockInputs: async (
|
||||||
block: AutomationStep,
|
block: AutomationStep,
|
||||||
data: Record<string, any>
|
data: Record<string, any>
|
||||||
|
@ -1706,4 +1690,20 @@ export const automationStore = new AutomationStore()
|
||||||
|
|
||||||
export const automationHistoryStore = automationStore.history
|
export const automationHistoryStore = automationStore.history
|
||||||
export const selectedAutomation = automationStore.selected
|
export const selectedAutomation = automationStore.selected
|
||||||
export const evaluationContext = automationStore.context
|
|
||||||
|
// Define an empty evaluate context at the start
|
||||||
|
const emptyContext: AutomationContext = {
|
||||||
|
user: {},
|
||||||
|
steps: {},
|
||||||
|
env: {},
|
||||||
|
settings: {},
|
||||||
|
}
|
||||||
|
|
||||||
|
// Page layout kicks off initialisation, subscription happens within the page
|
||||||
|
export const evaluationContext: Readable<AutomationContext> = readable(
|
||||||
|
emptyContext,
|
||||||
|
set => {
|
||||||
|
const unsubscribe = automationStore.context?.subscribe(set) ?? (() => {})
|
||||||
|
return () => unsubscribe()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
Loading…
Reference in New Issue