(buttons) Allow dynamic buttons from variable

Closes #237
This commit is contained in:
Baptiste Arnaud
2023-02-23 14:44:37 +01:00
parent 84628109d0
commit 2ff6991ca7
28 changed files with 290 additions and 116 deletions

View File

@@ -0,0 +1,31 @@
import { deepParseVariable } from '@/features/variables/utils'
import {
SessionState,
VariableWithValue,
ChoiceInputBlock,
ItemType,
} from 'models'
import { isDefined } from 'utils'
export const injectVariableValuesInButtonsInputBlock =
(variables: SessionState['typebot']['variables']) =>
(block: ChoiceInputBlock): ChoiceInputBlock => {
if (block.options.dynamicVariableId) {
const variable = variables.find(
(variable) =>
variable.id === block.options.dynamicVariableId &&
isDefined(variable.value)
) as VariableWithValue | undefined
if (!variable || typeof variable.value === 'string') return block
return {
...block,
items: variable.value.map((item, idx) => ({
id: idx.toString(),
type: ItemType.BUTTON,
blockId: block.id,
content: item,
})),
}
}
return deepParseVariable(variables)(block)
}

View File

@@ -11,11 +11,12 @@ import Stripe from 'stripe'
import { decrypt } from 'utils/api/encryption'
export const computePaymentInputRuntimeOptions =
(state: SessionState) => (options: PaymentInputOptions) =>
(state: Pick<SessionState, 'isPreview' | 'typebot'>) =>
(options: PaymentInputOptions) =>
createStripePaymentIntent(state)(options)
const createStripePaymentIntent =
(state: SessionState) =>
(state: Pick<SessionState, 'isPreview' | 'typebot'>) =>
async (options: PaymentInputOptions): Promise<PaymentInputRuntimeOptions> => {
const {
isPreview,

View File

@@ -53,24 +53,21 @@ export const getRow = async (
})
return { outgoingEdgeId, logs: log ? [log] : undefined }
}
const randomIndex = Math.floor(Math.random() * filteredRows.length)
const extractingColumns = cellsToExtract
.map((cell) => cell.column)
.filter(isNotEmpty)
const selectedRow = filteredRows
.map((row) =>
extractingColumns.reduce<{ [key: string]: string }>(
(obj, column) => ({ ...obj, [column]: row[column] }),
{}
)
const selectedRows = filteredRows.map((row) =>
extractingColumns.reduce<{ [key: string]: string }>(
(obj, column) => ({ ...obj, [column]: row[column] }),
{}
)
.at(randomIndex)
if (!selectedRow) return { outgoingEdgeId }
)
if (!selectedRows) return { outgoingEdgeId }
const newVariables = options.cellsToExtract.reduce<VariableWithValue[]>(
(newVariables, cell) => {
const existingVariable = variables.find(byId(cell.variableId))
const value = selectedRow[cell.column ?? ''] ?? null
const value = selectedRows.map((row) => row[cell.column ?? ''])
if (!existingVariable) return newVariables
return [
...newVariables,

View File

@@ -71,7 +71,7 @@ const sendEmail = async ({
}: SendEmailOptions & {
typebotId: string
resultId?: string
fileUrls?: string
fileUrls?: string | string[]
}) => {
const { name: replyToName } = parseEmailRecipient(replyTo)
@@ -121,7 +121,11 @@ const sendEmail = async ({
to: recipients,
replyTo,
subject,
attachments: fileUrls?.split(', ').map((url) => ({ path: url })),
attachments: fileUrls
? (typeof fileUrls === 'string' ? fileUrls.split(', ') : fileUrls).map(
(url) => ({ path: url })
)
: undefined,
...emailBody,
}
try {

View File

@@ -50,8 +50,8 @@ export const executeWebhookBlock = async (
return { outgoingEdgeId: block.outgoingEdgeId, logs: [log] }
}
const preparedWebhook = prepareWebhookAttributes(webhook, block.options)
const resultValues = result && (await getResultValues(result.id))
if (!resultValues) return { outgoingEdgeId: block.outgoingEdgeId }
const resultValues =
(result && (await getResultValues(result.id))) ?? undefined
const webhookResponse = await executeWebhook({ typebot })(
preparedWebhook,
typebot.variables,
@@ -139,8 +139,8 @@ export const executeWebhook =
webhook: Webhook,
variables: Variable[],
groupId: string,
resultValues: ResultValues,
resultId: string
resultValues?: ResultValues,
resultId?: string
): Promise<WebhookResponse> => {
if (!webhook.url || !webhook.method)
return {

View File

@@ -83,7 +83,7 @@ const parseResultSample = (
headerCells: ResultHeaderCell[],
variables: Variable[]
) =>
headerCells.reduce<Record<string, string | boolean | undefined>>(
headerCells.reduce<Record<string, string | string[] | undefined>>(
(resultSample, cell) => {
const inputBlock = inputBlocks.find((inputBlock) =>
cell.blocks?.some((block) => block.id === inputBlock.id)

View File

@@ -34,7 +34,9 @@ const executeComparison =
if (!comparison?.variableId) return false
const inputValue = (
variables.find((v) => v.id === comparison.variableId)?.value ?? ''
).trim()
)
.toString()
.trim()
const value = parseVariables(variables)(comparison.value).trim()
if (isNotDefined(value)) return false
switch (comparison.comparisonOperator) {