import React, { useEffect, useMemo, useState } from "react"; import { Button, Input, Dropdown, Tooltip, MenuProps, Divider } from "antd"; import { LeftOutlined, MenuOutlined } from "@ant-design/icons"; import logo from "@/assets/logo.png"; import { useModel, Icon } from "umi"; import { addTopic } from "../../mindMap"; import { TopicType } from "@/enum"; import { selectTopic, addBorder, addSummary } from "@/utils/mindmapHander"; import { createNew } from "@/utils"; export default function index() { const { mindProjectInfo, setMindProjectInfo, canRedo, canUndo, onRedo, onUndo, enableFormatBrush, toggleFormatBrush, graph, selectedCell, setCorrelationEdgeInfo, } = useModel("mindMapModel"); const currentNode = useMemo(() => { return selectedCell.filter(cell => cell.isNode()); }, [selectedCell]); const [title, setTitle] = useState<string>(mindProjectInfo?.name || ""); useEffect(() => { setTitle(mindProjectInfo?.name || ""); }, [mindProjectInfo?.name]) const handleChangeTitle = () => { mindProjectInfo && setMindProjectInfo({ ...mindProjectInfo, name: title, }) } // 预览 todo const handlePreview = () => {}; // 保存 todo const handleSave = () => {}; // 克隆 todo const handleClone = () => {}; // 历史记录 todo const handleHistory = () => {}; // 查找替换 const handleReplace = () => {}; // 增加子主题 const handleAddSubTopic = () => { if(!currentNode.length) return; const topic = addTopic( currentNode[0].data.type === TopicType.main ? TopicType.branch : TopicType.sub, setMindProjectInfo, currentNode[0] ); graph && selectTopic(graph, topic); }; // 添加边框 const handleAddBorder = () => { addBorder(currentNode.filter(item => item.data.parentId)); } // 添加概要 const handleAddSummary = () => { addSummary(currentNode.filter(item => item.data.parentId)) } // 添加关联线 const handleAddCorrelation = () => { if(!currentNode.length) return; setCorrelationEdgeInfo(currentNode[0]); }; const menuData: MenuProps["items"] = [ { key: "1", label: "新建", icon: <i className="w-20px iconfont icon-zengjiahuamian-1" />, children: [ { key: "1-1-1", label: "流程图", icon: <Icon width="20" className="mt-5px" icon="local:flow" />, onClick: () => { createNew("flow"); }, }, { key: "1-1-2", label: "思维导图", icon: <Icon width="20" className="mt-5px" icon="local:mind" />, onClick: () => { createNew("mindmap"); }, }, { key: "1-1-3", label: "UML", icon: <Icon width="20" className="mt-5px" icon="local:uml" />, onClick: () => { createNew("uml"); }, }, { key: "1-1-4", label: "网络拓扑图", icon: <Icon width="20" className="mt-5px" icon="local:net" />, onClick: () => { createNew("net"); }, }, { key: "1-1-5", label: "组织结构图", icon: <Icon width="20" className="mt-5px" icon="local:flow" />, onClick: () => { createNew("org"); }, }, { key: "1-1-6", label: "BPMN", icon: <Icon width="20" className="mt-5px" icon="local:bpmn" />, onClick: () => { createNew("bpmn"); }, }, ], }, // { // key: "2", // label: "预览", // icon: <i className="w-20px iconfont icon-yulan" />, // onClick: handlePreview, // }, { key: "3", label: ( <div className="flex justify-between"> <span>保存</span> <span>Ctrl+S</span> </div> ), icon: <i className="w-20px iconfont icon-shangchuan" />, onClick: handleSave, }, { key: "4", label: "克隆", icon: <i className="w-20px iconfont icon-niantie-1" />, onClick: handleClone, }, { key: "5", label: "查找替换", icon: <i className="w-20px iconfont icon-lishijilu" />, onClick: handleReplace, }, { key: "6", label: "历史记录", icon: <i className="w-20px iconfont icon-lishijilu" />, onClick: handleHistory, }, // { // key: "1-8", // type: "divider", // }, ]; const noParent = useMemo(() => { const nodes = selectedCell?.filter(cell => cell.isNode()); return !!(nodes.length && !nodes.find(node => !node.data?.parentId)); }, [selectedCell]); return ( <div className="absolute absolute top-8px left-8px bg-white shadow-md flex items-center gap-4px rounded-4px px-8px"> <Button type="text" icon={<LeftOutlined />}></Button> <Dropdown trigger={["hover"]} menu={{ items: menuData, style: { width: 200 } }} > <div className="flex items-center gap-4px"> <img className="w-22px" src={logo} /> <MenuOutlined /> </div> </Dropdown> <div className="flex flex-col leading-32px"> {mindProjectInfo && ( <Input className="text-16px max-w-100px" variant="borderless" value={title} onChange={(e) => setTitle(e.target.value) } onBlur={handleChangeTitle} onPressEnter={handleChangeTitle} /> )} </div> <Tooltip placement="bottom" title="撤销"> <Button type="text" icon={<i className="iconfont icon-undo"></i>} disabled={!canUndo} onClick={onUndo} /> </Tooltip> <Tooltip placement="bottom" title="恢复"> <Button type="text" icon={<i className="iconfont icon-redo"></i>} disabled={!canRedo} onClick={onRedo} /> </Tooltip> <Tooltip placement="bottom" title={`格式刷${enableFormatBrush ? "生效中按ESC取消" : "(Ctrl+Shift+C)"}`} > <Button type="text" icon={<i className="iconfont icon-geshishua"></i>} disabled={!currentNode?.length} className={ enableFormatBrush && currentNode?.length ? "active" : "" } onClick={() => graph && toggleFormatBrush(graph)} /> </Tooltip> <Divider type="vertical" /> <Tooltip placement="bottom" title="子主题"> <Button type="text" icon={<i className="iconfont icon-zizhuti"></i>} disabled={!currentNode.length} onClick={handleAddSubTopic} /> </Tooltip> <Tooltip placement="bottom" title="关联线"> <Button type="text" icon={<i className="iconfont icon-guanlianxian"></i>} disabled={!currentNode.length} onClick={handleAddCorrelation} /> </Tooltip> <Tooltip placement="bottom" title="概要"> <Button type="text" icon={<i className="iconfont icon-summary-outline"></i>} disabled={!noParent} onClick={handleAddSummary} /> </Tooltip> <Tooltip placement="bottom" title="外框"> <Button type="text" icon={<i className="iconfont icon-waikuang"></i>} disabled={!noParent} onClick={handleAddBorder} /> </Tooltip> </div> ); }