-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Showing
39 changed files
with
826 additions
and
38 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
44 changes: 44 additions & 0 deletions
44
apps/builder/src/features/blocks/integrations/pixel/components/PixelLogo.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
import { IconProps, Icon } from '@chakra-ui/react' | ||
|
||
export const PixelLogo = (props: IconProps) => ( | ||
<Icon viewBox="0 0 288 191" fill="none" {...props}> | ||
<path | ||
d="M31.06 125.96C31.06 136.94 33.47 145.37 36.62 150.47C40.75 157.15 46.91 159.98 53.19 159.98C61.29 159.98 68.7 157.97 82.98 138.22C94.42 122.39 107.9 100.17 116.97 86.24L132.33 62.64C143 46.25 155.35 28.03 169.51 15.68C181.07 5.6 193.54 0 206.09 0C227.16 0 247.23 12.21 262.59 35.11C279.4 60.19 287.56 91.78 287.56 124.38C287.56 143.76 283.74 158 277.24 169.25C270.96 180.13 258.72 191 238.13 191V159.98C255.76 159.98 260.16 143.78 260.16 125.24C260.16 98.82 254 69.5 240.43 48.55C230.8 33.69 218.32 24.61 204.59 24.61C189.74 24.61 177.79 35.81 164.36 55.78C157.22 66.39 149.89 79.32 141.66 93.91L132.6 109.96C114.4 142.23 109.79 149.58 100.69 161.71C84.74 182.95 71.12 191 53.19 191C31.92 191 18.47 181.79 10.14 167.91C3.34 156.6 0 141.76 0 124.85L31.06 125.96Z" | ||
fill="#0081FB" | ||
/> | ||
<path | ||
d="M24.4902 37.3C38.7302 15.35 59.2802 0 82.8502 0C96.5002 0 110.07 4.04 124.24 15.61C139.74 28.26 156.26 49.09 176.87 83.42L184.26 95.74C202.1 125.46 212.25 140.75 218.19 147.96C225.83 157.22 231.18 159.98 238.13 159.98C255.76 159.98 260.16 143.78 260.16 125.24L287.56 124.38C287.56 143.76 283.74 158 277.24 169.25C270.96 180.13 258.72 191 238.13 191C225.33 191 213.99 188.22 201.45 176.39C191.81 167.31 180.54 151.18 171.87 136.68L146.08 93.6C133.14 71.98 121.27 55.86 114.4 48.56C107.01 40.71 97.5102 31.23 82.3502 31.23C70.0802 31.23 59.6602 39.84 50.9402 53.01L24.4902 37.3Z" | ||
fill="url(#paint0_linear_1302_7)" | ||
/> | ||
<path | ||
d="M82.35 31.23C70.08 31.23 59.66 39.84 50.94 53.01C38.61 71.62 31.06 99.34 31.06 125.96C31.06 136.94 33.47 145.37 36.62 150.47L10.14 167.91C3.34 156.6 0 141.76 0 124.85C0 94.1 8.44 62.05 24.49 37.3C38.73 15.35 59.28 0 82.85 0L82.35 31.23Z" | ||
fill="url(#paint1_linear_1302_7)" | ||
/> | ||
<defs> | ||
<linearGradient | ||
id="paint0_linear_1302_7" | ||
x1="61.0002" | ||
y1="117" | ||
x2="259" | ||
y2="127" | ||
gradientUnits="userSpaceOnUse" | ||
> | ||
<stop stop-color="#0064E1" /> | ||
<stop offset="0.4" stop-color="#0064E1" /> | ||
<stop offset="0.83" stop-color="#0073EE" /> | ||
<stop offset="1" stop-color="#0082FB" /> | ||
</linearGradient> | ||
<linearGradient | ||
id="paint1_linear_1302_7" | ||
x1="45" | ||
y1="139" | ||
x2="45" | ||
y2="66" | ||
gradientUnits="userSpaceOnUse" | ||
> | ||
<stop stop-color="#0082FB" /> | ||
<stop offset="1" stop-color="#0064E0" /> | ||
</linearGradient> | ||
</defs> | ||
</Icon> | ||
) |
20 changes: 20 additions & 0 deletions
20
apps/builder/src/features/blocks/integrations/pixel/components/PixelNodeBody.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import React from 'react' | ||
import { Text } from '@chakra-ui/react' | ||
import { PixelBlock } from '@typebot.io/schemas' | ||
|
||
type Props = { | ||
options: PixelBlock['options'] | ||
} | ||
|
||
export const PixelNodeBody = ({ options }: Props) => ( | ||
<Text | ||
color={options.eventType || options.pixelId ? 'currentcolor' : 'gray.500'} | ||
noOfLines={1} | ||
> | ||
{options.eventType | ||
? `Track "${options.eventType}"` | ||
: options.pixelId | ||
? 'Init Pixel' | ||
: 'Configure...'} | ||
</Text> | ||
) |
185 changes: 185 additions & 0 deletions
185
apps/builder/src/features/blocks/integrations/pixel/components/PixelSettings.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,185 @@ | ||
import { DropdownList } from '@/components/DropdownList' | ||
import { SwitchWithRelatedSettings } from '@/components/SwitchWithRelatedSettings' | ||
import { TableList, TableListItemProps } from '@/components/TableList' | ||
import { TextLink } from '@/components/TextLink' | ||
import { TextInput } from '@/components/inputs' | ||
import { CodeEditor } from '@/components/inputs/CodeEditor' | ||
import { Select } from '@/components/inputs/Select' | ||
import { Stack, Text } from '@chakra-ui/react' | ||
import { isDefined, isEmpty } from '@typebot.io/lib' | ||
import { | ||
PixelBlock, | ||
pixelEventTypes, | ||
pixelObjectProperties, | ||
} from '@typebot.io/schemas' | ||
import React, { useMemo } from 'react' | ||
|
||
const pixelReferenceUrl = | ||
'https://developers.facebook.com/docs/meta-pixel/reference#standard-events' | ||
|
||
type Props = { | ||
options?: PixelBlock['options'] | ||
onOptionsChange: (options: PixelBlock['options']) => void | ||
} | ||
|
||
type Item = NonNullable<PixelBlock['options']['params']>[number] | ||
|
||
export const PixelSettings = ({ options, onOptionsChange }: Props) => { | ||
const updatePixelId = (pixelId: string) => | ||
onOptionsChange({ | ||
...options, | ||
pixelId: isEmpty(pixelId) ? undefined : pixelId, | ||
}) | ||
|
||
const updateIsTrackingEventEnabled = (isChecked: boolean) => | ||
onOptionsChange({ | ||
...options, | ||
params: isChecked && !options?.params ? [] : undefined, | ||
}) | ||
|
||
const updateEventType = ( | ||
_: string | undefined, | ||
eventType?: (typeof pixelEventTypes)[number] | 'Custom' | ||
) => | ||
onOptionsChange({ | ||
...options, | ||
params: [], | ||
eventType, | ||
}) | ||
|
||
const updateParams = (params: PixelBlock['options']['params']) => | ||
onOptionsChange({ | ||
...options, | ||
params, | ||
}) | ||
|
||
const updateEventName = (name: string) => { | ||
if (options?.eventType !== 'Custom') return | ||
onOptionsChange({ | ||
...options, | ||
name: isEmpty(name) ? undefined : name, | ||
}) | ||
} | ||
|
||
const Item = useMemo( | ||
() => | ||
function Component(props: TableListItemProps<Item>) { | ||
return <ParamItem {...props} eventType={options?.eventType} /> | ||
}, | ||
[options?.eventType] | ||
) | ||
|
||
return ( | ||
<Stack spacing={4}> | ||
<TextInput | ||
defaultValue={options?.pixelId ?? ''} | ||
onChange={updatePixelId} | ||
withVariableButton={false} | ||
placeholder='Pixel ID (e.g. "123456789")' | ||
/> | ||
<SwitchWithRelatedSettings | ||
label={'Track event'} | ||
initialValue={isDefined(options?.params)} | ||
onCheckChange={updateIsTrackingEventEnabled} | ||
> | ||
<Text fontSize="sm" color="gray.500"> | ||
Read the{' '} | ||
<TextLink href={pixelReferenceUrl} isExternal> | ||
reference | ||
</TextLink>{' '} | ||
to better understand the available options. | ||
</Text> | ||
<Select | ||
items={['Custom', ...pixelEventTypes] as const} | ||
selectedItem={options?.eventType} | ||
placeholder="Select event type" | ||
onSelect={updateEventType} | ||
/> | ||
{options?.eventType === 'Custom' && ( | ||
<TextInput | ||
defaultValue={options.name ?? ''} | ||
onChange={updateEventName} | ||
placeholder="Event name" | ||
/> | ||
)} | ||
{options?.eventType && | ||
(options.eventType === 'Custom' || | ||
pixelObjectProperties.filter((prop) => | ||
prop.associatedEvents.includes(options.eventType) | ||
).length > 0) && ( | ||
<TableList | ||
initialItems={options?.params ?? []} | ||
Item={Item} | ||
onItemsChange={updateParams} | ||
addLabel="Add parameter" | ||
/> | ||
)} | ||
</SwitchWithRelatedSettings> | ||
</Stack> | ||
) | ||
} | ||
|
||
type ParamItemProps = { | ||
item: Item | ||
eventType: 'Custom' | (typeof pixelEventTypes)[number] | undefined | ||
onItemChange: (item: Item) => void | ||
} | ||
|
||
const ParamItem = ({ item, eventType, onItemChange }: ParamItemProps) => { | ||
const possibleObjectProps = | ||
eventType && eventType !== 'Custom' | ||
? pixelObjectProperties.filter((prop) => | ||
prop.associatedEvents.includes(eventType) | ||
) | ||
: [] | ||
|
||
const currentObject = possibleObjectProps.find( | ||
(prop) => prop.key === item.key | ||
) | ||
|
||
const updateKey = (key: string) => | ||
onItemChange({ | ||
...item, | ||
key, | ||
}) | ||
|
||
const updateValue = (value: string) => | ||
onItemChange({ | ||
...item, | ||
value, | ||
}) | ||
|
||
if (!eventType) return null | ||
|
||
return ( | ||
<Stack p="4" rounded="md" flex="1" borderWidth="1px"> | ||
{eventType === 'Custom' ? ( | ||
<TextInput | ||
defaultValue={item.key} | ||
onChange={updateKey} | ||
placeholder="Key" | ||
/> | ||
) : ( | ||
<DropdownList | ||
currentItem={item.key} | ||
items={possibleObjectProps.map((prop) => prop.key)} | ||
onItemSelect={updateKey} | ||
placeholder="Select key" | ||
/> | ||
)} | ||
{currentObject?.type === 'code' ? ( | ||
<CodeEditor | ||
lang={'javascript'} | ||
defaultValue={item.value} | ||
onChange={updateValue} | ||
/> | ||
) : ( | ||
<TextInput | ||
defaultValue={item.value} | ||
onChange={updateValue} | ||
placeholder="Value" | ||
/> | ||
)} | ||
</Stack> | ||
) | ||
} |
37 changes: 37 additions & 0 deletions
37
apps/builder/src/features/blocks/integrations/pixel/pixel.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import test, { expect } from '@playwright/test' | ||
import { createTypebots } from '@typebot.io/lib/playwright/databaseActions' | ||
import { parseDefaultGroupWithBlock } from '@typebot.io/lib/playwright/databaseHelpers' | ||
import { IntegrationBlockType } from '@typebot.io/schemas' | ||
import { createId } from '@paralleldrive/cuid2' | ||
|
||
test.describe('Pixel block', () => { | ||
test('its configuration should work', async ({ page }) => { | ||
const typebotId = createId() | ||
await createTypebots([ | ||
{ | ||
id: typebotId, | ||
...parseDefaultGroupWithBlock({ | ||
type: IntegrationBlockType.PIXEL, | ||
options: {}, | ||
}), | ||
}, | ||
]) | ||
|
||
await page.goto(`/typebots/${typebotId}/edit`) | ||
await page.click('text=Configure...') | ||
await page.getByPlaceholder('Pixel ID (e.g. "123456789")').fill('pixelid') | ||
await expect(page.getByText('Init Pixel')).toBeVisible() | ||
await page.getByText('Track event').click() | ||
await page.getByPlaceholder('Select event type').click() | ||
await page.getByRole('menuitem', { name: 'Lead' }).click() | ||
await expect(page.getByText('Track "Lead"')).toBeVisible() | ||
await page.getByRole('button', { name: 'Add parameter' }).click() | ||
await page.getByRole('button', { name: 'Select key' }).click() | ||
await page.getByRole('menuitem', { name: 'currency' }).click() | ||
await page.getByPlaceholder('Value').fill('USD') | ||
await page.getByRole('button', { name: 'Preview' }).click() | ||
await expect( | ||
page.getByText('Pixel is not enabled in Preview mode').nth(1) | ||
).toBeVisible() | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
033f8f9
There was a problem hiding this comment.
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:
landing-page-v2 – ./apps/landing-page
landing-page-v2-git-main-typebot-io.vercel.app
typebot.io
landing-page-v2-typebot-io.vercel.app
www.typebot.io
www.get-typebot.com
get-typebot.com
033f8f9
There was a problem hiding this comment.
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:
viewer-v2 – ./apps/viewer
tiger.cr8.ai
video.cr8.ai
yoda.riku.ai
zebra.cr8.ai
bemestar.club
bergamo.store
bot.krdfy.com
bot.tvbeat.it
cgcassets.com
cnvhub.com.br
facelabko.com
filmylogy.com
goldorayo.com
prenota.aldoemaria.it
revistasaudeemdia.com
sbutton.wpwakanda.com
talk.convobuilder.com
test.leadbooster.help
whats.laracardoso.com
zillabot.saaszilla.co
815639944.21000000.one
83720273.bouclidom.com
aplicacao.bmind.com.br
apply.ansuraniphone.my
bbutton.wpwwakanda.com
bolsamaisbrasil.app.br
bot.clubedotrader.club
bot.ilmuseoaiborghi.it
bot.louismarcondes.com
bot.pratikmandalia.com
bot.t20worldcup.com.au
bot2.mycompany.reviews
bot3.mycompany.reviews
bot4.mycompany.reviews
c23111azqw.nigerias.io
chat.footballmeetup.ie
dieta.barrettamario.it
felipewelington.com.br
form.bridesquadapp.com
form.searchcube.com.sg
gcase.barrettamario.it
help.giversforgood.com
info.clickasuransi.com
kodawariab736.skeep.it
michaeljackson.riku.ai
premium.kandabrand.com
report.gratirabbit.com
resume.gratirabbit.com
83242573.actualizar.xyz
87656003.actualizar.xyz
88152257.actualizar.xyz
91375310.actualizar.xyz
app.youvisitedthis.site
arrivalx2.wpwakanda.com
bot.blackboxtips.com.br
bot.hotelplayarimini.it
bot.upgradesolutions.eu
chat.bebesemcolicas.com
filial.socialcliques.me
help.comebackreward.com
link.venturasuceder.com
upload.atlasoutfittersk9.com
atendimento.martinarod.online
bot.brigadeirosemdrama.com.br
mdb.eventoequipe.progenbr.com
tuttirecepcao.fratucci.com.br
forms.escoladeautomacao.com.br
onboarding.libertydreamcare.ie
type.talitasouzamarques.com.br
agendamento.sergiolimajr.com.br
anamnese.clinicamegasjdr.com.br
bookings.littlepartymonkeys.com
bot.comercializadoraomicron.com
elevateyourmind.groovepages.com
viewer-v2-typebot-io.vercel.app
yourfeedback.comebackreward.com
baleia.testeeventos.progenbr.com
bot.cabin-rentals-of-georgia.net
chat.portaloficialautorizado.com
open.campus.bot.aalen.university
sondaggio.mosaicohairboutique.it
baleia.testegabinete.progenbr.com
chat.alfabetizacaobilingue.com.br
gerador.verificadordehospedes.com
personal-trainer.barrettamario.it
sondaggio.mosaicohairboutique.com
mdb.assessoria.ademir.progenbr.com
preagendamento.sergiolimajr.com.br
studiotecnicoimmobiliaremerelli.it
download.thailandmicespecialist.com
register.thailandmicespecialist.com
mdb.evento.equipeinterna.progenbr.com
bot.studiotecnicoimmobiliaremerelli.it
pesquisa.escolamodacomproposito.com.br
anamnese.clinicaramosodontologia.com.br
gabinete.baleia.formulario.progenbr.com
chrome-os-inquiry-system.itschromeos.com
viewer-v2-git-main-typebot-io.vercel.app
main-menu-for-itschromeos.itschromeos.com
mdb.assessoria.qrcode.ademir.progenbr.com
033f8f9
There was a problem hiding this comment.
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-git-main-typebot-io.vercel.app
builder-v2-typebot-io.vercel.app
033f8f9
There was a problem hiding this comment.
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:
docs – ./apps/docs
docs-typebot-io.vercel.app
docs-git-main-typebot-io.vercel.app
docs.typebot.io