2
0

♻️ (editor) Improve webhook creation

Remove terrible useEffects
This commit is contained in:
Baptiste Arnaud
2023-02-15 14:51:58 +01:00
parent 6e066c44e1
commit ac464eabdf
23 changed files with 481 additions and 528 deletions

View File

@ -11,6 +11,7 @@ import { Router, useRouter } from 'next/router'
import {
createContext,
ReactNode,
useCallback,
useContext,
useEffect,
useMemo,
@ -34,7 +35,7 @@ import {
updatePublishedTypebotQuery,
deletePublishedTypebotQuery,
} from '@/features/publish/queries'
import { saveWebhookQuery } from '@/features/blocks/integrations/webhook/queries/saveWebhookQuery'
import { updateWebhookQuery } from '@/features/blocks/integrations/webhook/queries/updateWebhookQuery'
import {
checkIfTypebotsAreEqual,
checkIfPublished,
@ -43,6 +44,8 @@ import {
parsePublicTypebotToTypebot,
} from '@/features/publish/utils'
import { useAutoSave } from '@/hooks/useAutoSave'
import { createWebhookQuery } from '@/features/blocks/integrations/webhook/queries/createWebhookQuery'
import { duplicateWebhookQuery } from '@/features/blocks/integrations/webhook/queries/duplicateWebhookQuery'
const autoSaveTimeout = 10000
@ -306,20 +309,61 @@ export const TypebotProvider = ({
return saveTypebot()
}
const updateWebhook = async (
webhookId: string,
updates: Partial<Webhook>
const updateWebhook = useCallback(
async (webhookId: string, updates: Partial<Webhook>) => {
if (!typebot) return
const { data } = await updateWebhookQuery({
typebotId: typebot.id,
webhookId,
data: updates,
})
if (data)
mutate({
typebot,
publishedTypebot,
webhooks: (webhooks ?? []).map((w) =>
w.id === webhookId ? data.webhook : w
),
})
},
[mutate, publishedTypebot, typebot, webhooks]
)
const createWebhook = async (data: Partial<Webhook>) => {
if (!typebot) return
const response = await createWebhookQuery({
typebotId: typebot.id,
data,
})
if (!response.data?.webhook) return
mutate({
typebot,
publishedTypebot,
webhooks: (webhooks ?? []).concat(response.data?.webhook),
})
}
const duplicateWebhook = async (
existingWebhookId: string,
newWebhookId: string
) => {
if (!typebot) return
const { data } = await saveWebhookQuery(webhookId, updates)
if (data)
mutate({
typebot,
publishedTypebot,
webhooks: (webhooks ?? []).map((w) =>
w.id === webhookId ? data.webhook : w
),
})
const newWebhook = await duplicateWebhookQuery({
existingIds: {
typebotId: typebot.id,
webhookId: existingWebhookId,
},
newIds: {
typebotId: typebot.id,
webhookId: newWebhookId,
},
})
if (!newWebhook) return
mutate({
typebot,
publishedTypebot,
webhooks: (webhooks ?? []).concat(newWebhook),
})
}
return (
@ -343,8 +387,14 @@ export const TypebotProvider = ({
updateTypebot: updateLocalTypebot,
restorePublishedTypebot,
updateWebhook,
...groupsActions(setLocalTypebot as SetTypebot),
...blocksAction(setLocalTypebot as SetTypebot),
...groupsActions(setLocalTypebot as SetTypebot, {
onWebhookBlockCreated: createWebhook,
onWebhookBlockDuplicated: duplicateWebhook,
}),
...blocksAction(setLocalTypebot as SetTypebot, {
onWebhookBlockCreated: createWebhook,
onWebhookBlockDuplicated: duplicateWebhook,
}),
...variablesAction(setLocalTypebot as SetTypebot),
...edgesAction(setLocalTypebot as SetTypebot),
...itemsAction(setLocalTypebot as SetTypebot),

View File

@ -4,6 +4,7 @@ import {
DraggableBlock,
DraggableBlockType,
BlockIndices,
Webhook,
} from 'models'
import { WritableDraft } from 'immer/dist/types/types-external'
import { SetTypebot } from '../TypebotProvider'
@ -29,7 +30,18 @@ export type BlocksActions = {
deleteBlock: (indices: BlockIndices) => void
}
export const blocksAction = (setTypebot: SetTypebot): BlocksActions => ({
export type WebhookCallBacks = {
onWebhookBlockCreated: (data: Partial<Webhook>) => void
onWebhookBlockDuplicated: (
existingWebhookId: string,
newWebhookId: string
) => void
}
export const blocksAction = (
setTypebot: SetTypebot,
{ onWebhookBlockCreated, onWebhookBlockDuplicated }: WebhookCallBacks
): BlocksActions => ({
createBlock: (
groupId: string,
block: DraggableBlock | DraggableBlockType,
@ -37,7 +49,13 @@ export const blocksAction = (setTypebot: SetTypebot): BlocksActions => ({
) =>
setTypebot((typebot) =>
produce(typebot, (typebot) => {
createBlockDraft(typebot, block, groupId, indices)
createBlockDraft(
typebot,
block,
groupId,
indices,
onWebhookBlockCreated
)
})
),
updateBlock: (
@ -54,7 +72,10 @@ export const blocksAction = (setTypebot: SetTypebot): BlocksActions => ({
setTypebot((typebot) =>
produce(typebot, (typebot) => {
const block = { ...typebot.groups[groupIndex].blocks[blockIndex] }
const newBlock = duplicateBlockDraft(block.groupId)(block)
const newBlock = duplicateBlockDraft(block.groupId)(
block,
onWebhookBlockDuplicated
)
typebot.groups[groupIndex].blocks.splice(blockIndex + 1, 0, newBlock)
})
),
@ -81,7 +102,8 @@ export const createBlockDraft = (
typebot: WritableDraft<Typebot>,
block: DraggableBlock | DraggableBlockType,
groupId: string,
{ groupIndex, blockIndex }: BlockIndices
{ groupIndex, blockIndex }: BlockIndices,
onWebhookBlockCreated?: (data: Partial<Webhook>) => void
) => {
const blocks = typebot.groups[groupIndex].blocks
if (
@ -91,7 +113,13 @@ export const createBlockDraft = (
)
deleteEdgeDraft(typebot, blocks[blockIndex - 1].outgoingEdgeId as string)
typeof block === 'string'
? createNewBlock(typebot, block, groupId, { groupIndex, blockIndex })
? createNewBlock(
typebot,
block,
groupId,
{ groupIndex, blockIndex },
onWebhookBlockCreated
)
: moveBlockToGroup(typebot, block, groupId, { groupIndex, blockIndex })
removeEmptyGroups(typebot)
}
@ -100,10 +128,13 @@ const createNewBlock = async (
typebot: WritableDraft<Typebot>,
type: DraggableBlockType,
groupId: string,
{ groupIndex, blockIndex }: BlockIndices
{ groupIndex, blockIndex }: BlockIndices,
onWebhookBlockCreated?: (data: Partial<Webhook>) => void
) => {
const newBlock = parseNewBlock(type, groupId)
typebot.groups[groupIndex].blocks.splice(blockIndex ?? 0, 0, newBlock)
if (onWebhookBlockCreated && 'webhookId' in newBlock && newBlock.webhookId)
onWebhookBlockCreated({ id: newBlock.webhookId })
}
const moveBlockToGroup = (
@ -140,7 +171,10 @@ const moveBlockToGroup = (
export const duplicateBlockDraft =
(groupId: string) =>
(block: Block): Block => {
(
block: Block,
onWebhookBlockDuplicated: WebhookCallBacks['onWebhookBlockDuplicated']
): Block => {
const blockId = createId()
if (blockHasItems(block))
return {
@ -150,14 +184,17 @@ export const duplicateBlockDraft =
items: block.items.map(duplicateItemDraft(blockId)),
outgoingEdgeId: undefined,
} as Block
if (isWebhookBlock(block))
if (isWebhookBlock(block)) {
const newWebhookId = createId()
onWebhookBlockDuplicated(block.webhookId, newWebhookId)
return {
...block,
groupId,
id: blockId,
webhookId: createId(),
webhookId: newWebhookId,
outgoingEdgeId: undefined,
}
}
return {
...block,
groupId,

View File

@ -6,6 +6,7 @@ import {
deleteGroupDraft,
createBlockDraft,
duplicateBlockDraft,
WebhookCallBacks,
} from './blocks'
import { Coordinates } from '@/features/graph'
@ -22,7 +23,10 @@ export type GroupsActions = {
deleteGroup: (groupIndex: number) => void
}
const groupsActions = (setTypebot: SetTypebot): GroupsActions => ({
const groupsActions = (
setTypebot: SetTypebot,
{ onWebhookBlockCreated, onWebhookBlockDuplicated }: WebhookCallBacks
): GroupsActions => ({
createGroup: ({
id,
block,
@ -42,7 +46,13 @@ const groupsActions = (setTypebot: SetTypebot): GroupsActions => ({
blocks: [],
}
typebot.groups.push(newGroup)
createBlockDraft(typebot, block, newGroup.id, indices)
createBlockDraft(
typebot,
block,
newGroup.id,
indices,
onWebhookBlockCreated
)
})
),
updateGroup: (groupIndex: number, updates: Partial<Omit<Group, 'id'>>) =>
@ -61,7 +71,9 @@ const groupsActions = (setTypebot: SetTypebot): GroupsActions => ({
...group,
title: `${group.title} copy`,
id,
blocks: group.blocks.map(duplicateBlockDraft(id)),
blocks: group.blocks.map((block) =>
duplicateBlockDraft(id)(block, onWebhookBlockDuplicated)
),
graphCoordinates: {
x: group.graphCoordinates.x + 200,
y: group.graphCoordinates.y + 100,