106 lines
3.6 KiB
TypeScript
106 lines
3.6 KiB
TypeScript
import './menu-tree.css';
|
|
import {
|
|
CaretRightOutlined,
|
|
CaretDownOutlined,
|
|
PlusOutlined,
|
|
CloseOutlined,
|
|
EditOutlined,
|
|
} from '@ant-design/icons';
|
|
import {IMenuTree, IMenuTreeItem} from "../../interfaces/menu/IMenuTree.ts";
|
|
import {Popconfirm} from "antd";
|
|
|
|
export default function MenuTree(props: IMenuTree) {
|
|
|
|
const triggerChildren = (item: IMenuTreeItem) => {
|
|
|
|
const trigger = () => {
|
|
item.isOpen = !item.isOpen;
|
|
props.setMenuTreeArray(item);
|
|
}
|
|
|
|
trigger();
|
|
}
|
|
|
|
const renderBtnGroup = (item: IMenuTreeItem, index: number, parent?: IMenuTreeItem) => {
|
|
return (
|
|
<>
|
|
<EditOutlined className="icon" onClick={(e) => {
|
|
e.stopPropagation();
|
|
props.handleEditClick(item);
|
|
}}/>
|
|
<PlusOutlined className="icon" onClick={(e) => {
|
|
e.stopPropagation();
|
|
props.handleAddClick(item);
|
|
}}/>
|
|
<Popconfirm title={false}
|
|
description="确认删除吗?"
|
|
okText="确认"
|
|
cancelText="取消"
|
|
okButtonProps={{
|
|
style: {
|
|
backgroundColor: 'var(--color-primary)'
|
|
}
|
|
}}
|
|
onConfirm={(e) => {
|
|
e?.stopPropagation();
|
|
props.handleRemoveClick(item, index, parent);
|
|
}}
|
|
onCancel={(e) => {
|
|
e?.stopPropagation();
|
|
}}
|
|
>
|
|
<CloseOutlined className="icon" onClick={(e) => {
|
|
e.stopPropagation();
|
|
}}/>
|
|
</Popconfirm>
|
|
|
|
</>
|
|
);
|
|
}
|
|
|
|
const renderLabel = (item: IMenuTreeItem) => {
|
|
const icon = item.isOpen ? <CaretDownOutlined onClick={() => {
|
|
triggerChildren(item)
|
|
}}/> : <CaretRightOutlined onClick={() => {
|
|
triggerChildren(item)
|
|
}}/>;
|
|
const width = 180 - 50 - (item.level * 10) - (5 + (item.isParent ? 8.75 : 0));
|
|
return (
|
|
<>
|
|
{item.isParent ? icon : <></>}
|
|
<span
|
|
className={item.active ? 'active' : ''}
|
|
style={{width: width}}
|
|
onClick={(e) => {
|
|
e.stopPropagation();
|
|
props.handleClick(item);
|
|
}}
|
|
onDoubleClick={() => {
|
|
triggerChildren(item)
|
|
}}>{item.name}</span>
|
|
</>
|
|
)
|
|
}
|
|
|
|
const renderMenu = (children: Array<IMenuTreeItem> | null, parent?: IMenuTreeItem) => {
|
|
if (!children) {
|
|
return <></>
|
|
}
|
|
const lis = children.map((item, index) => {
|
|
const renderChildrenMenu = renderMenu(item.children, item);
|
|
return (
|
|
<li key={item.id}>
|
|
<div className="menu-title">
|
|
<div className="label">{renderLabel(item)}</div>
|
|
<div className="icon-group">{renderBtnGroup(item, index, parent)}</div>
|
|
</div>
|
|
{renderChildrenMenu}
|
|
</li>
|
|
)
|
|
})
|
|
const isOpen = parent ? parent.isOpen : true;
|
|
return <ul style={{display: isOpen ? 'block' : 'none'}}>{lis}</ul>
|
|
}
|
|
|
|
return <div className="menu-tree">{renderMenu(props.menus)}</div>
|
|
} |