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(