diff --git a/apps/builder/src/features/blocks/logic/setVariable/components/SetVariableContent.tsx b/apps/builder/src/features/blocks/logic/setVariable/components/SetVariableContent.tsx index 6f1e126b7..01df5bb9c 100644 --- a/apps/builder/src/features/blocks/logic/setVariable/components/SetVariableContent.tsx +++ b/apps/builder/src/features/blocks/logic/setVariable/components/SetVariableContent.tsx @@ -62,7 +62,19 @@ const Expression = ({ ) } case 'Empty': - return Reset {variableName} + return Reset {variableName} + case 'Shift': + case 'Pop': { + const itemVariableName = variables.find( + byId(options.saveItemInVariableId) + )?.name + return ( + + {options.type} {variableName} + {itemVariableName ? ` into ${itemVariableName}` : ''} + + ) + } case 'Random ID': case 'Today': case 'Now': diff --git a/apps/builder/src/features/blocks/logic/setVariable/components/SetVariableSettings.tsx b/apps/builder/src/features/blocks/logic/setVariable/components/SetVariableSettings.tsx index 70278aae8..07c019703 100644 --- a/apps/builder/src/features/blocks/logic/setVariable/components/SetVariableSettings.tsx +++ b/apps/builder/src/features/blocks/logic/setVariable/components/SetVariableSettings.tsx @@ -132,6 +132,14 @@ const SetVariableValue = ({ isExecutedOnClient, }) + const updateListVariableId = (variable?: Pick) => { + if (!options || (options.type !== 'Pop' && options.type !== 'Shift')) return + onOptionsChange({ + ...options, + saveItemInVariableId: variable?.id, + }) + } + const updateItemVariableId = (variable?: Pick) => { if (!options || options.type !== 'Map item with same index') return onOptionsChange({ @@ -222,6 +230,17 @@ const SetVariableValue = ({ ) + case 'Pop': + case 'Shift': + return ( + + ) case 'Map item with same index': { return ( diff --git a/packages/bot-engine/blocks/logic/setVariable/executeSetVariable.ts b/packages/bot-engine/blocks/logic/setVariable/executeSetVariable.ts index 23fb23454..2364e6671 100644 --- a/packages/bot-engine/blocks/logic/setVariable/executeSetVariable.ts +++ b/packages/bot-engine/blocks/logic/setVariable/executeSetVariable.ts @@ -4,6 +4,7 @@ import { SetVariableBlock, SetVariableHistoryItem, Variable, + VariableWithUnknowValue, } from '@typebot.io/schemas' import { byId, isEmpty } from '@typebot.io/lib' import { ExecuteLogicResponse } from '../../../types' @@ -80,6 +81,7 @@ export const executeSetVariable = async ( const { newSetVariableHistory, updatedState } = updateVariablesInSession({ state, newVariables: [ + ...parseColateralVariableChangeIfAny({ state, options: block.options }), { ...newVariable, isSessionVariable: sessionOnlySetVariableOptions.includes( @@ -183,6 +185,12 @@ const getExpressionToEvaluate = return `const itemIndex = ${options.mapListItemParams?.baseListVariableId}.indexOf(${options.mapListItemParams?.baseItemVariableId}) return ${options.mapListItemParams?.targetListVariableId}.at(itemIndex)` } + case 'Pop': { + return `${options.variableId} && Array.isArray(${options.variableId}) ? ${options.variableId}.slice(0, -1) : []` + } + case 'Shift': { + return `${options.variableId} && Array.isArray(${options.variableId}) ? ${options.variableId}.slice(1) : []` + } case 'Append value(s)': { const item = parseVariables(state.typebotsQueue[0].typebot.variables)( options.item @@ -329,3 +337,30 @@ const parseResultTranscriptProps = async ( .map((edge) => edge.edgeId), } } + +const parseColateralVariableChangeIfAny = ({ + state, + options, +}: { + state: SessionState + options: SetVariableBlock['options'] +}): VariableWithUnknowValue[] => { + if (!options || (options.type !== 'Pop' && options.type !== 'Shift')) + return [] + const listVariableValue = state.typebotsQueue[0].typebot.variables.find( + (v) => v.id === options.variableId + )?.value + const variable = state.typebotsQueue[0].typebot.variables.find( + (v) => v.id === options.saveItemInVariableId + ) + if (!variable || !listVariableValue) return [] + return [ + { + ...variable, + value: + options.type === 'Pop' + ? listVariableValue.at(-1) + : listVariableValue.at(0), + }, + ] +} diff --git a/packages/schemas/features/blocks/logic/setVariable/constants.ts b/packages/schemas/features/blocks/logic/setVariable/constants.ts index cbe608c9f..828f33882 100644 --- a/packages/schemas/features/blocks/logic/setVariable/constants.ts +++ b/packages/schemas/features/blocks/logic/setVariable/constants.ts @@ -15,6 +15,8 @@ export const valueTypes = [ 'Random ID', 'Moment of the day', 'Map item with same index', + 'Pop', + 'Shift', 'Phone number', 'Contact name', ] as const diff --git a/packages/schemas/features/blocks/logic/setVariable/schema.ts b/packages/schemas/features/blocks/logic/setVariable/schema.ts index 94dc36967..6e8a82bfb 100644 --- a/packages/schemas/features/blocks/logic/setVariable/schema.ts +++ b/packages/schemas/features/blocks/logic/setVariable/schema.ts @@ -25,6 +25,11 @@ const basicSetVariableOptionsSchema = baseOptions.extend({ ]), }) +const popOrShiftSetVariableOptionsSchema = baseOptions.extend({ + type: z.enum(['Pop', 'Shift']), + saveItemInVariableId: z.string().optional(), +}) + const dateSetVariableOptionsSchema = baseOptions.extend({ type: z.enum(['Now', 'Yesterday', 'Tomorrow']), timeZone: z.string().optional(), @@ -65,6 +70,7 @@ export const setVariableOptionsSchema = z.discriminatedUnion('type', [ customSetVariableOptionsSchema, mapListItemsOptionsSchema, appendItemToListOptionsSchema, + popOrShiftSetVariableOptionsSchema, ]) export const setVariableBlockSchema = blockBaseSchema.merge(