2
0

fix(editor): 🐛 Edge not properly connecting to step target

This commit is contained in:
Baptiste Arnaud
2022-02-19 18:09:09 +01:00
parent 3456e5af82
commit 7a4b96ff7e
6 changed files with 122 additions and 118 deletions

View File

@@ -1,5 +1,5 @@
import { Coordinates, useGraph } from 'contexts/GraphContext' import { Coordinates, useGraph } from 'contexts/GraphContext'
import React, { useMemo } from 'react' import React, { useLayoutEffect, useMemo, useState } from 'react'
import { import {
getAnchorsPosition, getAnchorsPosition,
computeEdgePath, computeEdgePath,
@@ -38,23 +38,22 @@ export const Edge = ({ edge }: { edge: EdgeProps }) => {
getSourceEndpointId(edge) getSourceEndpointId(edge)
), ),
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps
[ [sourceBlockCoordinates?.y, edge, sourceEndpoints]
sourceBlockCoordinates?.x,
sourceBlockCoordinates?.y,
edge,
sourceEndpoints,
]
) )
const targetTop = useMemo(
() => getEndpointTopOffset(targetEndpoints, graphOffsetY, edge?.to.stepId), const [targetTop, setTargetTop] = useState(
// eslint-disable-next-line react-hooks/exhaustive-deps getEndpointTopOffset(targetEndpoints, graphOffsetY, edge?.to.stepId)
[
targetBlockCoordinates?.x,
targetBlockCoordinates?.y,
edge?.to.stepId,
targetEndpoints,
]
) )
useLayoutEffect(() => {
setTargetTop(
getEndpointTopOffset(targetEndpoints, graphOffsetY, edge?.to.stepId)
)
}, [
targetBlockCoordinates?.y,
targetEndpoints,
graphOffsetY,
edge?.to.stepId,
])
const path = useMemo(() => { const path = useMemo(() => {
if (!sourceBlockCoordinates || !targetBlockCoordinates || !sourceTop) if (!sourceBlockCoordinates || !targetBlockCoordinates || !sourceTop)

View File

@@ -10,6 +10,7 @@ import { Block, DraggableStepType, PublicTypebot, Typebot } from 'models'
import { generate } from 'short-uuid' import { generate } from 'short-uuid'
import { AnswersCount } from 'services/analytics' import { AnswersCount } from 'services/analytics'
import { useDebounce } from 'use-debounce' import { useDebounce } from 'use-debounce'
import { DraggableCore, DraggableData, DraggableEvent } from 'react-draggable'
declare const window: { chrome: unknown | undefined } declare const window: { chrome: unknown | undefined }
@@ -115,34 +116,46 @@ export const Graph = ({
useEventListener('mouseup', handleMouseUp, graphContainerRef.current) useEventListener('mouseup', handleMouseUp, graphContainerRef.current)
useEventListener('mouseup', handleGlobalMouseUp) useEventListener('mouseup', handleGlobalMouseUp)
useEventListener('click', handleClick, editorContainerRef.current) useEventListener('click', handleClick, editorContainerRef.current)
const onDrag = (event: DraggableEvent, draggableData: DraggableData) => {
const { deltaX, deltaY } = draggableData
setGraphPosition({
x: graphPosition.x + deltaX,
y: graphPosition.y + deltaY,
scale: 1,
})
}
return ( return (
<Flex <DraggableCore onDrag={onDrag}>
ref={graphContainerRef}
onMouseDown={handleMouseDown}
onMouseMove={handleMouseMove}
position="relative"
{...props}
>
<Flex <Flex
flex="1" ref={graphContainerRef}
w="full" onMouseDown={handleMouseDown}
h="full" onMouseMove={handleMouseMove}
position="absolute" position="relative"
style={{ {...props}
transform,
}}
willChange="transform"
transformOrigin="0px 0px 0px"
> >
<Edges <Flex
edges={typebot?.edges ?? []} flex="1"
answersCounts={answersCounts} w="full"
onUnlockProPlanClick={onUnlockProPlanClick} h="full"
/> position="absolute"
{typebot?.blocks.map((block, idx) => ( style={{
<BlockNode block={block as Block} blockIndex={idx} key={block.id} /> transform,
))} }}
willChange="transform"
transformOrigin="0px 0px 0px"
>
<Edges
edges={typebot?.edges ?? []}
answersCounts={answersCounts}
onUnlockProPlanClick={onUnlockProPlanClick}
/>
{typebot?.blocks.map((block, idx) => (
<BlockNode block={block as Block} blockIndex={idx} key={block.id} />
))}
</Flex>
</Flex> </Flex>
</Flex> </DraggableCore>
) )
} }

View File

@@ -3,7 +3,6 @@ import {
EditableInput, EditableInput,
EditablePreview, EditablePreview,
Stack, Stack,
useEventListener,
} from '@chakra-ui/react' } from '@chakra-ui/react'
import React, { useEffect, useRef, useState } from 'react' import React, { useEffect, useRef, useState } from 'react'
import { Block } from 'models' import { Block } from 'models'
@@ -16,6 +15,7 @@ import { ContextMenu } from 'components/shared/ContextMenu'
import { BlockNodeContextMenu } from './BlockNodeContextMenu' import { BlockNodeContextMenu } from './BlockNodeContextMenu'
import { useDebounce } from 'use-debounce' import { useDebounce } from 'use-debounce'
import { setMultipleRefs } from 'services/utils' import { setMultipleRefs } from 'services/utils'
import { DraggableCore, DraggableData, DraggableEvent } from 'react-draggable'
type Props = { type Props = {
block: Block block: Block
@@ -67,25 +67,7 @@ export const BlockNode = ({ block, blockIndex }: Props) => {
const handleMouseDown = (e: React.MouseEvent) => { const handleMouseDown = (e: React.MouseEvent) => {
e.stopPropagation() e.stopPropagation()
setIsMouseDown(true)
} }
const handleMouseUp = () => {
setIsMouseDown(false)
}
useEventListener('mouseup', handleMouseUp)
const handleMouseMove = (event: MouseEvent) => {
if (!isMouseDown) return
const { movementX, movementY } = event
if (!blockCoordinates) return
updateBlockCoordinates(block.id, {
x: blockCoordinates.x + movementX,
y: blockCoordinates.y + movementY,
})
}
useEventListener('mousemove', handleMouseMove)
const handleMouseEnter = () => { const handleMouseEnter = () => {
if (isReadOnly) return if (isReadOnly) return
@@ -101,61 +83,71 @@ export const BlockNode = ({ block, blockIndex }: Props) => {
if (connectingIds) setConnectingIds({ ...connectingIds, target: undefined }) if (connectingIds) setConnectingIds({ ...connectingIds, target: undefined })
} }
const onDrag = (event: DraggableEvent, draggableData: DraggableData) => {
const { deltaX, deltaY } = draggableData
updateBlockCoordinates(block.id, {
x: blockCoordinates.x + deltaX,
y: blockCoordinates.y + deltaY,
})
}
return ( return (
<ContextMenu<HTMLDivElement> <ContextMenu<HTMLDivElement>
renderMenu={() => <BlockNodeContextMenu blockIndex={blockIndex} />} renderMenu={() => <BlockNodeContextMenu blockIndex={blockIndex} />}
isDisabled={isReadOnly} isDisabled={isReadOnly}
> >
{(ref, isOpened) => ( {(ref, isOpened) => (
<Stack <DraggableCore onDrag={onDrag} onMouseDown={(e) => e.stopPropagation()}>
ref={setMultipleRefs([ref, blockRef])} <Stack
data-testid="block" ref={setMultipleRefs([ref, blockRef])}
p="4" data-testid="block"
rounded="lg" p="4"
bgColor="blue.50" rounded="lg"
backgroundImage="linear-gradient(rgb(235, 239, 244), rgb(231, 234, 241))" bgColor="blue.50"
borderWidth="2px" backgroundImage="linear-gradient(rgb(235, 239, 244), rgb(231, 234, 241))"
borderColor={ borderWidth="2px"
isConnecting || isOpened || isPreviewing ? 'blue.400' : 'white' borderColor={
} isConnecting || isOpened || isPreviewing ? 'blue.400' : 'white'
w="300px" }
transition="border 300ms, box-shadow 200ms" w="300px"
pos="absolute" transition="border 300ms, box-shadow 200ms"
style={{ pos="absolute"
transform: `translate(${blockCoordinates?.x ?? 0}px, ${ style={{
blockCoordinates?.y ?? 0 transform: `translate(${blockCoordinates?.x ?? 0}px, ${
}px)`, blockCoordinates?.y ?? 0
}} }px)`,
onMouseDown={handleMouseDown} }}
onMouseEnter={handleMouseEnter} onMouseDown={handleMouseDown}
onMouseLeave={handleMouseLeave} onMouseEnter={handleMouseEnter}
cursor={isMouseDown ? 'grabbing' : 'pointer'} onMouseLeave={handleMouseLeave}
boxShadow="0px 0px 0px 1px #e9edf3;" cursor={isMouseDown ? 'grabbing' : 'pointer'}
_hover={{ shadow: 'lg' }} boxShadow="0px 0px 0px 1px #e9edf3;"
> _hover={{ shadow: 'lg' }}
<Editable
defaultValue={block.title}
onSubmit={handleTitleSubmit}
fontWeight="semibold"
pointerEvents={isReadOnly ? 'none' : 'auto'}
> >
<EditablePreview <Editable
_hover={{ bgColor: 'gray.300' }} defaultValue={block.title}
px="1" onSubmit={handleTitleSubmit}
userSelect={'none'} fontWeight="semibold"
/> pointerEvents={isReadOnly ? 'none' : 'auto'}
<EditableInput minW="0" px="1" /> >
</Editable> <EditablePreview
{typebot && ( _hover={{ bgColor: 'gray.300' }}
<StepNodesList px="1"
blockId={block.id} userSelect={'none'}
steps={block.steps} />
blockIndex={blockIndex} <EditableInput minW="0" px="1" />
blockRef={ref} </Editable>
isStartBlock={isStartBlock} {typebot && (
/> <StepNodesList
)} blockId={block.id}
</Stack> steps={block.steps}
blockIndex={blockIndex}
blockRef={ref}
isStartBlock={isStartBlock}
/>
)}
</Stack>
</DraggableCore>
)} )}
</ContextMenu> </ContextMenu>
) )

View File

@@ -66,6 +66,7 @@
"qs": "^6.10.3", "qs": "^6.10.3",
"react": "^17.0.2", "react": "^17.0.2",
"react-dom": "^17.0.2", "react-dom": "^17.0.2",
"react-draggable": "^4.4.4",
"react-table": "^7.7.0", "react-table": "^7.7.0",
"short-uuid": "^4.2.0", "short-uuid": "^4.2.0",
"slate": "^0.72.8", "slate": "^0.72.8",

View File

@@ -6,15 +6,6 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
if (req.method === 'POST') { if (req.method === 'POST') {
const { from, port, isTlsEnabled, username, password, host, to } = const { from, port, isTlsEnabled, username, password, host, to } =
JSON.parse(req.body) as SmtpCredentialsData & { to: string } JSON.parse(req.body) as SmtpCredentialsData & { to: string }
console.log({
host,
port,
secure: isTlsEnabled ?? undefined,
auth: {
user: username,
pass: password,
},
})
const transporter = createTransport({ const transporter = createTransport({
host, host,
port, port,

View File

@@ -11547,7 +11547,7 @@ prompts@^2.4.1, prompts@^2.4.2:
kleur "^3.0.3" kleur "^3.0.3"
sisteransi "^1.0.5" sisteransi "^1.0.5"
prop-types@^15.6.2, prop-types@^15.7.2: prop-types@^15.6.0, prop-types@^15.6.2, prop-types@^15.7.2:
version "15.8.1" version "15.8.1"
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5"
integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==
@@ -11817,6 +11817,14 @@ react-dom@17.0.2, react-dom@^17.0.2:
object-assign "^4.1.1" object-assign "^4.1.1"
scheduler "^0.20.2" scheduler "^0.20.2"
react-draggable@^4.4.4:
version "4.4.4"
resolved "https://registry.yarnpkg.com/react-draggable/-/react-draggable-4.4.4.tgz#5b26d9996be63d32d285a426f41055de87e59b2f"
integrity sha512-6e0WdcNLwpBx/YIDpoyd2Xb04PB0elrDrulKUgdrIlwuYvxh5Ok9M+F8cljm8kPXXs43PmMzek9RrB1b7mLMqA==
dependencies:
clsx "^1.1.1"
prop-types "^15.6.0"
react-error-overlay@^6.0.10: react-error-overlay@^6.0.10:
version "6.0.10" version "6.0.10"
resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-6.0.10.tgz#0fe26db4fa85d9dbb8624729580e90e7159a59a6" resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-6.0.10.tgz#0fe26db4fa85d9dbb8624729580e90e7159a59a6"