From b7cdc0d14a83891786507f6cdf76339b320461c3 Mon Sep 17 00:00:00 2001
From: Baptiste Arnaud
Date: Wed, 22 Dec 2021 14:59:07 +0100
Subject: [PATCH] =?UTF-8?q?=F0=9F=9A=80=20Init=20preview=20and=20typebot?=
=?UTF-8?q?=20cotext=20in=20editor?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.gitignore | 1 +
apps/builder/assets/icons.tsx | 59 +
apps/builder/assets/styles/plate.css | 31 +
.../components/auth/SocialLoginButtons.tsx | 3 -
apps/builder/components/board/Board.tsx | 31 +-
.../board/StepTypesList/StepCard.tsx | 2 -
.../board/StepTypesList/StepIcon.tsx | 11 +-
.../board/StepTypesList/StepLabel.tsx | 7 +-
.../board/StepTypesList/StepTypesList.tsx | 4 +-
.../components/board/StepTypesList/index.tsx | 2 +-
.../board/graph/BlockNode/BlockNode.tsx | 92 +-
.../graph/BlockNode/BlockNodeContextMenu.tsx | 18 +
.../board/graph/BlockNode/StartBlockNode.tsx | 30 +-
.../BlockNode/StepNode/RightClickMenu.tsx | 24 +
.../graph/BlockNode/StepNode/StepContent.tsx | 31 +
.../graph/BlockNode/StepNode/StepNode.tsx | 231 +--
.../BlockNode/StepNode/StepNodeOverlay.tsx | 28 +
.../StepNode/TextEditor/TextEditor.tsx | 97 +
.../BlockNode/StepNode/TextEditor/ToolBar.tsx | 40 +
.../BlockNode/StepNode/TextEditor/index.tsx | 1 +
.../board/graph/BlockNode/StepNode/index.tsx | 3 +-
.../board/graph/BlockNode/StepsList.tsx | 14 +-
.../board/graph/Edges/DrawingEdge.tsx | 28 +-
.../components/board/graph/Edges/Edge.tsx | 24 +-
.../components/board/graph/Edges/Edges.tsx | 7 +-
apps/builder/components/board/graph/Graph.tsx | 37 +-
.../board/preview/PreviewDrawer.tsx | 119 ++
.../components/dashboard/FolderContent.tsx | 4 +-
.../dashboard/FolderContent/FolderButton.tsx | 1 -
.../dashboard/FolderContent/TypebotButton.tsx | 3 +-
.../FolderContent/TypebotButtonOverlay.tsx | 3 +-
.../components/modals/ConfirmModal.tsx | 2 +-
.../builder/components/shared/ContextMenu.tsx | 106 +
apps/builder/components/shared/KBar.tsx | 71 +
.../TypebotHeader/EditableTypebotName.tsx | 26 +
.../shared/TypebotHeader/SaveButton.tsx | 33 +
.../shared/TypebotHeader/TypebotHeader.tsx | 123 ++
.../components/shared/TypebotHeader/index.tsx | 1 +
.../shared/buttons/PublishButton.tsx | 9 +
apps/builder/contexts/EditorContext.tsx | 35 +
apps/builder/contexts/GraphContext.tsx | 176 +-
apps/builder/contexts/TypebotContext.tsx | 246 ++-
apps/builder/libs/chakra.ts | 5 -
apps/builder/libs/kbar.ts | 16 +
apps/builder/libs/plate.ts | 56 +
apps/builder/next.config.js | 6 -
apps/builder/package.json | 42 +-
apps/builder/pages/_app.tsx | 1 +
apps/builder/pages/api/typebots.ts | 64 +-
.../typebots/{[id].tsx => [id]/edit.tsx} | 21 +-
apps/builder/services/graph.ts | 55 +-
apps/builder/services/typebots.ts | 91 +-
apps/builder/services/utils.ts | 19 +
apps/viewer/next.config.js | 6 -
packages/bot-engine/.gitignore | 3 +-
packages/bot-engine/package.json | 33 +-
packages/bot-engine/postcss.config.js | 1 +
packages/bot-engine/rollup.config.js | 48 +
packages/bot-engine/src/assets/icons.tsx | 13 +
packages/bot-engine/src/assets/style.css | 384 ++++
.../ChatBlock/AvatarSideContainer.tsx | 50 +
.../src/components/ChatBlock/ChatBlock.tsx | 61 +
.../ChatBlock/ChatStep/ChatStep.tsx | 39 +
.../ChatStep/bubbles/GuestBubble.tsx | 20 +
.../ChatStep/bubbles/HostMessageBubble.tsx | 78 +
.../ChatStep/bubbles/TypingContent.tsx | 9 +
.../components/ChatBlock/ChatStep/index.tsx | 1 +
.../ChatBlock/ChatStep/inputs/TextInput.tsx | 46 +
.../src/components/ChatBlock/index.tsx | 1 +
.../src/components/ConversationContainer.tsx | 54 +
.../src/components/TypebotViewer.tsx | 38 +-
.../src/components/avatars/DefaultAvatar.tsx | 60 +
.../src/components/avatars/HostAvatar.tsx | 14 +
.../src/contexts/HostAvatarsContext.tsx | 38 +
.../src/contexts/ResultsContext.tsx | 50 +
.../src/contexts/TypebotContext.tsx | 27 +
packages/bot-engine/src/models/index.ts | 2 +
.../bot-engine/src/models/publicTypebot.ts | 10 +
packages/bot-engine/src/models/result.ts | 11 +
packages/bot-engine/src/models/typebot.ts | 37 +-
packages/bot-engine/src/services/utils.ts | 7 +
packages/bot-engine/src/style.css | 1 -
packages/bot-engine/tailwind.config.js | 8 +-
packages/db/package.json | 6 +-
.../migration.sql | 12 +
packages/db/prisma/schema.prisma | 3 +-
yarn.lock | 1805 +++++++++++++++--
87 files changed, 4431 insertions(+), 735 deletions(-)
create mode 100644 apps/builder/assets/styles/plate.css
create mode 100644 apps/builder/components/board/graph/BlockNode/BlockNodeContextMenu.tsx
create mode 100644 apps/builder/components/board/graph/BlockNode/StepNode/RightClickMenu.tsx
create mode 100644 apps/builder/components/board/graph/BlockNode/StepNode/StepContent.tsx
create mode 100644 apps/builder/components/board/graph/BlockNode/StepNode/StepNodeOverlay.tsx
create mode 100644 apps/builder/components/board/graph/BlockNode/StepNode/TextEditor/TextEditor.tsx
create mode 100644 apps/builder/components/board/graph/BlockNode/StepNode/TextEditor/ToolBar.tsx
create mode 100644 apps/builder/components/board/graph/BlockNode/StepNode/TextEditor/index.tsx
create mode 100644 apps/builder/components/board/preview/PreviewDrawer.tsx
create mode 100644 apps/builder/components/shared/ContextMenu.tsx
create mode 100644 apps/builder/components/shared/KBar.tsx
create mode 100644 apps/builder/components/shared/TypebotHeader/EditableTypebotName.tsx
create mode 100644 apps/builder/components/shared/TypebotHeader/SaveButton.tsx
create mode 100644 apps/builder/components/shared/TypebotHeader/TypebotHeader.tsx
create mode 100644 apps/builder/components/shared/TypebotHeader/index.tsx
create mode 100644 apps/builder/components/shared/buttons/PublishButton.tsx
create mode 100644 apps/builder/contexts/EditorContext.tsx
create mode 100644 apps/builder/libs/kbar.ts
create mode 100644 apps/builder/libs/plate.ts
delete mode 100644 apps/builder/next.config.js
rename apps/builder/pages/typebots/{[id].tsx => [id]/edit.tsx} (51%)
delete mode 100644 apps/viewer/next.config.js
create mode 100644 packages/bot-engine/postcss.config.js
create mode 100644 packages/bot-engine/rollup.config.js
create mode 100644 packages/bot-engine/src/assets/icons.tsx
create mode 100644 packages/bot-engine/src/assets/style.css
create mode 100644 packages/bot-engine/src/components/ChatBlock/AvatarSideContainer.tsx
create mode 100644 packages/bot-engine/src/components/ChatBlock/ChatBlock.tsx
create mode 100644 packages/bot-engine/src/components/ChatBlock/ChatStep/ChatStep.tsx
create mode 100644 packages/bot-engine/src/components/ChatBlock/ChatStep/bubbles/GuestBubble.tsx
create mode 100644 packages/bot-engine/src/components/ChatBlock/ChatStep/bubbles/HostMessageBubble.tsx
create mode 100644 packages/bot-engine/src/components/ChatBlock/ChatStep/bubbles/TypingContent.tsx
create mode 100644 packages/bot-engine/src/components/ChatBlock/ChatStep/index.tsx
create mode 100644 packages/bot-engine/src/components/ChatBlock/ChatStep/inputs/TextInput.tsx
create mode 100644 packages/bot-engine/src/components/ChatBlock/index.tsx
create mode 100644 packages/bot-engine/src/components/ConversationContainer.tsx
create mode 100644 packages/bot-engine/src/components/avatars/DefaultAvatar.tsx
create mode 100644 packages/bot-engine/src/components/avatars/HostAvatar.tsx
create mode 100644 packages/bot-engine/src/contexts/HostAvatarsContext.tsx
create mode 100644 packages/bot-engine/src/contexts/ResultsContext.tsx
create mode 100644 packages/bot-engine/src/contexts/TypebotContext.tsx
create mode 100644 packages/bot-engine/src/models/publicTypebot.ts
create mode 100644 packages/bot-engine/src/models/result.ts
create mode 100644 packages/bot-engine/src/services/utils.ts
delete mode 100644 packages/bot-engine/src/style.css
create mode 100644 packages/db/prisma/migrations/20211222135449_init_answers_field_in_result/migration.sql
diff --git a/.gitignore b/.gitignore
index dd141b6aa..0317e5179 100644
--- a/.gitignore
+++ b/.gitignore
@@ -34,3 +34,4 @@ workspace.code-workspace
.DS_Store
.turbo
+apps/builder/tsconfig.tsbuildinfo
diff --git a/apps/builder/assets/icons.tsx b/apps/builder/assets/icons.tsx
index a15f0df5e..9cebf0eae 100644
--- a/apps/builder/assets/icons.tsx
+++ b/apps/builder/assets/icons.tsx
@@ -7,6 +7,9 @@ const featherIconsBaseProps: IconProps = {
strokeLinecap: 'round',
strokeLinejoin: 'round',
}
+
+// 99% of these icons are from Feather icons (https://feathericons.com/)
+
export const SettingsIcon = (props: IconProps) => (
@@ -102,3 +105,59 @@ export const FlagIcon = (props: IconProps) => (
)
+
+export const BoldIcon = (props: IconProps) => (
+
+
+
+
+)
+
+export const ItalicIcon = (props: IconProps) => (
+
+
+
+
+
+)
+
+export const UnderlineIcon = (props: IconProps) => (
+
+
+
+
+)
+
+export const LinkIcon = (props: IconProps) => (
+
+
+
+
+)
+
+export const SaveIcon = (props: IconProps) => (
+
+
+
+
+
+)
+
+export const CheckIcon = (props: IconProps) => (
+
+
+
+)
+
+export const ChatIcon = (props: IconProps) => (
+
+
+
+)
+
+export const TrashIcon = (props: IconProps) => (
+
+
+
+
+)
diff --git a/apps/builder/assets/styles/plate.css b/apps/builder/assets/styles/plate.css
new file mode 100644
index 000000000..cf36697c2
--- /dev/null
+++ b/apps/builder/assets/styles/plate.css
@@ -0,0 +1,31 @@
+.slate-bold {
+ font-weight: bold;
+}
+
+.slate-italic {
+ font-style: oblique;
+}
+
+.slate-underline {
+ text-decoration: underline;
+}
+
+.slate-ToolbarButton-active {
+ color: blue !important;
+}
+.slate-ToolbarButton-active > svg {
+ stroke-width: 2px;
+}
+
+.slate-ToolbarButton {
+ color: gray;
+}
+
+.slate-a {
+ color: blue !important;
+ text-decoration: underline;
+}
+
+.slate-html-container > div {
+ min-height: 24px;
+}
diff --git a/apps/builder/components/auth/SocialLoginButtons.tsx b/apps/builder/components/auth/SocialLoginButtons.tsx
index ca6313585..387303ca4 100644
--- a/apps/builder/components/auth/SocialLoginButtons.tsx
+++ b/apps/builder/components/auth/SocialLoginButtons.tsx
@@ -16,7 +16,6 @@ export const SocialLoginButtons = () => {
}
- colorScheme="gray"
onClick={handleGitHubClick}
data-testid="github"
isLoading={['loading', 'authenticated'].includes(status)}
@@ -25,7 +24,6 @@ export const SocialLoginButtons = () => {
}
- colorScheme="gray"
onClick={handleGoogleClick}
data-testid="google"
isLoading={['loading', 'authenticated'].includes(status)}
@@ -34,7 +32,6 @@ export const SocialLoginButtons = () => {
}
- colorScheme="gray"
onClick={handleFacebookClick}
data-testid="facebook"
isLoading={['loading', 'authenticated'].includes(status)}
diff --git a/apps/builder/components/board/Board.tsx b/apps/builder/components/board/Board.tsx
index 6e4f45538..ae4f34d2c 100644
--- a/apps/builder/components/board/Board.tsx
+++ b/apps/builder/components/board/Board.tsx
@@ -2,13 +2,26 @@ import { Flex } from '@chakra-ui/react'
import React from 'react'
import Graph from './graph/Graph'
import { DndContext } from 'contexts/DndContext'
-import StepTypesList from './StepTypesList'
+import { headerHeight } from 'components/shared/TypebotHeader/TypebotHeader'
+import { StepTypesList } from './StepTypesList'
+import { PreviewDrawer } from './preview/PreviewDrawer'
+import { RightPanel, useEditor } from 'contexts/EditorContext'
-export const Board = () => (
-
-
-
-
-
-
-)
+export const Board = () => {
+ const { rightPanel } = useEditor()
+ return (
+
+
+
+
+ {rightPanel === RightPanel.PREVIEW && }
+
+
+ )
+}
diff --git a/apps/builder/components/board/StepTypesList/StepCard.tsx b/apps/builder/components/board/StepTypesList/StepCard.tsx
index ba5a0fc25..e5274fdf9 100644
--- a/apps/builder/components/board/StepTypesList/StepCard.tsx
+++ b/apps/builder/components/board/StepTypesList/StepCard.tsx
@@ -29,7 +29,6 @@ export const StepCard = ({
rounded="lg"
flex="1"
cursor={'grab'}
- colorScheme="gray"
opacity={isMouseDown ? '0.4' : '1'}
onMouseDown={handleMouseDown}
>
@@ -54,7 +53,6 @@ export const StepCardOverlay = ({
borderWidth="1px"
rounded="lg"
cursor={'grab'}
- colorScheme="gray"
w="147px"
pos="fixed"
top="0"
diff --git a/apps/builder/components/board/StepTypesList/StepIcon.tsx b/apps/builder/components/board/StepTypesList/StepIcon.tsx
index fa425c3ea..90d30ce37 100644
--- a/apps/builder/components/board/StepTypesList/StepIcon.tsx
+++ b/apps/builder/components/board/StepTypesList/StepIcon.tsx
@@ -1,4 +1,4 @@
-import { CalendarIcon, FlagIcon, ImageIcon, TextIcon } from 'assets/icons'
+import { ChatIcon, FlagIcon, TextIcon } from 'assets/icons'
import { StepType } from 'bot-engine'
import React from 'react'
@@ -6,15 +6,12 @@ type StepIconProps = { type: StepType }
export const StepIcon = ({ type }: StepIconProps) => {
switch (type) {
+ case StepType.TEXT: {
+ return
+ }
case StepType.TEXT: {
return
}
- case StepType.IMAGE: {
- return
- }
- case StepType.DATE_PICKER: {
- return
- }
case StepType.START: {
return
}
diff --git a/apps/builder/components/board/StepTypesList/StepLabel.tsx b/apps/builder/components/board/StepTypesList/StepLabel.tsx
index 4d1b9a75b..8679fc56c 100644
--- a/apps/builder/components/board/StepTypesList/StepLabel.tsx
+++ b/apps/builder/components/board/StepTypesList/StepLabel.tsx
@@ -9,11 +9,8 @@ export const StepLabel = ({ type }: Props) => {
case StepType.TEXT: {
return Text
}
- case StepType.IMAGE: {
- return Image
- }
- case StepType.DATE_PICKER: {
- return Date
+ case StepType.TEXT_INPUT: {
+ return Text
}
default: {
return <>>
diff --git a/apps/builder/components/board/StepTypesList/StepTypesList.tsx b/apps/builder/components/board/StepTypesList/StepTypesList.tsx
index 84cca87e5..ea9ab7606 100644
--- a/apps/builder/components/board/StepTypesList/StepTypesList.tsx
+++ b/apps/builder/components/board/StepTypesList/StepTypesList.tsx
@@ -14,8 +14,8 @@ export const stepListItems: {
bubbles: { type: StepType }[]
inputs: { type: StepType }[]
} = {
- bubbles: [{ type: StepType.TEXT }, { type: StepType.IMAGE }],
- inputs: [{ type: StepType.DATE_PICKER }],
+ bubbles: [{ type: StepType.TEXT }],
+ inputs: [{ type: StepType.TEXT_INPUT }],
}
export const StepTypesList = () => {
diff --git a/apps/builder/components/board/StepTypesList/index.tsx b/apps/builder/components/board/StepTypesList/index.tsx
index c62cbe021..532a5f880 100644
--- a/apps/builder/components/board/StepTypesList/index.tsx
+++ b/apps/builder/components/board/StepTypesList/index.tsx
@@ -1 +1 @@
-export { StepTypesList as default } from './StepTypesList'
+export { StepTypesList } from './StepTypesList'
diff --git a/apps/builder/components/board/graph/BlockNode/BlockNode.tsx b/apps/builder/components/board/graph/BlockNode/BlockNode.tsx
index a8cb79ee6..1fbd2b1b2 100644
--- a/apps/builder/components/board/graph/BlockNode/BlockNode.tsx
+++ b/apps/builder/components/board/graph/BlockNode/BlockNode.tsx
@@ -5,27 +5,31 @@ import {
Stack,
useEventListener,
} from '@chakra-ui/react'
-import React, { useEffect, useRef, useState } from 'react'
+import React, { useEffect, useMemo, useState } from 'react'
import { Block, StartBlock } from 'bot-engine'
import { useGraph } from 'contexts/GraphContext'
import { useDnd } from 'contexts/DndContext'
import { StepsList } from './StepsList'
import { isNotDefined } from 'services/utils'
+import { useTypebot } from 'contexts/TypebotContext'
+import { ContextMenu } from 'components/shared/ContextMenu'
+import { BlockNodeContextMenu } from './BlockNodeContextMenu'
export const BlockNode = ({ block }: { block: Block | StartBlock }) => {
- const {
- updateBlockPosition,
- addNewStepToBlock,
- connectingIds,
- setConnectingIds,
- } = useGraph()
+ const { connectingIds, setConnectingIds, previewingIds } = useGraph()
+ const { updateBlockPosition, addStepToBlock } = useTypebot()
const { draggedStep, draggedStepType, setDraggedStepType, setDraggedStep } =
useDnd()
- const blockRef = useRef(null)
const [isMouseDown, setIsMouseDown] = useState(false)
const [titleValue, setTitleValue] = useState(block.title)
const [showSortPlaceholders, setShowSortPlaceholders] = useState(false)
const [isConnecting, setIsConnecting] = useState(false)
+ const isPreviewing = useMemo(
+ () =>
+ previewingIds.sourceId === block.id ||
+ previewingIds.targetId === block.id,
+ [block.id, previewingIds.sourceId, previewingIds.targetId]
+ )
useEffect(() => {
setIsConnecting(
@@ -69,44 +73,56 @@ export const BlockNode = ({ block }: { block: Block | StartBlock }) => {
const handleStepDrop = (index: number) => {
setShowSortPlaceholders(false)
if (draggedStepType) {
- addNewStepToBlock(block.id, draggedStepType, index)
+ addStepToBlock(block.id, draggedStepType, index)
setDraggedStepType(undefined)
}
if (draggedStep) {
- addNewStepToBlock(block.id, draggedStep, index)
+ addStepToBlock(block.id, draggedStep, index)
setDraggedStep(undefined)
}
}
return (
-
+ renderMenu={() => }
>
-
-
-
-
-
-
+ {(ref, isOpened) => (
+
+
+
+
+
+
+
+ )}
+
)
}
diff --git a/apps/builder/components/board/graph/BlockNode/BlockNodeContextMenu.tsx b/apps/builder/components/board/graph/BlockNode/BlockNodeContextMenu.tsx
new file mode 100644
index 000000000..be95a922f
--- /dev/null
+++ b/apps/builder/components/board/graph/BlockNode/BlockNodeContextMenu.tsx
@@ -0,0 +1,18 @@
+import { MenuList, MenuItem } from '@chakra-ui/react'
+import { TrashIcon } from 'assets/icons'
+import { useTypebot } from 'contexts/TypebotContext'
+
+export const BlockNodeContextMenu = ({ blockId }: { blockId: string }) => {
+ const { removeBlock } = useTypebot()
+
+ const handleDeleteClick = () => {
+ removeBlock(blockId)
+ }
+ return (
+
+ } onClick={handleDeleteClick}>
+ Delete
+
+
+ )
+}
diff --git a/apps/builder/components/board/graph/BlockNode/StartBlockNode.tsx b/apps/builder/components/board/graph/BlockNode/StartBlockNode.tsx
index d214b555e..4f7a026df 100644
--- a/apps/builder/components/board/graph/BlockNode/StartBlockNode.tsx
+++ b/apps/builder/components/board/graph/BlockNode/StartBlockNode.tsx
@@ -5,15 +5,21 @@ import {
Stack,
useEventListener,
} from '@chakra-ui/react'
-import React, { useState } from 'react'
+import React, { useMemo, useState } from 'react'
import { StartBlock } from 'bot-engine'
-import { useGraph } from 'contexts/GraphContext'
import { StepNode } from './StepNode'
+import { useTypebot } from 'contexts/TypebotContext'
+import { useGraph } from 'contexts/GraphContext'
export const StartBlockNode = ({ block }: { block: StartBlock }) => {
- const { setStartBlock } = useGraph()
+ const { previewingIds } = useGraph()
const [isMouseDown, setIsMouseDown] = useState(false)
const [titleValue, setTitleValue] = useState(block.title)
+ const { updateBlockPosition } = useTypebot()
+ const isPreviewing = useMemo(
+ () => previewingIds.sourceId === block.id,
+ [block.id, previewingIds.sourceId]
+ )
const handleTitleChange = (title: string) => setTitleValue(title)
@@ -28,15 +34,11 @@ export const StartBlockNode = ({ block }: { block: StartBlock }) => {
if (!isMouseDown) return
const { movementX, movementY } = event
- setStartBlock({
- ...block,
- graphCoordinates: {
- x: block.graphCoordinates.x + movementX,
- y: block.graphCoordinates.y + movementY,
- },
+ updateBlockPosition(block.id, {
+ x: block.graphCoordinates.x + movementX,
+ y: block.graphCoordinates.y + movementY,
})
}
-
useEventListener('mousemove', handleMouseMove)
return (
@@ -45,7 +47,7 @@ export const StartBlockNode = ({ block }: { block: StartBlock }) => {
rounded="lg"
bgColor="blue.50"
borderWidth="2px"
- borderColor="gray.400"
+ borderColor={isPreviewing ? 'blue.400' : 'gray.400'}
minW="300px"
transition="border 300ms"
pos="absolute"
@@ -57,7 +59,11 @@ export const StartBlockNode = ({ block }: { block: StartBlock }) => {
spacing="14px"
>
-
+
diff --git a/apps/builder/components/board/graph/BlockNode/StepNode/RightClickMenu.tsx b/apps/builder/components/board/graph/BlockNode/StepNode/RightClickMenu.tsx
new file mode 100644
index 000000000..c522a33b6
--- /dev/null
+++ b/apps/builder/components/board/graph/BlockNode/StepNode/RightClickMenu.tsx
@@ -0,0 +1,24 @@
+import { MenuList, MenuItem } from '@chakra-ui/react'
+import { TrashIcon } from 'assets/icons'
+import { useTypebot } from 'contexts/TypebotContext'
+
+export const StepNodeContextMenu = ({
+ blockId,
+ stepId,
+}: {
+ blockId: string
+ stepId: string
+}) => {
+ const { removeStepFromBlock } = useTypebot()
+
+ const handleDeleteClick = () => {
+ removeStepFromBlock(blockId, stepId)
+ }
+ return (
+
+ } onClick={handleDeleteClick}>
+ Delete
+
+
+ )
+}
diff --git a/apps/builder/components/board/graph/BlockNode/StepNode/StepContent.tsx b/apps/builder/components/board/graph/BlockNode/StepNode/StepContent.tsx
new file mode 100644
index 000000000..bbc2e2f92
--- /dev/null
+++ b/apps/builder/components/board/graph/BlockNode/StepNode/StepContent.tsx
@@ -0,0 +1,31 @@
+import { Flex, Text } from '@chakra-ui/react'
+import { Step, StartStep, StepType } from 'bot-engine'
+
+export const StepContent = (props: Step | StartStep) => {
+ switch (props.type) {
+ case StepType.TEXT: {
+ return (
+ Click to edit...
`
+ : props.content.html,
+ }}
+ >
+ )
+ }
+ case StepType.TEXT_INPUT: {
+ return Type your answer...
+ }
+ case StepType.START: {
+ return {props.label}
+ }
+ default: {
+ return No input
+ }
+ }
+}
diff --git a/apps/builder/components/board/graph/BlockNode/StepNode/StepNode.tsx b/apps/builder/components/board/graph/BlockNode/StepNode/StepNode.tsx
index 0b9ca24a8..43c27785c 100644
--- a/apps/builder/components/board/graph/BlockNode/StepNode/StepNode.tsx
+++ b/apps/builder/components/board/graph/BlockNode/StepNode/StepNode.tsx
@@ -1,10 +1,16 @@
-import { Box, Flex, HStack, StackProps, Text } from '@chakra-ui/react'
-import React, { useEffect, useMemo, useRef, useState } from 'react'
+import { Box, Flex, HStack, useEventListener } from '@chakra-ui/react'
+import React, { useEffect, useMemo, useState } from 'react'
import { Block, StartStep, Step, StepType } from 'bot-engine'
import { SourceEndpoint } from './SourceEndpoint'
import { useGraph } from 'contexts/GraphContext'
import { StepIcon } from 'components/board/StepTypesList/StepIcon'
import { isDefined } from 'services/utils'
+import { Coordinates } from '@dnd-kit/core/dist/types'
+import { TextEditor } from './TextEditor/TextEditor'
+import { StepContent } from './StepContent'
+import { useTypebot } from 'contexts/TypebotContext'
+import { ContextMenu } from 'components/shared/ContextMenu'
+import { StepNodeContextMenu } from './RightClickMenu'
export const StepNode = ({
step,
@@ -17,17 +23,18 @@ export const StepNode = ({
isConnectable: boolean
onMouseMoveBottomOfElement?: () => void
onMouseMoveTopOfElement?: () => void
- onMouseDown?: (e: React.MouseEvent, step: Step) => void
+ onMouseDown?: (
+ stepNodePosition: { absolute: Coordinates; relative: Coordinates },
+ step: Step
+ ) => void
}) => {
- const stepRef = useRef(null)
- const {
- setConnectingIds,
- removeStepFromBlock,
- blocks,
- connectingIds,
- startBlock,
- } = useGraph()
+ const { setConnectingIds, connectingIds } = useGraph()
+ const { removeStepFromBlock, typebot } = useTypebot()
+ const { blocks, startBlock } = typebot ?? {}
const [isConnecting, setIsConnecting] = useState(false)
+ const [mouseDownEvent, setMouseDownEvent] =
+ useState<{ absolute: Coordinates; relative: Coordinates }>()
+ const [isEditing, setIsEditing] = useState(undefined)
useEffect(() => {
setIsConnecting(
@@ -59,12 +66,38 @@ export const StepNode = ({
const handleMouseDown = (e: React.MouseEvent) => {
if (!onMouseDown) return
e.stopPropagation()
- onMouseDown(e, step as Step)
- removeStepFromBlock(step.blockId, step.id)
+ const element = e.currentTarget as HTMLDivElement
+ const rect = element.getBoundingClientRect()
+ const relativeX = e.clientX - rect.left
+ const relativeY = e.clientY - rect.top
+ setMouseDownEvent({
+ absolute: { x: e.clientX + relativeX, y: e.clientY + relativeY },
+ relative: { x: relativeX, y: relativeY },
+ })
+ }
+
+ const handleGlobalMouseUp = () => {
+ setMouseDownEvent(undefined)
+ }
+ useEventListener('mouseup', handleGlobalMouseUp)
+
+ const handleMouseUp = () => {
+ if (mouseDownEvent) {
+ setIsEditing(true)
+ }
}
const handleMouseMove = (event: React.MouseEvent) => {
if (!onMouseMoveBottomOfElement || !onMouseMoveTopOfElement) return
+ const isMovingAndIsMouseDown =
+ mouseDownEvent &&
+ onMouseDown &&
+ (event.movementX > 0 || event.movementY > 0)
+ if (isMovingAndIsMouseDown) {
+ onMouseDown(mouseDownEvent, step as Step)
+ removeStepFromBlock(step.blockId, step.id)
+ setMouseDownEvent(undefined)
+ }
const element = event.currentTarget as HTMLDivElement
const rect = element.getBoundingClientRect()
const y = event.clientY - rect.top
@@ -72,8 +105,12 @@ export const StepNode = ({
else onMouseMoveTopOfElement()
}
+ const handleCloseEditor = () => {
+ setIsEditing(false)
+ }
+
const connectedStubPosition: 'right' | 'left' | undefined = useMemo(() => {
- const currentBlock = [startBlock, ...blocks].find(
+ const currentBlock = [startBlock, ...(blocks ?? [])].find(
(b) => b?.id === step.blockId
)
const isDragginConnectorFromCurrentBlock =
@@ -83,7 +120,7 @@ export const StepNode = ({
? connectingIds.target?.blockId
: step.target?.blockId
const targetedBlock = targetBlockId
- ? blocks.find((b) => b.id === targetBlockId)
+ ? (blocks ?? []).find((b) => b.id === targetBlockId)
: undefined
return targetedBlock
? targetedBlock.graphCoordinates.x <
@@ -100,106 +137,74 @@ export const StepNode = ({
startBlock,
])
- return (
-
+ ) : (
+
+ renderMenu={() => (
+
+ )}
>
- {connectedStubPosition === 'left' && (
-
- )}
-
-
-
- {isConnectable && (
-
- )}
-
+ {(ref, isOpened) => (
+
+ {connectedStubPosition === 'left' && (
+
+ )}
+
+
+
+ {isConnectable && (
+
+ )}
+
- {isDefined(connectedStubPosition) && (
-
+ {isDefined(connectedStubPosition) && (
+
+ )}
+
)}
-
- )
-}
-
-export const StepContent = (props: Step | StartStep) => {
- switch (props.type) {
- case StepType.TEXT: {
- return (
-
- {props.content === '' ? 'Type text...' : props.content}
-
- )
- }
- case StepType.DATE_PICKER: {
- return (
-
- {props.content === '' ? 'Pick a date...' : props.content}
-
- )
- }
- case StepType.START: {
- return {props.label}
- }
- default: {
- return No input
- }
- }
-}
-
-export const StepNodeOverlay = ({
- step,
- ...props
-}: { step: Step } & StackProps) => {
- return (
-
-
-
-
+
)
}
diff --git a/apps/builder/components/board/graph/BlockNode/StepNode/StepNodeOverlay.tsx b/apps/builder/components/board/graph/BlockNode/StepNode/StepNodeOverlay.tsx
new file mode 100644
index 000000000..d4f30cf9d
--- /dev/null
+++ b/apps/builder/components/board/graph/BlockNode/StepNode/StepNodeOverlay.tsx
@@ -0,0 +1,28 @@
+import { StackProps, HStack } from '@chakra-ui/react'
+import { Step } from 'bot-engine'
+import { StepIcon } from 'components/board/StepTypesList/StepIcon'
+import { StepContent } from './StepContent'
+
+export const StepNodeOverlay = ({
+ step,
+ ...props
+}: { step: Step } & StackProps) => {
+ return (
+
+
+
+
+ )
+}
diff --git a/apps/builder/components/board/graph/BlockNode/StepNode/TextEditor/TextEditor.tsx b/apps/builder/components/board/graph/BlockNode/StepNode/TextEditor/TextEditor.tsx
new file mode 100644
index 000000000..a49b3ff39
--- /dev/null
+++ b/apps/builder/components/board/graph/BlockNode/StepNode/TextEditor/TextEditor.tsx
@@ -0,0 +1,97 @@
+import { Stack, useOutsideClick } from '@chakra-ui/react'
+import React, { useEffect, useMemo, useRef, useState } from 'react'
+import {
+ Plate,
+ selectEditor,
+ serializeHtml,
+ TDescendant,
+ withPlate,
+} from '@udecode/plate-core'
+import { editorStyle, platePlugins } from 'libs/plate'
+import { useDebounce } from 'use-debounce'
+import { useTypebot } from 'contexts/TypebotContext'
+import { createEditor } from 'slate'
+import { ToolBar } from './ToolBar'
+import { parseHtmlStringToPlainText } from 'services/utils'
+
+type TextEditorProps = {
+ ids: { stepId: string; blockId: string }
+ initialValue: TDescendant[]
+ onClose: () => void
+}
+
+export const TextEditor = ({ initialValue, ids, onClose }: TextEditorProps) => {
+ const editor = useMemo(
+ () => withPlate(createEditor(), { id: ids.stepId, plugins: platePlugins }),
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ []
+ )
+ const { updateStep } = useTypebot()
+ const [value, setValue] = useState(initialValue)
+ const [debouncedValue] = useDebounce(value, 500)
+ const textEditorRef = useRef(null)
+ useOutsideClick({
+ ref: textEditorRef,
+ handler: () => {
+ save(value)
+ onClose()
+ },
+ })
+
+ useEffect(() => {
+ save(debouncedValue)
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, [debouncedValue])
+
+ const save = (value: unknown[]) => {
+ console.log('SAVE', value)
+ if (value.length === 0) return
+ const html = serializeHtml(editor, {
+ nodes: value,
+ })
+ updateStep(ids, {
+ content: {
+ html,
+ richText: value,
+ plainText: parseHtmlStringToPlainText(html),
+ },
+ })
+ }
+
+ const handleMouseDown = (e: React.MouseEvent) => {
+ e.stopPropagation()
+ }
+ return (
+
+
+ {
+ if (editor.children.length === 0) return
+ selectEditor(editor, {
+ edge: 'end',
+ })
+ },
+ }}
+ initialValue={
+ initialValue.length === 0
+ ? [{ type: 'p', children: [{ text: '' }] }]
+ : initialValue
+ }
+ onChange={setValue}
+ editor={editor}
+ />
+
+ )
+}
diff --git a/apps/builder/components/board/graph/BlockNode/StepNode/TextEditor/ToolBar.tsx b/apps/builder/components/board/graph/BlockNode/StepNode/TextEditor/ToolBar.tsx
new file mode 100644
index 000000000..9a655f54b
--- /dev/null
+++ b/apps/builder/components/board/graph/BlockNode/StepNode/TextEditor/ToolBar.tsx
@@ -0,0 +1,40 @@
+import { StackProps, HStack, Button } from '@chakra-ui/react'
+import {
+ MARK_BOLD,
+ MARK_ITALIC,
+ MARK_UNDERLINE,
+} from '@udecode/plate-basic-marks'
+import { usePlateEditorRef, getPluginType } from '@udecode/plate-core'
+import { LinkToolbarButton } from '@udecode/plate-ui-link'
+import { MarkToolbarButton } from '@udecode/plate-ui-toolbar'
+import { BoldIcon, ItalicIcon, UnderlineIcon, LinkIcon } from 'assets/icons'
+
+export const ToolBar = (props: StackProps) => {
+ const editor = usePlateEditorRef()
+ return (
+
+
+ }
+ />
+ }
+ />
+ }
+ />
+ } />
+
+ )
+}
diff --git a/apps/builder/components/board/graph/BlockNode/StepNode/TextEditor/index.tsx b/apps/builder/components/board/graph/BlockNode/StepNode/TextEditor/index.tsx
new file mode 100644
index 000000000..74fb5325a
--- /dev/null
+++ b/apps/builder/components/board/graph/BlockNode/StepNode/TextEditor/index.tsx
@@ -0,0 +1 @@
+export { TextEditor } from './TextEditor'
diff --git a/apps/builder/components/board/graph/BlockNode/StepNode/index.tsx b/apps/builder/components/board/graph/BlockNode/StepNode/index.tsx
index b36791297..2284b1b24 100644
--- a/apps/builder/components/board/graph/BlockNode/StepNode/index.tsx
+++ b/apps/builder/components/board/graph/BlockNode/StepNode/index.tsx
@@ -1 +1,2 @@
-export { StepNode, StepNodeOverlay } from './StepNode'
+export { StepNode } from './StepNode'
+export { StepNodeOverlay } from './StepNodeOverlay'
diff --git a/apps/builder/components/board/graph/BlockNode/StepsList.tsx b/apps/builder/components/board/graph/BlockNode/StepsList.tsx
index d731d1d84..f63a8f341 100644
--- a/apps/builder/components/board/graph/BlockNode/StepsList.tsx
+++ b/apps/builder/components/board/graph/BlockNode/StepsList.tsx
@@ -1,6 +1,7 @@
import { useEventListener, Stack, Flex, Portal } from '@chakra-ui/react'
import { StartStep, Step } from 'bot-engine'
import { useDnd } from 'contexts/DndContext'
+import { Coordinates } from 'contexts/GraphContext'
import { useState } from 'react'
import { StepNode, StepNodeOverlay } from './StepNode'
@@ -51,13 +52,12 @@ export const StepsList = ({
onMouseUp(expandedPlaceholderIndex)
}
- const handleStepMouseDown = (e: React.MouseEvent, step: Step) => {
- const element = e.currentTarget as HTMLDivElement
- const rect = element.getBoundingClientRect()
- const relativeX = e.clientX - rect.left
- const relativeY = e.clientY - rect.top
- setPosition({ x: e.clientX - relativeX, y: e.clientY - relativeY })
- setRelativeCoordinates({ x: relativeX, y: relativeY })
+ const handleStepMouseDown = (
+ { absolute, relative }: { absolute: Coordinates; relative: Coordinates },
+ step: Step
+ ) => {
+ setPosition(absolute)
+ setRelativeCoordinates(relative)
setDraggedStep(step)
}
diff --git a/apps/builder/components/board/graph/Edges/DrawingEdge.tsx b/apps/builder/components/board/graph/Edges/DrawingEdge.tsx
index ece353b0a..1f7624ba3 100644
--- a/apps/builder/components/board/graph/Edges/DrawingEdge.tsx
+++ b/apps/builder/components/board/graph/Edges/DrawingEdge.tsx
@@ -1,6 +1,7 @@
import { useEventListener } from '@chakra-ui/hooks'
import { Coordinates } from '@dnd-kit/core/dist/types'
import { Block } from 'bot-engine'
+import { headerHeight } from 'components/shared/TypebotHeader/TypebotHeader'
import {
blockWidth,
firstStepOffsetY,
@@ -8,6 +9,7 @@ import {
stubLength,
useGraph,
} from 'contexts/GraphContext'
+import { useTypebot } from 'contexts/TypebotContext'
import React, { useMemo, useState } from 'react'
import {
computeFlowChartConnectorPath,
@@ -16,18 +18,16 @@ import {
import { roundCorners } from 'svg-round-corners'
export const DrawingEdge = () => {
- const {
- graphPosition,
- setConnectingIds,
- blocks,
- connectingIds,
- addTarget,
- startBlock,
- } = useGraph()
+ const { graphPosition, setConnectingIds, connectingIds } = useGraph()
+ const { typebot, updateTarget } = useTypebot()
+ const { startBlock, blocks } = typebot ?? {}
const [mousePosition, setMousePosition] = useState({ x: 0, y: 0 })
const sourceBlock = useMemo(
- () => [startBlock, ...blocks].find((b) => b?.id === connectingIds?.blockId),
+ () =>
+ [startBlock, ...(blocks ?? [])].find(
+ (b) => b?.id === connectingIds?.blockId
+ ),
// eslint-disable-next-line react-hooks/exhaustive-deps
[connectingIds]
)
@@ -35,7 +35,7 @@ export const DrawingEdge = () => {
const path = useMemo(() => {
if (!sourceBlock) return ``
if (connectingIds?.target) {
- const targetedBlock = blocks.find(
+ const targetedBlock = blocks?.find(
(b) => b.id === connectingIds.target?.blockId
) as Block
const targetedStepIndex = connectingIds.target.stepId
@@ -62,12 +62,12 @@ export const DrawingEdge = () => {
const handleMouseMove = (e: MouseEvent) => {
setMousePosition({
x: e.clientX - graphPosition.x,
- y: e.clientY - graphPosition.y,
+ y: e.clientY - graphPosition.y - headerHeight,
})
}
useEventListener('mousemove', handleMouseMove)
useEventListener('mouseup', () => {
- if (connectingIds?.target) addTarget(connectingIds)
+ if (connectingIds?.target) updateTarget(connectingIds)
setConnectingIds(null)
})
@@ -117,8 +117,8 @@ const computeThreeSegments = (
const segments = []
const firstSegmentX =
sourceType === 'right'
- ? sourcePosition.x + stubLength
- : sourcePosition.x - stubLength
+ ? sourcePosition.x + stubLength + 40
+ : sourcePosition.x - stubLength - 40
segments.push(`L${firstSegmentX},${sourcePosition.y}`)
segments.push(`L${firstSegmentX},${targetPosition.y}`)
segments.push(`L${targetPosition.x},${targetPosition.y}`)
diff --git a/apps/builder/components/board/graph/Edges/Edge.tsx b/apps/builder/components/board/graph/Edges/Edge.tsx
index 784c4b11e..069488335 100644
--- a/apps/builder/components/board/graph/Edges/Edge.tsx
+++ b/apps/builder/components/board/graph/Edges/Edge.tsx
@@ -1,5 +1,6 @@
import { Block, StartStep, Step, Target } from 'bot-engine'
import { Coordinates, useGraph } from 'contexts/GraphContext'
+import { useTypebot } from 'contexts/TypebotContext'
import React, { useMemo } from 'react'
import {
getAnchorsPosition,
@@ -18,17 +19,32 @@ export type StepWithTarget = Omit & {
}
export const Edge = ({ step }: { step: StepWithTarget }) => {
- const { blocks, startBlock } = useGraph()
+ const { typebot } = useTypebot()
+ const { previewingIds } = useGraph()
+ const isPreviewing = useMemo(
+ () =>
+ previewingIds.sourceId === step.blockId &&
+ previewingIds.targetId === step.target.blockId,
+ [
+ previewingIds.sourceId,
+ previewingIds.targetId,
+ step.blockId,
+ step.target.blockId,
+ ]
+ )
+ const { blocks, startBlock } = typebot ?? {}
const { sourceBlock, targetBlock, targetStepIndex } = useMemo(() => {
- const targetBlock = blocks.find(
+ const targetBlock = blocks?.find(
(b) => b?.id === step.target.blockId
) as Block
const targetStepIndex = step.target.stepId
? targetBlock.steps.findIndex((s) => s.id === step.target.stepId)
: undefined
return {
- sourceBlock: [startBlock, ...blocks].find((b) => b?.id === step.blockId),
+ sourceBlock: [startBlock, ...(blocks ?? [])].find(
+ (b) => b?.id === step.blockId
+ ),
targetBlock,
targetStepIndex,
}
@@ -54,7 +70,7 @@ export const Edge = ({ step }: { step: StepWithTarget }) => {
return (
{
- const { blocks, startBlock } = useGraph()
+ const { typebot } = useTypebot()
+ const { blocks, startBlock } = typebot ?? {}
const stepsWithTarget: StepWithTarget[] = useMemo(() => {
if (!startBlock) return []
return [
...(startBlock.steps.filter((s) => s.target) as StepWithTarget[]),
- ...(blocks
+ ...((blocks ?? [])
.flatMap((b) => b.steps)
.filter((s) => s.target) as StepWithTarget[]),
]
diff --git a/apps/builder/components/board/graph/Graph.tsx b/apps/builder/components/board/graph/Graph.tsx
index 7976e2fd0..137109770 100644
--- a/apps/builder/components/board/graph/Graph.tsx
+++ b/apps/builder/components/board/graph/Graph.tsx
@@ -1,39 +1,25 @@
import { Flex, useEventListener } from '@chakra-ui/react'
-import React, { useRef, useMemo, useEffect } from 'react'
+import React, { useRef, useMemo } from 'react'
import { blockWidth, useGraph } from 'contexts/GraphContext'
import { BlockNode } from './BlockNode/BlockNode'
import { useDnd } from 'contexts/DndContext'
import { Edges } from './Edges'
import { useTypebot } from 'contexts/TypebotContext'
import { StartBlockNode } from './BlockNode/StartBlockNode'
+import { headerHeight } from 'components/shared/TypebotHeader/TypebotHeader'
const Graph = () => {
const { draggedStepType, setDraggedStepType, draggedStep, setDraggedStep } =
useDnd()
const graphContainerRef = useRef(null)
- const { typebot } = useTypebot()
- const {
- blocks,
- setBlocks,
- graphPosition,
- setGraphPosition,
- addNewBlock,
- setStartBlock,
- startBlock,
- } = useGraph()
+ const { typebot, addNewBlock } = useTypebot()
+ const { graphPosition, setGraphPosition } = useGraph()
const transform = useMemo(
() =>
`translate(${graphPosition.x}px, ${graphPosition.y}px) scale(${graphPosition.scale})`,
[graphPosition]
)
- useEffect(() => {
- if (!typebot) return
- setBlocks(typebot.blocks)
- setStartBlock(typebot.startBlock)
- // eslint-disable-next-line react-hooks/exhaustive-deps
- }, [typebot?.blocks])
-
const handleMouseWheel = (e: WheelEvent) => {
e.preventDefault()
const isPinchingTrackpad = e.ctrlKey
@@ -59,26 +45,33 @@ const Graph = () => {
step: draggedStep,
type: draggedStepType,
x: e.clientX - graphPosition.x - blockWidth / 3,
- y: e.clientY - graphPosition.y - 20,
+ y: e.clientY - graphPosition.y - 20 - headerHeight,
})
setDraggedStep(undefined)
setDraggedStepType(undefined)
}
useEventListener('mouseup', handleMouseUp, graphContainerRef.current)
+ const handleMouseDown = (e: MouseEvent) => {
+ const isRightClick = e.button === 2
+ if (isRightClick) e.stopPropagation()
+ }
+ useEventListener('mousedown', handleMouseDown, undefined, { capture: true })
+
if (!typebot) return <>>
return (
-
+
- {startBlock && }
- {blocks.map((block) => (
+ {typebot.startBlock && }
+ {(typebot.blocks ?? []).map((block) => (
))}
diff --git a/apps/builder/components/board/preview/PreviewDrawer.tsx b/apps/builder/components/board/preview/PreviewDrawer.tsx
new file mode 100644
index 000000000..e7cf54081
--- /dev/null
+++ b/apps/builder/components/board/preview/PreviewDrawer.tsx
@@ -0,0 +1,119 @@
+import {
+ Box,
+ Button,
+ CloseButton,
+ Fade,
+ Flex,
+ FlexProps,
+ useEventListener,
+ VStack,
+} from '@chakra-ui/react'
+import { TypebotViewer } from 'bot-engine'
+import { headerHeight } from 'components/shared/TypebotHeader'
+import { useEditor } from 'contexts/EditorContext'
+import { useGraph } from 'contexts/GraphContext'
+import { useTypebot } from 'contexts/TypebotContext'
+import React, { useMemo, useState } from 'react'
+import { parseTypebotToPublicTypebot } from 'services/typebots'
+
+export const PreviewDrawer = () => {
+ const { typebot } = useTypebot()
+ const { setRightPanel } = useEditor()
+ const { previewingIds, setPreviewingIds } = useGraph()
+ const [isResizing, setIsResizing] = useState(false)
+ const [width, setWidth] = useState(400)
+ const [isResizeHandleVisible, setIsResizeHandleVisible] = useState(false)
+
+ const publicTypebot = useMemo(
+ () => (typebot ? parseTypebotToPublicTypebot(typebot) : undefined),
+ [typebot]
+ )
+
+ const handleMouseDown = () => {
+ setIsResizing(true)
+ }
+
+ const handleMouseMove = (e: MouseEvent) => {
+ if (!isResizing) return
+ setWidth(width - e.movementX)
+ }
+ useEventListener('mousemove', handleMouseMove)
+
+ const handleMouseUp = () => {
+ setIsResizing(false)
+ }
+ useEventListener('mouseup', handleMouseUp)
+
+ const handleNewBlockVisible = (targetId: string) =>
+ setPreviewingIds({
+ sourceId: !previewingIds.sourceId
+ ? 'start-block'
+ : previewingIds.targetId,
+ targetId: targetId,
+ })
+
+ return (
+ setIsResizeHandleVisible(true)}
+ onMouseLeave={() => setIsResizeHandleVisible(false)}
+ p="6"
+ >
+
+
+
+
+
+
+
+ setRightPanel(undefined)} />
+
+
+ {publicTypebot && (
+
+
+
+ )}
+
+
+ )
+}
+
+const ResizeHandle = (props: FlexProps) => {
+ return (
+
+
+
+
+ )
+}
diff --git a/apps/builder/components/dashboard/FolderContent.tsx b/apps/builder/components/dashboard/FolderContent.tsx
index ae8c233da..058af136f 100644
--- a/apps/builder/components/dashboard/FolderContent.tsx
+++ b/apps/builder/components/dashboard/FolderContent.tsx
@@ -1,4 +1,5 @@
-import { DashboardFolder, Typebot } from '.prisma/client'
+import { DashboardFolder } from '.prisma/client'
+import { Typebot } from 'bot-engine'
import {
Button,
Flex,
@@ -133,7 +134,6 @@ export const FolderContent = ({ folder }: Props) => {
{folder && }
}
onClick={handleCreateFolder}
isLoading={isCreatingFolder || isFolderLoading}
diff --git a/apps/builder/components/dashboard/FolderContent/FolderButton.tsx b/apps/builder/components/dashboard/FolderContent/FolderButton.tsx
index 4038a8ec7..cf6368a70 100644
--- a/apps/builder/components/dashboard/FolderContent/FolderButton.tsx
+++ b/apps/builder/components/dashboard/FolderContent/FolderButton.tsx
@@ -148,7 +148,6 @@ export const ButtonSkeleton = () => (
pos="relative"
cursor="pointer"
variant="outline"
- colorScheme={'gray'}
>
diff --git a/apps/builder/components/dashboard/FolderContent/TypebotButton.tsx b/apps/builder/components/dashboard/FolderContent/TypebotButton.tsx
index 51affb480..dfaae89f6 100644
--- a/apps/builder/components/dashboard/FolderContent/TypebotButton.tsx
+++ b/apps/builder/components/dashboard/FolderContent/TypebotButton.tsx
@@ -11,12 +11,12 @@ import {
} from '@chakra-ui/react'
import { useDraggable } from '@dnd-kit/core'
import { useRouter } from 'next/router'
-import { Typebot } from 'db'
import { isMobile } from 'services/utils'
import { MoreButton } from 'components/MoreButton'
import { ConfirmModal } from 'components/modals/ConfirmModal'
import { GlobeIcon, ToolIcon } from 'assets/icons'
import { deleteTypebot, duplicateTypebot } from 'services/typebots'
+import { Typebot } from 'bot-engine'
type ChatbotCardProps = {
typebot: Typebot
@@ -77,7 +77,6 @@ export const TypebotButton = ({
display="flex"
flexDir="column"
variant="outline"
- colorScheme="gray"
color="gray.800"
w="225px"
h="270px"
diff --git a/apps/builder/components/dashboard/FolderContent/TypebotButtonOverlay.tsx b/apps/builder/components/dashboard/FolderContent/TypebotButtonOverlay.tsx
index f5152aad5..b40529a37 100644
--- a/apps/builder/components/dashboard/FolderContent/TypebotButtonOverlay.tsx
+++ b/apps/builder/components/dashboard/FolderContent/TypebotButtonOverlay.tsx
@@ -1,6 +1,6 @@
import { Button, Flex, Text, VStack } from '@chakra-ui/react'
-import { Typebot } from '.prisma/client'
import { GlobeIcon, ToolIcon } from 'assets/icons'
+import { Typebot } from 'bot-engine'
type Props = {
typebot: Typebot
@@ -16,7 +16,6 @@ export const TypebotCardOverlay = ({ typebot }: Props) => {
display="flex"
flexDir="column"
variant="outline"
- colorScheme="gray"
w="full"
h="full"
whiteSpace="normal"
diff --git a/apps/builder/components/modals/ConfirmModal.tsx b/apps/builder/components/modals/ConfirmModal.tsx
index 5f53385ed..bcfed137f 100644
--- a/apps/builder/components/modals/ConfirmModal.tsx
+++ b/apps/builder/components/modals/ConfirmModal.tsx
@@ -58,7 +58,7 @@ export const ConfirmModal = ({
{message}
-