Dynamically enrich button actions at runtime and provide additional ephemeral button action output context
This commit is contained in:
parent
6aaab83895
commit
d9f4c3a4b0
|
@ -27,7 +27,6 @@
|
||||||
actions,
|
actions,
|
||||||
selectedAction?.id
|
selectedAction?.id
|
||||||
)
|
)
|
||||||
$: console.log(buttonContextBindings)
|
|
||||||
$: allBindings = buttonContextBindings.concat(bindings)
|
$: allBindings = buttonContextBindings.concat(bindings)
|
||||||
|
|
||||||
// Assign a unique ID to each action
|
// Assign a unique ID to each action
|
||||||
|
|
|
@ -8,6 +8,7 @@ import {
|
||||||
} from "stores"
|
} from "stores"
|
||||||
import { saveRow, deleteRow, executeQuery, triggerAutomation } from "api"
|
import { saveRow, deleteRow, executeQuery, triggerAutomation } from "api"
|
||||||
import { ActionTypes } from "constants"
|
import { ActionTypes } from "constants"
|
||||||
|
import { enrichDataBindings } from "./enrichDataBinding"
|
||||||
|
|
||||||
const saveRowHandler = async (action, context) => {
|
const saveRowHandler = async (action, context) => {
|
||||||
const { fields, providerId, tableId } = action.parameters
|
const { fields, providerId, tableId } = action.parameters
|
||||||
|
@ -25,7 +26,10 @@ const saveRowHandler = async (action, context) => {
|
||||||
if (tableId) {
|
if (tableId) {
|
||||||
payload.tableId = tableId
|
payload.tableId = tableId
|
||||||
}
|
}
|
||||||
await saveRow(payload)
|
const row = await saveRow(payload)
|
||||||
|
return {
|
||||||
|
row,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const duplicateRowHandler = async (action, context) => {
|
const duplicateRowHandler = async (action, context) => {
|
||||||
|
@ -178,11 +182,26 @@ export const enrichButtonActions = (actions, context) => {
|
||||||
return actions
|
return actions
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Button context is built up as actions are executed.
|
||||||
|
// Inherit any previous button context which may have come from actions
|
||||||
|
// before a confirmable action since this breaks the chain.
|
||||||
|
let buttonContext = context.actions || []
|
||||||
|
|
||||||
const handlers = actions.map(def => handlerMap[def["##eventHandlerType"]])
|
const handlers = actions.map(def => handlerMap[def["##eventHandlerType"]])
|
||||||
return async () => {
|
return async () => {
|
||||||
for (let i = 0; i < handlers.length; i++) {
|
for (let i = 0; i < handlers.length; i++) {
|
||||||
try {
|
try {
|
||||||
const action = actions[i]
|
// Skip any non-existent action definitions
|
||||||
|
if (!handlers[i]) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Built total context for this action
|
||||||
|
const totalContext = { ...context, actions: buttonContext }
|
||||||
|
|
||||||
|
// Get and enrich this button action with the total context
|
||||||
|
let action = actions[i]
|
||||||
|
action = enrichDataBindings(action, totalContext)
|
||||||
const callback = async () => handlers[i](action, context)
|
const callback = async () => handlers[i](action, context)
|
||||||
|
|
||||||
// If this action is confirmable, show confirmation and await a
|
// If this action is confirmable, show confirmation and await a
|
||||||
|
@ -198,7 +217,15 @@ export const enrichButtonActions = (actions, context) => {
|
||||||
// then execute the rest of the actions in the chain
|
// then execute the rest of the actions in the chain
|
||||||
const result = await callback()
|
const result = await callback()
|
||||||
if (result !== false) {
|
if (result !== false) {
|
||||||
const next = enrichButtonActions(actions.slice(i + 1), context)
|
// Generate a new total context to pass into the next enrichment
|
||||||
|
buttonContext.push(result)
|
||||||
|
const newContext = { ...context, actions: buttonContext }
|
||||||
|
|
||||||
|
// Enrich and call the next button action
|
||||||
|
const next = enrichButtonActions(
|
||||||
|
actions.slice(i + 1),
|
||||||
|
newContext
|
||||||
|
)
|
||||||
await next()
|
await next()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -214,6 +241,8 @@ export const enrichButtonActions = (actions, context) => {
|
||||||
const result = await callback()
|
const result = await callback()
|
||||||
if (result === false) {
|
if (result === false) {
|
||||||
return
|
return
|
||||||
|
} else {
|
||||||
|
buttonContext.push(result)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|
|
@ -32,35 +32,56 @@ export const enrichProps = (props, context) => {
|
||||||
data: context[context.closestComponentId],
|
data: context[context.closestComponentId],
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enrich all data bindings in top level props
|
// We want to exclude any button actions from enrichment at this stage.
|
||||||
let enrichedProps = enrichDataBindings(props, totalContext)
|
// Extract top level button action settings.
|
||||||
|
let normalProps = { ...props }
|
||||||
// Enrich click actions if they exist
|
let actionProps = {}
|
||||||
Object.keys(enrichedProps).forEach(prop => {
|
Object.keys(normalProps).forEach(prop => {
|
||||||
if (prop?.toLowerCase().includes("onclick")) {
|
if (prop?.toLowerCase().includes("onclick")) {
|
||||||
enrichedProps[prop] = enrichButtonActions(
|
actionProps[prop] = normalProps[prop]
|
||||||
enrichedProps[prop],
|
delete normalProps[prop]
|
||||||
totalContext
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// Enrich any click actions in conditions
|
// Handle conditional UI separately after normal settings
|
||||||
if (enrichedProps._conditions) {
|
let conditions = normalProps._conditions
|
||||||
enrichedProps._conditions.forEach(condition => {
|
delete normalProps._conditions
|
||||||
if (condition.setting?.toLowerCase().includes("onclick")) {
|
|
||||||
condition.settingValue = enrichButtonActions(
|
|
||||||
condition.settingValue,
|
|
||||||
totalContext
|
|
||||||
)
|
|
||||||
|
|
||||||
// If there is an onclick function in here then it won't be serialised
|
// Enrich all props except button actions
|
||||||
// properly, and therefore will not be updated properly.
|
let enrichedProps = enrichDataBindings(normalProps, totalContext)
|
||||||
// The solution to this is add a rand which will ensure diffs happen
|
|
||||||
// every time.
|
// Enrich button actions.
|
||||||
condition.rand = Math.random()
|
// Actions are enriched into a function at this stage, but actual data
|
||||||
|
// binding enrichment is done dynamically at runtime.
|
||||||
|
Object.keys(actionProps).forEach(prop => {
|
||||||
|
enrichedProps[prop] = enrichButtonActions(actionProps[prop], totalContext)
|
||||||
|
})
|
||||||
|
|
||||||
|
// Conditions
|
||||||
|
if (conditions?.length) {
|
||||||
|
let enrichedConditions = []
|
||||||
|
conditions.forEach(condition => {
|
||||||
|
if (condition.setting?.toLowerCase().includes("onclick")) {
|
||||||
|
// Copy and remove the setting value from the condition as it needs
|
||||||
|
// enriched separately
|
||||||
|
let toEnrich = { ...condition }
|
||||||
|
delete toEnrich.settingValue
|
||||||
|
|
||||||
|
// Join the condition back together
|
||||||
|
enrichedConditions.push({
|
||||||
|
...enrichDataBindings(toEnrich, totalContext),
|
||||||
|
settingValue: enrichButtonActions(
|
||||||
|
condition.settingValue,
|
||||||
|
totalContext
|
||||||
|
),
|
||||||
|
rand: Math.random(),
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
// Normal condition
|
||||||
|
enrichedConditions.push(enrichDataBindings(condition, totalContext))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
enrichedProps._conditions = enrichedConditions
|
||||||
}
|
}
|
||||||
|
|
||||||
return enrichedProps
|
return enrichedProps
|
||||||
|
|
Loading…
Reference in New Issue