♻️ (editor) Improve webhook creation
Remove terrible useEffects
This commit is contained in:
@@ -22,17 +22,16 @@ import {
|
||||
VariableForTest,
|
||||
ResponseVariableMapping,
|
||||
WebhookBlock,
|
||||
defaultWebhookAttributes,
|
||||
Webhook,
|
||||
MakeComBlock,
|
||||
PabblyConnectBlock,
|
||||
Webhook,
|
||||
} from 'models'
|
||||
import { DropdownList } from '@/components/DropdownList'
|
||||
import { CodeEditor } from '@/components/CodeEditor'
|
||||
import { HeadersInputs, QueryParamsInputs } from './KeyValueInputs'
|
||||
import { VariableForTestInputs } from './VariableForTestInputs'
|
||||
import { DataVariableInputs } from './ResponseMappingInputs'
|
||||
import { byId } from 'utils'
|
||||
import { byId, env } from 'utils'
|
||||
import { ExternalLinkIcon } from '@/components/icons'
|
||||
import { useToast } from '@/hooks/useToast'
|
||||
import { SwitchWithLabel } from '@/components/SwitchWithLabel'
|
||||
@@ -41,11 +40,15 @@ import { executeWebhook } from '../../queries/executeWebhookQuery'
|
||||
import { getDeepKeys } from '../../utils/getDeepKeys'
|
||||
import { Input } from '@/components/inputs'
|
||||
import { convertVariablesForTestToVariables } from '../../utils/convertVariablesForTestToVariables'
|
||||
import { useDebouncedCallback } from 'use-debounce'
|
||||
|
||||
const debounceWebhookTimeout = 2000
|
||||
|
||||
type Provider = {
|
||||
name: 'Make.com' | 'Pabbly Connect'
|
||||
name: 'Pabbly Connect'
|
||||
url: string
|
||||
}
|
||||
|
||||
type Props = {
|
||||
block: WebhookBlock | MakeComBlock | PabblyConnectBlock
|
||||
onOptionsChange: (options: WebhookOptions) => void
|
||||
@@ -61,39 +64,28 @@ export const WebhookSettings = ({
|
||||
const [isTestResponseLoading, setIsTestResponseLoading] = useState(false)
|
||||
const [testResponse, setTestResponse] = useState<string>()
|
||||
const [responseKeys, setResponseKeys] = useState<string[]>([])
|
||||
|
||||
const { showToast } = useToast()
|
||||
const [localWebhook, setLocalWebhook] = useState(
|
||||
const [localWebhook, _setLocalWebhook] = useState(
|
||||
webhooks.find(byId(webhookId))
|
||||
)
|
||||
const updateWebhookDebounced = useDebouncedCallback(
|
||||
async (newLocalWebhook) => {
|
||||
await updateWebhook(newLocalWebhook.id, newLocalWebhook)
|
||||
},
|
||||
env('E2E_TEST') === 'true' ? 0 : debounceWebhookTimeout
|
||||
)
|
||||
|
||||
useEffect(() => {
|
||||
if (localWebhook) return
|
||||
const incomingWebhook = webhooks.find(byId(webhookId))
|
||||
setLocalWebhook(incomingWebhook)
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [webhooks])
|
||||
const setLocalWebhook = (newLocalWebhook: Webhook) => {
|
||||
_setLocalWebhook(newLocalWebhook)
|
||||
updateWebhookDebounced(newLocalWebhook)
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (!typebot) return
|
||||
if (!localWebhook) {
|
||||
const newWebhook = {
|
||||
id: webhookId,
|
||||
...defaultWebhookAttributes,
|
||||
typebotId: typebot.id,
|
||||
} as Webhook
|
||||
updateWebhook(webhookId, newWebhook)
|
||||
}
|
||||
|
||||
return () => {
|
||||
setLocalWebhook((localWebhook) => {
|
||||
if (!localWebhook) return
|
||||
updateWebhook(webhookId, localWebhook).then()
|
||||
return localWebhook
|
||||
})
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [])
|
||||
useEffect(
|
||||
() => () => {
|
||||
updateWebhookDebounced.flush()
|
||||
},
|
||||
[updateWebhookDebounced]
|
||||
)
|
||||
|
||||
const handleUrlChange = (url?: string) =>
|
||||
localWebhook && setLocalWebhook({ ...localWebhook, url: url ?? null })
|
||||
@@ -126,8 +118,7 @@ export const WebhookSettings = ({
|
||||
const handleTestRequestClick = async () => {
|
||||
if (!typebot || !localWebhook) return
|
||||
setIsTestResponseLoading(true)
|
||||
await updateWebhook(localWebhook.id, localWebhook)
|
||||
await save()
|
||||
await Promise.all([updateWebhook(localWebhook.id, localWebhook), save()])
|
||||
const { data, error } = await executeWebhook(
|
||||
typebot.id,
|
||||
convertVariablesForTestToVariables(
|
||||
@@ -152,6 +143,7 @@ export const WebhookSettings = ({
|
||||
)
|
||||
|
||||
if (!localWebhook) return <Spinner />
|
||||
|
||||
return (
|
||||
<Stack spacing={4}>
|
||||
{provider && (
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
export { duplicateWebhookQueries } from './queries/duplicateWebhookQuery'
|
||||
export { duplicateWebhookQuery } from './queries/duplicateWebhookQuery'
|
||||
export { WebhookSettings } from './components/WebhookSettings'
|
||||
export { WebhookContent } from './components/WebhookContent'
|
||||
export { WebhookIcon } from './components/WebhookIcon'
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
import { Webhook } from 'models'
|
||||
import { sendRequest } from 'utils'
|
||||
|
||||
type Props = {
|
||||
typebotId: string
|
||||
data: Partial<Omit<Webhook, 'typebotId'>>
|
||||
}
|
||||
|
||||
export const createWebhookQuery = ({ typebotId, data }: Props) =>
|
||||
sendRequest<{ webhook: Webhook }>({
|
||||
method: 'POST',
|
||||
url: `/api/typebots/${typebotId}/webhooks`,
|
||||
body: { data },
|
||||
})
|
||||
@@ -1,17 +1,27 @@
|
||||
import { Webhook } from 'models'
|
||||
import { sendRequest } from 'utils'
|
||||
import { saveWebhookQuery } from './saveWebhookQuery'
|
||||
import { createWebhookQuery } from './createWebhookQuery'
|
||||
|
||||
export const duplicateWebhookQueries = async (
|
||||
typebotId: string,
|
||||
existingWebhookId: string,
|
||||
newWebhookId: string
|
||||
): Promise<Webhook | undefined> => {
|
||||
type Props = {
|
||||
existingIds: { typebotId: string; webhookId: string }
|
||||
newIds: { typebotId: string; webhookId: string }
|
||||
}
|
||||
export const duplicateWebhookQuery = async ({
|
||||
existingIds,
|
||||
newIds,
|
||||
}: Props): Promise<Webhook | undefined> => {
|
||||
const { data } = await sendRequest<{ webhook: Webhook }>(
|
||||
`/api/webhooks/${existingWebhookId}`
|
||||
`/api/typebots/${existingIds.typebotId}/webhooks/${existingIds.webhookId}`
|
||||
)
|
||||
if (!data) return
|
||||
const newWebhook = { ...data.webhook, id: newWebhookId, typebotId }
|
||||
await saveWebhookQuery(newWebhook.id, newWebhook)
|
||||
const newWebhook = {
|
||||
...data.webhook,
|
||||
id: newIds.webhookId,
|
||||
typebotId: newIds.typebotId,
|
||||
}
|
||||
await createWebhookQuery({
|
||||
typebotId: newIds.typebotId,
|
||||
data: { ...data.webhook, id: newIds.webhookId },
|
||||
})
|
||||
return newWebhook
|
||||
}
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
import { Webhook } from 'models'
|
||||
import { sendRequest } from 'utils'
|
||||
|
||||
export const saveWebhookQuery = (
|
||||
webhookId: string,
|
||||
webhook: Partial<Webhook>
|
||||
) =>
|
||||
sendRequest<{ webhook: Webhook }>({
|
||||
method: 'PUT',
|
||||
url: `/api/webhooks/${webhookId}`,
|
||||
body: webhook,
|
||||
})
|
||||
@@ -0,0 +1,15 @@
|
||||
import { Webhook } from 'models'
|
||||
import { sendRequest } from 'utils'
|
||||
|
||||
type Props = {
|
||||
typebotId: string
|
||||
webhookId: string
|
||||
data: Partial<Omit<Webhook, 'id' | 'typebotId'>>
|
||||
}
|
||||
|
||||
export const updateWebhookQuery = ({ typebotId, webhookId, data }: Props) =>
|
||||
sendRequest<{ webhook: Webhook }>({
|
||||
method: 'PATCH',
|
||||
url: `/api/typebots/${typebotId}/webhooks/${webhookId}`,
|
||||
body: { data },
|
||||
})
|
||||
Reference in New Issue
Block a user