2
0

feat(flow): Edge menu on click

This commit is contained in:
Baptiste Arnaud
2022-03-02 09:21:09 +01:00
parent 5a06bb0500
commit 3c6783727e
3 changed files with 92 additions and 9 deletions

View File

@ -7,6 +7,9 @@ import {
getSourceEndpointId,
} from 'services/graph'
import { Edge as EdgeProps } from 'models'
import { Portal, useDisclosure } from '@chakra-ui/react'
import { useTypebot } from 'contexts/TypebotContext'
import { EdgeMenu } from './EdgeMenu'
export type AnchorsPositionProps = {
sourcePosition: Coordinates
@ -16,6 +19,7 @@ export type AnchorsPositionProps = {
}
export const Edge = ({ edge }: { edge: EdgeProps }) => {
const { deleteEdge } = useTypebot()
const {
previewingEdge,
sourceEndpoints,
@ -23,7 +27,11 @@ export const Edge = ({ edge }: { edge: EdgeProps }) => {
blocksCoordinates,
graphOffsetY,
} = useGraph()
const isPreviewing = previewingEdge?.id === edge.id
const [isMouseOver, setIsMouseOver] = useState(false)
const { isOpen, onOpen, onClose } = useDisclosure()
const [edgeMenuPosition, setEdgeMenuPosition] = useState({ x: 0, y: 0 })
const isPreviewing = isMouseOver || previewingEdge?.id === edge.id
const sourceBlockCoordinates =
blocksCoordinates && blocksCoordinates[edge.from.blockId]
@ -74,7 +82,31 @@ export const Edge = ({ edge }: { edge: EdgeProps }) => {
sourceTop,
])
const handleMouseEnter = () => setIsMouseOver(true)
const handleMouseLeave = () => setIsMouseOver(false)
const handleEdgeClick = (e: React.MouseEvent) => {
setEdgeMenuPosition({ x: e.clientX, y: e.clientY })
onOpen()
}
const handleDeleteEdge = () => deleteEdge(edge.id)
return (
<>
<path
data-testid="clickable-edge"
d={path}
strokeWidth="12px"
stroke="white"
fill="none"
pointerEvents="stroke"
style={{ cursor: 'pointer', visibility: 'hidden' }}
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
onClick={handleEdgeClick}
/>
<path
data-testid="edge"
d={path}
@ -83,5 +115,14 @@ export const Edge = ({ edge }: { edge: EdgeProps }) => {
markerEnd={isPreviewing ? 'url(#blue-arrow)' : 'url(#arrow)'}
fill="none"
/>
<Portal>
<EdgeMenu
isOpen={isOpen}
position={edgeMenuPosition}
onDeleteEdge={handleDeleteEdge}
onClose={onClose}
/>
</Portal>
</>
)
}

View File

@ -0,0 +1,37 @@
import { Menu, MenuButton, MenuList, MenuItem } from '@chakra-ui/react'
import { TrashIcon } from 'assets/icons'
import React from 'react'
type Props = {
isOpen: boolean
position: { x: number; y: number }
onDeleteEdge: () => void
onClose: () => void
}
export const EdgeMenu = ({
isOpen,
onClose,
position,
onDeleteEdge,
}: Props) => {
return (
<Menu isOpen={isOpen} gutter={0} onClose={onClose} isLazy>
<MenuButton
aria-hidden={true}
w={1}
h={1}
pos="absolute"
style={{
left: position.x,
top: position.y,
}}
/>
<MenuList>
<MenuItem icon={<TrashIcon />} onClick={onDeleteEdge}>
Delete
</MenuItem>
</MenuList>
</Menu>
)
}

View File

@ -50,6 +50,11 @@ test.describe.parallel('Editor', () => {
)
await expect(page.locator('[data-testid="edge"] >> nth=0')).toBeVisible()
await expect(page.locator('[data-testid="edge"] >> nth=1')).toBeVisible()
await page.click('[data-testid="clickable-edge"] >> nth=0', { force: true })
await page.click('text=Delete')
const total = await page.locator('[data-testid="edge"]').count()
expect(total).toBe(1)
})
test('Drag and drop steps and items should work', async ({ page }) => {
const typebotId = generate()