import { useDisclosure, useOutsideClick, Flex, Popover, PopoverTrigger, Input, PopoverContent, Button, InputProps, IconButton, } from '@chakra-ui/react' import { PlusIcon, TrashIcon } from 'assets/icons' import { useTypebot } from 'contexts/TypebotContext' import { Variable } from 'models' import React, { useState, useRef, ChangeEvent, useMemo, useEffect } from 'react' import { generate } from 'short-uuid' import { useDebounce } from 'use-debounce' import { isDefined } from 'utils' type Props = { initialVariableId?: string onSelectVariable: ( variable: Pick | undefined ) => void isDefaultOpen?: boolean } & InputProps export const VariableSearchInput = ({ initialVariableId, onSelectVariable, isDefaultOpen, ...inputProps }: Props) => { const { onOpen, onClose, isOpen } = useDisclosure() const { typebot, createVariable, deleteVariable } = useTypebot() const variables = useMemo( () => typebot?.variables.allIds.map((id) => typebot.variables.byId[id]) ?? [], [typebot?.variables] ) const [inputValue, setInputValue] = useState( typebot?.variables.byId[initialVariableId ?? '']?.name ?? '' ) const [debouncedInputValue] = useDebounce(inputValue, 200) const [filteredItems, setFilteredItems] = useState(variables) const dropdownRef = useRef(null) const inputRef = useRef(null) useOutsideClick({ ref: dropdownRef, handler: onClose, }) useEffect(() => { if (isDefaultOpen) onOpen() // eslint-disable-next-line react-hooks/exhaustive-deps }, []) useEffect(() => { const variable = variables.find((v) => v.name === debouncedInputValue) if (variable) onSelectVariable(variable) // eslint-disable-next-line react-hooks/exhaustive-deps }, [debouncedInputValue]) const onInputChange = (e: ChangeEvent) => { setInputValue(e.target.value) onOpen() if (e.target.value === '') { setFilteredItems([...variables.slice(0, 50)]) onSelectVariable(undefined) return } setFilteredItems([ ...variables .filter((item) => item.name.toLowerCase().includes((e.target.value ?? '').toLowerCase()) ) .slice(0, 50), ]) } const handleVariableNameClick = (variable: Variable) => () => { setInputValue(variable.name) onSelectVariable(variable) onClose() } const handleCreateNewVariableClick = () => { if (!inputValue || inputValue === '') return const id = generate() createVariable({ id, name: inputValue }) onSelectVariable({ id, name: inputValue }) onClose() } const handleDeleteVariableClick = (variable: Variable) => (e: React.MouseEvent) => { e.stopPropagation() deleteVariable(variable.id) setFilteredItems(filteredItems.filter((item) => item.id !== variable.id)) if (variable.name === inputValue) setInputValue('') } return ( {(inputValue?.length ?? 0) > 0 && !isDefined(variables.find((v) => v.name === inputValue)) && ( )} {filteredItems.length > 0 && ( <> {filteredItems.map((item, idx) => { return ( ) })} )} ) }