2
0

feat(engine): ️ Accept variables as webhook data path

This commit is contained in:
Baptiste Arnaud
2022-05-31 11:06:58 +02:00
parent b65d153bf0
commit 26cf38fb21
4 changed files with 61 additions and 11 deletions

View File

@ -25,6 +25,7 @@ export const DataVariableInputs = ({
onValueChange={handleBodyPathChange}
placeholder="Select the data"
debounceTimeout={debounceTimeout}
withVariableButton
/>
</FormControl>
<FormControl>

View File

@ -8,25 +8,31 @@ import {
PopoverContent,
Button,
InputProps,
HStack,
} from '@chakra-ui/react'
import { Variable } from 'models'
import { useState, useRef, useEffect, ChangeEvent } from 'react'
import { useDebouncedCallback } from 'use-debounce'
import { isEmpty } from 'utils'
import { VariablesButton } from './buttons/VariablesButton'
type Props = {
selectedItem?: string
items: string[]
debounceTimeout?: number
withVariableButton?: boolean
onValueChange?: (value: string) => void
} & InputProps
export const SearchableDropdown = ({
selectedItem,
items,
withVariableButton = false,
debounceTimeout = 1000,
onValueChange,
...inputProps
}: Props) => {
const [carretPosition, setCarretPosition] = useState<number>(0)
const { onOpen, onClose, isOpen } = useDisclosure()
const [inputValue, setInputValue] = useState(selectedItem ?? '')
const debounced = useDebouncedCallback(
@ -42,7 +48,7 @@ export const SearchableDropdown = ({
.slice(0, 50),
])
const dropdownRef = useRef(null)
const inputRef = useRef(null)
const inputRef = useRef<HTMLInputElement>(null)
useEffect(
() => () => {
@ -93,6 +99,37 @@ export const SearchableDropdown = ({
onClose()
}
const handleVariableSelected = (variable?: Variable) => {
if (!inputRef.current || !variable) return
const cursorPosition = carretPosition
const textBeforeCursorPosition = inputRef.current.value.substring(
0,
cursorPosition
)
const textAfterCursorPosition = inputRef.current.value.substring(
cursorPosition,
inputRef.current.value.length
)
const newValue =
textBeforeCursorPosition +
`{{${variable.name}}}` +
textAfterCursorPosition
setInputValue(newValue)
debounced(newValue)
inputRef.current.focus()
setTimeout(() => {
if (!inputRef.current) return
inputRef.current.selectionStart = inputRef.current.selectionEnd =
carretPosition + `{{${variable.name}}}`.length
setCarretPosition(inputRef.current.selectionStart)
}, 100)
}
const handleKeyUp = () => {
if (!inputRef.current?.selectionStart) return
setCarretPosition(inputRef.current.selectionStart)
}
return (
<Flex ref={dropdownRef} w="full">
<Popover
@ -103,14 +140,23 @@ export const SearchableDropdown = ({
isLazy
>
<PopoverTrigger>
<Input
ref={inputRef}
value={inputValue}
onChange={onInputChange}
onClick={onOpen}
type="text"
{...inputProps}
/>
<HStack spacing={0} align={'flex-end'}>
<Input
ref={inputRef}
value={inputValue}
onChange={onInputChange}
onClick={onOpen}
type="text"
onKeyUp={handleKeyUp}
{...inputProps}
/>
{withVariableButton && (
<VariablesButton
onSelectVariable={handleVariableSelected}
onClick={onClose}
/>
)}
</HStack>
</PopoverTrigger>
<PopoverContent
maxH="35vh"

View File

@ -20,7 +20,7 @@ type Props = {
export const VariablesButton = ({ onSelectVariable, ...props }: Props) => {
return (
<Popover isLazy placement="bottom-end">
<Popover isLazy placement="bottom-end" gutter={0}>
<PopoverTrigger>
<Flex>
<Tooltip label="Insert a variable">