131 lines
4.1 KiB
TypeScript
131 lines
4.1 KiB
TypeScript
import React, { useState } from 'react';
|
|
import { Button, Card, ConfigProvider, theme, Flex, Input, InputProps, TransferProps, TreeDataNode, TreeProps, Tree } from 'antd';
|
|
import './index.less'
|
|
import { DeleteOutlined, DoubleRightOutlined, SearchOutlined } from '@ant-design/icons';
|
|
|
|
const componentName = 'zhst-biz-treeTransfer'
|
|
|
|
export interface TreeTransferProps {
|
|
dataSource: TreeDataNode[]
|
|
treeProps?: TreeProps
|
|
searchInputProps?: InputProps
|
|
targetItems: TreeDataNode[];
|
|
checkedKeys: string[];
|
|
onTreeSelect?: TreeProps['onSelect']
|
|
onTreeCheck?: TreeProps['onCheck']
|
|
onItemDelete?: (key: string, info?: TreeDataNode) => void
|
|
onChange?: TransferProps['onChange'];
|
|
onOk?: (data: any) => void;
|
|
onReset?: () => void;
|
|
}
|
|
|
|
const { useToken } = theme
|
|
|
|
const TreeTransfer: React.FC<TreeTransferProps> = ({
|
|
dataSource,
|
|
treeProps,
|
|
searchInputProps,
|
|
targetItems = [],
|
|
checkedKeys = [],
|
|
onTreeCheck,
|
|
onTreeSelect,
|
|
onItemDelete,
|
|
onOk,
|
|
onReset
|
|
}) => {
|
|
|
|
const { token } = useToken()
|
|
const [keyWords, setKeyWords ] = useState('')
|
|
|
|
function findNodesWithKeyword(_keyWords: string, _treeData: TreeDataNode[]) {
|
|
// @ts-ignore
|
|
function dfs(node: any) {
|
|
return node.filter((item: { title: string | string[]; }) => item.title.includes(_keyWords))
|
|
}
|
|
|
|
const data = dfs(_treeData)
|
|
return data || [];
|
|
}
|
|
|
|
return (
|
|
<Flex gap={20} className={componentName} align='center' justify='center'>
|
|
<div className={`${componentName}-left`}>
|
|
<Card
|
|
className={`${componentName}-left_card`}
|
|
title={<div style={{ textAlign: 'center' }} >可选择的范围</div>}
|
|
>
|
|
<Input prefix={<SearchOutlined />} onChange={e => setKeyWords(e.target.value)} placeholder='请输入设备名称' {...searchInputProps} />
|
|
<ConfigProvider
|
|
theme={{
|
|
components: {
|
|
Tree: {
|
|
colorBgContainer: '#FCFCFC'
|
|
}
|
|
}
|
|
}}
|
|
>
|
|
<Tree
|
|
className={`${componentName}-left_card-tree`}
|
|
height={420}
|
|
blockNode
|
|
checkable
|
|
checkedKeys={checkedKeys}
|
|
treeData={findNodesWithKeyword(keyWords, dataSource)}
|
|
onCheck={(keys, info) => onTreeCheck?.(keys, info)}
|
|
onSelect={(keys, info) => onTreeSelect?.(keys, info)}
|
|
{...treeProps}
|
|
/>
|
|
</ConfigProvider>
|
|
</Card>
|
|
</div>
|
|
<DoubleRightOutlined/>
|
|
<div className={`${componentName}-right`}>
|
|
<Card
|
|
className={`${componentName}-right_card`}
|
|
title={<div style={{ textAlign: 'center' }}>已选择的范围</div>}
|
|
>
|
|
<div
|
|
className={`${componentName}-right_card__items`}
|
|
>
|
|
{targetItems.map(item => (
|
|
<div
|
|
className={`${componentName}-right_card__items___item`}
|
|
key={item.key}
|
|
onMouseEnter={(e: any) => {
|
|
e.target.style.backgroundColor = token.colorPrimaryBg
|
|
e.target.style.color = token.colorPrimary
|
|
}}
|
|
onMouseLeave={(e: any) => {
|
|
e.target.style.color = token.colorText
|
|
e.target.style.backgroundColor = null
|
|
}}
|
|
>
|
|
{item.title as any}
|
|
<div style={{ float: 'right' }}>
|
|
<DeleteOutlined onClick={() => {
|
|
// const { root, keys } = getAllRootKeyById(item.key as string, dataSource)
|
|
onItemDelete?.(item.key as string, item)
|
|
}} />
|
|
</div>
|
|
</div>
|
|
))}
|
|
|
|
</div>
|
|
<Flex
|
|
className={`${componentName}-right_card__btns`}
|
|
>
|
|
<Button style={{ marginRight: 8, width: '50%' }} disabled={targetItems.length <= 0} onClick={onReset}>重置</Button>
|
|
<Button
|
|
style={{ width: '50%' }}
|
|
type='primary'
|
|
onClick={() => onOk?.(targetItems)}
|
|
>确定</Button>
|
|
</Flex>
|
|
</Card>
|
|
</div>
|
|
</Flex>
|
|
);
|
|
}
|
|
|
|
export default TreeTransfer
|