From 0c19ea20f8dec85fa6a7a7c5afd6b2dbfaafa7e2 Mon Sep 17 00:00:00 2001 From: Baptiste Arnaud Date: Tue, 7 Mar 2023 09:47:05 +0100 Subject: [PATCH] :children_crossing: (condition) Improve comparison with lists Closes #363 --- .../condition/api/utils/executeCondition.ts | 47 ++++++++++++++----- apps/viewer/src/features/variables/utils.ts | 11 +++++ 2 files changed, 45 insertions(+), 13 deletions(-) diff --git a/apps/viewer/src/features/blocks/logic/condition/api/utils/executeCondition.ts b/apps/viewer/src/features/blocks/logic/condition/api/utils/executeCondition.ts index 49a4b8e01..f79cadd83 100644 --- a/apps/viewer/src/features/blocks/logic/condition/api/utils/executeCondition.ts +++ b/apps/viewer/src/features/blocks/logic/condition/api/utils/executeCondition.ts @@ -1,5 +1,5 @@ import { ExecuteLogicResponse } from '@/features/chat' -import { parseVariables } from '@/features/variables' +import { findUniqueVariableValue, parseVariables } from '@/features/variables' import { Comparison, ComparisonOperators, @@ -34,32 +34,53 @@ const executeComparison = if (!comparison?.variableId) return false const inputValue = variables.find((v) => v.id === comparison.variableId)?.value ?? '' - const value = parseVariables(variables)(comparison.value) + const value = + findUniqueVariableValue(variables)(comparison.value) ?? + parseVariables(variables)(comparison.value) if (isNotDefined(value)) return false switch (comparison.comparisonOperator) { case ComparisonOperators.CONTAINS: { - const normalizeString = (value: string) => value.toLowerCase().trim() - const contains = (inputValue: string) => - normalizeString(inputValue).includes(normalizeString(value)) - if (typeof inputValue === 'string') return contains(inputValue) - return inputValue.some(contains) + const contains = (a: string, b: string) => { + if (b === '') return false + return a.toLowerCase().trim().includes(b.toLowerCase().trim()) + } + return compare(contains, inputValue, value) } case ComparisonOperators.EQUAL: { - return inputValue === value + return compare((a, b) => a === b, inputValue, value) } case ComparisonOperators.NOT_EQUAL: { - return inputValue !== value + return compare((a, b) => a !== b, inputValue, value) } case ComparisonOperators.GREATER: { - if (typeof inputValue !== 'string') return false - return parseFloat(inputValue) > parseFloat(value) + return compare( + (a, b) => parseFloat(a) > parseFloat(b), + inputValue, + value + ) } case ComparisonOperators.LESS: { - if (typeof inputValue !== 'string') return false - return parseFloat(inputValue) < parseFloat(value) + return compare( + (a, b) => parseFloat(a) < parseFloat(b), + inputValue, + value + ) } case ComparisonOperators.IS_SET: { return isDefined(inputValue) && inputValue.length > 0 } } } + +const compare = ( + func: (a: string, b: string) => boolean, + a: string | string[], + b: string | string[] +): boolean => { + if (typeof a === 'string') { + if (typeof b === 'string') return func(a, b) + return b.some((b) => func(a, b)) + } + if (typeof b === 'string') return a.some((a) => func(a, b)) + return a.some((a) => b.some((b) => func(a, b))) +} diff --git a/apps/viewer/src/features/variables/utils.ts b/apps/viewer/src/features/variables/utils.ts index 8363f066f..73d075182 100644 --- a/apps/viewer/src/features/variables/utils.ts +++ b/apps/viewer/src/features/variables/utils.ts @@ -218,3 +218,14 @@ const updateTypebotVariables = ...serializedNewVariables, ] } + +export const findUniqueVariableValue = + (variables: Variable[]) => + (value: string | undefined): string | string[] | null => { + if (!value || !value.startsWith('{{') || !value.endsWith('}}')) return null + const variableName = value.slice(2, -2) + const variable = variables.find( + (variable) => variable.name === variableName + ) + return variable?.value ?? null + }