♻️ (builder) Change to features-centric folder structure
This commit is contained in:
committed by
Baptiste Arnaud
parent
3686465a85
commit
643571fe7d
@ -0,0 +1,18 @@
|
||||
import { Typebot } from 'models'
|
||||
import { sendRequest } from 'utils'
|
||||
|
||||
export const createTypebotQuery = async ({
|
||||
folderId,
|
||||
workspaceId,
|
||||
}: Pick<Typebot, 'folderId' | 'workspaceId'>) => {
|
||||
const typebot = {
|
||||
folderId,
|
||||
name: 'My typebot',
|
||||
workspaceId,
|
||||
}
|
||||
return sendRequest<Typebot>({
|
||||
url: `/api/typebots`,
|
||||
method: 'POST',
|
||||
body: typebot,
|
||||
})
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
import { sendRequest } from 'utils'
|
||||
|
||||
export const deleteTypebotQuery = async (id: string) =>
|
||||
sendRequest({
|
||||
url: `/api/typebots/${id}`,
|
||||
method: 'DELETE',
|
||||
})
|
@ -0,0 +1,8 @@
|
||||
import { Typebot } from 'models'
|
||||
import { sendRequest } from 'utils'
|
||||
|
||||
export const getTypebotQuery = (typebotId: string) =>
|
||||
sendRequest<{ typebot: Typebot }>({
|
||||
url: `/api/typebots/${typebotId}`,
|
||||
method: 'GET',
|
||||
})
|
@ -0,0 +1,134 @@
|
||||
import { duplicateWebhookQueries } from '@/features/blocks/integrations/webhook'
|
||||
import cuid from 'cuid'
|
||||
import { Plan } from 'db'
|
||||
import {
|
||||
ChoiceInputBlock,
|
||||
ConditionBlock,
|
||||
LogicBlockType,
|
||||
Typebot,
|
||||
} from 'models'
|
||||
import { blockHasItems, isDefined, isWebhookBlock, sendRequest } from 'utils'
|
||||
|
||||
export const importTypebotQuery = async (typebot: Typebot, userPlan: Plan) => {
|
||||
const { typebot: newTypebot, webhookIdsMapping } = duplicateTypebot(
|
||||
typebot,
|
||||
userPlan
|
||||
)
|
||||
const { data, error } = await sendRequest<Typebot>({
|
||||
url: `/api/typebots`,
|
||||
method: 'POST',
|
||||
body: newTypebot,
|
||||
})
|
||||
if (!data) return { data, error }
|
||||
const webhookBlocks = typebot.groups
|
||||
.flatMap((b) => b.blocks)
|
||||
.filter(isWebhookBlock)
|
||||
await Promise.all(
|
||||
webhookBlocks.map((s) =>
|
||||
duplicateWebhookQueries(
|
||||
newTypebot.id,
|
||||
s.webhookId,
|
||||
webhookIdsMapping.get(s.webhookId) as string
|
||||
)
|
||||
)
|
||||
)
|
||||
return { data, error }
|
||||
}
|
||||
|
||||
const duplicateTypebot = (
|
||||
typebot: Typebot,
|
||||
userPlan: Plan
|
||||
): { typebot: Typebot; webhookIdsMapping: Map<string, string> } => {
|
||||
const groupIdsMapping = generateOldNewIdsMapping(typebot.groups)
|
||||
const edgeIdsMapping = generateOldNewIdsMapping(typebot.edges)
|
||||
const webhookIdsMapping = generateOldNewIdsMapping(
|
||||
typebot.groups
|
||||
.flatMap((b) => b.blocks)
|
||||
.filter(isWebhookBlock)
|
||||
.map((s) => ({ id: s.webhookId }))
|
||||
)
|
||||
const id = cuid()
|
||||
return {
|
||||
typebot: {
|
||||
...typebot,
|
||||
id,
|
||||
name: `${typebot.name} copy`,
|
||||
publishedTypebotId: null,
|
||||
publicId: null,
|
||||
customDomain: null,
|
||||
groups: typebot.groups.map((b) => ({
|
||||
...b,
|
||||
id: groupIdsMapping.get(b.id) as string,
|
||||
blocks: b.blocks.map((s) => {
|
||||
const newIds = {
|
||||
groupId: groupIdsMapping.get(s.groupId) as string,
|
||||
outgoingEdgeId: s.outgoingEdgeId
|
||||
? edgeIdsMapping.get(s.outgoingEdgeId)
|
||||
: undefined,
|
||||
}
|
||||
if (
|
||||
s.type === LogicBlockType.TYPEBOT_LINK &&
|
||||
s.options.typebotId === 'current' &&
|
||||
isDefined(s.options.groupId)
|
||||
)
|
||||
return {
|
||||
...s,
|
||||
options: {
|
||||
...s.options,
|
||||
groupId: groupIdsMapping.get(s.options.groupId as string),
|
||||
},
|
||||
}
|
||||
if (blockHasItems(s))
|
||||
return {
|
||||
...s,
|
||||
items: s.items.map((item) => ({
|
||||
...item,
|
||||
outgoingEdgeId: item.outgoingEdgeId
|
||||
? (edgeIdsMapping.get(item.outgoingEdgeId) as string)
|
||||
: undefined,
|
||||
})),
|
||||
...newIds,
|
||||
} as ChoiceInputBlock | ConditionBlock
|
||||
if (isWebhookBlock(s)) {
|
||||
return {
|
||||
...s,
|
||||
webhookId: webhookIdsMapping.get(s.webhookId) as string,
|
||||
...newIds,
|
||||
}
|
||||
}
|
||||
return {
|
||||
...s,
|
||||
...newIds,
|
||||
}
|
||||
}),
|
||||
})),
|
||||
edges: typebot.edges.map((e) => ({
|
||||
...e,
|
||||
id: edgeIdsMapping.get(e.id) as string,
|
||||
from: {
|
||||
...e.from,
|
||||
groupId: groupIdsMapping.get(e.from.groupId) as string,
|
||||
},
|
||||
to: { ...e.to, groupId: groupIdsMapping.get(e.to.groupId) as string },
|
||||
})),
|
||||
settings:
|
||||
typebot.settings.general.isBrandingEnabled === false &&
|
||||
userPlan === Plan.FREE
|
||||
? {
|
||||
...typebot.settings,
|
||||
general: { ...typebot.settings.general, isBrandingEnabled: true },
|
||||
}
|
||||
: typebot.settings,
|
||||
createdAt: new Date().toISOString(),
|
||||
updatedAt: new Date().toISOString(),
|
||||
resultsTablePreferences: typebot.resultsTablePreferences ?? undefined,
|
||||
},
|
||||
webhookIdsMapping,
|
||||
}
|
||||
}
|
||||
|
||||
const generateOldNewIdsMapping = (itemWithId: { id: string }[]) => {
|
||||
const idsMapping: Map<string, string> = new Map()
|
||||
itemWithId.forEach((item) => idsMapping.set(item.id, cuid()))
|
||||
return idsMapping
|
||||
}
|
4
apps/builder/src/features/dashboard/queries/index.ts
Normal file
4
apps/builder/src/features/dashboard/queries/index.ts
Normal file
@ -0,0 +1,4 @@
|
||||
export * from './createTypebotQuery'
|
||||
export * from './deleteTypebotQuery'
|
||||
export * from './getTypebotQuery'
|
||||
export * from './importTypebotQuery'
|
Reference in New Issue
Block a user