@@ -1,10 +1,10 @@
|
||||
import test, { expect } from '@playwright/test'
|
||||
import { createTypebots } from '@typebot.io/lib/playwright/databaseActions'
|
||||
import { parseDefaultGroupWithBlock } from '@typebot.io/lib/playwright/databaseHelpers'
|
||||
import { BubbleBlockType, defaultAudioBubbleContent } from '@typebot.io/schemas'
|
||||
import { createId } from '@paralleldrive/cuid2'
|
||||
import { getTestAsset } from '@/test/utils/playwright'
|
||||
import { proWorkspaceId } from '@typebot.io/lib/playwright/databaseSetup'
|
||||
import { BubbleBlockType } from '@typebot.io/schemas/features/blocks/bubbles/constants'
|
||||
|
||||
const audioSampleUrl =
|
||||
'https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3'
|
||||
@@ -16,7 +16,6 @@ test('should work as expected', async ({ page }) => {
|
||||
id: typebotId,
|
||||
...parseDefaultGroupWithBlock({
|
||||
type: BubbleBlockType.AUDIO,
|
||||
content: defaultAudioBubbleContent,
|
||||
}),
|
||||
},
|
||||
])
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
import { Button, Flex, HStack, Stack, Text } from '@chakra-ui/react'
|
||||
import { AudioBubbleContent } from '@typebot.io/schemas'
|
||||
import { TextInput } from '@/components/inputs'
|
||||
import { useState } from 'react'
|
||||
import { UploadButton } from '@/components/ImageUploadContent/UploadButton'
|
||||
import { SwitchWithLabel } from '@/components/inputs/SwitchWithLabel'
|
||||
import { useTranslate } from '@tolgee/react'
|
||||
import { FilePathUploadProps } from '@/features/upload/api/generateUploadUrl'
|
||||
import { AudioBubbleBlock } from '@typebot.io/schemas'
|
||||
import { defaultAudioBubbleContent } from '@typebot.io/schemas/features/blocks/bubbles/audio/constants'
|
||||
|
||||
type Props = {
|
||||
uploadFileProps: FilePathUploadProps
|
||||
content: AudioBubbleContent
|
||||
onContentChange: (content: AudioBubbleContent) => void
|
||||
content: AudioBubbleBlock['content']
|
||||
onContentChange: (content: AudioBubbleBlock['content']) => void
|
||||
}
|
||||
|
||||
export const AudioBubbleForm = ({
|
||||
@@ -64,7 +65,7 @@ export const AudioBubbleForm = ({
|
||||
placeholder={t(
|
||||
'editor.blocks.bubbles.audio.settings.worksWith.placeholder'
|
||||
)}
|
||||
defaultValue={content.url ?? ''}
|
||||
defaultValue={content?.url ?? ''}
|
||||
onChange={updateUrl}
|
||||
/>
|
||||
<Text fontSize="sm" color="gray.400" textAlign="center">
|
||||
@@ -75,7 +76,10 @@ export const AudioBubbleForm = ({
|
||||
</Stack>
|
||||
<SwitchWithLabel
|
||||
label={t('editor.blocks.bubbles.audio.settings.autoplay.label')}
|
||||
initialValue={content.isAutoplayEnabled ?? true}
|
||||
initialValue={
|
||||
content?.isAutoplayEnabled ??
|
||||
defaultAudioBubbleContent.isAutoplayEnabled
|
||||
}
|
||||
onCheckChange={updateAutoPlay}
|
||||
/>
|
||||
</Stack>
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { Text } from '@chakra-ui/react'
|
||||
import { AudioBubbleContent } from '@typebot.io/schemas'
|
||||
import { isDefined } from '@typebot.io/lib'
|
||||
import { useTranslate } from '@tolgee/react'
|
||||
import { AudioBubbleBlock } from '@typebot.io/schemas'
|
||||
|
||||
type Props = {
|
||||
url: AudioBubbleContent['url']
|
||||
url: NonNullable<AudioBubbleBlock['content']>['url']
|
||||
}
|
||||
|
||||
export const AudioBubbleNode = ({ url }: Props) => {
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import { TextInput, NumberInput } from '@/components/inputs'
|
||||
import { Stack, Text } from '@chakra-ui/react'
|
||||
import { EmbedBubbleContent } from '@typebot.io/schemas'
|
||||
import { EmbedBubbleBlock } from '@typebot.io/schemas'
|
||||
import { sanitizeUrl } from '@typebot.io/lib'
|
||||
import { useTranslate } from '@tolgee/react'
|
||||
import { defaultEmbedBubbleContent } from '@typebot.io/schemas/features/blocks/bubbles/embed/constants'
|
||||
|
||||
type Props = {
|
||||
content: EmbedBubbleContent
|
||||
onSubmit: (content: EmbedBubbleContent) => void
|
||||
content: EmbedBubbleBlock['content']
|
||||
onSubmit: (content: EmbedBubbleBlock['content']) => void
|
||||
}
|
||||
|
||||
export const EmbedUploadContent = ({ content, onSubmit }: Props) => {
|
||||
@@ -18,8 +19,9 @@ export const EmbedUploadContent = ({ content, onSubmit }: Props) => {
|
||||
onSubmit({ ...content, url: iframeUrl })
|
||||
}
|
||||
|
||||
const handleHeightChange = (height?: EmbedBubbleContent['height']) =>
|
||||
height && onSubmit({ ...content, height })
|
||||
const handleHeightChange = (
|
||||
height?: NonNullable<EmbedBubbleBlock['content']>['height']
|
||||
) => height && onSubmit({ ...content, height })
|
||||
|
||||
return (
|
||||
<Stack p="2" spacing={6}>
|
||||
@@ -38,7 +40,7 @@ export const EmbedUploadContent = ({ content, onSubmit }: Props) => {
|
||||
|
||||
<NumberInput
|
||||
label="Height:"
|
||||
defaultValue={content?.height}
|
||||
defaultValue={content?.height ?? defaultEmbedBubbleContent.height}
|
||||
onValueChange={handleHeightChange}
|
||||
suffix={t('editor.blocks.bubbles.embed.settings.numberInput.unit')}
|
||||
width="150px"
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import test, { expect } from '@playwright/test'
|
||||
import { BubbleBlockType, defaultEmbedBubbleContent } from '@typebot.io/schemas'
|
||||
import { createId } from '@paralleldrive/cuid2'
|
||||
import { createTypebots } from '@typebot.io/lib/playwright/databaseActions'
|
||||
import { parseDefaultGroupWithBlock } from '@typebot.io/lib/playwright/databaseHelpers'
|
||||
import { BubbleBlockType } from '@typebot.io/schemas/features/blocks/bubbles/constants'
|
||||
|
||||
const pdfSrc = 'https://www.orimi.com/pdf-test.pdf'
|
||||
const siteSrc = 'https://app.cal.com/baptistearno/15min'
|
||||
@@ -16,7 +16,6 @@ test.describe.parallel('Embed bubble block', () => {
|
||||
id: typebotId,
|
||||
...parseDefaultGroupWithBlock({
|
||||
type: BubbleBlockType.EMBED,
|
||||
content: defaultEmbedBubbleContent,
|
||||
}),
|
||||
},
|
||||
])
|
||||
|
||||
@@ -7,6 +7,7 @@ import { Stack } from '@chakra-ui/react'
|
||||
import { isDefined, isNotEmpty } from '@typebot.io/lib'
|
||||
import { ImageBubbleBlock } from '@typebot.io/schemas'
|
||||
import React, { useState } from 'react'
|
||||
import { defaultImageBubbleContent } from '@typebot.io/schemas/features/blocks/bubbles/image/constants'
|
||||
|
||||
type Props = {
|
||||
uploadFileProps: FilePathUploadProps
|
||||
@@ -21,7 +22,7 @@ export const ImageBubbleSettings = ({
|
||||
}: Props) => {
|
||||
const { t } = useTranslate()
|
||||
const [showClickLinkInput, setShowClickLinkInput] = useState(
|
||||
isNotEmpty(block.content.clickLink?.url)
|
||||
isNotEmpty(block.content?.clickLink?.url)
|
||||
)
|
||||
|
||||
const updateImage = (url: string) => {
|
||||
@@ -31,19 +32,19 @@ export const ImageBubbleSettings = ({
|
||||
const updateClickLinkUrl = (url: string) => {
|
||||
onContentChange({
|
||||
...block.content,
|
||||
clickLink: { ...block.content.clickLink, url },
|
||||
clickLink: { ...block.content?.clickLink, url },
|
||||
})
|
||||
}
|
||||
|
||||
const updateClickLinkAltText = (alt: string) => {
|
||||
onContentChange({
|
||||
...block.content,
|
||||
clickLink: { ...block.content.clickLink, alt },
|
||||
clickLink: { ...block.content?.clickLink, alt },
|
||||
})
|
||||
}
|
||||
|
||||
const toggleClickLink = () => {
|
||||
if (isDefined(block.content.clickLink) && showClickLinkInput) {
|
||||
if (isDefined(block.content?.clickLink) && showClickLinkInput) {
|
||||
onContentChange({ ...block.content, clickLink: undefined })
|
||||
}
|
||||
setShowClickLinkInput(!showClickLinkInput)
|
||||
@@ -55,6 +56,7 @@ export const ImageBubbleSettings = ({
|
||||
uploadFileProps={uploadFileProps}
|
||||
defaultUrl={block.content?.url}
|
||||
onSubmit={updateImage}
|
||||
excludedTabs={['emoji']}
|
||||
/>
|
||||
<Stack>
|
||||
<SwitchWithLabel
|
||||
@@ -68,14 +70,17 @@ export const ImageBubbleSettings = ({
|
||||
autoFocus
|
||||
placeholder="https://example.com"
|
||||
onChange={updateClickLinkUrl}
|
||||
defaultValue={block.content.clickLink?.url}
|
||||
defaultValue={block.content?.clickLink?.url}
|
||||
/>
|
||||
<TextInput
|
||||
placeholder={t(
|
||||
'editor.blocks.bubbles.image.switchWithLabel.onClick.placeholder'
|
||||
)}
|
||||
onChange={updateClickLinkAltText}
|
||||
defaultValue={block.content.clickLink?.alt}
|
||||
defaultValue={
|
||||
block.content?.clickLink?.alt ??
|
||||
defaultImageBubbleContent.clickLink.alt
|
||||
}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import test, { expect } from '@playwright/test'
|
||||
import { createTypebots } from '@typebot.io/lib/playwright/databaseActions'
|
||||
import { parseDefaultGroupWithBlock } from '@typebot.io/lib/playwright/databaseHelpers'
|
||||
import { BubbleBlockType, defaultImageBubbleContent } from '@typebot.io/schemas'
|
||||
import { createId } from '@paralleldrive/cuid2'
|
||||
import { getTestAsset } from '@/test/utils/playwright'
|
||||
import { proWorkspaceId } from '@typebot.io/lib/playwright/databaseSetup'
|
||||
import { BubbleBlockType } from '@typebot.io/schemas/features/blocks/bubbles/constants'
|
||||
|
||||
const unsplashImageSrc =
|
||||
'https://images.unsplash.com/photo-1504297050568-910d24c426d3?ixlib=rb-1.2.1&ixid=MnwxMjA3fDF8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1287&q=80'
|
||||
@@ -18,7 +18,6 @@ test.describe.parallel('Image bubble block', () => {
|
||||
id: typebotId,
|
||||
...parseDefaultGroupWithBlock({
|
||||
type: BubbleBlockType.IMAGE,
|
||||
content: defaultImageBubbleContent,
|
||||
}),
|
||||
},
|
||||
])
|
||||
@@ -44,7 +43,6 @@ test.describe.parallel('Image bubble block', () => {
|
||||
id: typebotId,
|
||||
...parseDefaultGroupWithBlock({
|
||||
type: BubbleBlockType.IMAGE,
|
||||
content: defaultImageBubbleContent,
|
||||
}),
|
||||
},
|
||||
])
|
||||
@@ -66,7 +64,6 @@ test.describe.parallel('Image bubble block', () => {
|
||||
id: typebotId,
|
||||
...parseDefaultGroupWithBlock({
|
||||
type: BubbleBlockType.IMAGE,
|
||||
content: defaultImageBubbleContent,
|
||||
}),
|
||||
},
|
||||
])
|
||||
|
||||
@@ -8,7 +8,7 @@ type Props = {
|
||||
}
|
||||
|
||||
export const TextBubbleContent = ({ block }: Props) => {
|
||||
const isEmpty = block.content.richText.length === 0
|
||||
const isEmpty = (block.content?.richText?.length ?? 0) === 0
|
||||
return (
|
||||
<Flex
|
||||
w="90%"
|
||||
@@ -17,7 +17,7 @@ export const TextBubbleContent = ({ block }: Props) => {
|
||||
className="slate-html-container"
|
||||
color={isEmpty ? 'gray.500' : 'inherit'}
|
||||
>
|
||||
{block.content.richText.map((element, idx) => (
|
||||
{block.content?.richText?.map((element, idx) => (
|
||||
<PlateBlock key={idx} element={element} />
|
||||
))}
|
||||
</Flex>
|
||||
|
||||
@@ -26,22 +26,32 @@ export const PlateText = ({
|
||||
|
||||
const PlateTextContent = ({ text }: { text: string }) => {
|
||||
const { typebot } = useTypebot()
|
||||
|
||||
return (
|
||||
<>
|
||||
{text.split(/\{\{(.*?\}\})/g).map((str, idx) => {
|
||||
if (str.endsWith('}}')) {
|
||||
const variableName = str.trim().slice(0, -2)
|
||||
const matchingVariable = typebot?.variables.find(
|
||||
(variable) => variable.name === variableName
|
||||
)
|
||||
if (!matchingVariable) return '{{' + str
|
||||
{text.split(/\{\{=(.*?=\}\})/g).map((str, idx) => {
|
||||
if (str.endsWith('=}}')) {
|
||||
return (
|
||||
<span className="slate-variable" key={idx}>
|
||||
{str.trim().slice(0, -2)}
|
||||
<span className="slate-inline-code" key={idx}>
|
||||
{str.trim().slice(0, -3)}
|
||||
</span>
|
||||
)
|
||||
}
|
||||
return str
|
||||
return str.split(/\{\{(.*?\}\})/g).map((str, idx) => {
|
||||
if (str.endsWith('}}')) {
|
||||
const variableName = str.trim().slice(0, -2)
|
||||
const matchingVariable = typebot?.variables.find(
|
||||
(variable) => variable.name === variableName
|
||||
)
|
||||
if (!matchingVariable) return '{{' + str
|
||||
return (
|
||||
<span className="slate-variable" key={idx}>
|
||||
{str.trim().slice(0, -2)}
|
||||
</span>
|
||||
)
|
||||
}
|
||||
return str
|
||||
})
|
||||
})}
|
||||
</>
|
||||
)
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import test, { expect } from '@playwright/test'
|
||||
import { createTypebots } from '@typebot.io/lib/playwright/databaseActions'
|
||||
import { parseDefaultGroupWithBlock } from '@typebot.io/lib/playwright/databaseHelpers'
|
||||
import { BubbleBlockType, defaultTextBubbleContent } from '@typebot.io/schemas'
|
||||
import { createId } from '@paralleldrive/cuid2'
|
||||
import { BubbleBlockType } from '@typebot.io/schemas/features/blocks/bubbles/constants'
|
||||
|
||||
test.describe('Text bubble block', () => {
|
||||
test('rich text features should work', async ({ page }) => {
|
||||
@@ -12,7 +12,6 @@ test.describe('Text bubble block', () => {
|
||||
id: typebotId,
|
||||
...parseDefaultGroupWithBlock({
|
||||
type: BubbleBlockType.TEXT,
|
||||
content: defaultTextBubbleContent,
|
||||
}),
|
||||
},
|
||||
])
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { useTranslate } from '@tolgee/react'
|
||||
import { Box, Text, Image } from '@chakra-ui/react'
|
||||
import { VideoBubbleBlock, VideoBubbleContentType } from '@typebot.io/schemas'
|
||||
import { VideoBubbleBlock } from '@typebot.io/schemas'
|
||||
import { VideoBubbleContentType } from '@typebot.io/schemas/features/blocks/bubbles/video/constants'
|
||||
|
||||
type Props = {
|
||||
block: VideoBubbleBlock
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
import { Stack, Text } from '@chakra-ui/react'
|
||||
import {
|
||||
VariableString,
|
||||
VideoBubbleContent,
|
||||
VideoBubbleContentType,
|
||||
} from '@typebot.io/schemas'
|
||||
import { VariableString, VideoBubbleBlock } from '@typebot.io/schemas'
|
||||
import { NumberInput, TextInput } from '@/components/inputs'
|
||||
import { useTranslate } from '@tolgee/react'
|
||||
import { parseVideoUrl } from '@typebot.io/lib/parseVideoUrl'
|
||||
import {
|
||||
VideoBubbleContentType,
|
||||
defaultVideoBubbleContent,
|
||||
} from '@typebot.io/schemas/features/blocks/bubbles/video/constants'
|
||||
|
||||
type Props = {
|
||||
content?: VideoBubbleContent
|
||||
onSubmit: (content: VideoBubbleContent) => void
|
||||
content?: VideoBubbleBlock['content']
|
||||
onSubmit: (content: VideoBubbleBlock['content']) => void
|
||||
}
|
||||
|
||||
export const VideoUploadContent = ({ content, onSubmit }: Props) => {
|
||||
@@ -47,7 +47,7 @@ export const VideoUploadContent = ({ content, onSubmit }: Props) => {
|
||||
{content?.type !== VideoBubbleContentType.URL && (
|
||||
<NumberInput
|
||||
label="Height:"
|
||||
defaultValue={content?.height ?? 400}
|
||||
defaultValue={content?.height ?? defaultVideoBubbleContent.height}
|
||||
onValueChange={updateHeight}
|
||||
suffix={t('editor.blocks.bubbles.video.settings.numberInput.unit')}
|
||||
width="150px"
|
||||
|
||||
@@ -1,12 +1,9 @@
|
||||
import test, { expect } from '@playwright/test'
|
||||
import { createTypebots } from '@typebot.io/lib/playwright/databaseActions'
|
||||
import { parseDefaultGroupWithBlock } from '@typebot.io/lib/playwright/databaseHelpers'
|
||||
import {
|
||||
BubbleBlockType,
|
||||
defaultVideoBubbleContent,
|
||||
VideoBubbleContentType,
|
||||
} from '@typebot.io/schemas'
|
||||
import { createId } from '@paralleldrive/cuid2'
|
||||
import { BubbleBlockType } from '@typebot.io/schemas/features/blocks/bubbles/constants'
|
||||
import { VideoBubbleContentType } from '@typebot.io/schemas/features/blocks/bubbles/video/constants'
|
||||
|
||||
const videoSrc =
|
||||
'http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerEscapes.mp4'
|
||||
@@ -22,7 +19,6 @@ test.describe.parallel('Video bubble block', () => {
|
||||
id: typebotId,
|
||||
...parseDefaultGroupWithBlock({
|
||||
type: BubbleBlockType.VIDEO,
|
||||
content: defaultVideoBubbleContent,
|
||||
}),
|
||||
},
|
||||
])
|
||||
|
||||
Reference in New Issue
Block a user