2023-06-05 17:33:43 +02:00
|
|
|
import { Flex, useColorModeValue, Stack } from '@chakra-ui/react'
|
2023-03-15 11:51:30 +01:00
|
|
|
import { useTypebot } from '@/features/editor/providers/TypebotProvider'
|
2023-11-08 15:34:16 +01:00
|
|
|
import { BlockWithItems, Item, ItemIndices } from '@typebot.io/schemas'
|
2022-02-04 19:00:08 +01:00
|
|
|
import React, { useRef, useState } from 'react'
|
2023-11-08 15:34:16 +01:00
|
|
|
import { BlockSourceEndpoint } from '../../endpoints/BlockSourceEndpoint'
|
2022-02-04 19:00:08 +01:00
|
|
|
import { ItemNodeContent } from './ItemNodeContent'
|
|
|
|
import { ItemNodeContextMenu } from './ItemNodeContextMenu'
|
2022-11-15 09:35:48 +01:00
|
|
|
import { ContextMenu } from '@/components/ContextMenu'
|
2023-03-15 08:35:16 +01:00
|
|
|
import { isDefined } from '@typebot.io/lib'
|
2023-03-15 11:51:30 +01:00
|
|
|
import { Coordinates } from '@/features/graph/types'
|
|
|
|
import {
|
2023-11-08 15:34:16 +01:00
|
|
|
DraggableItem,
|
2023-03-15 11:51:30 +01:00
|
|
|
NodePosition,
|
|
|
|
useDragDistance,
|
|
|
|
} from '@/features/graph/providers/GraphDndProvider'
|
|
|
|
import { useGraph } from '@/features/graph/providers/GraphProvider'
|
|
|
|
import { setMultipleRefs } from '@/helpers/setMultipleRefs'
|
2023-06-05 17:33:43 +02:00
|
|
|
import { ConditionContent } from '@/features/blocks/logic/condition/components/ConditionContent'
|
2023-07-25 17:29:06 +02:00
|
|
|
import { useRouter } from 'next/router'
|
2023-11-08 15:34:16 +01:00
|
|
|
import { LogicBlockType } from '@typebot.io/schemas/features/blocks/logic/constants'
|
2022-02-04 19:00:08 +01:00
|
|
|
|
|
|
|
type Props = {
|
|
|
|
item: Item
|
2023-11-08 15:34:16 +01:00
|
|
|
block: BlockWithItems
|
2022-02-04 19:00:08 +01:00
|
|
|
indices: ItemIndices
|
|
|
|
onMouseDown?: (
|
2022-06-11 07:27:38 +02:00
|
|
|
blockNodePosition: { absolute: Coordinates; relative: Coordinates },
|
2023-11-08 15:34:16 +01:00
|
|
|
item: DraggableItem
|
2022-02-04 19:00:08 +01:00
|
|
|
) => void
|
2022-11-16 14:56:09 +01:00
|
|
|
connectionDisabled?: boolean
|
2022-02-04 19:00:08 +01:00
|
|
|
}
|
|
|
|
|
2022-11-16 14:56:09 +01:00
|
|
|
export const ItemNode = ({
|
|
|
|
item,
|
2023-11-08 15:34:16 +01:00
|
|
|
block,
|
2022-11-16 14:56:09 +01:00
|
|
|
indices,
|
|
|
|
onMouseDown,
|
|
|
|
connectionDisabled,
|
|
|
|
}: Props) => {
|
2022-12-20 16:55:43 +01:00
|
|
|
const previewingBorderColor = useColorModeValue('blue.400', 'blue.300')
|
|
|
|
const borderColor = useColorModeValue('gray.200', 'gray.700')
|
2023-04-17 16:47:17 +02:00
|
|
|
const bg = useColorModeValue('white', 'gray.850')
|
2022-02-04 19:00:08 +01:00
|
|
|
const { typebot } = useTypebot()
|
2022-04-02 12:03:21 +02:00
|
|
|
const { previewingEdge } = useGraph()
|
2023-07-25 17:29:06 +02:00
|
|
|
const { pathname } = useRouter()
|
2022-02-04 19:00:08 +01:00
|
|
|
const [isMouseOver, setIsMouseOver] = useState(false)
|
|
|
|
const itemRef = useRef<HTMLDivElement | null>(null)
|
2023-11-08 15:34:16 +01:00
|
|
|
const isPreviewing =
|
|
|
|
previewingEdge &&
|
|
|
|
'itemId' in previewingEdge.from &&
|
|
|
|
previewingEdge.from.itemId === item.id
|
2022-11-16 14:56:09 +01:00
|
|
|
const isConnectable =
|
2023-02-06 09:48:48 +01:00
|
|
|
isDefined(typebot) &&
|
2022-11-16 14:56:09 +01:00
|
|
|
!connectionDisabled &&
|
|
|
|
!(
|
2023-11-08 15:34:16 +01:00
|
|
|
block.options &&
|
|
|
|
'isMultipleChoice' in block.options &&
|
|
|
|
block.options.isMultipleChoice
|
|
|
|
)
|
2022-02-04 19:00:08 +01:00
|
|
|
const onDrag = (position: NodePosition) => {
|
2023-11-08 15:34:16 +01:00
|
|
|
if (!onMouseDown || block.type === LogicBlockType.AB_TEST) return
|
2023-12-05 08:22:46 +01:00
|
|
|
onMouseDown(position, { ...item, type: block.type, blockId: block.id })
|
2022-02-04 19:00:08 +01:00
|
|
|
}
|
|
|
|
useDragDistance({
|
|
|
|
ref: itemRef,
|
|
|
|
onDrag,
|
2022-11-16 14:56:09 +01:00
|
|
|
isDisabled: !onMouseDown,
|
2022-02-04 19:00:08 +01:00
|
|
|
})
|
|
|
|
|
|
|
|
const handleMouseEnter = () => setIsMouseOver(true)
|
|
|
|
const handleMouseLeave = () => setIsMouseOver(false)
|
|
|
|
|
|
|
|
return (
|
|
|
|
<ContextMenu<HTMLDivElement>
|
|
|
|
renderMenu={() => <ItemNodeContextMenu indices={indices} />}
|
|
|
|
>
|
2022-12-20 16:55:43 +01:00
|
|
|
{(ref, isContextMenuOpened) => (
|
2023-06-05 17:33:43 +02:00
|
|
|
<Stack
|
2022-02-04 19:00:08 +01:00
|
|
|
data-testid="item"
|
|
|
|
pos="relative"
|
2022-04-02 12:03:21 +02:00
|
|
|
ref={setMultipleRefs([ref, itemRef])}
|
2022-11-16 14:56:09 +01:00
|
|
|
w="full"
|
2022-02-04 19:00:08 +01:00
|
|
|
>
|
2023-06-05 17:33:43 +02:00
|
|
|
{'displayCondition' in item &&
|
|
|
|
item.displayCondition?.isEnabled &&
|
|
|
|
item.displayCondition.condition && (
|
|
|
|
<ConditionContent
|
|
|
|
condition={item.displayCondition.condition}
|
|
|
|
variables={typebot?.variables ?? []}
|
|
|
|
size="xs"
|
|
|
|
displaySemicolon
|
|
|
|
/>
|
|
|
|
)}
|
2022-04-02 12:03:21 +02:00
|
|
|
<Flex
|
|
|
|
align="center"
|
|
|
|
onMouseEnter={handleMouseEnter}
|
|
|
|
onMouseLeave={handleMouseLeave}
|
|
|
|
shadow="sm"
|
2022-11-16 14:56:09 +01:00
|
|
|
_hover={{ shadow: 'md' }}
|
2022-04-02 12:03:21 +02:00
|
|
|
transition="box-shadow 200ms, border-color 200ms"
|
|
|
|
rounded="md"
|
2022-12-20 16:55:43 +01:00
|
|
|
bg={bg}
|
2023-06-05 14:49:04 +02:00
|
|
|
borderWidth={1}
|
2022-12-20 16:55:43 +01:00
|
|
|
borderColor={
|
|
|
|
isContextMenuOpened || isPreviewing
|
|
|
|
? previewingBorderColor
|
|
|
|
: borderColor
|
|
|
|
}
|
2022-04-02 12:03:21 +02:00
|
|
|
w="full"
|
|
|
|
>
|
|
|
|
<ItemNodeContent
|
2023-11-08 15:34:16 +01:00
|
|
|
blockType={block.type}
|
2022-04-02 12:03:21 +02:00
|
|
|
item={item}
|
|
|
|
isMouseOver={isMouseOver}
|
|
|
|
indices={indices}
|
2022-02-04 19:00:08 +01:00
|
|
|
/>
|
2023-07-25 17:29:06 +02:00
|
|
|
{typebot && (isConnectable || pathname.endsWith('analytics')) && (
|
2023-11-08 15:34:16 +01:00
|
|
|
<BlockSourceEndpoint
|
2022-04-02 12:03:21 +02:00
|
|
|
source={{
|
2023-11-08 15:34:16 +01:00
|
|
|
blockId: block.id,
|
2022-04-02 12:03:21 +02:00
|
|
|
itemId: item.id,
|
|
|
|
}}
|
2023-11-08 15:34:16 +01:00
|
|
|
groupId={typebot.groups[indices.groupIndex].id}
|
2022-04-02 12:03:21 +02:00
|
|
|
pos="absolute"
|
|
|
|
right="-49px"
|
2023-05-04 09:20:30 -04:00
|
|
|
bottom="9px"
|
2022-04-02 12:03:21 +02:00
|
|
|
pointerEvents="all"
|
2023-07-25 17:29:06 +02:00
|
|
|
isHidden={!isConnectable}
|
2022-04-02 12:03:21 +02:00
|
|
|
/>
|
|
|
|
)}
|
|
|
|
</Flex>
|
2023-06-05 17:33:43 +02:00
|
|
|
</Stack>
|
2022-02-04 19:00:08 +01:00
|
|
|
)}
|
|
|
|
</ContextMenu>
|
|
|
|
)
|
|
|
|
}
|