Skip to content

Commit

Permalink
fix(webhook): 🐛 Sample result w/ multi input blocks
Browse files Browse the repository at this point in the history
  • Loading branch information
baptisteArno committed Mar 21, 2022
1 parent 5d3010d commit 7399140
Show file tree
Hide file tree
Showing 12 changed files with 421 additions and 202 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@
/* eslint-disable react/jsx-key */
import { Button, chakra, Checkbox, Flex, HStack, Text } from '@chakra-ui/react'
import { AlignLeftTextIcon } from 'assets/icons'
import { ResultHeaderCell } from 'models'
import React, { useEffect, useMemo, useRef } from 'react'
import { Hooks, useRowSelect, useTable } from 'react-table'
import { parseSubmissionsColumns, ResultHeaderCell } from 'services/typebots'
import { parseSubmissionsColumns } from 'services/typebots'
import { LoadingRows } from './LoadingRows'

type SubmissionsTableProps = {
Expand Down
3 changes: 1 addition & 2 deletions apps/builder/layouts/results/SubmissionContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,13 @@ import {
deleteAllResults,
deleteResults,
getAllResults,
parseResultHeader,
useResults,
} from 'services/typebots'
import { unparse } from 'papaparse'
import { UnlockProPlanInfo } from 'components/shared/Info'
import { LogsModal } from './LogsModal'
import { useTypebot } from 'contexts/TypebotContext'
import { isDefined } from 'utils'
import { isDefined, parseResultHeader } from 'utils'

type Props = {
typebotId: string
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
{
"id": "cl10u677f0075a01a6xgl6phe",
"createdAt": "2022-03-21T15:01:46.107Z",
"updatedAt": "2022-03-21T15:03:07.312Z",
"name": "My typebot",
"ownerId": "cl10hgjy90000lm1a1gyccuqj",
"publishedTypebotId": null,
"folderId": null,
"blocks": [
{
"id": "cl10u677d0000a01aa4g4aazg",
"steps": [
{
"id": "cl10u677d0001a01a0xfo3d11",
"type": "start",
"label": "Start",
"blockId": "cl10u677d0000a01aa4g4aazg",
"outgoingEdgeId": "cl10u6cw500052e6dq284zju3"
}
],
"title": "Start",
"graphCoordinates": { "x": 0, "y": 0 }
},
{
"id": "cl10u68pw00032e6depze2oiy",
"graphCoordinates": { "x": 353, "y": 121 },
"title": "Block #1",
"steps": [
{
"id": "cl10u68q000042e6dhdipu2wg",
"blockId": "cl10u68pw00032e6depze2oiy",
"type": "text",
"content": {
"html": "<div>Hi how are you?</div>",
"richText": [
{ "type": "p", "children": [{ "text": "Hi how are you?" }] }
],
"plainText": "Hi how are you?"
}
},
{
"id": "cl10u6ey300062e6dea9ikpko",
"blockId": "cl10u68pw00032e6depze2oiy",
"type": "text input",
"options": {
"isLong": false,
"labels": { "button": "Send", "placeholder": "Type your answer..." }
},
"outgoingEdgeId": "cl10u7ax4000g2e6dkqoq18kp"
}
]
},
{
"id": "cl10u6jzd00072e6dvo0zwy0s",
"graphCoordinates": { "x": 691, "y": 127 },
"title": "Block #2",
"steps": [
{
"id": "cl10u6jzt00082e6dgw1piz0q",
"blockId": "cl10u6jzd00072e6dvo0zwy0s",
"type": "text",
"content": {
"html": "<div>How old are you?</div>",
"richText": [
{ "type": "p", "children": [{ "text": "How old are you?" }] }
],
"plainText": "How old are you?"
}
},
{
"id": "cl10u6qa300092e6dh5izz7ig",
"blockId": "cl10u6jzd00072e6dvo0zwy0s",
"type": "number input",
"options": {
"labels": { "button": "Send", "placeholder": "Type a number..." }
}
},
{
"id": "cl10u6vbo000a2e6davz2hfw7",
"blockId": "cl10u6jzd00072e6dvo0zwy0s",
"type": "text",
"content": {
"html": "<div>Do you like cookies?</div>",
"richText": [
{ "type": "p", "children": [{ "text": "Do you like cookies?" }] }
],
"plainText": "Do you like cookies?"
}
},
{
"id": "cl10u6zk0000b2e6dvabq067r",
"blockId": "cl10u6jzd00072e6dvo0zwy0s",
"type": "choice input",
"options": { "buttonLabel": "Send", "isMultipleChoice": false },
"items": [
{
"id": "cl10u6zk1000c2e6d0d4ivgcl",
"stepId": "cl10u6zk0000b2e6dvabq067r",
"type": 0,
"content": "Yes"
},
{
"stepId": "cl10u6zk0000b2e6dvabq067r",
"type": 0,
"id": "cl10u70gi000d2e6d924ywjsb",
"content": "No"
}
]
},
{
"id": "cl10u759h000f2e6d0rhfwep4",
"blockId": "cl10u6jzd00072e6dvo0zwy0s",
"type": "text",
"content": {
"html": "<div>Alright, cheers!</div>",
"richText": [
{ "type": "p", "children": [{ "text": "Alright, cheers!" }] }
],
"plainText": "Alright, cheers!"
}
},
{
"id": "cl10u7i6n000h2e6d537h38pg",
"blockId": "cl10u6jzd00072e6dvo0zwy0s",
"type": "Webhook",
"options": {
"responseVariableMapping": [],
"variablesForTest": [],
"isAdvancedConfig": false,
"isCustomBody": false
},
"webhookId": "webhook1"
}
]
}
],
"variables": [],
"edges": [
{
"from": {
"blockId": "cl10u677d0000a01aa4g4aazg",
"stepId": "cl10u677d0001a01a0xfo3d11"
},
"to": { "blockId": "cl10u68pw00032e6depze2oiy" },
"id": "cl10u6cw500052e6dq284zju3"
},
{
"from": {
"blockId": "cl10u68pw00032e6depze2oiy",
"stepId": "cl10u6ey300062e6dea9ikpko"
},
"to": { "blockId": "cl10u6jzd00072e6dvo0zwy0s" },
"id": "cl10u7ax4000g2e6dkqoq18kp"
}
],
"theme": {
"chat": {
"inputs": {
"color": "#303235",
"backgroundColor": "#FFFFFF",
"placeholderColor": "#9095A0"
},
"buttons": { "color": "#FFFFFF", "backgroundColor": "#0042DA" },
"hostBubbles": { "color": "#303235", "backgroundColor": "#F7F8FF" },
"guestBubbles": { "color": "#FFFFFF", "backgroundColor": "#FF8E21" }
},
"general": { "font": "Open Sans", "background": { "type": "None" } }
},
"settings": {
"general": {
"isBrandingEnabled": true,
"isInputPrefillEnabled": true,
"isNewResultOnRefreshEnabled": false
},
"metadata": {
"description": "Build beautiful conversational forms and embed them directly in your applications without a line of code. Triple your response rate and collect answers that has more value compared to a traditional form."
},
"typingEmulation": { "speed": 300, "enabled": true, "maxDelay": 1.5 }
},
"publicId": null,
"customDomain": null
}
7 changes: 5 additions & 2 deletions apps/builder/playwright/tests/integrations/webhook.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ test.describe('Webhook step', () => {
test('easy configuration should work', async ({ page }) => {
const typebotId = cuid()
await importTypebotInDatabase(
path.join(__dirname, '../../fixtures/typebots/integrations/webhook.json'),
path.join(
__dirname,
'../../fixtures/typebots/integrations/easyConfigWebhook.json'
),
{
id: typebotId,
}
Expand All @@ -22,7 +25,7 @@ test.describe('Webhook step', () => {
)
await page.click('text=Test the request')
await expect(page.locator('div[role="textbox"] >> nth=-1')).toContainText(
'"statusCode": 200'
`"Block #1": "answer value", "Block #2": "20", "Block #2 (1)": "Yes"`
)
})
test('Generated body should work', async ({ page }) => {
Expand Down
96 changes: 2 additions & 94 deletions apps/builder/services/typebots/results.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,8 @@
import {
Block,
InputStep,
InputStepType,
ResultWithAnswers,
Variable,
VariableWithValue,
} from 'models'
import { ResultWithAnswers, VariableWithValue, ResultHeaderCell } from 'models'
import useSWRInfinite from 'swr/infinite'
import { stringify } from 'qs'
import { Answer } from 'db'
import { byId, isDefined, isInputStep, sendRequest } from 'utils'
import { isDefined, sendRequest } from 'utils'
import { fetcher } from 'services/utils'
import { HStack, Text } from '@chakra-ui/react'
import { CodeIcon, CalendarIcon } from 'assets/icons'
Expand Down Expand Up @@ -110,14 +103,6 @@ type HeaderCell = {
accessor: string
}

export type ResultHeaderCell = {
label: string
stepId?: string
stepType?: InputStepType
isLong?: boolean
variableId?: string
}

export const parseSubmissionsColumns = (
resultHeader: ResultHeaderCell[]
): HeaderCell[] =>
Expand All @@ -140,83 +125,6 @@ const HeaderIcon = ({ header }: { header: ResultHeaderCell }) =>
<CalendarIcon />
)

export const parseResultHeader = ({
blocks,
variables,
}: {
blocks: Block[]
variables: Variable[]
}): ResultHeaderCell[] => {
const parsedBlocks = parseInputsResultHeader({ blocks, variables })
return [
{ label: 'Submitted at' },
...parsedBlocks,
...parseVariablesHeaders(variables, parsedBlocks),
]
}

const parseInputsResultHeader = ({
blocks,
variables,
}: {
blocks: Block[]
variables: Variable[]
}): ResultHeaderCell[] =>
(
blocks
.flatMap((b) =>
b.steps.map((s) => ({
...s,
blockTitle: b.title,
}))
)
.filter((step) => isInputStep(step)) as (InputStep & {
blockTitle: string
})[]
).reduce<ResultHeaderCell[]>((headers, inputStep) => {
if (
headers.find(
(h) =>
isDefined(h.variableId) &&
h.variableId ===
variables.find(byId(inputStep.options.variableId))?.id
)
)
return headers
const matchedVariableName =
inputStep.options.variableId &&
variables.find(byId(inputStep.options.variableId))?.name

let label = matchedVariableName ?? inputStep.blockTitle
const totalPrevious = headers.filter((h) => h.label.includes(label)).length
if (totalPrevious > 0) label = label + ` (${totalPrevious})`
return [
...headers,
{
stepType: inputStep.type,
stepId: inputStep.id,
variableId: inputStep.options.variableId,
label,
isLong: 'isLong' in inputStep.options && inputStep.options.isLong,
},
]
}, [])

const parseVariablesHeaders = (
variables: Variable[],
stepResultHeader: ResultHeaderCell[]
) =>
variables.reduce<ResultHeaderCell[]>((headers, v) => {
if (stepResultHeader.find((h) => h.variableId === v.id)) return headers
return [
...headers,
{
label: v.name,
variableId: v.id,
},
]
}, [])

export const convertResultsToTableData = (
results: ResultWithAnswers[] | undefined,
header: ResultHeaderCell[]
Expand Down
8 changes: 3 additions & 5 deletions apps/viewer/pages/api/typebots/[typebotId]/results.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import prisma from 'libs/prisma'
import { ResultWithAnswers, Typebot, VariableWithValue } from 'models'
import { ResultWithAnswers, VariableWithValue } from 'models'
import { NextApiRequest, NextApiResponse } from 'next'
import { authenticateUser } from 'services/api/utils'
import { methodNotAllowed, parseAnswers } from 'utils'
import { methodNotAllowed } from 'utils'

const handler = async (req: NextApiRequest, res: NextApiResponse) => {
if (req.method === 'GET') {
Expand All @@ -20,9 +20,7 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
take: limit,
include: { answers: true },
})) as unknown as ResultWithAnswers[]
return res.send({
results: results.map(parseAnswers(typebot as unknown as Typebot)),
})
return res.send({ results })
}
if (req.method === 'POST') {
const typebotId = req.query.typebotId as string
Expand Down
Loading

3 comments on commit 7399140

@vercel
Copy link

@vercel vercel bot commented on 7399140 Mar 21, 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

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

@vercel
Copy link

@vercel vercel bot commented on 7399140 Mar 21, 2022

Choose a reason for hiding this comment

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

@vercel
Copy link

@vercel vercel bot commented on 7399140 Mar 21, 2022

Please sign in to comment.