2
0

🐛 (script) Execute client side actions before first bubbles

This commit is contained in:
Baptiste Arnaud
2023-02-27 18:30:20 +01:00
parent eaf8024c84
commit d5b8a43d3f
5 changed files with 20 additions and 27 deletions

View File

@ -1,7 +1,6 @@
import { FormLabel, Stack, Text } from '@chakra-ui/react' import { FormLabel, Stack, Text } from '@chakra-ui/react'
import { CodeEditor } from '@/components/CodeEditor' import { CodeEditor } from '@/components/CodeEditor'
import React from 'react' import React from 'react'
import { SwitchWithLabel } from '@/components/SwitchWithLabel'
import { Input } from '@/components/inputs' import { Input } from '@/components/inputs'
import { ScriptOptions } from 'models' import { ScriptOptions } from 'models'
@ -15,9 +14,6 @@ export const ScriptSettings = ({ options, onOptionsChange }: Props) => {
onOptionsChange({ ...options, name }) onOptionsChange({ ...options, name })
const handleCodeChange = (content: string) => const handleCodeChange = (content: string) =>
onOptionsChange({ ...options, content }) onOptionsChange({ ...options, content })
const handleShouldExecuteInParentContextChange = (
shouldExecuteInParentContext: boolean
) => onOptionsChange({ ...options, shouldExecuteInParentContext })
return ( return (
<Stack spacing={4}> <Stack spacing={4}>
@ -32,12 +28,6 @@ export const ScriptSettings = ({ options, onOptionsChange }: Props) => {
withVariableButton={false} withVariableButton={false}
/> />
</Stack> </Stack>
<SwitchWithLabel
label="Execute in parent window"
moreInfoContent="Execute the code in the parent window context (when the bot is embedded). If it isn't detected, the code will be executed in the current window context."
initialValue={options.shouldExecuteInParentContext ?? false}
onCheckChange={handleShouldExecuteInParentContextChange}
/>
<Stack> <Stack>
<Text>Code:</Text> <Text>Code:</Text>
<CodeEditor <CodeEditor

View File

@ -162,18 +162,6 @@ test('API chat execution should work on published bot', async ({ request }) => {
expect(input.type).toBe('choice input') expect(input.type).toBe('choice input')
}) })
await test.step('Answer Buttons question with invalid choice', async () => {
const { messages, input } = await (
await request.post(`/api/v1/sendMessage`, {
data: { message: 'Yolo', sessionId: chatSessionId },
})
).json()
expect(messages[0].content.plainText).toBe(
'Invalid message. Please, try again.'
)
expect(input.type).toBe('choice input')
})
await test.step('Answer Buttons question with invalid choice', async () => { await test.step('Answer Buttons question with invalid choice', async () => {
const { messages } = await ( const { messages } = await (
await request.post(`/api/v1/sendMessage`, { await request.post(`/api/v1/sendMessage`, {

View File

@ -1,6 +1,6 @@
{ {
"name": "@typebot.io/js", "name": "@typebot.io/js",
"version": "0.0.15", "version": "0.0.16",
"description": "Javascript library to display typebots on your website", "description": "Javascript library to display typebots on your website",
"type": "module", "type": "module",
"main": "dist/index.js", "main": "dist/index.js",

View File

@ -1,5 +1,5 @@
import type { ChatReply, Theme } from 'models' import type { ChatReply, Theme } from 'models'
import { createEffect, createSignal, For, Show } from 'solid-js' import { createEffect, createSignal, For, onMount, Show } from 'solid-js'
import { sendMessageQuery } from '@/queries/sendMessageQuery' import { sendMessageQuery } from '@/queries/sendMessageQuery'
import { ChatChunk } from './ChatChunk' import { ChatChunk } from './ChatChunk'
import { BotContext, InitialChatReply, OutgoingLog } from '@/types' import { BotContext, InitialChatReply, OutgoingLog } from '@/types'
@ -60,6 +60,21 @@ export const ConversationContainer = (props: Props) => {
const [isSending, setIsSending] = createSignal(false) const [isSending, setIsSending] = createSignal(false)
const [blockedPopupUrl, setBlockedPopupUrl] = createSignal<string>() const [blockedPopupUrl, setBlockedPopupUrl] = createSignal<string>()
onMount(() => {
;(async () => {
const initialChunk = chatChunks()[0]
if (initialChunk.clientSideActions) {
const actionsBeforeFirstBubble = initialChunk.clientSideActions.filter(
(action) => isNotDefined(action.lastBubbleBlockId)
)
for (const action of actionsBeforeFirstBubble) {
const response = await executeClientSideAction(action)
if (response) setBlockedPopupUrl(response.blockedPopupUrl)
}
}
})()
})
createEffect(() => { createEffect(() => {
setTheme( setTheme(
parseDynamicTheme(props.initialChatReply.typebot.theme, dynamicTheme()) parseDynamicTheme(props.initialChatReply.typebot.theme, dynamicTheme())
@ -90,10 +105,10 @@ export const ConversationContainer = (props: Props) => {
}) })
} }
if (data.clientSideActions) { if (data.clientSideActions) {
const actionsToExecute = data.clientSideActions.filter((action) => const actionsBeforeFirstBubble = data.clientSideActions.filter((action) =>
isNotDefined(action.lastBubbleBlockId) isNotDefined(action.lastBubbleBlockId)
) )
for (const action of actionsToExecute) { for (const action of actionsBeforeFirstBubble) {
const response = await executeClientSideAction(action) const response = await executeClientSideAction(action)
if (response) setBlockedPopupUrl(response.blockedPopupUrl) if (response) setBlockedPopupUrl(response.blockedPopupUrl)
} }

View File

@ -1,6 +1,6 @@
{ {
"name": "@typebot.io/react", "name": "@typebot.io/react",
"version": "0.0.15", "version": "0.0.16",
"description": "React library to display typebots on your website", "description": "React library to display typebots on your website",
"main": "dist/index.js", "main": "dist/index.js",
"types": "dist/index.d.ts", "types": "dist/index.d.ts",