import { useCallback, useMemo, useState } from 'react'; import { useClientContext } from '@flowgram.ai/fixed-layout-editor'; import { type FlowNodeEntity } from '@flowgram.ai/fixed-layout-editor'; import { Popover, message, Typography } from 'antd'; import { NodeList } from '../node-list'; import { readData } from '../../shortcuts/utils'; import { generateNodeId } from './utils'; import { PasteIcon, Wrap } from './styles'; import { CopyOutlined, PlusOutlined } from '@ant-design/icons'; const generateNewIdForChildren = (n: FlowNodeEntity): FlowNodeEntity => { if (n.blocks) { return { ...n, id: generateNodeId(n), blocks: n.blocks.map((b) => generateNewIdForChildren(b)), } as FlowNodeEntity; } else { return { ...n, id: generateNodeId(n), } as FlowNodeEntity; } }; export default function Adder(props: { from: FlowNodeEntity; to?: FlowNodeEntity; hoverActivated: boolean; }) { const { from } = props; const isVertical = from.isVertical; const [visible, setVisible] = useState(false); const { playground, operation, clipboard } = useClientContext(); const [pasteIconVisible, setPasteIconVisible] = useState(false); const activated = useMemo( () => props.hoverActivated && !playground.config.readonly, [props.hoverActivated, playground.config.readonly] ); const add = (addProps: any) => { const blocks = addProps.blocks ? addProps.blocks : undefined; const block = operation.addFromNode(from, { ...addProps, blocks, }); setTimeout(() => { playground.scrollToView({ bounds: block.bounds, scrollToCenter: true, }); }, 10); setVisible(false); }; const handlePaste = useCallback(async (e: any) => { try { e.stopPropagation(); const nodes = await readData(clipboard); if (!nodes) { message.error({ content: 'The clipboard content has been updated, please copy the node again.', }); return; } nodes.reverse().forEach((n: FlowNodeEntity) => { const newNodeData = generateNewIdForChildren(n); operation.addFromNode(from, newNodeData); }); message.success({ content: 'Paste successfully!', }); } catch (error) { console.error(error); message.error({ content: ( Paste failed, please check if you have permission to read the clipboard, ), }); } }, []); if (playground.config.readonly) return null; return ( } placement="right" trigger="click" align={{ offset: [30, 0] }} overlayStyle={{ padding: 0, }} > e.stopPropagation()} > {props.hoverActivated ? ( { setVisible(true); }} onMouseEnter={() => { const data = clipboard.readText(); setPasteIconVisible(!!data); }} style={{ backgroundColor: '#fff', color: '#3370ff', borderRadius: 15, }} /> ) : ( '' )} {activated && pasteIconVisible && ( )} ); }