From 26cf38fb2181de71fdc07663f70128088ae8bee0 Mon Sep 17 00:00:00 2001 From: Baptiste Arnaud Date: Tue, 31 May 2022 11:06:58 +0200 Subject: [PATCH] =?UTF-8?q?feat(engine):=20=E2=9A=A1=EF=B8=8F=20Accept=20v?= =?UTF-8?q?ariables=20as=20webhook=20data=20path?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../WebhookSettings/ResponseMappingInputs.tsx | 1 + .../components/shared/SearchableDropdown.tsx | 64 ++++++++++++++++--- .../shared/buttons/VariablesButton.tsx | 2 +- .../bot-engine/src/services/integration.ts | 5 +- 4 files changed, 61 insertions(+), 11 deletions(-) diff --git a/apps/builder/components/shared/Graph/Nodes/StepNode/SettingsPopoverContent/bodies/WebhookSettings/ResponseMappingInputs.tsx b/apps/builder/components/shared/Graph/Nodes/StepNode/SettingsPopoverContent/bodies/WebhookSettings/ResponseMappingInputs.tsx index 881097a1f..3d173b94c 100644 --- a/apps/builder/components/shared/Graph/Nodes/StepNode/SettingsPopoverContent/bodies/WebhookSettings/ResponseMappingInputs.tsx +++ b/apps/builder/components/shared/Graph/Nodes/StepNode/SettingsPopoverContent/bodies/WebhookSettings/ResponseMappingInputs.tsx @@ -25,6 +25,7 @@ export const DataVariableInputs = ({ onValueChange={handleBodyPathChange} placeholder="Select the data" debounceTimeout={debounceTimeout} + withVariableButton /> diff --git a/apps/builder/components/shared/SearchableDropdown.tsx b/apps/builder/components/shared/SearchableDropdown.tsx index d9692a42f..a868a52dd 100644 --- a/apps/builder/components/shared/SearchableDropdown.tsx +++ b/apps/builder/components/shared/SearchableDropdown.tsx @@ -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(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(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 ( - + + + {withVariableButton && ( + + )} + { return ( - + diff --git a/packages/bot-engine/src/services/integration.ts b/packages/bot-engine/src/services/integration.ts index 3acac1d20..88907a227 100644 --- a/packages/bot-engine/src/services/integration.ts +++ b/packages/bot-engine/src/services/integration.ts @@ -258,7 +258,10 @@ const executeWebhook = async ( if (!varMapping?.bodyPath || !varMapping.variableId) return newVariables const existingVariable = variables.find(byId(varMapping.variableId)) if (!existingVariable) return newVariables - const func = Function('data', `return data.${varMapping?.bodyPath}`) + const func = Function( + 'data', + `return data.${parseVariables(variables)(varMapping?.bodyPath)}` + ) try { const value = func(data) updateVariableValue(existingVariable?.id, value)