129 lines
4.1 KiB
TypeScript
129 lines
4.1 KiB
TypeScript
import React, { FC, useState } from 'react';
|
|
import { Tree, Badge, TreeDataNode, Space, TreeProps } from 'antd';
|
|
import theme from 'antd/es/theme'
|
|
import { CloseOutlined, EditOutlined, SettingOutlined } from '@ant-design/icons'
|
|
import { ModalForm, ProFormText } from '@ant-design/pro-components';
|
|
import './index.less'
|
|
|
|
const componentName = 'zhst-biz-tree'
|
|
const { useToken } = theme
|
|
|
|
export interface BoxTreeProps extends TreeProps {
|
|
data: TreeDataNode[]
|
|
treeCheckable?: boolean
|
|
showItemOption?: boolean
|
|
customOptions?: any;
|
|
onItemCheck?: TreeProps['onCheck']
|
|
onItemSelect?: TreeProps['onSelect']
|
|
onItemSetting?: (_data: any) => void
|
|
onItemDelete?: (_data: any) => void
|
|
onItemRename?: (_nodeData: any) => void
|
|
onItemRenameFinish?: (_data: any, _nodeData: any) => Promise<any>
|
|
}
|
|
|
|
const boxTree: FC<BoxTreeProps> = (props) => {
|
|
const {
|
|
onItemSelect,
|
|
onItemCheck,
|
|
onItemSetting,
|
|
onItemDelete,
|
|
data = [],
|
|
showItemOption = true,
|
|
treeCheckable = false,
|
|
onItemRename,
|
|
onItemRenameFinish,
|
|
customOptions
|
|
} = props
|
|
const { token } = useToken()
|
|
const [checkedItem, setCheckedItem] = useState<React.Key>('')
|
|
|
|
const cameraStatus = new Map([
|
|
['0', 'error'],
|
|
['1', 'success'],
|
|
['3', 'processing'],
|
|
['4', 'default'],
|
|
])
|
|
|
|
return (
|
|
<Tree
|
|
checkable={treeCheckable}
|
|
blockNode
|
|
onSelect={(selectedKeys, info) => {
|
|
setCheckedItem(selectedKeys[0])
|
|
onItemSelect?.(selectedKeys, info)
|
|
}}
|
|
onCheck={onItemCheck}
|
|
treeData={data}
|
|
titleRender={(_nodeData) => {
|
|
return (
|
|
<div className={`${componentName}-item-render`}>
|
|
{/* @ts-ignore */}
|
|
{!_nodeData.children && _nodeData.isCamera && <Badge style={{ marginRight: '6px' }} status={cameraStatus.get(_nodeData.status || '4')} />}
|
|
<span
|
|
// @ts-ignore
|
|
style={(checkedItem === _nodeData.key) && _nodeData.isCamera ? {
|
|
color: token.colorPrimary
|
|
} : {}}
|
|
>
|
|
{_nodeData.title as any}
|
|
</span>
|
|
{showItemOption && (
|
|
<Space className={`${componentName}-item-render_right`} style={{ float:'right' }} >
|
|
{customOptions || (
|
|
<>
|
|
<ModalForm
|
|
title="重命名"
|
|
width={600}
|
|
modalProps={{ destroyOnClose: true }}
|
|
layout='horizontal'
|
|
labelCol={{ span: 6 }}
|
|
wrapperCol={{ span: 18 }}
|
|
trigger={<EditOutlined onClick={(e) => {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
onItemRename?.(_nodeData)
|
|
}} />}
|
|
submitter={{
|
|
searchConfig: {
|
|
submitText: '确定',
|
|
resetText: '取消',
|
|
},
|
|
}}
|
|
onFinish={async (value) => onItemRenameFinish?.(value, _nodeData)}
|
|
>
|
|
<ProFormText
|
|
rules={[
|
|
{
|
|
required: true,
|
|
},
|
|
]}
|
|
width="md"
|
|
name="name"
|
|
label="盒子名称"
|
|
placeholder="请输入盒子名称"
|
|
/>
|
|
</ModalForm>
|
|
<SettingOutlined onClick={(e) => {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
onItemSetting?.(_nodeData)}
|
|
} />
|
|
<CloseOutlined onClick={(e) => {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
onItemDelete?.(_nodeData)
|
|
}} />
|
|
</>
|
|
)}
|
|
</Space>
|
|
)}
|
|
</div>
|
|
)
|
|
}}
|
|
{...props}
|
|
/>
|
|
);
|
|
};
|
|
|
|
export default boxTree;
|