diff --git a/apps/builder/src/features/blocks/integrations/makeCom/components/MakeComContent.tsx b/apps/builder/src/features/blocks/integrations/makeCom/components/MakeComContent.tsx
index e3256091e3..2b58e10353 100644
--- a/apps/builder/src/features/blocks/integrations/makeCom/components/MakeComContent.tsx
+++ b/apps/builder/src/features/blocks/integrations/makeCom/components/MakeComContent.tsx
@@ -1,7 +1,6 @@
import { Text } from '@chakra-ui/react'
import { useTypebot } from '@/features/editor'
-import { defaultWebhookAttributes, MakeComBlock, Webhook } from 'models'
-import { useEffect } from 'react'
+import { MakeComBlock } from 'models'
import { byId, isNotDefined } from 'utils'
type Props = {
@@ -9,22 +8,9 @@ type Props = {
}
export const MakeComContent = ({ block }: Props) => {
- const { webhooks, typebot, updateWebhook } = useTypebot()
+ const { webhooks } = useTypebot()
const webhook = webhooks.find(byId(block.webhookId))
- useEffect(() => {
- if (!typebot) return
- if (!webhook) {
- const { webhookId } = block
- const newWebhook = {
- id: webhookId,
- ...defaultWebhookAttributes,
- typebotId: typebot.id,
- } as Webhook
- updateWebhook(webhookId, newWebhook)
- }
- }, [block, typebot, updateWebhook, webhook])
-
if (isNotDefined(webhook?.body))
return Configure...
return (
diff --git a/apps/builder/src/features/blocks/integrations/makeCom/components/MakeComSettings.tsx b/apps/builder/src/features/blocks/integrations/makeCom/components/MakeComSettings.tsx
index d5b97371a8..702771ddd6 100644
--- a/apps/builder/src/features/blocks/integrations/makeCom/components/MakeComSettings.tsx
+++ b/apps/builder/src/features/blocks/integrations/makeCom/components/MakeComSettings.tsx
@@ -1,31 +1,68 @@
-import {
- Alert,
- AlertIcon,
- Button,
- Input,
- Link,
- Stack,
- Text,
-} from '@chakra-ui/react'
+import { Alert, AlertIcon, Button, Link, Stack, Text } from '@chakra-ui/react'
import { ExternalLinkIcon } from '@/components/icons'
import { useTypebot } from '@/features/editor'
-import { MakeComBlock } from 'models'
-import React from 'react'
-import { byId } from 'utils'
+import { MakeComBlock, Webhook, WebhookOptions } from 'models'
+import React, { useCallback, useEffect, useState } from 'react'
+import { byId, env } from 'utils'
+import { WebhookAdvancedConfigForm } from '../../webhook/components/WebhookAdvancedConfigForm'
+import { useDebouncedCallback } from 'use-debounce'
+
+const debounceWebhookTimeout = 2000
type Props = {
block: MakeComBlock
+ onOptionsChange: (options: WebhookOptions) => void
}
-export const MakeComSettings = ({ block }: Props) => {
- const { webhooks } = useTypebot()
- const webhook = webhooks.find(byId(block.webhookId))
+export const MakeComSettings = ({
+ block: { webhookId, id: blockId, options },
+ onOptionsChange,
+}: Props) => {
+ const { webhooks, updateWebhook } = useTypebot()
+ const webhook = webhooks.find(byId(webhookId))
+
+ const [localWebhook, _setLocalWebhook] = useState(webhook)
+ const updateWebhookDebounced = useDebouncedCallback(
+ async (newLocalWebhook) => {
+ await updateWebhook(newLocalWebhook.id, newLocalWebhook)
+ },
+ env('E2E_TEST') === 'true' ? 0 : debounceWebhookTimeout
+ )
+
+ const setLocalWebhook = useCallback(
+ (newLocalWebhook: Webhook) => {
+ _setLocalWebhook(newLocalWebhook)
+ updateWebhookDebounced(newLocalWebhook)
+ },
+ [updateWebhookDebounced]
+ )
+
+ useEffect(() => {
+ if (
+ !localWebhook ||
+ localWebhook.url ||
+ !webhook?.url ||
+ webhook.url === localWebhook.url
+ )
+ return
+ setLocalWebhook({
+ ...localWebhook,
+ url: webhook?.url,
+ })
+ }, [webhook, localWebhook, setLocalWebhook])
+
+ useEffect(
+ () => () => {
+ updateWebhookDebounced.flush()
+ },
+ [updateWebhookDebounced]
+ )
return (
-
+
- {webhook?.url ? (
+ {localWebhook?.url ? (
<>Your scenario is correctly configured 🚀>
) : (
@@ -41,7 +78,15 @@ export const MakeComSettings = ({ block }: Props) => {
)}
- {webhook?.url && }
+ {localWebhook && (
+
+ )}
)
}
diff --git a/apps/builder/src/features/blocks/integrations/pabbly/components/PabblyConnectContent.tsx b/apps/builder/src/features/blocks/integrations/pabbly/components/PabblyConnectContent.tsx
index 7babcc1ea1..9db2fb3b70 100644
--- a/apps/builder/src/features/blocks/integrations/pabbly/components/PabblyConnectContent.tsx
+++ b/apps/builder/src/features/blocks/integrations/pabbly/components/PabblyConnectContent.tsx
@@ -1,7 +1,6 @@
import { Text } from '@chakra-ui/react'
import { useTypebot } from '@/features/editor'
-import { defaultWebhookAttributes, PabblyConnectBlock, Webhook } from 'models'
-import { useEffect } from 'react'
+import { PabblyConnectBlock } from 'models'
import { byId, isNotDefined } from 'utils'
type Props = {
@@ -9,22 +8,9 @@ type Props = {
}
export const PabblyConnectContent = ({ block }: Props) => {
- const { webhooks, typebot, updateWebhook } = useTypebot()
+ const { webhooks } = useTypebot()
const webhook = webhooks.find(byId(block.webhookId))
- useEffect(() => {
- if (!typebot) return
- if (!webhook) {
- const { webhookId } = block
- const newWebhook = {
- id: webhookId,
- ...defaultWebhookAttributes,
- typebotId: typebot.id,
- } as Webhook
- updateWebhook(webhookId, newWebhook)
- }
- }, [block, typebot, updateWebhook, webhook])
-
if (isNotDefined(webhook?.body))
return Configure...
return (
diff --git a/apps/builder/src/features/blocks/integrations/pabbly/components/PabblyConnectSettings.tsx b/apps/builder/src/features/blocks/integrations/pabbly/components/PabblyConnectSettings.tsx
new file mode 100644
index 0000000000..cd91c9aa54
--- /dev/null
+++ b/apps/builder/src/features/blocks/integrations/pabbly/components/PabblyConnectSettings.tsx
@@ -0,0 +1,92 @@
+import { Alert, AlertIcon, Button, Link, Stack, Text } from '@chakra-ui/react'
+import { ExternalLinkIcon } from '@/components/icons'
+import { useTypebot } from '@/features/editor'
+import { PabblyConnectBlock, Webhook, WebhookOptions } from 'models'
+import React, { useEffect, useState } from 'react'
+import { byId, env } from 'utils'
+import { WebhookAdvancedConfigForm } from '../../webhook/components/WebhookAdvancedConfigForm'
+import { useDebouncedCallback } from 'use-debounce'
+import { TextInput } from '@/components/inputs'
+
+const debounceWebhookTimeout = 2000
+
+type Props = {
+ block: PabblyConnectBlock
+ onOptionsChange: (options: WebhookOptions) => void
+}
+
+export const PabblyConnectSettings = ({
+ block: { webhookId, id: blockId, options },
+ onOptionsChange,
+}: Props) => {
+ const { webhooks, updateWebhook } = useTypebot()
+
+ const [localWebhook, _setLocalWebhook] = useState(
+ webhooks.find(byId(webhookId))
+ )
+
+ const updateWebhookDebounced = useDebouncedCallback(
+ async (newLocalWebhook) => {
+ await updateWebhook(newLocalWebhook.id, newLocalWebhook)
+ },
+ env('E2E_TEST') === 'true' ? 0 : debounceWebhookTimeout
+ )
+
+ const setLocalWebhook = (newLocalWebhook: Webhook) => {
+ _setLocalWebhook(newLocalWebhook)
+ updateWebhookDebounced(newLocalWebhook)
+ }
+
+ useEffect(
+ () => () => {
+ updateWebhookDebounced.flush()
+ },
+ [updateWebhookDebounced]
+ )
+
+ const handleUrlChange = (url: string) =>
+ localWebhook &&
+ setLocalWebhook({
+ ...localWebhook,
+ url,
+ })
+
+ return (
+
+
+
+ {localWebhook?.url ? (
+ <>Your scenario is correctly configured 🚀>
+ ) : (
+
+ Head up to Pabbly Connect to get the webhook URL:
+
+
+ )}
+
+
+ {localWebhook && (
+
+ )}
+
+ )
+}
diff --git a/apps/builder/src/features/blocks/integrations/webhook/components/WebhookAdvancedConfigForm.tsx b/apps/builder/src/features/blocks/integrations/webhook/components/WebhookAdvancedConfigForm.tsx
new file mode 100644
index 0000000000..73facb9c41
--- /dev/null
+++ b/apps/builder/src/features/blocks/integrations/webhook/components/WebhookAdvancedConfigForm.tsx
@@ -0,0 +1,232 @@
+import { DropdownList } from '@/components/DropdownList'
+import { CodeEditor } from '@/components/inputs/CodeEditor'
+import { SwitchWithLabel } from '@/components/inputs/SwitchWithLabel'
+import { TableList, TableListItemProps } from '@/components/TableList'
+import { useTypebot } from '@/features/editor'
+import { useToast } from '@/hooks/useToast'
+import {
+ Stack,
+ HStack,
+ Accordion,
+ AccordionItem,
+ AccordionButton,
+ AccordionIcon,
+ AccordionPanel,
+ Button,
+ Text,
+} from '@chakra-ui/react'
+import {
+ HttpMethod,
+ KeyValue,
+ VariableForTest,
+ ResponseVariableMapping,
+ WebhookOptions,
+ Webhook,
+} from 'models'
+import { useState, useMemo } from 'react'
+import { executeWebhook } from '../queries/executeWebhookQuery'
+import { convertVariablesForTestToVariables } from '../utils/convertVariablesForTestToVariables'
+import { getDeepKeys } from '../utils/getDeepKeys'
+import {
+ QueryParamsInputs,
+ HeadersInputs,
+} from './WebhookSettings/KeyValueInputs'
+import { DataVariableInputs } from './WebhookSettings/ResponseMappingInputs'
+import { VariableForTestInputs } from './WebhookSettings/VariableForTestInputs'
+
+type Props = {
+ blockId: string
+ webhook: Webhook
+ options: WebhookOptions
+ onWebhookChange: (webhook: Webhook) => void
+ onOptionsChange: (options: WebhookOptions) => void
+}
+
+export const WebhookAdvancedConfigForm = ({
+ blockId,
+ webhook,
+ options,
+ onWebhookChange,
+ onOptionsChange,
+}: Props) => {
+ const { typebot, save, updateWebhook } = useTypebot()
+ const [isTestResponseLoading, setIsTestResponseLoading] = useState(false)
+ const [testResponse, setTestResponse] = useState()
+ const [responseKeys, setResponseKeys] = useState([])
+ const { showToast } = useToast()
+
+ const handleMethodChange = (method: HttpMethod) =>
+ onWebhookChange({ ...webhook, method })
+
+ const handleQueryParamsChange = (queryParams: KeyValue[]) =>
+ onWebhookChange({ ...webhook, queryParams })
+
+ const handleHeadersChange = (headers: KeyValue[]) =>
+ onWebhookChange({ ...webhook, headers })
+
+ const handleBodyChange = (body: string) =>
+ onWebhookChange({ ...webhook, body })
+
+ const handleVariablesChange = (variablesForTest: VariableForTest[]) =>
+ onOptionsChange({ ...options, variablesForTest })
+
+ const handleResponseMappingChange = (
+ responseVariableMapping: ResponseVariableMapping[]
+ ) => onOptionsChange({ ...options, responseVariableMapping })
+
+ const handleAdvancedConfigChange = (isAdvancedConfig: boolean) =>
+ onOptionsChange({ ...options, isAdvancedConfig })
+
+ const handleBodyFormStateChange = (isCustomBody: boolean) =>
+ onOptionsChange({ ...options, isCustomBody })
+
+ const handleTestRequestClick = async () => {
+ if (!typebot || !webhook) return
+ setIsTestResponseLoading(true)
+ await Promise.all([updateWebhook(webhook.id, webhook), save()])
+ const { data, error } = await executeWebhook(
+ typebot.id,
+ convertVariablesForTestToVariables(
+ options.variablesForTest,
+ typebot.variables
+ ),
+ { blockId }
+ )
+ if (error)
+ return showToast({ title: error.name, description: error.message })
+ setTestResponse(JSON.stringify(data, undefined, 2))
+ setResponseKeys(getDeepKeys(data))
+ setIsTestResponseLoading(false)
+ }
+
+ const ResponseMappingInputs = useMemo(
+ () =>
+ function Component(props: TableListItemProps) {
+ return
+ },
+ [responseKeys]
+ )
+
+ return (
+ <>
+
+ {(options.isAdvancedConfig ?? true) && (
+ <>
+
+ Method:
+
+ currentItem={webhook.method as HttpMethod}
+ onItemSelect={handleMethodChange}
+ items={Object.values(HttpMethod)}
+ />
+
+
+
+
+ Query params
+
+
+
+
+ initialItems={webhook.queryParams}
+ onItemsChange={handleQueryParamsChange}
+ Item={QueryParamsInputs}
+ addLabel="Add a param"
+ debounceTimeout={0}
+ />
+
+
+
+
+ Headers
+
+
+
+
+ initialItems={webhook.headers}
+ onItemsChange={handleHeadersChange}
+ Item={HeadersInputs}
+ addLabel="Add a value"
+ debounceTimeout={0}
+ />
+
+
+
+
+ Body
+
+
+
+
+ {(options.isCustomBody ?? true) && (
+
+ )}
+
+
+
+
+ Variable values for test
+
+
+
+
+ initialItems={
+ options?.variablesForTest ?? { byId: {}, allIds: [] }
+ }
+ onItemsChange={handleVariablesChange}
+ Item={VariableForTestInputs}
+ addLabel="Add an entry"
+ debounceTimeout={0}
+ />
+
+
+
+ >
+ )}
+ {webhook.url && (
+
+ )}
+ {testResponse && (
+
+ )}
+ {(testResponse || options?.responseVariableMapping.length > 0) && (
+
+
+
+ Save in variables
+
+
+
+
+ initialItems={options.responseVariableMapping}
+ onItemsChange={handleResponseMappingChange}
+ Item={ResponseMappingInputs}
+ addLabel="Add an entry"
+ debounceTimeout={0}
+ />
+
+
+
+ )}
+ >
+ )
+}
diff --git a/apps/builder/src/features/blocks/integrations/webhook/components/WebhookSettings/WebhookSettings.tsx b/apps/builder/src/features/blocks/integrations/webhook/components/WebhookSettings/WebhookSettings.tsx
index cfe0e23fde..41ca7597fb 100644
--- a/apps/builder/src/features/blocks/integrations/webhook/components/WebhookSettings/WebhookSettings.tsx
+++ b/apps/builder/src/features/blocks/integrations/webhook/components/WebhookSettings/WebhookSettings.tsx
@@ -1,70 +1,24 @@
-import React, { useEffect, useMemo, useState } from 'react'
-import {
- Accordion,
- AccordionButton,
- AccordionIcon,
- AccordionItem,
- AccordionPanel,
- Button,
- HStack,
- Spinner,
- Stack,
- Text,
- Alert,
- AlertIcon,
- Link,
-} from '@chakra-ui/react'
+import React, { useEffect, useState } from 'react'
+import { Spinner, Stack } from '@chakra-ui/react'
import { useTypebot } from '@/features/editor'
-import {
- HttpMethod,
- KeyValue,
- WebhookOptions,
- VariableForTest,
- ResponseVariableMapping,
- WebhookBlock,
- MakeComBlock,
- PabblyConnectBlock,
- Webhook,
-} from 'models'
-import { DropdownList } from '@/components/DropdownList'
-import { CodeEditor } from '@/components/inputs/CodeEditor'
-import { HeadersInputs, QueryParamsInputs } from './KeyValueInputs'
-import { VariableForTestInputs } from './VariableForTestInputs'
-import { DataVariableInputs } from './ResponseMappingInputs'
+import { WebhookOptions, Webhook, WebhookBlock } from 'models'
import { byId, env } from 'utils'
-import { ExternalLinkIcon } from '@/components/icons'
-import { useToast } from '@/hooks/useToast'
-import { SwitchWithLabel } from '@/components/inputs/SwitchWithLabel'
-import { TableListItemProps, TableList } from '@/components/TableList'
-import { executeWebhook } from '../../queries/executeWebhookQuery'
-import { getDeepKeys } from '../../utils/getDeepKeys'
import { TextInput } from '@/components/inputs'
-import { convertVariablesForTestToVariables } from '../../utils/convertVariablesForTestToVariables'
import { useDebouncedCallback } from 'use-debounce'
+import { WebhookAdvancedConfigForm } from '../WebhookAdvancedConfigForm'
const debounceWebhookTimeout = 2000
-type Provider = {
- name: 'Pabbly Connect'
- url: string
-}
-
type Props = {
- block: WebhookBlock | MakeComBlock | PabblyConnectBlock
+ block: WebhookBlock
onOptionsChange: (options: WebhookOptions) => void
- provider?: Provider
}
export const WebhookSettings = ({
- block: { options, id: blockId, webhookId },
+ block: { webhookId, id: blockId, options },
onOptionsChange,
- provider,
}: Props) => {
- const { typebot, save, webhooks, updateWebhook } = useTypebot()
- const [isTestResponseLoading, setIsTestResponseLoading] = useState(false)
- const [testResponse, setTestResponse] = useState()
- const [responseKeys, setResponseKeys] = useState([])
- const { showToast } = useToast()
+ const { webhooks, updateWebhook } = useTypebot()
const [localWebhook, _setLocalWebhook] = useState(
webhooks.find(byId(webhookId))
)
@@ -90,200 +44,23 @@ export const WebhookSettings = ({
const handleUrlChange = (url?: string) =>
localWebhook && setLocalWebhook({ ...localWebhook, url: url ?? null })
- const handleMethodChange = (method: HttpMethod) =>
- localWebhook && setLocalWebhook({ ...localWebhook, method })
-
- const handleQueryParamsChange = (queryParams: KeyValue[]) =>
- localWebhook && setLocalWebhook({ ...localWebhook, queryParams })
-
- const handleHeadersChange = (headers: KeyValue[]) =>
- localWebhook && setLocalWebhook({ ...localWebhook, headers })
-
- const handleBodyChange = (body: string) =>
- localWebhook && setLocalWebhook({ ...localWebhook, body })
-
- const handleVariablesChange = (variablesForTest: VariableForTest[]) =>
- onOptionsChange({ ...options, variablesForTest })
-
- const handleResponseMappingChange = (
- responseVariableMapping: ResponseVariableMapping[]
- ) => onOptionsChange({ ...options, responseVariableMapping })
-
- const handleAdvancedConfigChange = (isAdvancedConfig: boolean) =>
- onOptionsChange({ ...options, isAdvancedConfig })
-
- const handleBodyFormStateChange = (isCustomBody: boolean) =>
- onOptionsChange({ ...options, isCustomBody })
-
- const handleTestRequestClick = async () => {
- if (!typebot || !localWebhook) return
- setIsTestResponseLoading(true)
- await Promise.all([updateWebhook(localWebhook.id, localWebhook), save()])
- const { data, error } = await executeWebhook(
- typebot.id,
- convertVariablesForTestToVariables(
- options.variablesForTest,
- typebot.variables
- ),
- { blockId }
- )
- if (error)
- return showToast({ title: error.name, description: error.message })
- setTestResponse(JSON.stringify(data, undefined, 2))
- setResponseKeys(getDeepKeys(data))
- setIsTestResponseLoading(false)
- }
-
- const ResponseMappingInputs = useMemo(
- () =>
- function Component(props: TableListItemProps) {
- return
- },
- [responseKeys]
- )
-
if (!localWebhook) return
return (
- {provider && (
-
-
-
- Head up to {provider.name} to configure this block:
-
-
-
- )}
-
- {(options.isAdvancedConfig ?? true) && (
-
-
- Method:
-
- currentItem={localWebhook.method as HttpMethod}
- onItemSelect={handleMethodChange}
- items={Object.values(HttpMethod)}
- />
-
-
-
-
- Query params
-
-
-
-
- initialItems={localWebhook.queryParams}
- onItemsChange={handleQueryParamsChange}
- Item={QueryParamsInputs}
- addLabel="Add a param"
- debounceTimeout={0}
- />
-
-
-
-
- Headers
-
-
-
-
- initialItems={localWebhook.headers}
- onItemsChange={handleHeadersChange}
- Item={HeadersInputs}
- addLabel="Add a value"
- debounceTimeout={0}
- />
-
-
-
-
- Body
-
-
-
-
- {(options.isCustomBody ?? true) && (
-
- )}
-
-
-
-
- Variable values for test
-
-
-
-
- initialItems={
- options?.variablesForTest ?? { byId: {}, allIds: [] }
- }
- onItemsChange={handleVariablesChange}
- Item={VariableForTestInputs}
- addLabel="Add an entry"
- debounceTimeout={0}
- />
-
-
-
-
- )}
-
- {localWebhook.url && (
-
- )}
- {testResponse && (
-
- )}
- {(testResponse || options?.responseVariableMapping.length > 0) && (
-
-
-
- Save in variables
-
-
-
-
- initialItems={options.responseVariableMapping}
- onItemsChange={handleResponseMappingChange}
- Item={ResponseMappingInputs}
- addLabel="Add an entry"
- debounceTimeout={0}
- />
-
-
-
- )}
-
)
}
diff --git a/apps/builder/src/features/blocks/integrations/zapier/components/ZapierContent.tsx b/apps/builder/src/features/blocks/integrations/zapier/components/ZapierContent.tsx
index c95346c70e..92564d3075 100644
--- a/apps/builder/src/features/blocks/integrations/zapier/components/ZapierContent.tsx
+++ b/apps/builder/src/features/blocks/integrations/zapier/components/ZapierContent.tsx
@@ -1,7 +1,6 @@
import { Text } from '@chakra-ui/react'
import { useTypebot } from '@/features/editor'
-import { defaultWebhookAttributes, Webhook, ZapierBlock } from 'models'
-import { useEffect } from 'react'
+import { ZapierBlock } from 'models'
import { byId, isNotDefined } from 'utils'
type Props = {
@@ -9,22 +8,9 @@ type Props = {
}
export const ZapierContent = ({ block }: Props) => {
- const { webhooks, typebot, updateWebhook } = useTypebot()
+ const { webhooks } = useTypebot()
const webhook = webhooks.find(byId(block.webhookId))
- useEffect(() => {
- if (!typebot) return
- if (!webhook) {
- const { webhookId } = block
- const newWebhook = {
- id: webhookId,
- ...defaultWebhookAttributes,
- typebotId: typebot.id,
- } as Webhook
- updateWebhook(webhookId, newWebhook)
- }
- }, [block, typebot, updateWebhook, webhook])
-
if (isNotDefined(webhook?.body))
return Configure...
return (
diff --git a/apps/builder/src/features/blocks/integrations/zapier/components/ZapierSettings.tsx b/apps/builder/src/features/blocks/integrations/zapier/components/ZapierSettings.tsx
index ca33a6755a..4133f2b7f0 100644
--- a/apps/builder/src/features/blocks/integrations/zapier/components/ZapierSettings.tsx
+++ b/apps/builder/src/features/blocks/integrations/zapier/components/ZapierSettings.tsx
@@ -1,31 +1,69 @@
-import {
- Alert,
- AlertIcon,
- Button,
- Input,
- Link,
- Stack,
- Text,
-} from '@chakra-ui/react'
+import { Alert, AlertIcon, Button, Link, Stack, Text } from '@chakra-ui/react'
import { ExternalLinkIcon } from '@/components/icons'
import { useTypebot } from '@/features/editor'
-import { ZapierBlock } from 'models'
-import React from 'react'
-import { byId } from 'utils'
+import { Webhook, WebhookOptions, ZapierBlock } from 'models'
+import React, { useCallback, useEffect, useState } from 'react'
+import { byId, env } from 'utils'
+import { WebhookAdvancedConfigForm } from '../../webhook/components/WebhookAdvancedConfigForm'
+import { useDebouncedCallback } from 'use-debounce'
+
+const debounceWebhookTimeout = 2000
type Props = {
block: ZapierBlock
+ onOptionsChange: (options: WebhookOptions) => void
}
-export const ZapierSettings = ({ block }: Props) => {
- const { webhooks } = useTypebot()
- const webhook = webhooks.find(byId(block.webhookId))
+export const ZapierSettings = ({
+ block: { webhookId, id: blockId, options },
+ onOptionsChange,
+}: Props) => {
+ const { webhooks, updateWebhook } = useTypebot()
+ const webhook = webhooks.find(byId(webhookId))
+
+ const [localWebhook, _setLocalWebhook] = useState(webhook)
+
+ const updateWebhookDebounced = useDebouncedCallback(
+ async (newLocalWebhook) => {
+ await updateWebhook(newLocalWebhook.id, newLocalWebhook)
+ },
+ env('E2E_TEST') === 'true' ? 0 : debounceWebhookTimeout
+ )
+
+ const setLocalWebhook = useCallback(
+ (newLocalWebhook: Webhook) => {
+ _setLocalWebhook(newLocalWebhook)
+ updateWebhookDebounced(newLocalWebhook)
+ },
+ [updateWebhookDebounced]
+ )
+
+ useEffect(() => {
+ if (
+ !localWebhook ||
+ localWebhook.url ||
+ !webhook?.url ||
+ webhook.url === localWebhook.url
+ )
+ return
+ setLocalWebhook({
+ ...localWebhook,
+ url: webhook?.url,
+ })
+ }, [webhook, localWebhook, setLocalWebhook])
+
+ useEffect(
+ () => () => {
+ updateWebhookDebounced.flush()
+ },
+ [updateWebhookDebounced]
+ )
return (
-
+
- {webhook?.url ? (
+ {localWebhook?.url ? (
<>Your zap is correctly configured 🚀>
) : (
@@ -41,7 +79,15 @@ export const ZapierSettings = ({ block }: Props) => {
)}
- {webhook?.url && }
+ {localWebhook && (
+
+ )}
)
}
diff --git a/apps/builder/src/features/graph/components/Nodes/BlockNode/SettingsPopoverContent/SettingsPopoverContent.tsx b/apps/builder/src/features/graph/components/Nodes/BlockNode/SettingsPopoverContent/SettingsPopoverContent.tsx
index 35ad6d59ed..9f3d2eb086 100644
--- a/apps/builder/src/features/graph/components/Nodes/BlockNode/SettingsPopoverContent/SettingsPopoverContent.tsx
+++ b/apps/builder/src/features/graph/components/Nodes/BlockNode/SettingsPopoverContent/SettingsPopoverContent.tsx
@@ -38,11 +38,12 @@ import { SetVariableSettings } from '@/features/blocks/logic/setVariable'
import { TypebotLinkForm } from '@/features/blocks/logic/typebotLink'
import { ButtonsBlockSettings } from '@/features/blocks/inputs/buttons'
import { ChatwootSettingsForm } from '@/features/blocks/integrations/chatwoot'
-import { MakeComSettings } from '@/features/blocks/integrations/makeCom'
import { HelpDocButton } from './HelpDocButton'
import { WaitSettings } from '@/features/blocks/logic/wait/components/WaitSettings'
import { ScriptSettings } from '@/features/blocks/logic/script/components/ScriptSettings'
import { JumpSettings } from '@/features/blocks/logic/jump/components/JumpSettings'
+import { MakeComSettings } from '@/features/blocks/integrations/makeCom/components/MakeComSettings'
+import { PabblyConnectSettings } from '@/features/blocks/integrations/pabbly/components/PabblyConnectSettings'
type Props = {
block: BlockWithOptions
@@ -248,20 +249,20 @@ export const BlockSettings = ({
)
}
case IntegrationBlockType.ZAPIER: {
- return
+ return (
+
+ )
}
case IntegrationBlockType.MAKE_COM: {
- return
+ return (
+
+ )
}
case IntegrationBlockType.PABBLY_CONNECT: {
return (
-
)
}