diff --git a/apps/builder/assets/icons.tsx b/apps/builder/assets/icons.tsx
index 714e1d7ea..ae6959dd0 100644
--- a/apps/builder/assets/icons.tsx
+++ b/apps/builder/assets/icons.tsx
@@ -297,3 +297,17 @@ export const GripIcon = (props: IconProps) => (
)
+
+export const LockedIcon = (props: IconProps) => (
+
+
+
+
+)
+
+export const UnlockedIcon = (props: IconProps) => (
+
+
+
+
+)
diff --git a/apps/builder/components/board/Board.tsx b/apps/builder/components/board/Board.tsx
index 8c98018af..dfcb064a4 100644
--- a/apps/builder/components/board/Board.tsx
+++ b/apps/builder/components/board/Board.tsx
@@ -2,7 +2,7 @@ import { Flex } from '@chakra-ui/react'
import React from 'react'
import Graph from './graph/Graph'
import { StepDndContext } from 'contexts/StepDndContext'
-import { StepTypesList } from './StepTypesList'
+import { StepsSideBar } from './StepsSideBar'
import { PreviewDrawer } from './preview/PreviewDrawer'
import { RightPanel, useEditor } from 'contexts/EditorContext'
import { GraphProvider } from 'contexts/GraphContext'
@@ -13,7 +13,7 @@ export const Board = () => {
return (
-
+
diff --git a/apps/builder/components/board/StepTypesList/StepTypesList.tsx b/apps/builder/components/board/StepTypesList/StepTypesList.tsx
deleted file mode 100644
index 57388014c..000000000
--- a/apps/builder/components/board/StepTypesList/StepTypesList.tsx
+++ /dev/null
@@ -1,137 +0,0 @@
-import {
- Stack,
- Input,
- Text,
- SimpleGrid,
- useEventListener,
- Portal,
-} from '@chakra-ui/react'
-import {
- BubbleStepType,
- DraggableStepType,
- InputStepType,
- IntegrationStepType,
- LogicStepType,
-} from 'models'
-import { useStepDnd } from 'contexts/StepDndContext'
-import React, { useState } from 'react'
-import { StepCard, StepCardOverlay } from './StepCard'
-
-export const StepTypesList = () => {
- const { setDraggedStepType, draggedStepType } = useStepDnd()
- const [position, setPosition] = useState({
- x: 0,
- y: 0,
- })
- const [relativeCoordinates, setRelativeCoordinates] = useState({ x: 0, y: 0 })
-
- const handleMouseMove = (event: MouseEvent) => {
- if (!draggedStepType) return
- const { clientX, clientY } = event
- setPosition({
- ...position,
- x: clientX - relativeCoordinates.x,
- y: clientY - relativeCoordinates.y,
- })
- }
- useEventListener('mousemove', handleMouseMove)
-
- const handleMouseDown = (e: React.MouseEvent, type: DraggableStepType) => {
- const element = e.currentTarget as HTMLDivElement
- const rect = element.getBoundingClientRect()
- setPosition({ x: rect.left, y: rect.top })
- const x = e.clientX - rect.left
- const y = e.clientY - rect.top
- setRelativeCoordinates({ x, y })
- setDraggedStepType(type)
- }
-
- const handleMouseUp = () => {
- if (!draggedStepType) return
- setDraggedStepType(undefined)
- setPosition({
- x: 0,
- y: 0,
- })
- }
- useEventListener('mouseup', handleMouseUp)
-
- return (
-
-
-
-
- Bubbles
-
-
- {Object.values(BubbleStepType).map((type) => (
-
- ))}
-
-
-
-
-
- Inputs
-
-
- {Object.values(InputStepType).map((type) => (
-
- ))}
-
-
-
-
-
- Logic
-
-
- {Object.values(LogicStepType).map((type) => (
-
- ))}
-
-
-
-
-
- Integrations
-
-
- {Object.values(IntegrationStepType).map((type) => (
-
- ))}
-
-
-
- {draggedStepType && (
-
-
-
- )}
-
- )
-}
diff --git a/apps/builder/components/board/StepTypesList/index.tsx b/apps/builder/components/board/StepTypesList/index.tsx
deleted file mode 100644
index 532a5f880..000000000
--- a/apps/builder/components/board/StepTypesList/index.tsx
+++ /dev/null
@@ -1 +0,0 @@
-export { StepTypesList } from './StepTypesList'
diff --git a/apps/builder/components/board/StepTypesList/StepCard.tsx b/apps/builder/components/board/StepsSideBar/StepCard.tsx
similarity index 100%
rename from apps/builder/components/board/StepTypesList/StepCard.tsx
rename to apps/builder/components/board/StepsSideBar/StepCard.tsx
diff --git a/apps/builder/components/board/StepTypesList/StepIcon.tsx b/apps/builder/components/board/StepsSideBar/StepIcon.tsx
similarity index 64%
rename from apps/builder/components/board/StepTypesList/StepIcon.tsx
rename to apps/builder/components/board/StepsSideBar/StepIcon.tsx
index d496cc116..3baebc9fe 100644
--- a/apps/builder/components/board/StepTypesList/StepIcon.tsx
+++ b/apps/builder/components/board/StepsSideBar/StepIcon.tsx
@@ -31,31 +31,31 @@ type StepIconProps = { type: StepType } & IconProps
export const StepIcon = ({ type, ...props }: StepIconProps) => {
switch (type) {
case BubbleStepType.TEXT:
- return
+ return
case BubbleStepType.IMAGE:
- return
+ return
case BubbleStepType.VIDEO:
- return
+ return
case InputStepType.TEXT:
- return
+ return
case InputStepType.NUMBER:
- return
+ return
case InputStepType.EMAIL:
- return
+ return
case InputStepType.URL:
- return
+ return
case InputStepType.DATE:
- return
+ return
case InputStepType.PHONE:
- return
+ return
case InputStepType.CHOICE:
- return
+ return
case LogicStepType.SET_VARIABLE:
- return
+ return
case LogicStepType.CONDITION:
- return
+ return
case LogicStepType.REDIRECT:
- return
+ return
case IntegrationStepType.GOOGLE_SHEETS:
return
case IntegrationStepType.GOOGLE_ANALYTICS:
diff --git a/apps/builder/components/board/StepsSideBar/StepSideBar.tsx b/apps/builder/components/board/StepsSideBar/StepSideBar.tsx
new file mode 100644
index 000000000..f619fd54f
--- /dev/null
+++ b/apps/builder/components/board/StepsSideBar/StepSideBar.tsx
@@ -0,0 +1,191 @@
+import {
+ Stack,
+ Input,
+ Text,
+ SimpleGrid,
+ useEventListener,
+ Portal,
+ Flex,
+ IconButton,
+ Tooltip,
+ Fade,
+} from '@chakra-ui/react'
+import {
+ BubbleStepType,
+ DraggableStepType,
+ InputStepType,
+ IntegrationStepType,
+ LogicStepType,
+} from 'models'
+import { useStepDnd } from 'contexts/StepDndContext'
+import React, { useState } from 'react'
+import { StepCard, StepCardOverlay } from './StepCard'
+import { LockedIcon, UnlockedIcon } from 'assets/icons'
+import { headerHeight } from 'components/shared/TypebotHeader'
+
+export const StepsSideBar = () => {
+ const { setDraggedStepType, draggedStepType } = useStepDnd()
+ const [position, setPosition] = useState({
+ x: 0,
+ y: 0,
+ })
+ const [relativeCoordinates, setRelativeCoordinates] = useState({ x: 0, y: 0 })
+ const [isLocked, setIsLocked] = useState(true)
+ const [isExtended, setIsExtended] = useState(true)
+
+ const handleMouseMove = (event: MouseEvent) => {
+ if (!draggedStepType) return
+ const { clientX, clientY } = event
+ setPosition({
+ ...position,
+ x: clientX - relativeCoordinates.x,
+ y: clientY - relativeCoordinates.y,
+ })
+ }
+ useEventListener('mousemove', handleMouseMove)
+
+ const handleMouseDown = (e: React.MouseEvent, type: DraggableStepType) => {
+ const element = e.currentTarget as HTMLDivElement
+ const rect = element.getBoundingClientRect()
+ setPosition({ x: rect.left, y: rect.top })
+ const x = e.clientX - rect.left
+ const y = e.clientY - rect.top
+ setRelativeCoordinates({ x, y })
+ setDraggedStepType(type)
+ }
+
+ const handleMouseUp = () => {
+ if (!draggedStepType) return
+ setDraggedStepType(undefined)
+ setPosition({
+ x: 0,
+ y: 0,
+ })
+ }
+ useEventListener('mouseup', handleMouseUp)
+
+ const handleLockClick = () => setIsLocked(!isLocked)
+
+ const handleDockBarEnter = () => setIsExtended(true)
+
+ const handleMouseLeave = () => {
+ if (isLocked) return
+ setIsExtended(false)
+ }
+
+ return (
+
+
+
+
+
+ : }
+ aria-label={isLocked ? 'Unlock' : 'Lock'}
+ size="sm"
+ variant="outline"
+ onClick={handleLockClick}
+ />
+
+
+
+
+
+
+
+ Bubbles
+
+
+ {Object.values(BubbleStepType).map((type) => (
+
+ ))}
+
+
+
+
+
+ Inputs
+
+
+ {Object.values(InputStepType).map((type) => (
+
+ ))}
+
+
+
+
+
+ Logic
+
+
+ {Object.values(LogicStepType).map((type) => (
+
+ ))}
+
+
+
+
+
+ Integrations
+
+
+ {Object.values(IntegrationStepType).map((type) => (
+
+ ))}
+
+
+
+ {draggedStepType && (
+
+
+
+ )}
+
+
+
+
+
+
+
+ )
+}
diff --git a/apps/builder/components/board/StepTypesList/StepTypeLabel.tsx b/apps/builder/components/board/StepsSideBar/StepTypeLabel.tsx
similarity index 100%
rename from apps/builder/components/board/StepTypesList/StepTypeLabel.tsx
rename to apps/builder/components/board/StepsSideBar/StepTypeLabel.tsx
diff --git a/apps/builder/components/board/StepsSideBar/index.tsx b/apps/builder/components/board/StepsSideBar/index.tsx
new file mode 100644
index 000000000..5d4f2b6bf
--- /dev/null
+++ b/apps/builder/components/board/StepsSideBar/index.tsx
@@ -0,0 +1 @@
+export { StepsSideBar } from './StepSideBar'
diff --git a/apps/builder/components/board/graph/BlockNode/StepNode/ChoiceInputStepNode/ChoiceItemNode.tsx b/apps/builder/components/board/graph/BlockNode/StepNode/ChoiceInputStepNode/ChoiceItemNode.tsx
index 16a9af312..8eea2a5e4 100644
--- a/apps/builder/components/board/graph/BlockNode/StepNode/ChoiceInputStepNode/ChoiceItemNode.tsx
+++ b/apps/builder/components/board/graph/BlockNode/StepNode/ChoiceInputStepNode/ChoiceItemNode.tsx
@@ -94,6 +94,7 @@ export const ChoiceItemNode = ({
>
{(ref, isOpened) => (
{
return (
-
+
diff --git a/apps/builder/components/board/graph/BlockNode/StepNode/StepNode.tsx b/apps/builder/components/board/graph/BlockNode/StepNode/StepNode.tsx
index 797b02f77..de99b9c5f 100644
--- a/apps/builder/components/board/graph/BlockNode/StepNode/StepNode.tsx
+++ b/apps/builder/components/board/graph/BlockNode/StepNode/StepNode.tsx
@@ -9,7 +9,7 @@ import {
import React, { useEffect, useState } from 'react'
import { BubbleStep, DraggableStep, Step, TextBubbleStep } from 'models'
import { Coordinates, useGraph } from 'contexts/GraphContext'
-import { StepIcon } from 'components/board/StepTypesList/StepIcon'
+import { StepIcon } from 'components/board/StepsSideBar/StepIcon'
import { isBubbleStep, isTextBubbleStep } from 'utils'
import { TextEditor } from './TextEditor/TextEditor'
import { StepNodeContent } from './StepNodeContent/StepNodeContent'
@@ -152,7 +152,7 @@ export const StepNode = ({
renderMenu={() => }
>
{(ref, isOpened) => (
-
+
({
{currentItem ?? placeholder}
-
+
{items.map((item) => (
)
}
@@ -106,11 +106,14 @@ const EmbedLinkContent = ({ initialUrl, onNewUrl }: ContentProps) => {
setImageUrl(e.target.value)
return (
-
+
+
+
)
}
diff --git a/apps/builder/libs/chakra.ts b/apps/builder/libs/chakra.ts
index 27be24e64..973f71dd2 100644
--- a/apps/builder/libs/chakra.ts
+++ b/apps/builder/libs/chakra.ts
@@ -90,6 +90,14 @@ const components = {
_hover: { textDecoration: 'none' },
},
},
+ Menu: {
+ parts: ['list'],
+ defaultProps: {
+ list: {
+ shadow: 'lg',
+ },
+ },
+ },
}
export const customTheme = extendTheme({ colors, fonts, components })
diff --git a/apps/builder/pages/api/auth/[...nextauth].ts b/apps/builder/pages/api/auth/[...nextauth].ts
index 3efa15328..52b12f5b0 100644
--- a/apps/builder/pages/api/auth/[...nextauth].ts
+++ b/apps/builder/pages/api/auth/[...nextauth].ts
@@ -12,7 +12,7 @@ const providers: Provider[] = [
EmailProvider({
server: {
host: process.env.EMAIL_SERVER_HOST,
- port: process.env.EMAIL_SERVER_PORT,
+ port: Number(process.env.EMAIL_SERVER_PORT),
auth: {
user: process.env.EMAIL_SERVER_USER,
pass: process.env.EMAIL_SERVER_PASSWORD,
diff --git a/apps/builder/services/publicTypebot.tsx b/apps/builder/services/publicTypebot.tsx
index fbe28bc8f..36ea0be07 100644
--- a/apps/builder/services/publicTypebot.tsx
+++ b/apps/builder/services/publicTypebot.tsx
@@ -2,7 +2,7 @@ import { PublicTypebot, Typebot } from 'models'
import shortId from 'short-uuid'
import { HStack, Text } from '@chakra-ui/react'
import { CalendarIcon } from 'assets/icons'
-import { StepIcon } from 'components/board/StepTypesList/StepIcon'
+import { StepIcon } from 'components/board/StepsSideBar/StepIcon'
import { isInputStep, sendRequest } from 'utils'
export const parseTypebotToPublicTypebot = (