assistant-note/src/components/ItemTree/index.jsx

256 lines
9.4 KiB
React
Raw Normal View History

2024-01-24 04:59:31 -05:00
import React, {useEffect, useMemo, useState} from 'react';
2024-01-25 04:56:53 -05:00
import {Input, Tree} from 'antd';
2024-02-06 02:19:12 -05:00
import {FolderOutlined, FileMarkdownOutlined, FileOutlined, DeleteOutlined, RedoOutlined} from '@ant-design/icons';
import {message, Popconfirm} from 'antd';
2024-01-25 05:46:51 -05:00
import "./index.less"
2024-02-05 03:34:41 -05:00
2024-01-25 04:56:53 -05:00
const {Search} = Input;
2024-02-05 03:34:41 -05:00
import {useSelector, useDispatch} from "react-redux";
2024-02-06 20:46:28 -05:00
import {addExpandedKeys, addTableBarItem, setExpandedKeys} from "../../redux/tableBarItem_reducer";
2024-02-04 21:59:35 -05:00
import {readDir} from "../../utils/File";
import {nextDirAdd} from "../../redux/dirMessage_reducer";
2024-02-05 03:34:41 -05:00
// const defaultData = [];
2024-01-12 00:13:58 -05:00
// 将树平铺用于查找
const dataList = [];
const generateList = (data) => {
for (let i = 0; i < data.length; i++) {
const node = data[i];
2024-01-25 04:56:53 -05:00
const {key, title, icon} = node;
2024-01-12 00:13:58 -05:00
dataList.push({
key,
title,
icon
});
if (node.children) {
generateList(node.children);
}
}
};
2024-02-05 03:34:41 -05:00
// generateList(defaultData);
2024-01-12 00:13:58 -05:00
const getParentKey = (key, tree) => {
let parentKey;
for (let i = 0; i < tree.length; i++) {
const node = tree[i];
if (node.children) {
if (node.children.some((item) => item.key === key)) {
parentKey = node.key;
} else if (getParentKey(key, node.children)) {
parentKey = getParentKey(key, node.children);
}
}
}
return parentKey;
};
2024-01-24 04:59:31 -05:00
2024-01-25 04:56:53 -05:00
function generateChildList(fileList) {
2024-01-24 04:59:31 -05:00
const result = []
for (let i = 0; i < fileList.length; i++) {
2024-02-05 03:34:41 -05:00
const {fileName, filePath, dirFlag, childList} = fileList[i];
2024-02-04 21:59:35 -05:00
const childListM = []
2024-02-05 03:34:41 -05:00
if (Array.isArray(childList) && childList.length > 0) {
2024-02-04 21:59:35 -05:00
childListM.push(...generateChildList(childList));
}
2024-01-24 04:59:31 -05:00
result.push({
2024-01-25 04:56:53 -05:00
"key": filePath,
2024-02-06 04:08:41 -05:00
"title": titleExtended(fileName,dirFlag,filePath),
2024-02-05 03:34:41 -05:00
"icon": dirFlag ? <FolderOutlined/> : fileName.endsWith(".md") ? <FileMarkdownOutlined/> : <FileOutlined/>,
2024-01-25 04:56:53 -05:00
"dirFlag": dirFlag,
2024-02-04 21:59:35 -05:00
"children": childListM
2024-01-24 04:59:31 -05:00
});
}
return result;
}
2024-01-25 04:56:53 -05:00
2024-02-06 04:08:41 -05:00
const titleExtended = (fileName, dirFlag,filePath) => {
2024-02-06 02:19:12 -05:00
const confirm = (e) => {
console.log(e);
message.success('Click on Yes');
};
const cancel = (e) => {
console.log(e);
message.error('Click on No');
};
2024-02-06 04:08:41 -05:00
return <span title = {filePath}>{fileName}
2024-02-06 02:19:12 -05:00
{dirFlag && <span style={{float: "right"}}>
<Popconfirm
title="更新当前目录"
description="更新当前目录内容"
onConfirm={confirm}
onCancel={cancel}
okText="确认"
cancelText="取消"
>
<RedoOutlined/>
</Popconfirm>
<Popconfirm
title="关闭当前目录"
description="从列表中移除目录并不会删除本地文件"
onConfirm={confirm}
onCancel={cancel}
okText="确认"
cancelText="取消"
>
<DeleteOutlined/>
</Popconfirm>
</span>}
</span>
}
2024-02-05 03:34:41 -05:00
/**
* 将文件信息改为树信息
* @param fileDirDate
* @returns {*[]}
*/
const flushTree = (fileDirDate) => {
2024-02-03 23:30:40 -05:00
const defaultValueStateSet = [];
2024-02-05 03:34:41 -05:00
if (Array.isArray(fileDirDate) && fileDirDate.length > 0) {
2024-02-03 23:30:40 -05:00
for (let i = 0; i < fileDirDate.length; i++) {
const node = fileDirDate[i];
console.log("node:", node)
const {fileName, filePath, childList, dirFlag} = node;
const childListM = []
2024-02-05 03:34:41 -05:00
if (Array.isArray(childList) && childList.length > 0) {
2024-02-03 23:30:40 -05:00
childListM.push(...generateChildList(childList));
2024-01-27 22:48:48 -05:00
}
2024-02-05 03:34:41 -05:00
defaultValueStateSet.push({
"key": filePath,
2024-02-06 04:08:41 -05:00
// 修改属性后此处也需要修改
"title": titleExtended(fileName.substring(fileName.lastIndexOf("/")+1), dirFlag,filePath),
2024-02-05 03:34:41 -05:00
"icon": <FolderOutlined/>,
"dirFlag": dirFlag,
"children": childListM
});
2024-02-06 02:19:12 -05:00
2024-02-03 23:30:40 -05:00
}
}
2024-02-05 03:34:41 -05:00
return defaultValueStateSet;
}
2024-02-05 21:11:26 -05:00
const ItemTree = (prop) => {
2024-02-06 02:19:12 -05:00
console.log("prop.filePath:", prop.filePath)
2024-02-05 03:34:41 -05:00
const dispatch = useDispatch()
2024-02-06 20:46:28 -05:00
// const [expandedKeys, setExpandedKeys] = useState([]);
const expandedKeys = useSelector(state => state.tableBarItem.expandedKeyList)
const [searchValue, setSearchValue] = useState('');
2024-02-05 03:34:41 -05:00
const [autoExpandParent, setAutoExpandParent] = useState(true);
2024-02-05 21:11:26 -05:00
// let filePath = useSelector(state => state.dirMessage.data);
const [defaultValueState, setDefaultValueState] = useState(flushTree(prop.filePath));
useEffect(() => {
setDefaultValueState(flushTree(prop.filePath))
}, [prop]);
2024-01-12 00:13:58 -05:00
const onExpand = (newExpandedKeys) => {
2024-02-06 20:46:28 -05:00
dispatch(setExpandedKeys(newExpandedKeys));
2024-01-12 00:13:58 -05:00
setAutoExpandParent(false);
};
2024-02-05 03:34:41 -05:00
const addChildNode = (valueState, fileStateList) => {
valueState.forEach(file => {
2024-02-06 02:19:12 -05:00
if (fileStateList[0].key.startsWith(file.key)) {
2024-02-05 03:34:41 -05:00
if (file.key === fileStateList[0].key) {
file.children = fileStateList[0].children
} else if (Array.isArray(file.children) && file.children.length > 0) {
addChildNode(file.children, fileStateList)
}
}
})
}
2024-01-12 00:13:58 -05:00
const onChange = (e) => {
2024-01-25 04:56:53 -05:00
const {value} = e.target;
2024-01-12 00:13:58 -05:00
const newExpandedKeys = dataList
.map((item) => {
if (item.title.indexOf(value) > -1) {
2024-02-05 03:34:41 -05:00
return getParentKey(item.key, defaultValueState);
2024-01-12 00:13:58 -05:00
}
return null;
})
.filter((item, i, self) => !!(item && self.indexOf(item) === i));
2024-02-06 20:46:28 -05:00
dispatch(setExpandedKeys(newExpandedKeys));
2024-01-12 00:13:58 -05:00
setSearchValue(value);
setAutoExpandParent(true);
};
2024-01-25 04:56:53 -05:00
const onSelect = (selectedKeys, e) => {
2024-02-04 21:59:35 -05:00
if (e.selected) {
2024-01-25 04:56:53 -05:00
console.log('onSelect.selectedKeys', selectedKeys, e)
2024-02-05 03:34:41 -05:00
if (e.node.dirFlag) {
2024-02-04 21:59:35 -05:00
// 加载目录下一级文件信息
2024-02-05 03:34:41 -05:00
if (!Array.isArray(e.node.children) || e.node.children.length === 0) {
readDir(e.node.key).then(fileStateList => {
if (Array.isArray(fileStateList[0].childList) && fileStateList[0].childList.length > 0) {
dispatch(nextDirAdd({selectDirKey: e.node.key, fileStateList}))
// 添加下级节点
addChildNode(defaultValueState, flushTree(fileStateList))
const result = [...defaultValueState]
2024-02-06 02:19:12 -05:00
console.log("[...defaultValueState]:", result)
2024-02-05 03:34:41 -05:00
setDefaultValueState(result)
}
})
}
// 打开当前目录
2024-02-06 20:46:28 -05:00
dispatch(addExpandedKeys([e.node.key]));
2024-02-05 03:34:41 -05:00
setAutoExpandParent(false);
} else {
2024-02-04 21:59:35 -05:00
// 打开文件
2024-02-05 03:34:41 -05:00
dispatch(addTableBarItem({
2024-02-06 03:03:26 -05:00
label: e.node.title.props.children[0],
2024-02-05 03:34:41 -05:00
children: e.node.key,
key: e.node.key,
activeKey: e.node.key
}))
2024-02-04 21:59:35 -05:00
}
2024-01-25 02:26:23 -05:00
}
}
2024-01-24 04:59:31 -05:00
// const treeData = useMemo(() => {
// const loop = (data) =>
// data.map((item) => {
// const strTitle = item.title;
// const index = strTitle.indexOf(searchValue);
// const beforeStr = strTitle.substring(0, index);
// const afterStr = strTitle.slice(index + searchValue.length);
// const title =
// index > -1 ? (
// <span>{beforeStr}
// <span className="site-tree-search-value">{searchValue}</span>{afterStr}</span>
// ) : (
// <span>{strTitle}</span>
// );
// if (item.children) {
// return {
// title,
// key: item.key,
// icon: item.icon,
// children: loop(item.children),
// };
// }
// return {
// title,
// icon: item.icon,
// key: item.key,
// };
// });
// return loop(defaultData);
// }, [searchValue]);
2024-01-12 00:13:58 -05:00
return (
2024-02-06 02:19:12 -05:00
<div style={{height: "100%"}}>
2024-01-12 00:13:58 -05:00
<Search
style={{marginBottom: 8,}}
placeholder="Search"
onChange={onChange}
/>
<Tree
// 展开/收起节点时触发
onExpand={onExpand}
//(受控)展开指定的树节点
expandedKeys={expandedKeys}
// 是否自动展开父节点
autoExpandParent={autoExpandParent}
2024-01-25 04:56:53 -05:00
showIcon={true}
2024-02-06 20:46:28 -05:00
defaultSelectedKeys={[useSelector(state => state.tableBarItem.activeKey)]}
defaultExpandedKeys={useSelector(state => state.tableBarItem.expandedKeyList)}
2024-01-12 00:13:58 -05:00
// treeNodes 数据,如果设置则不需要手动构造 TreeNode 节点key 在整个树范围内唯一)
2024-01-24 04:59:31 -05:00
treeData={defaultValueState}
2024-01-25 02:26:23 -05:00
onSelect={onSelect}
2024-01-12 00:13:58 -05:00
/>
</div>
);
};
export default ItemTree;