2021-01-19 18:38:24 +01:00
|
|
|
import { get } from "svelte/store"
|
2022-03-07 13:06:11 +01:00
|
|
|
import download from "downloadjs"
|
2021-07-25 13:09:50 +02:00
|
|
|
import {
|
|
|
|
routeStore,
|
|
|
|
builderStore,
|
|
|
|
confirmationStore,
|
|
|
|
authStore,
|
2021-08-26 12:28:44 +02:00
|
|
|
stateStore,
|
2022-01-20 10:40:53 +01:00
|
|
|
notificationStore,
|
|
|
|
dataSourceStore,
|
2022-01-11 15:01:21 +01:00
|
|
|
uploadStore,
|
2022-03-07 13:06:11 +01:00
|
|
|
rowSelectionStore,
|
2022-11-14 16:02:57 +01:00
|
|
|
sidePanelStore,
|
2021-09-01 12:41:48 +02:00
|
|
|
} from "stores"
|
2022-01-20 10:40:53 +01:00
|
|
|
import { API } from "api"
|
2021-09-01 12:41:48 +02:00
|
|
|
import { ActionTypes } from "constants"
|
2021-12-09 12:25:32 +01:00
|
|
|
import { enrichDataBindings } from "./enrichDataBinding"
|
2022-01-20 11:16:13 +01:00
|
|
|
import { Helpers } from "@budibase/bbui"
|
2020-11-25 10:50:51 +01:00
|
|
|
|
|
|
|
const saveRowHandler = async (action, context) => {
|
2022-11-13 18:25:48 +01:00
|
|
|
const { fields, providerId, tableId, notificationOverride } =
|
|
|
|
action.parameters
|
2021-12-07 14:59:12 +01:00
|
|
|
let payload
|
|
|
|
if (providerId) {
|
2021-12-09 15:36:24 +01:00
|
|
|
payload = { ...context[providerId] }
|
2021-12-07 14:59:12 +01:00
|
|
|
} else {
|
|
|
|
payload = {}
|
|
|
|
}
|
|
|
|
if (fields) {
|
|
|
|
for (let [field, value] of Object.entries(fields)) {
|
2022-01-20 11:16:13 +01:00
|
|
|
Helpers.deepSet(payload, field, value)
|
2021-12-07 14:59:12 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if (tableId) {
|
|
|
|
payload.tableId = tableId
|
|
|
|
}
|
2022-01-20 10:40:53 +01:00
|
|
|
try {
|
|
|
|
const row = await API.saveRow(payload)
|
2022-11-13 18:25:48 +01:00
|
|
|
|
|
|
|
if (!notificationOverride) {
|
2022-11-13 18:08:23 +01:00
|
|
|
notificationStore.actions.success("Row saved")
|
|
|
|
}
|
2022-01-20 10:40:53 +01:00
|
|
|
|
|
|
|
// Refresh related datasources
|
2022-03-18 16:21:24 +01:00
|
|
|
await dataSourceStore.actions.invalidateDataSource(row.tableId, {
|
|
|
|
invalidateRelationships: true,
|
|
|
|
})
|
2022-01-20 10:40:53 +01:00
|
|
|
|
|
|
|
return { row }
|
|
|
|
} catch (error) {
|
|
|
|
// Abort next actions
|
|
|
|
return false
|
2021-12-09 12:25:32 +01:00
|
|
|
}
|
2021-12-07 14:59:12 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
const duplicateRowHandler = async (action, context) => {
|
2022-11-13 18:25:48 +01:00
|
|
|
const { fields, providerId, tableId, notificationOverride } =
|
|
|
|
action.parameters
|
2021-01-19 18:38:24 +01:00
|
|
|
if (providerId) {
|
2021-12-10 15:18:01 +01:00
|
|
|
let payload = { ...context[providerId] }
|
2021-01-19 18:38:24 +01:00
|
|
|
if (fields) {
|
2021-02-18 18:44:56 +01:00
|
|
|
for (let [field, value] of Object.entries(fields)) {
|
2022-01-20 11:16:13 +01:00
|
|
|
Helpers.deepSet(payload, field, value)
|
2021-01-21 12:31:45 +01:00
|
|
|
}
|
2021-01-19 18:38:24 +01:00
|
|
|
}
|
2021-07-22 17:50:35 +02:00
|
|
|
if (tableId) {
|
2021-12-10 15:18:01 +01:00
|
|
|
payload.tableId = tableId
|
2021-07-22 17:50:35 +02:00
|
|
|
}
|
2021-12-10 15:18:01 +01:00
|
|
|
delete payload._id
|
|
|
|
delete payload._rev
|
2022-01-20 10:40:53 +01:00
|
|
|
try {
|
|
|
|
const row = await API.saveRow(payload)
|
2022-11-13 18:25:48 +01:00
|
|
|
if (!notificationOverride) {
|
2022-11-13 18:08:23 +01:00
|
|
|
notificationStore.actions.success("Row saved")
|
|
|
|
}
|
2022-01-20 10:40:53 +01:00
|
|
|
|
|
|
|
// Refresh related datasources
|
2022-03-18 16:21:24 +01:00
|
|
|
await dataSourceStore.actions.invalidateDataSource(row.tableId, {
|
|
|
|
invalidateRelationships: true,
|
|
|
|
})
|
2022-01-20 10:40:53 +01:00
|
|
|
|
|
|
|
return { row }
|
|
|
|
} catch (error) {
|
|
|
|
// Abort next actions
|
|
|
|
return false
|
2021-12-09 17:29:22 +01:00
|
|
|
}
|
2020-11-25 10:50:51 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-02-17 15:49:35 +01:00
|
|
|
const fetchRowHandler = async action => {
|
|
|
|
const { tableId, rowId } = action.parameters
|
|
|
|
|
|
|
|
if (tableId && rowId) {
|
|
|
|
try {
|
|
|
|
const row = await API.fetchRow({ tableId, rowId })
|
|
|
|
|
|
|
|
return { row }
|
|
|
|
} catch (error) {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-07-14 10:11:34 +02:00
|
|
|
const deleteRowHandler = async (action, context) => {
|
|
|
|
const { tableId, rowId: rowConfig, notificationOverride } = action.parameters
|
|
|
|
|
|
|
|
if (tableId && rowConfig) {
|
2022-01-20 10:40:53 +01:00
|
|
|
try {
|
2023-07-14 10:11:34 +02:00
|
|
|
let requestConfig
|
|
|
|
|
|
|
|
let parsedRowConfig = []
|
|
|
|
if (typeof rowConfig === "string") {
|
|
|
|
try {
|
|
|
|
parsedRowConfig = JSON.parse(rowConfig)
|
|
|
|
} catch (e) {
|
|
|
|
parsedRowConfig = rowConfig
|
|
|
|
.split(",")
|
|
|
|
.map(id => id.trim())
|
|
|
|
.filter(id => id)
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
parsedRowConfig = rowConfig
|
|
|
|
}
|
|
|
|
|
|
|
|
if (
|
|
|
|
typeof parsedRowConfig === "object" &&
|
|
|
|
parsedRowConfig.constructor === Object
|
|
|
|
) {
|
|
|
|
requestConfig = [parsedRowConfig]
|
|
|
|
} else if (Array.isArray(parsedRowConfig)) {
|
|
|
|
requestConfig = parsedRowConfig
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!requestConfig.length) {
|
|
|
|
notificationStore.actions.warning("No valid rows were supplied")
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
const resp = await API.deleteRows({ tableId, rows: requestConfig })
|
|
|
|
|
2022-11-13 18:25:48 +01:00
|
|
|
if (!notificationOverride) {
|
2023-07-14 10:11:34 +02:00
|
|
|
notificationStore.actions.success(
|
|
|
|
resp?.length == 1 ? "Row deleted" : `${resp.length} Rows deleted`
|
|
|
|
)
|
2022-11-13 18:08:23 +01:00
|
|
|
}
|
2022-01-20 10:40:53 +01:00
|
|
|
|
|
|
|
// Refresh related datasources
|
2022-03-18 16:21:24 +01:00
|
|
|
await dataSourceStore.actions.invalidateDataSource(tableId, {
|
|
|
|
invalidateRelationships: true,
|
|
|
|
})
|
2022-01-20 10:40:53 +01:00
|
|
|
} catch (error) {
|
2023-07-14 10:11:34 +02:00
|
|
|
console.error(error)
|
|
|
|
notificationStore.actions.error(
|
|
|
|
"An error occurred while executing the query"
|
|
|
|
)
|
2022-01-20 10:40:53 +01:00
|
|
|
}
|
2021-01-19 18:38:24 +01:00
|
|
|
}
|
2020-11-25 10:50:51 +01:00
|
|
|
}
|
|
|
|
|
2021-05-04 12:32:22 +02:00
|
|
|
const triggerAutomationHandler = async action => {
|
2023-05-12 16:56:24 +02:00
|
|
|
const { fields, notificationOverride, timeout } = action.parameters
|
2021-01-21 12:31:45 +01:00
|
|
|
if (fields) {
|
2022-01-20 10:40:53 +01:00
|
|
|
try {
|
2023-05-12 16:56:24 +02:00
|
|
|
const result = await API.triggerAutomation({
|
|
|
|
automationId: action.parameters.automationId,
|
|
|
|
fields,
|
|
|
|
timeout,
|
|
|
|
})
|
|
|
|
|
|
|
|
// Value will exist if automation is synchronous, so return it.
|
|
|
|
if (result.value) {
|
2023-05-16 10:59:37 +02:00
|
|
|
if (!notificationOverride) {
|
|
|
|
notificationStore.actions.success("Automation ran successfully")
|
|
|
|
}
|
2023-05-09 13:10:20 +02:00
|
|
|
return { result }
|
2022-11-13 18:08:23 +01:00
|
|
|
}
|
2023-05-16 10:59:37 +02:00
|
|
|
|
|
|
|
if (!notificationOverride) {
|
|
|
|
notificationStore.actions.success("Automation triggered")
|
|
|
|
}
|
2022-01-20 10:40:53 +01:00
|
|
|
} catch (error) {
|
|
|
|
// Abort next actions
|
|
|
|
return false
|
|
|
|
}
|
2021-01-08 18:25:06 +01:00
|
|
|
}
|
|
|
|
}
|
2021-05-04 12:32:22 +02:00
|
|
|
const navigationHandler = action => {
|
2023-03-01 18:41:50 +01:00
|
|
|
const { url, peek, externalNewTab } = action.parameters
|
|
|
|
routeStore.actions.navigate(url, peek, externalNewTab)
|
2020-11-25 10:50:51 +01:00
|
|
|
}
|
|
|
|
|
2023-06-23 12:51:49 +02:00
|
|
|
const scrollHandler = async (action, context) => {
|
|
|
|
return await executeActionHandler(
|
|
|
|
context,
|
|
|
|
action.parameters.componentId,
|
|
|
|
ActionTypes.ScrollTo,
|
|
|
|
{
|
|
|
|
field: action.parameters.field,
|
|
|
|
}
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2021-05-04 12:32:22 +02:00
|
|
|
const queryExecutionHandler = async action => {
|
2022-11-13 18:25:48 +01:00
|
|
|
const { datasourceId, queryId, queryParams, notificationOverride } =
|
|
|
|
action.parameters
|
2022-01-20 10:40:53 +01:00
|
|
|
try {
|
|
|
|
const query = await API.fetchQueryDefinition(queryId)
|
|
|
|
if (query?.datasourceId == null) {
|
|
|
|
notificationStore.actions.error("That query couldn't be found")
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
const result = await API.executeQuery({
|
|
|
|
datasourceId,
|
|
|
|
queryId,
|
|
|
|
parameters: queryParams,
|
|
|
|
})
|
|
|
|
|
|
|
|
// Trigger a notification and invalidate the datasource as long as this
|
|
|
|
// was not a readable query
|
|
|
|
if (!query.readable) {
|
2022-11-13 18:25:48 +01:00
|
|
|
if (!notificationOverride) {
|
2022-11-13 18:08:23 +01:00
|
|
|
notificationStore.actions.success("Query executed successfully")
|
|
|
|
}
|
2022-01-20 10:40:53 +01:00
|
|
|
await dataSourceStore.actions.invalidateDataSource(query.datasourceId)
|
|
|
|
}
|
|
|
|
|
|
|
|
return { result }
|
|
|
|
} catch (error) {
|
2022-02-25 22:29:02 +01:00
|
|
|
notificationStore.actions.error(
|
|
|
|
"An error occurred while executing the query"
|
|
|
|
)
|
|
|
|
|
2022-01-20 10:40:53 +01:00
|
|
|
// Abort next actions
|
|
|
|
return false
|
|
|
|
}
|
2021-01-04 19:57:16 +01:00
|
|
|
}
|
|
|
|
|
2021-08-19 13:52:50 +02:00
|
|
|
const executeActionHandler = async (
|
|
|
|
context,
|
|
|
|
componentId,
|
|
|
|
actionType,
|
|
|
|
params
|
|
|
|
) => {
|
2021-02-05 13:54:36 +01:00
|
|
|
const fn = context[`${componentId}_${actionType}`]
|
2021-02-01 19:51:22 +01:00
|
|
|
if (fn) {
|
2021-08-19 13:52:50 +02:00
|
|
|
return await fn(params)
|
2021-02-01 19:51:22 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-14 10:46:07 +02:00
|
|
|
const updateFieldValueHandler = async (action, context) => {
|
|
|
|
return await executeActionHandler(
|
|
|
|
context,
|
|
|
|
action.parameters.componentId,
|
|
|
|
ActionTypes.UpdateFieldValue,
|
|
|
|
{
|
|
|
|
type: action.parameters.type,
|
|
|
|
field: action.parameters.field,
|
|
|
|
value: action.parameters.value,
|
|
|
|
}
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2021-02-05 13:54:36 +01:00
|
|
|
const validateFormHandler = async (action, context) => {
|
|
|
|
return await executeActionHandler(
|
|
|
|
context,
|
|
|
|
action.parameters.componentId,
|
2022-07-20 15:16:08 +02:00
|
|
|
ActionTypes.ValidateForm
|
2021-02-05 13:54:36 +01:00
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2021-09-23 20:34:01 +02:00
|
|
|
const refreshDataProviderHandler = async (action, context) => {
|
2021-02-05 13:54:36 +01:00
|
|
|
return await executeActionHandler(
|
|
|
|
context,
|
|
|
|
action.parameters.componentId,
|
|
|
|
ActionTypes.RefreshDatasource
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2022-01-19 12:22:27 +01:00
|
|
|
const logoutHandler = async action => {
|
2021-07-25 13:07:25 +02:00
|
|
|
await authStore.actions.logOut()
|
2022-01-19 13:50:07 +01:00
|
|
|
let redirectUrl = "/builder/auth/login"
|
2022-01-19 12:22:27 +01:00
|
|
|
let internal = false
|
2022-01-19 13:50:07 +01:00
|
|
|
if (action.parameters.redirectUrl) {
|
|
|
|
internal = action.parameters.redirectUrl?.startsWith("/")
|
|
|
|
redirectUrl = routeStore.actions.createFullURL(
|
|
|
|
action.parameters.redirectUrl
|
|
|
|
)
|
2022-01-19 12:22:27 +01:00
|
|
|
}
|
2022-01-19 13:50:07 +01:00
|
|
|
window.location.href = redirectUrl
|
2022-01-19 12:22:27 +01:00
|
|
|
if (internal) {
|
|
|
|
window.location.reload()
|
|
|
|
}
|
2021-07-25 13:07:25 +02:00
|
|
|
}
|
|
|
|
|
2021-07-26 13:58:18 +02:00
|
|
|
const clearFormHandler = async (action, context) => {
|
|
|
|
return await executeActionHandler(
|
|
|
|
context,
|
|
|
|
action.parameters.componentId,
|
|
|
|
ActionTypes.ClearForm
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2021-08-20 10:54:54 +02:00
|
|
|
const changeFormStepHandler = async (action, context) => {
|
2021-08-18 16:21:18 +02:00
|
|
|
return await executeActionHandler(
|
|
|
|
context,
|
|
|
|
action.parameters.componentId,
|
2021-08-20 10:54:54 +02:00
|
|
|
ActionTypes.ChangeFormStep,
|
|
|
|
action.parameters
|
2021-08-18 16:21:18 +02:00
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2022-09-28 14:50:23 +02:00
|
|
|
const closeScreenModalHandler = action => {
|
2022-11-03 14:23:29 +01:00
|
|
|
let url
|
|
|
|
if (action?.parameters) {
|
|
|
|
url = action.parameters.url
|
|
|
|
}
|
2021-08-02 16:12:38 +02:00
|
|
|
// Emit this as a window event, so parent screens which are iframing us in
|
|
|
|
// can close the modal
|
2022-09-29 15:10:34 +02:00
|
|
|
window.parent.postMessage({ type: "close-screen-modal", url })
|
2021-08-02 16:12:38 +02:00
|
|
|
}
|
|
|
|
|
2021-08-26 12:28:44 +02:00
|
|
|
const updateStateHandler = action => {
|
2021-08-26 18:52:04 +02:00
|
|
|
const { type, key, value, persist } = action.parameters
|
2021-08-26 12:28:44 +02:00
|
|
|
if (type === "set") {
|
2021-08-26 18:52:04 +02:00
|
|
|
stateStore.actions.setValue(key, value, persist)
|
2021-08-26 12:28:44 +02:00
|
|
|
} else if (type === "delete") {
|
|
|
|
stateStore.actions.deleteValue(key)
|
|
|
|
}
|
2021-12-14 15:04:10 +01:00
|
|
|
|
|
|
|
// Emit this as an event so that parent windows which are iframing us in
|
|
|
|
// can also update their state
|
|
|
|
if (get(routeStore).queryParams?.peek) {
|
|
|
|
window.parent.postMessage({
|
|
|
|
type: "update-state",
|
|
|
|
detail: { type, key, value, persist },
|
|
|
|
})
|
|
|
|
}
|
2021-08-26 12:28:44 +02:00
|
|
|
}
|
|
|
|
|
2022-01-11 15:01:21 +01:00
|
|
|
const s3UploadHandler = async action => {
|
|
|
|
const { componentId } = action.parameters
|
|
|
|
if (!componentId) {
|
|
|
|
return
|
|
|
|
}
|
2022-01-14 11:40:38 +01:00
|
|
|
const res = await uploadStore.actions.processFileUpload(componentId)
|
|
|
|
return {
|
|
|
|
publicUrl: res?.publicUrl,
|
|
|
|
}
|
2022-01-11 15:01:21 +01:00
|
|
|
}
|
|
|
|
|
2022-03-07 13:06:11 +01:00
|
|
|
const exportDataHandler = async action => {
|
|
|
|
let selection = rowSelectionStore.actions.getSelection(
|
2022-03-08 13:58:05 +01:00
|
|
|
action.parameters.tableComponentId
|
2022-03-07 13:06:11 +01:00
|
|
|
)
|
|
|
|
if (selection.selectedRows && selection.selectedRows.length > 0) {
|
|
|
|
try {
|
|
|
|
const data = await API.exportRows({
|
|
|
|
tableId: selection.tableId,
|
|
|
|
rows: selection.selectedRows,
|
2022-03-16 11:22:06 +01:00
|
|
|
format: action.parameters.type,
|
2022-06-20 13:32:13 +02:00
|
|
|
columns: action.parameters.columns,
|
2022-03-07 13:06:11 +01:00
|
|
|
})
|
2022-03-16 11:22:06 +01:00
|
|
|
download(data, `${selection.tableId}.${action.parameters.type}`)
|
2022-03-07 13:06:11 +01:00
|
|
|
} catch (error) {
|
|
|
|
notificationStore.actions.error("There was an error exporting the data")
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
notificationStore.actions.error("Please select at least one row")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-03-25 10:26:15 +01:00
|
|
|
const continueIfHandler = action => {
|
|
|
|
const { type, value, operator, referenceValue } = action.parameters
|
|
|
|
if (!type || !operator) {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
let match = false
|
|
|
|
if (value == null && referenceValue == null) {
|
|
|
|
match = true
|
|
|
|
} else if (value === referenceValue) {
|
|
|
|
match = true
|
|
|
|
} else {
|
|
|
|
match = JSON.stringify(value) === JSON.stringify(referenceValue)
|
|
|
|
}
|
|
|
|
if (type === "continue") {
|
|
|
|
return operator === "equal" ? match : !match
|
|
|
|
} else {
|
|
|
|
return operator === "equal" ? !match : match
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-08-22 12:00:51 +02:00
|
|
|
const showNotificationHandler = action => {
|
2022-08-22 12:08:52 +02:00
|
|
|
const { message, type, autoDismiss } = action.parameters
|
2022-08-22 12:00:51 +02:00
|
|
|
if (!message || !type) {
|
|
|
|
return
|
|
|
|
}
|
2022-08-22 12:08:52 +02:00
|
|
|
notificationStore.actions[type]?.(message, autoDismiss)
|
2022-08-22 12:00:51 +02:00
|
|
|
}
|
|
|
|
|
2022-12-15 17:21:24 +01:00
|
|
|
const promptUserHandler = () => {}
|
|
|
|
|
2022-11-15 12:54:20 +01:00
|
|
|
const OpenSidePanelHandler = action => {
|
|
|
|
const { id } = action.parameters
|
|
|
|
if (id) {
|
2022-11-14 16:02:57 +01:00
|
|
|
sidePanelStore.actions.open(id)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-11-15 12:54:20 +01:00
|
|
|
const CloseSidePanelHandler = () => {
|
|
|
|
sidePanelStore.actions.close()
|
|
|
|
}
|
|
|
|
|
2020-11-25 10:50:51 +01:00
|
|
|
const handlerMap = {
|
2023-02-17 15:49:35 +01:00
|
|
|
["Fetch Row"]: fetchRowHandler,
|
2020-11-25 10:50:51 +01:00
|
|
|
["Save Row"]: saveRowHandler,
|
2021-12-07 14:59:12 +01:00
|
|
|
["Duplicate Row"]: duplicateRowHandler,
|
2020-11-25 10:50:51 +01:00
|
|
|
["Delete Row"]: deleteRowHandler,
|
|
|
|
["Navigate To"]: navigationHandler,
|
2023-06-23 12:51:49 +02:00
|
|
|
["Scroll To Field"]: scrollHandler,
|
2021-01-04 19:57:16 +01:00
|
|
|
["Execute Query"]: queryExecutionHandler,
|
2021-01-08 18:25:06 +01:00
|
|
|
["Trigger Automation"]: triggerAutomationHandler,
|
2021-02-01 19:51:22 +01:00
|
|
|
["Validate Form"]: validateFormHandler,
|
2022-04-14 10:46:07 +02:00
|
|
|
["Update Field Value"]: updateFieldValueHandler,
|
2021-09-23 20:34:01 +02:00
|
|
|
["Refresh Data Provider"]: refreshDataProviderHandler,
|
2021-07-25 13:07:25 +02:00
|
|
|
["Log Out"]: logoutHandler,
|
2021-07-26 15:22:14 +02:00
|
|
|
["Clear Form"]: clearFormHandler,
|
2021-08-02 16:50:59 +02:00
|
|
|
["Close Screen Modal"]: closeScreenModalHandler,
|
2021-08-20 10:54:54 +02:00
|
|
|
["Change Form Step"]: changeFormStepHandler,
|
2021-08-26 12:28:44 +02:00
|
|
|
["Update State"]: updateStateHandler,
|
2022-01-11 15:01:21 +01:00
|
|
|
["Upload File to S3"]: s3UploadHandler,
|
2022-03-07 13:06:11 +01:00
|
|
|
["Export Data"]: exportDataHandler,
|
2022-03-25 10:26:15 +01:00
|
|
|
["Continue if / Stop if"]: continueIfHandler,
|
2022-08-22 12:00:51 +02:00
|
|
|
["Show Notification"]: showNotificationHandler,
|
2022-12-15 17:21:24 +01:00
|
|
|
["Prompt User"]: promptUserHandler,
|
2022-11-15 12:54:20 +01:00
|
|
|
["Open Side Panel"]: OpenSidePanelHandler,
|
|
|
|
["Close Side Panel"]: CloseSidePanelHandler,
|
2021-06-21 10:56:46 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
const confirmTextMap = {
|
|
|
|
["Delete Row"]: "Are you sure you want to delete this row?",
|
|
|
|
["Save Row"]: "Are you sure you want to save this row?",
|
|
|
|
["Execute Query"]: "Are you sure you want to execute this query?",
|
|
|
|
["Trigger Automation"]: "Are you sure you want to trigger this automation?",
|
2023-04-27 17:06:57 +02:00
|
|
|
["Prompt User"]: "Are you sure you want to continue?",
|
2020-11-25 10:50:51 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Parses an array of actions and returns a function which will execute the
|
|
|
|
* actions in the current context.
|
2021-06-21 10:56:46 +02:00
|
|
|
* A handler returning `false` is a flag to stop execution of handlers
|
2020-11-25 10:50:51 +01:00
|
|
|
*/
|
|
|
|
export const enrichButtonActions = (actions, context) => {
|
2021-01-19 18:38:24 +01:00
|
|
|
// Prevent button actions in the builder preview
|
2022-08-17 16:43:25 +02:00
|
|
|
if (!actions?.length || get(builderStore).inBuilder) {
|
|
|
|
return null
|
2021-01-19 18:38:24 +01:00
|
|
|
}
|
2021-11-04 12:30:43 +01:00
|
|
|
|
|
|
|
// If this is a function then it has already been enriched
|
|
|
|
if (typeof actions === "function") {
|
|
|
|
return actions
|
|
|
|
}
|
|
|
|
|
2021-05-04 12:32:22 +02:00
|
|
|
const handlers = actions.map(def => handlerMap[def["##eventHandlerType"]])
|
2022-03-15 12:16:51 +01:00
|
|
|
return async eventContext => {
|
2022-04-05 15:00:44 +02:00
|
|
|
// 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 || []
|
|
|
|
|
2020-11-25 10:50:51 +01:00
|
|
|
for (let i = 0; i < handlers.length; i++) {
|
2021-02-01 19:51:22 +01:00
|
|
|
try {
|
2021-12-09 12:25:32 +01:00
|
|
|
// Skip any non-existent action definitions
|
|
|
|
if (!handlers[i]) {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
// Built total context for this action
|
2022-03-15 12:16:51 +01:00
|
|
|
const totalContext = {
|
|
|
|
...context,
|
2022-04-01 19:36:41 +02:00
|
|
|
state: get(stateStore),
|
2022-03-15 12:16:51 +01:00
|
|
|
actions: buttonContext,
|
|
|
|
eventContext,
|
|
|
|
}
|
2021-12-09 12:25:32 +01:00
|
|
|
|
|
|
|
// Get and enrich this button action with the total context
|
|
|
|
let action = actions[i]
|
|
|
|
action = enrichDataBindings(action, totalContext)
|
2021-12-09 15:36:24 +01:00
|
|
|
const callback = async () => handlers[i](action, totalContext)
|
2021-06-21 10:56:46 +02:00
|
|
|
|
|
|
|
// If this action is confirmable, show confirmation and await a
|
|
|
|
// callback to execute further actions
|
|
|
|
if (action.parameters?.confirm) {
|
2022-03-16 15:53:12 +01:00
|
|
|
return new Promise(resolve => {
|
|
|
|
const defaultText = confirmTextMap[action["##eventHandlerType"]]
|
|
|
|
const confirmText = action.parameters?.confirmText || defaultText
|
2022-12-15 17:21:24 +01:00
|
|
|
|
|
|
|
const defaultTitleText = action["##eventHandlerType"]
|
|
|
|
const customTitleText =
|
|
|
|
action.parameters?.customTitleText || defaultTitleText
|
2022-03-16 15:53:12 +01:00
|
|
|
confirmationStore.actions.showConfirmation(
|
2022-12-15 17:21:24 +01:00
|
|
|
customTitleText,
|
2022-03-16 15:53:12 +01:00
|
|
|
confirmText,
|
|
|
|
async () => {
|
|
|
|
// When confirmed, execute this action immediately,
|
|
|
|
// then execute the rest of the actions in the chain
|
|
|
|
const result = await callback()
|
|
|
|
if (result !== false) {
|
|
|
|
// Generate a new total context to pass into the next enrichment
|
|
|
|
buttonContext.push(result)
|
|
|
|
const newContext = { ...context, actions: buttonContext }
|
|
|
|
|
2022-12-15 17:21:24 +01:00
|
|
|
// Enrich and call the next button action if there is more than one action remaining
|
2022-03-16 15:53:12 +01:00
|
|
|
const next = enrichButtonActions(
|
|
|
|
actions.slice(i + 1),
|
|
|
|
newContext
|
|
|
|
)
|
|
|
|
resolve(await next())
|
|
|
|
} else {
|
|
|
|
resolve(false)
|
|
|
|
}
|
|
|
|
},
|
|
|
|
() => {
|
|
|
|
resolve(false)
|
2021-06-21 11:46:55 +02:00
|
|
|
}
|
2022-03-16 15:53:12 +01:00
|
|
|
)
|
|
|
|
})
|
2021-02-01 19:51:22 +01:00
|
|
|
}
|
2021-06-21 10:56:46 +02:00
|
|
|
|
2021-06-21 11:11:18 +02:00
|
|
|
// For non-confirmable actions, execute the handler immediately
|
2021-06-21 10:56:46 +02:00
|
|
|
else {
|
|
|
|
const result = await callback()
|
|
|
|
if (result === false) {
|
|
|
|
return
|
2021-12-09 12:25:32 +01:00
|
|
|
} else {
|
|
|
|
buttonContext.push(result)
|
2021-06-21 10:56:46 +02:00
|
|
|
}
|
|
|
|
}
|
2021-02-01 19:51:22 +01:00
|
|
|
} catch (error) {
|
|
|
|
console.error("Error while executing button handler")
|
|
|
|
console.error(error)
|
2021-06-21 10:56:46 +02:00
|
|
|
// Stop executing further actions on error
|
2021-02-01 19:51:22 +01:00
|
|
|
return
|
|
|
|
}
|
2020-11-25 10:50:51 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|