2
0

📝 (embed) Add new script embed instructions

This commit is contained in:
Baptiste Arnaud
2023-02-25 10:16:57 +01:00
parent 8034ceeede
commit 2b2b1c3d6d
8 changed files with 211 additions and 0 deletions

View File

@ -24,6 +24,8 @@ import {
WixModal,
} from './modals'
import { OtherModal } from './modals/OtherModal'
import { ScriptIcon } from '@/features/blocks/logic/script'
import { ScriptModal } from './modals/Script/ScriptModal'
export type ModalProps = {
publicId: string
@ -112,6 +114,14 @@ export const integrationsList = [
{...props}
/>
),
(props: Pick<ModalProps, 'publicId' | 'isPublished'>) => (
<EmbedButton
logo={<ScriptIcon height={100} width="70px" color="gray.300" />}
label="Script"
Modal={ScriptModal}
{...props}
/>
),
(props: Pick<ModalProps, 'publicId' | 'isPublished'>) => (
<EmbedButton
logo={<NotionLogo height={100} width="60px" />}

View File

@ -0,0 +1,25 @@
import React, { useState } from 'react'
import { ModalProps } from '../../EmbedButton'
import { EmbedModal } from '../../EmbedModal'
import { isDefined } from '@udecode/plate-common'
import { ScriptInstructions } from './instructions/ScriptInstructions'
export const ScriptModal = ({ isOpen, onClose, isPublished }: ModalProps) => {
const [selectedEmbedType, setSelectedEmbedType] = useState<
'standard' | 'popup' | 'bubble' | undefined
>()
return (
<EmbedModal
titlePrefix="Script"
isOpen={isOpen}
onClose={onClose}
isPublished={isPublished}
onSelectEmbedType={setSelectedEmbedType}
selectedEmbedType={selectedEmbedType}
>
{isDefined(selectedEmbedType) && (
<ScriptInstructions type={selectedEmbedType} />
)}
</EmbedModal>
)
}

View File

@ -0,0 +1,55 @@
import { CodeEditor } from '@/components/CodeEditor'
import { useTypebot } from '@/features/editor'
import { isCloudProdInstance } from '@/utils/helpers'
import { Stack, Text } from '@chakra-ui/react'
import { BubbleProps } from '@typebot.io/js'
import { Typebot } from 'models'
import { useState } from 'react'
import { env, getViewerUrl } from 'utils'
import { BubbleSettings } from '../../../settings/BubbleSettings/BubbleSettings'
import { parseInlineScript, parseInitBubbleCode } from '../../../snippetParsers'
export const parseDefaultBubbleTheme = (typebot?: Typebot) => ({
button: {
backgroundColor: typebot?.theme.chat.buttons.backgroundColor,
iconColor: typebot?.theme.chat.buttons.color,
},
previewMessage: {
backgroundColor: typebot?.theme.general.background.content ?? 'white',
textColor: 'black',
},
})
export const ScriptBubbleInstructions = () => {
const { typebot } = useTypebot()
const [theme, setTheme] = useState<BubbleProps['theme']>(
parseDefaultBubbleTheme(typebot)
)
const [previewMessage, setPreviewMessage] =
useState<BubbleProps['previewMessage']>()
const scriptSnippet = parseInlineScript(
parseInitBubbleCode({
typebot: typebot?.publicId ?? '',
apiHost: isCloudProdInstance
? undefined
: env('VIEWER_INTERNAL_URL') ?? getViewerUrl(),
theme,
previewMessage,
})
)
return (
<Stack spacing={4}>
<BubbleSettings
theme={theme}
previewMessage={previewMessage}
defaultPreviewMessageAvatar={typebot?.theme.chat.hostAvatar?.url ?? ''}
onThemeChange={setTheme}
onPreviewMessageChange={setPreviewMessage}
/>
<Text>Run this script to initialize the typebot:</Text>
<CodeEditor isReadOnly value={scriptSnippet} lang="javascript" />
</Stack>
)
}

View File

@ -0,0 +1,21 @@
import { ScriptBubbleInstructions } from './ScriptBubbleInstructions'
import { ScriptPopupInstructions } from './ScriptPopupInstructions'
import { ScriptStandardInstructions } from './ScriptStandardInstructions'
type Props = {
type: 'standard' | 'popup' | 'bubble'
}
export const ScriptInstructions = ({ type }: Props) => {
switch (type) {
case 'standard': {
return <ScriptStandardInstructions />
}
case 'popup': {
return <ScriptPopupInstructions />
}
case 'bubble': {
return <ScriptBubbleInstructions />
}
}
}

View File

@ -0,0 +1,34 @@
import { CodeEditor } from '@/components/CodeEditor'
import { useTypebot } from '@/features/editor'
import { isCloudProdInstance } from '@/utils/helpers'
import { Stack, Text } from '@chakra-ui/react'
import { useState } from 'react'
import { env, getViewerUrl } from 'utils'
import { PopupSettings } from '../../../settings/PopupSettings'
import { parseInitPopupCode } from '../../../snippetParsers'
import { parseInlineScript } from '../../../snippetParsers/shared'
export const ScriptPopupInstructions = () => {
const { typebot } = useTypebot()
const [inputValue, setInputValue] = useState<number>()
const scriptSnippet = parseInlineScript(
parseInitPopupCode({
typebot: typebot?.publicId ?? '',
apiHost: isCloudProdInstance
? undefined
: env('VIEWER_INTERNAL_URL') ?? getViewerUrl(),
autoShowDelay: inputValue,
})
)
return (
<Stack spacing={4}>
<PopupSettings
onUpdateSettings={(settings) => setInputValue(settings.autoShowDelay)}
/>
<Text>Run this script to initialize the typebot:</Text>
<CodeEditor isReadOnly value={scriptSnippet} lang="javascript" />
</Stack>
)
}

View File

@ -0,0 +1,50 @@
import { CodeEditor } from '@/components/CodeEditor'
import { useTypebot } from '@/features/editor'
import { isCloudProdInstance } from '@/utils/helpers'
import { Stack, Code, Text } from '@chakra-ui/react'
import { useState } from 'react'
import { env, getViewerUrl } from 'utils'
import { StandardSettings } from '../../../settings/StandardSettings'
import { parseInitStandardCode } from '../../../snippetParsers/standard'
import { parseStandardElementCode } from '../../Javascript/JavascriptStandardSnippet'
import { parseInlineScript } from '../../../snippetParsers/shared'
export const ScriptStandardInstructions = () => {
const { typebot } = useTypebot()
const [inputValues, setInputValues] = useState<{
heightLabel: string
widthLabel?: string
}>({
heightLabel: '100%',
widthLabel: '100%',
})
const standardElementSnippet = parseStandardElementCode(
inputValues.widthLabel,
inputValues.heightLabel
)
const scriptSnippet = parseInlineScript(
parseInitStandardCode({
typebot: typebot?.publicId ?? '',
apiHost: isCloudProdInstance
? undefined
: env('VIEWER_INTERNAL_URL') ?? getViewerUrl(),
})
)
return (
<Stack spacing={4}>
<StandardSettings
onUpdateWindowSettings={(settings) => setInputValues({ ...settings })}
/>
<Text>
Make sure you have this <Code>typebot-standard</Code> element in your{' '}
<Code>{'<body>'}</Code>:
</Text>
<CodeEditor isReadOnly value={standardElementSnippet} lang="html" />
<Text>Then, run this script to initialize the typebot:</Text>
<CodeEditor isReadOnly value={scriptSnippet} lang="javascript" />
</Stack>
)
}

View File

@ -1,4 +1,6 @@
import { BotProps } from '@typebot.io/js'
import parserBabel from 'prettier/parser-babel'
import prettier from 'prettier/standalone'
import { isDefined } from 'utils'
export const parseStringParam = (fieldName: string, fieldValue?: string) =>
@ -30,3 +32,12 @@ export const parseReactBotProps = ({ typebot, apiHost }: BotProps) => {
}
export const typebotImportUrl = `https://cdn.jsdelivr.net/npm/@typebot.io/js@0.0.14/dist/web.js`
export const parseInlineScript = (script: string) =>
prettier.format(
`const typebotInitScript = document.createElement("script");
typebotInitScript.type = "module";
typebotInitScript.innerHTML = \`${script}\`;
document.body.append(typebotInitScript);`,
{ parser: 'babel', plugins: [parserBabel] }
)