Skip to content

Commit

Permalink
fix: 🚑️ Webhook and instant updates
Browse files Browse the repository at this point in the history
  • Loading branch information
baptisteArno committed Feb 22, 2022
1 parent 642a427 commit d49461c
Show file tree
Hide file tree
Showing 36 changed files with 314 additions and 201 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -91,13 +91,20 @@ export const BlockNode = ({ block, blockIndex }: Props) => {
})
}

const onDragStart = () => setIsMouseDown(true)
const onDragStop = () => setIsMouseDown(false)
return (
<ContextMenu<HTMLDivElement>
renderMenu={() => <BlockNodeContextMenu blockIndex={blockIndex} />}
isDisabled={isReadOnly}
>
{(ref, isOpened) => (
<DraggableCore onDrag={onDrag} onMouseDown={(e) => e.stopPropagation()}>
<DraggableCore
onDrag={onDrag}
onStart={onDragStart}
onStop={onDragStop}
onMouseDown={(e) => e.stopPropagation()}
>
<Stack
ref={setMultipleRefs([ref, blockRef])}
data-testid="block"
Expand Down
13 changes: 9 additions & 4 deletions apps/builder/contexts/TypebotContext/TypebotContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,14 @@ export const TypebotContext = ({
})

useEffect(() => {
if (!typebot || !localTypebot || deepEqual(typebot, localTypebot)) return
if (typebot?.blocks.length === localTypebot?.blocks.length)
setLocalTypebot({ ...typebot })
if (
!typebot ||
!localTypebot ||
typebot.updatedAt <= localTypebot.updatedAt ||
deepEqual(typebot, localTypebot)
)
return
setLocalTypebot({ ...typebot })
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [typebot])

Expand All @@ -113,8 +118,8 @@ export const TypebotContext = ({
] = useUndo<Typebot | undefined>(undefined)

const saveTypebot = async () => {
if (deepEqual(typebot, localTypebot)) return
const typebotToSave = currentTypebotRef.current
if (deepEqual(typebot, typebotToSave)) return
if (!typebotToSave) return
setIsSavingLoading(true)
const { error } = await updateTypebot(typebotToSave.id, typebotToSave)
Expand Down
3 changes: 2 additions & 1 deletion apps/builder/pages/api/coupons/redeem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
return res.status(401).json({ message: 'Not authenticated' })

const user = session.user as User
const { code } = JSON.parse(req.body)
const { code } =
typeof req.body === 'string' ? JSON.parse(req.body) : req.body
const coupon = await prisma.coupon.findFirst({
where: { code, dateRedeemed: null },
})
Expand Down
4 changes: 3 additions & 1 deletion apps/builder/pages/api/folders.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
return res.send({ folders })
}
if (req.method === 'POST') {
const data = JSON.parse(req.body) as Pick<DashboardFolder, 'parentFolderId'>
const data = (
typeof req.body === 'string' ? JSON.parse(req.body) : req.body
) as Pick<DashboardFolder, 'parentFolderId'>
const folder = await prisma.dashboardFolder.create({
data: { ...data, ownerId: user.id, name: 'New folder' },
})
Expand Down
4 changes: 3 additions & 1 deletion apps/builder/pages/api/folders/[id].ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
return res.send({ folders })
}
if (req.method === 'PATCH') {
const data = JSON.parse(req.body) as Partial<DashboardFolder>
const data = (
typeof req.body === 'string' ? JSON.parse(req.body) : req.body
) as Partial<DashboardFolder>
const folders = await prisma.dashboardFolder.update({
where: { id_ownerId: { id, ownerId: user.id } },
data,
Expand Down
5 changes: 3 additions & 2 deletions apps/builder/pages/api/integrations/email/test-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ import { createTransport } from 'nodemailer'

const handler = async (req: NextApiRequest, res: NextApiResponse) => {
if (req.method === 'POST') {
const { from, port, isTlsEnabled, username, password, host, to } =
JSON.parse(req.body) as SmtpCredentialsData & { to: string }
const { from, port, isTlsEnabled, username, password, host, to } = (
typeof req.body === 'string' ? JSON.parse(req.body) : req.body
) as SmtpCredentialsData & { to: string }
const transporter = createTransport({
host,
port,
Expand Down
3 changes: 2 additions & 1 deletion apps/builder/pages/api/publicTypebots.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {

try {
if (req.method === 'POST') {
const data = JSON.parse(req.body)
const data =
typeof req.body === 'string' ? JSON.parse(req.body) : req.body
const typebot = await prisma.publicTypebot.create({
data: { ...data },
})
Expand Down
2 changes: 1 addition & 1 deletion apps/builder/pages/api/publicTypebots/[id].ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {

const id = req.query.id.toString()
if (req.method === 'PUT') {
const data = JSON.parse(req.body)
const data = typeof req.body === 'string' ? JSON.parse(req.body) : req.body
const typebots = await prisma.publicTypebot.update({
where: { id },
data,
Expand Down
3 changes: 2 additions & 1 deletion apps/builder/pages/api/stripe/checkout.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY, {
apiVersion: '2020-08-27',
})
const { email, currency } = JSON.parse(req.body)
const { email, currency } =
typeof req.body === 'string' ? JSON.parse(req.body) : req.body
const session = await stripe.checkout.sessions.create({
success_url: `${req.headers.origin}/typebots?stripe=success`,
cancel_url: `${req.headers.origin}/typebots?stripe=cancel`,
Expand Down
3 changes: 2 additions & 1 deletion apps/builder/pages/api/typebots.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
return res.send({ typebots })
}
if (req.method === 'POST') {
const data = JSON.parse(req.body)
const data =
typeof req.body === 'string' ? JSON.parse(req.body) : req.body
const typebot = await prisma.typebot.create({
data:
'blocks' in data
Expand Down
4 changes: 2 additions & 2 deletions apps/builder/pages/api/typebots/[typebotId].ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
return res.send({ typebots })
}
if (req.method === 'PUT') {
const data = JSON.parse(req.body)
const data = typeof req.body === 'string' ? JSON.parse(req.body) : req.body
const typebots = await prisma.typebot.update({
where: { id_ownerId: { id: typebotId, ownerId: user.id } },
data: {
Expand All @@ -53,7 +53,7 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
return res.send({ typebots })
}
if (req.method === 'PATCH') {
const data = JSON.parse(req.body)
const data = typeof req.body === 'string' ? JSON.parse(req.body) : req.body
const typebots = await prisma.typebot.update({
where: { id_ownerId: { id: typebotId, ownerId: user.id } },
data,
Expand Down
2 changes: 1 addition & 1 deletion apps/builder/pages/api/users/[id].ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {

const id = req.query.id.toString()
if (req.method === 'PUT') {
const data = JSON.parse(req.body)
const data = typeof req.body === 'string' ? JSON.parse(req.body) : req.body
const typebots = await prisma.user.update({
where: { id },
data,
Expand Down
4 changes: 3 additions & 1 deletion apps/builder/pages/api/users/[id]/credentials.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
return res.send({ credentials })
}
if (req.method === 'POST') {
const data = JSON.parse(req.body) as Omit<Credentials, 'ownerId'>
const data = (
typeof req.body === 'string' ? JSON.parse(req.body) : req.body
) as Omit<Credentials, 'ownerId'>
const { encryptedData, iv } = encrypt(data.data)
const credentials = await prisma.credentials.create({
data: {
Expand Down
4 changes: 3 additions & 1 deletion apps/builder/pages/api/users/[id]/customDomains.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
return res.send({ customDomains })
}
if (req.method === 'POST') {
const data = JSON.parse(req.body) as Omit<CustomDomain, 'ownerId'>
const data = (
typeof req.body === 'string' ? JSON.parse(req.body) : req.body
) as Omit<CustomDomain, 'ownerId'>
try {
await createDomainOnVercel(data.name)
} catch (err) {
Expand Down
5 changes: 2 additions & 3 deletions apps/builder/playwright/services/database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ const createAnswers = () => {
const parseTypebotToPublicTypebot = (
id: string,
typebot: Typebot
): PublicTypebot => ({
): Omit<PublicTypebot, 'createdAt' | 'updatedAt'> => ({
id,
name: typebot.name,
blocks: parseBlocksToPublicBlocks(typebot.blocks),
Expand Down Expand Up @@ -157,10 +157,9 @@ const parseTestTypebot = (partialTypebot: Partial<Typebot>): Typebot => ({
ownerId: 'proUser',
theme: defaultTheme,
settings: defaultSettings,
createdAt: new Date(),
publicId: null,
publishedTypebotId: null,
updatedAt: new Date(),
publishedTypebotId: null,
customDomain: null,
variables: [{ id: 'var1', name: 'var1' }],
...partialTypebot,
Expand Down
2 changes: 1 addition & 1 deletion apps/builder/playwright/tests/customDomains.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import path from 'path'

const typebotId = generate()
test.describe('Dashboard page', () => {
test('folders navigation should work', async ({ page }) => {
test('should be able to connect custom domain', async ({ page }) => {
await createTypebots([
{
id: typebotId,
Expand Down
4 changes: 3 additions & 1 deletion apps/viewer/pages/api/answers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ import { methodNotAllowed } from 'utils'

const handler = async (req: NextApiRequest, res: NextApiResponse) => {
if (req.method === 'PUT') {
const answer = JSON.parse(req.body) as Answer
const answer = (
typeof req.body === 'string' ? JSON.parse(req.body) : req.body
) as Answer
const result = await prisma.answer.upsert({
where: {
resultId_blockId_stepId: {
Expand Down
4 changes: 2 additions & 2 deletions apps/viewer/pages/api/integrations/email.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ const defaultFrom = {
const handler = async (req: NextApiRequest, res: NextApiResponse) => {
await cors(req, res)
if (req.method === 'POST') {
const { credentialsId, recipients, body, subject, cc, bcc } = JSON.parse(
req.body
const { credentialsId, recipients, body, subject, cc, bcc } = (
typeof req.body === 'string' ? JSON.parse(req.body) : req.body
) as SendEmailOptions

const { host, port, isTlsEnabled, username, password, from } =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
if (req.method === 'POST') {
const spreadsheetId = req.query.spreadsheetId.toString()
const sheetId = req.query.sheetId.toString()
const { credentialsId, values } = JSON.parse(req.body) as {
const { credentialsId, values } = (
typeof req.body === 'string' ? JSON.parse(req.body) : req.body
) as {
credentialsId: string
values: { [key: string]: string }
}
Expand All @@ -51,7 +53,9 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
if (req.method === 'PATCH') {
const spreadsheetId = req.query.spreadsheetId.toString()
const sheetId = req.query.sheetId.toString()
const { credentialsId, values, referenceCell } = JSON.parse(req.body) as {
const { credentialsId, values, referenceCell } = (
typeof req.body === 'string' ? JSON.parse(req.body) : req.body
) as {
credentialsId: string
referenceCell: Cell
values: { [key: string]: string }
Expand Down
4 changes: 3 additions & 1 deletion apps/viewer/pages/api/results.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ import { methodNotAllowed } from 'utils'

const handler = async (req: NextApiRequest, res: NextApiResponse) => {
if (req.method === 'POST') {
const resultData = JSON.parse(req.body) as {
const resultData = (
typeof req.body === 'string' ? JSON.parse(req.body) : req.body
) as {
typebotId: string
prefilledVariables: VariableWithValue[]
}
Expand Down
4 changes: 3 additions & 1 deletion apps/viewer/pages/api/results/[id].ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ import { methodNotAllowed } from 'utils'

const handler = async (req: NextApiRequest, res: NextApiResponse) => {
if (req.method === 'PATCH') {
const data = JSON.parse(req.body) as { isCompleted: true }
const data = (
typeof req.body === 'string' ? JSON.parse(req.body) : req.body
) as { isCompleted: true }
const id = req.query.id.toString()
const result = await prisma.result.update({
where: { id },
Expand Down
Loading

2 comments on commit d49461c

@vercel
Copy link

@vercel vercel bot commented on d49461c Feb 22, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

builder-v2 – ./apps/builder

app.typebot.io
builder-v2-typebot-io.vercel.app
builder-v2-git-main-typebot-io.vercel.app

@vercel
Copy link

@vercel vercel bot commented on d49461c Feb 22, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.