2
0

🐛 (sheets) Fix empty and unique filter

This commit is contained in:
Baptiste Arnaud
2023-05-26 10:46:40 +02:00
parent 75f9da0a4f
commit 154271c7f2
4 changed files with 41 additions and 20 deletions

View File

@ -41,13 +41,14 @@ export const RowsFilterComparisonItem = ({
items={Object.values(ComparisonOperators)} items={Object.values(ComparisonOperators)}
placeholder="Select an operator" placeholder="Select an operator"
/> />
{item.comparisonOperator !== ComparisonOperators.IS_SET && ( {item.comparisonOperator !== ComparisonOperators.IS_SET &&
<TextInput item.comparisonOperator !== ComparisonOperators.IS_EMPTY && (
defaultValue={item.value ?? ''} <TextInput
onChange={handleChangeValue} defaultValue={item.value ?? ''}
placeholder="Type a value..." onChange={handleChangeValue}
/> placeholder="Type a value..."
)} />
)}
</Stack> </Stack>
) )
} }

View File

@ -6,20 +6,23 @@ import {
} from '@typebot.io/schemas' } from '@typebot.io/schemas'
import { isDefined } from '@typebot.io/lib' import { isDefined } from '@typebot.io/lib'
import { deepParseVariables } from '@/features/variables/deepParseVariable' import { deepParseVariables } from '@/features/variables/deepParseVariable'
import { transformStringVariablesToList } from '@/features/variables/transformVariablesToList'
import { updateVariables } from '@/features/variables/updateVariables'
export const injectVariableValuesInButtonsInputBlock = export const injectVariableValuesInButtonsInputBlock =
(variables: SessionState['typebot']['variables']) => (state: SessionState) =>
(block: ChoiceInputBlock): ChoiceInputBlock => { async (block: ChoiceInputBlock): Promise<ChoiceInputBlock> => {
if (block.options.dynamicVariableId) { if (block.options.dynamicVariableId) {
const variable = variables.find( const variable = state.typebot.variables.find(
(variable) => (variable) =>
variable.id === block.options.dynamicVariableId && variable.id === block.options.dynamicVariableId &&
isDefined(variable.value) isDefined(variable.value)
) as VariableWithValue | undefined ) as VariableWithValue | undefined
if (!variable || typeof variable.value === 'string') return block if (!variable) return block
const value = await getVariableValue(state)(variable)
return { return {
...block, ...block,
items: variable.value.filter(isDefined).map((item, idx) => ({ items: value.filter(isDefined).map((item, idx) => ({
id: idx.toString(), id: idx.toString(),
type: ItemType.BUTTON, type: ItemType.BUTTON,
blockId: block.id, blockId: block.id,
@ -27,5 +30,18 @@ export const injectVariableValuesInButtonsInputBlock =
})), })),
} }
} }
return deepParseVariables(variables)(block) return deepParseVariables(state.typebot.variables)(block)
}
const getVariableValue =
(state: SessionState) =>
async (variable: VariableWithValue): Promise<(string | null)[]> => {
if (!Array.isArray(variable.value)) {
const [transformedVariable] = transformStringVariablesToList(
state.typebot.variables
)([variable.id])
await updateVariables(state)([transformedVariable])
return transformedVariable.value as string[]
}
return variable.value
} }

View File

@ -35,10 +35,11 @@ const matchComparison = (
inputValue?: string, inputValue?: string,
comparisonOperator?: ComparisonOperators, comparisonOperator?: ComparisonOperators,
value?: string value?: string
): boolean => { ): boolean | undefined => {
if (!inputValue || !comparisonOperator || !value) return false if (!comparisonOperator) return false
switch (comparisonOperator) { switch (comparisonOperator) {
case ComparisonOperators.CONTAINS: { case ComparisonOperators.CONTAINS: {
if (!inputValue || !value) return false
return inputValue.toLowerCase().includes(value.toLowerCase()) return inputValue.toLowerCase().includes(value.toLowerCase())
} }
case ComparisonOperators.EQUAL: { case ComparisonOperators.EQUAL: {
@ -48,9 +49,11 @@ const matchComparison = (
return inputValue !== value return inputValue !== value
} }
case ComparisonOperators.GREATER: { case ComparisonOperators.GREATER: {
if (!inputValue || !value) return false
return parseFloat(inputValue) > parseFloat(value) return parseFloat(inputValue) > parseFloat(value)
} }
case ComparisonOperators.LESS: { case ComparisonOperators.LESS: {
if (!inputValue || !value) return false
return parseFloat(inputValue) < parseFloat(value) return parseFloat(inputValue) < parseFloat(value)
} }
case ComparisonOperators.IS_SET: { case ComparisonOperators.IS_SET: {
@ -60,13 +63,16 @@ const matchComparison = (
return !isDefined(inputValue) || inputValue.length === 0 return !isDefined(inputValue) || inputValue.length === 0
} }
case ComparisonOperators.STARTS_WITH: { case ComparisonOperators.STARTS_WITH: {
if (!inputValue || !value) return false
return inputValue.toLowerCase().startsWith(value.toLowerCase()) return inputValue.toLowerCase().startsWith(value.toLowerCase())
} }
case ComparisonOperators.ENDS_WITH: { case ComparisonOperators.ENDS_WITH: {
if (!inputValue || !value) return false
return inputValue.toLowerCase().endsWith(value.toLowerCase()) return inputValue.toLowerCase().endsWith(value.toLowerCase())
} }
case ComparisonOperators.NOT_CONTAINS: { case ComparisonOperators.NOT_CONTAINS: {
return !inputValue.toLowerCase().includes(value.toLowerCase()) if (!inputValue || !value) return false
return !inputValue?.toLowerCase().includes(value.toLowerCase())
} }
} }
} }

View File

@ -184,13 +184,11 @@ const parseBubbleBlock =
} }
const injectVariablesValueInBlock = const injectVariablesValueInBlock =
(state: Pick<SessionState, 'result' | 'typebot'>) => (state: SessionState) =>
async (block: InputBlock): Promise<ChatReply['input']> => { async (block: InputBlock): Promise<ChatReply['input']> => {
switch (block.type) { switch (block.type) {
case InputBlockType.CHOICE: { case InputBlockType.CHOICE: {
return injectVariableValuesInButtonsInputBlock(state.typebot.variables)( return injectVariableValuesInButtonsInputBlock(state)(block)
block
)
} }
case InputBlockType.PICTURE_CHOICE: { case InputBlockType.PICTURE_CHOICE: {
return injectVariableValuesInPictureChoiceBlock( return injectVariableValuesInPictureChoiceBlock(