feat:菜单功能
This commit is contained in:
parent
9037bfe7c9
commit
fe07a2f982
|
@ -0,0 +1,15 @@
|
||||||
|
import React from 'react';
|
||||||
|
import {Menu} from 'antd';
|
||||||
|
import {useDispatch} from "react-redux";
|
||||||
|
import {dirRemove} from "../../../redux/dirMessage_reducer";
|
||||||
|
|
||||||
|
function CloseDir (prop) {
|
||||||
|
console.log("prop",prop)
|
||||||
|
const dispatch = useDispatch()
|
||||||
|
const closeDir = ()=>{
|
||||||
|
dispatch(dirRemove({selectDirKey: prop.filePath}))
|
||||||
|
prop.closeMenu()
|
||||||
|
}
|
||||||
|
return <span onClick={closeDir}>关闭目录</span>
|
||||||
|
}
|
||||||
|
export default CloseDir;
|
|
@ -0,0 +1,56 @@
|
||||||
|
import React, {useRef, useState} from 'react';
|
||||||
|
import {Input, message, Modal} from 'antd';
|
||||||
|
import {useDispatch} from "react-redux";
|
||||||
|
import {newFile} from "../../../utils/File";
|
||||||
|
import {dirFileAdd} from "../../../redux/dirMessage_reducer";
|
||||||
|
import {addTableBarItem} from "../../../redux/tableBarItem_reducer";
|
||||||
|
import {isEmpty} from "../../../utils/ObjectUtils";
|
||||||
|
|
||||||
|
const DirAddFile = (prop) => {
|
||||||
|
console.log("prop",prop)
|
||||||
|
const [isModalOpen, setIsModalOpen] = useState(false);
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
const inputValue = useRef(null);
|
||||||
|
const [messageApi, contextHolder] = message.useMessage();
|
||||||
|
|
||||||
|
const showModal = () => {
|
||||||
|
setIsModalOpen(true);
|
||||||
|
};
|
||||||
|
const handleOk = () => {
|
||||||
|
console.log("inputValue",inputValue.current.input.value)
|
||||||
|
// 如果为空则提示
|
||||||
|
if (isEmpty(inputValue.current.input.value)){
|
||||||
|
let messageType = messageApi.open({
|
||||||
|
type: 'error',
|
||||||
|
content: '文件名不能为空',
|
||||||
|
});
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 新建文件
|
||||||
|
let fileName = prop.filePath+"/"+inputValue.current.input.value+".lexical"
|
||||||
|
newFile(fileName)
|
||||||
|
// 更新树
|
||||||
|
dispatch(dirFileAdd({"filePath":prop.filePath,fileName}))
|
||||||
|
// 选中key,添加bar
|
||||||
|
dispatch(addTableBarItem({
|
||||||
|
label: inputValue.current.input.value+".lexical",
|
||||||
|
children: fileName,
|
||||||
|
key: fileName,
|
||||||
|
activeKey: fileName
|
||||||
|
}))
|
||||||
|
setIsModalOpen(false);
|
||||||
|
prop.closeMenu()
|
||||||
|
};
|
||||||
|
const handleCancel = () => {
|
||||||
|
setIsModalOpen(false);
|
||||||
|
prop.closeMenu()
|
||||||
|
};
|
||||||
|
return <>
|
||||||
|
{contextHolder}
|
||||||
|
<span onClick={showModal}>添加文件</span>
|
||||||
|
<Modal title="新建文件名" open={isModalOpen} onOk={handleOk} onCancel={handleCancel}>
|
||||||
|
<Input ref={inputValue} placeholder="文件名不能为空" />
|
||||||
|
</Modal>
|
||||||
|
</>;
|
||||||
|
};
|
||||||
|
export default DirAddFile;
|
|
@ -0,0 +1,55 @@
|
||||||
|
import React from 'react';
|
||||||
|
import {Popconfirm} from 'antd';
|
||||||
|
import {deleteFileAndDir} from "../../../utils/File";
|
||||||
|
import {useDispatch, useSelector} from "react-redux";
|
||||||
|
import {dirFileRemove} from "../../../redux/dirMessage_reducer";
|
||||||
|
import {removeTableBarItem, setActiveKey} from "../../../redux/tableBarItem_reducer";
|
||||||
|
const DirDeleteFile = (prop) => {
|
||||||
|
console.log("prop",prop)
|
||||||
|
const dispatch= useDispatch()
|
||||||
|
const activeKey=useSelector(state => state.tableBarItem.activeKey);
|
||||||
|
const items = useSelector(state => state.tableBarItem.data)
|
||||||
|
|
||||||
|
const deleteFile = () => {
|
||||||
|
// 删除文件
|
||||||
|
deleteFileAndDir(prop.filePath)
|
||||||
|
// 更新树
|
||||||
|
dispatch(dirFileRemove({"filePath":prop.filePath}))
|
||||||
|
// 更新bar
|
||||||
|
let targetKey = prop.filePath
|
||||||
|
let newActiveKey = activeKey;
|
||||||
|
let lastIndex = -1;
|
||||||
|
items.forEach((item, i) => {
|
||||||
|
if (item.key === targetKey) {
|
||||||
|
lastIndex = i - 1;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
dispatch(removeTableBarItem(targetKey));
|
||||||
|
const newPanes = items.filter((item) => item.key !== targetKey);
|
||||||
|
if (newPanes.length && newActiveKey === targetKey) {
|
||||||
|
if (lastIndex >= 0) {
|
||||||
|
newActiveKey = newPanes[lastIndex].key;
|
||||||
|
} else {
|
||||||
|
newActiveKey = newPanes[0].key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dispatch(setActiveKey({"activeKey":newActiveKey}));
|
||||||
|
prop.closeMenu()
|
||||||
|
};
|
||||||
|
const cancelDeleteFile = () => {
|
||||||
|
|
||||||
|
prop.closeMenu()
|
||||||
|
};
|
||||||
|
return <Popconfirm
|
||||||
|
placement="right"
|
||||||
|
title="确认删除文件"
|
||||||
|
description="文件删除后将从磁盘删除"
|
||||||
|
onConfirm={deleteFile}
|
||||||
|
onCancel={cancelDeleteFile}
|
||||||
|
okText="确认"
|
||||||
|
cancelText="取消"
|
||||||
|
>
|
||||||
|
<span>删除文件</span>
|
||||||
|
</Popconfirm>;
|
||||||
|
};
|
||||||
|
export default DirDeleteFile;
|
|
@ -0,0 +1,19 @@
|
||||||
|
import React, {useRef, useState} from 'react';
|
||||||
|
import {Button, Input, Menu, Modal} from 'antd';
|
||||||
|
import {readDir} from "../../../utils/File";
|
||||||
|
import {nextDirAdd} from "../../../redux/dirMessage_reducer";
|
||||||
|
import {useDispatch} from "react-redux";
|
||||||
|
|
||||||
|
const RefreshDir = (prop) => {
|
||||||
|
console.log("prop",prop)
|
||||||
|
const dispatch = useDispatch()
|
||||||
|
const refreshDir = () => {
|
||||||
|
prop.refreshDir(prop.filePath)
|
||||||
|
prop.closeMenu()
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<span onClick={refreshDir}>更新目录</span>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
export default RefreshDir;
|
|
@ -0,0 +1,48 @@
|
||||||
|
import React, {useRef, useState} from 'react';
|
||||||
|
import {Input, Menu, Modal} from 'antd';
|
||||||
|
import {updateFileName} from "../../../utils/File";
|
||||||
|
import {useDispatch} from "react-redux";
|
||||||
|
import {updateFileName as updateFileNameRedux} from "../../../redux/dirMessage_reducer";
|
||||||
|
import {updateFileName as updateFileNameBar} from "../../../redux/tableBarItem_reducer";
|
||||||
|
|
||||||
|
const UpdateFileName = (prop) => {
|
||||||
|
console.log("prop",prop)
|
||||||
|
const [isModalOpen, setIsModalOpen] = useState(false);
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
const inputValue = useRef(null);
|
||||||
|
const showModal = () => {
|
||||||
|
setIsModalOpen(true);
|
||||||
|
};
|
||||||
|
const handleOk = () => {
|
||||||
|
setIsModalOpen(false);
|
||||||
|
console.log("inputValue",inputValue.current.input.value)
|
||||||
|
// 如果和原始名称一样,关闭菜单直接返回
|
||||||
|
// 如果不一样,修改文件名并且更新树,同步条目
|
||||||
|
if (prop.fileName!==inputValue.current.input.value){
|
||||||
|
// 修改文件名
|
||||||
|
let first = prop.filePath.lastIndexOf("/")
|
||||||
|
let second = prop.filePath.lastIndexOf(".")
|
||||||
|
let newFilePath= prop.filePath.substring(0,first+1)+inputValue.current.input.value+prop.filePath.substring(second)
|
||||||
|
updateFileName(prop.filePath,newFilePath)
|
||||||
|
// 更新树
|
||||||
|
dispatch(updateFileNameRedux({"oldFilePath":prop.filePath,"newFilePath":newFilePath}))
|
||||||
|
// 同步条目
|
||||||
|
dispatch(updateFileNameBar({"oldFilePath":prop.filePath,"newFilePath":newFilePath}))
|
||||||
|
|
||||||
|
}
|
||||||
|
prop.closeMenu()
|
||||||
|
};
|
||||||
|
const handleCancel = () => {
|
||||||
|
setIsModalOpen(false);
|
||||||
|
prop.closeMenu()
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<span onClick={showModal}>修改文件名</span>
|
||||||
|
<Modal title="修改文件名" open={isModalOpen} onOk={handleOk} onCancel={handleCancel}>
|
||||||
|
<Input ref={inputValue} placeholder={prop.fileName} />
|
||||||
|
</Modal>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
export default UpdateFileName;
|
|
@ -1,16 +1,19 @@
|
||||||
import React, {useEffect, useMemo, useState} from 'react';
|
import React, {useEffect, useMemo, useState} from 'react';
|
||||||
import {Input, Menu, Tree} from 'antd';
|
import {Input, Menu, Tree} from 'antd';
|
||||||
import {FolderOutlined, FileMarkdownOutlined, FileOutlined, DeleteOutlined, RedoOutlined} from '@ant-design/icons';
|
import {FolderOutlined, FileMarkdownOutlined, FileOutlined, DeleteOutlined, RedoOutlined} from '@ant-design/icons';
|
||||||
import {message, Popconfirm} from 'antd';
|
|
||||||
import "./index.less"
|
import "./index.less"
|
||||||
|
import {getFileNameByPath} from "../../utils/File";
|
||||||
const {Search} = Input;
|
const {Search} = Input;
|
||||||
import {useSelector, useDispatch} from "react-redux";
|
import {useSelector, useDispatch} from "react-redux";
|
||||||
import {addExpandedKeys, addTableBarItem, setExpandedKeys} from "../../redux/tableBarItem_reducer";
|
import {addExpandedKeys, addTableBarItem, setExpandedKeys} from "../../redux/tableBarItem_reducer";
|
||||||
import {readDir} from "../../utils/File";
|
import {readDir} from "../../utils/File";
|
||||||
import {nextDirAdd} from "../../redux/dirMessage_reducer";
|
import {nextDirAdd} from "../../redux/dirMessage_reducer";
|
||||||
import Icon from "antd/lib/icon";
|
|
||||||
import {isEmpty} from "../../utils/ObjectUtils";
|
import {isEmpty} from "../../utils/ObjectUtils";
|
||||||
|
import UpdateFileName from "./UpdateFileName";
|
||||||
|
import RefreshDir from "./RefreshDir";
|
||||||
|
import CloseDir from "./CloseDir";
|
||||||
|
import DirAddFile from "./DirAddFile";
|
||||||
|
import DirDeleteFile from "./DirDeleteFile";
|
||||||
// const defaultData = [];
|
// const defaultData = [];
|
||||||
// 将树平铺用于查找
|
// 将树平铺用于查找
|
||||||
const dataList = [];
|
const dataList = [];
|
||||||
|
@ -54,7 +57,7 @@ function generateChildList(fileList) {
|
||||||
}
|
}
|
||||||
result.push({
|
result.push({
|
||||||
"key": filePath,
|
"key": filePath,
|
||||||
"title": titleExtended(fileName,dirFlag,filePath),
|
"title": titleExtended(fileName, dirFlag, filePath),
|
||||||
"icon": dirFlag ? <FolderOutlined/> : fileName.endsWith(".md") ? <FileMarkdownOutlined/> : <FileOutlined/>,
|
"icon": dirFlag ? <FolderOutlined/> : fileName.endsWith(".md") ? <FileMarkdownOutlined/> : <FileOutlined/>,
|
||||||
"dirFlag": dirFlag,
|
"dirFlag": dirFlag,
|
||||||
"children": childListM
|
"children": childListM
|
||||||
|
@ -63,40 +66,8 @@ function generateChildList(fileList) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
const titleExtended = (fileName, dirFlag,filePath) => {
|
const titleExtended = (fileName, dirFlag, filePath) => {
|
||||||
|
return <span title={filePath}>{fileName}</span>
|
||||||
const confirm = (e) => {
|
|
||||||
console.log(e);
|
|
||||||
message.success('Click on Yes');
|
|
||||||
};
|
|
||||||
const cancel = (e) => {
|
|
||||||
console.log(e);
|
|
||||||
message.error('Click on No');
|
|
||||||
};
|
|
||||||
return <span title = {filePath}>{fileName}
|
|
||||||
{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>
|
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* 将文件信息改为树信息
|
* 将文件信息改为树信息
|
||||||
|
@ -117,7 +88,7 @@ const flushTree = (fileDirDate) => {
|
||||||
defaultValueStateSet.push({
|
defaultValueStateSet.push({
|
||||||
"key": filePath,
|
"key": filePath,
|
||||||
// 修改属性后此处也需要修改
|
// 修改属性后此处也需要修改
|
||||||
"title": titleExtended(fileName.substring(fileName.lastIndexOf("/")+1), dirFlag,filePath),
|
"title": titleExtended(getFileNameByPath(fileName), dirFlag, filePath),
|
||||||
"icon": <FolderOutlined/>,
|
"icon": <FolderOutlined/>,
|
||||||
"dirFlag": dirFlag,
|
"dirFlag": dirFlag,
|
||||||
"children": childListM
|
"children": childListM
|
||||||
|
@ -171,30 +142,38 @@ const ItemTree = (prop) => {
|
||||||
setSearchValue(value);
|
setSearchValue(value);
|
||||||
setAutoExpandParent(true);
|
setAutoExpandParent(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const refreshDir = (filePath) => {
|
||||||
|
readDir(filePath).then(fileStateList => {
|
||||||
|
if (Array.isArray(fileStateList[0].childList) && fileStateList[0].childList.length > 0) {
|
||||||
|
dispatch(nextDirAdd({selectDirKey: filePath, fileStateList}))
|
||||||
|
// 添加下级节点
|
||||||
|
addChildNode(defaultValueState, flushTree(fileStateList))
|
||||||
|
const result = [...defaultValueState]
|
||||||
|
console.log("[...defaultValueState]:", result)
|
||||||
|
setDefaultValueState(result)
|
||||||
|
// 打开当前目录
|
||||||
|
dispatch(addExpandedKeys([filePath]));
|
||||||
|
setAutoExpandParent(false);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
const onSelect = (selectedKeys, e) => {
|
const onSelect = (selectedKeys, e) => {
|
||||||
if (e.selected) {
|
if (e.selected) {
|
||||||
console.log('onSelect.selectedKeys', selectedKeys, e)
|
console.log('onSelect.selectedKeys', selectedKeys, e)
|
||||||
if (e.node.dirFlag) {
|
if (e.node.dirFlag) {
|
||||||
// 加载目录下一级文件信息
|
// 加载目录下一级文件信息
|
||||||
if (!Array.isArray(e.node.children) || e.node.children.length === 0) {
|
if (!Array.isArray(e.node.children) || e.node.children.length === 0) {
|
||||||
readDir(e.node.key).then(fileStateList => {
|
refreshDir(e.node.key)
|
||||||
if (Array.isArray(fileStateList[0].childList) && fileStateList[0].childList.length > 0) {
|
} else {
|
||||||
dispatch(nextDirAdd({selectDirKey: e.node.key, fileStateList}))
|
|
||||||
// 添加下级节点
|
|
||||||
addChildNode(defaultValueState, flushTree(fileStateList))
|
|
||||||
const result = [...defaultValueState]
|
|
||||||
console.log("[...defaultValueState]:", result)
|
|
||||||
setDefaultValueState(result)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
// 打开当前目录
|
// 打开当前目录
|
||||||
dispatch(addExpandedKeys([e.node.key]));
|
dispatch(addExpandedKeys([e.node.key]));
|
||||||
setAutoExpandParent(false);
|
setAutoExpandParent(false);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// 打开文件
|
// 打开文件
|
||||||
dispatch(addTableBarItem({
|
dispatch(addTableBarItem({
|
||||||
label: e.node.title.props.children[0],
|
label: e.node.title.props.children,
|
||||||
children: e.node.key,
|
children: e.node.key,
|
||||||
key: e.node.key,
|
key: e.node.key,
|
||||||
activeKey: e.node.key
|
activeKey: e.node.key
|
||||||
|
@ -232,35 +211,59 @@ const ItemTree = (prop) => {
|
||||||
// });
|
// });
|
||||||
// return loop(defaultData);
|
// return loop(defaultData);
|
||||||
// }, [searchValue]);
|
// }, [searchValue]);
|
||||||
const treeNodeOnRightClick=(e,node)=> {
|
const treeNodeOnRightClick = (e) => {
|
||||||
console.log("e,node",node)
|
console.log("e,node", e)
|
||||||
setState({
|
setState({
|
||||||
rightClickNodeTreeItem: {
|
rightClickNodeTreeItem: {
|
||||||
pageX: e.event.pageX,
|
pageX: e.event.pageX,
|
||||||
pageY: e.event.pageY,
|
pageY: e.event.pageY,
|
||||||
id: e.node.key
|
key: e.node.key,
|
||||||
|
dirFlag: e.node.dirFlag,
|
||||||
|
title: getFileNameByPath(e.node.key),
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
const getNodeTreeRightClickMenu=()=> {
|
const getNodeTreeRightClickMenu = () => {
|
||||||
console.log("state",state,isEmpty(state))
|
console.log("state", state, isEmpty(state))
|
||||||
if (isEmpty(state)){
|
if (isEmpty(state)) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const {pageX, pageY} = {...state.rightClickNodeTreeItem};
|
const {pageX, pageY, title, dirFlag, key} = {...state.rightClickNodeTreeItem};
|
||||||
const tmpStyle = {
|
const tmpStyle = {
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
left: `${pageX}px`,
|
left: `${pageX}px`,
|
||||||
top: `${pageY}px`,
|
top: `${pageY}px`,
|
||||||
popupBg:"#ec0f0f",
|
popupBg: "#ec0f0f",
|
||||||
"z-index":"9999"
|
zIndex: "9999"
|
||||||
};
|
};
|
||||||
|
const menuItem = [
|
||||||
|
!dirFlag &&
|
||||||
|
<Menu.Item key='1'>
|
||||||
|
<UpdateFileName fileName={title} filePath={key} closeMenu={() => setState("")}/>
|
||||||
|
</Menu.Item>,
|
||||||
|
dirFlag &&
|
||||||
|
<Menu.Item key='2'>
|
||||||
|
<RefreshDir filePath={key} refreshDir={refreshDir} closeMenu={() => setState("")}/>
|
||||||
|
</Menu.Item>,
|
||||||
|
dirFlag &&
|
||||||
|
<Menu.Item key='3'>
|
||||||
|
<DirAddFile filePath={key} closeMenu={() => setState("")}/>
|
||||||
|
</Menu.Item>,
|
||||||
|
!dirFlag &&
|
||||||
|
<Menu.Item key='4'>
|
||||||
|
<DirDeleteFile filePath={key} closeMenu={() => setState("")}></DirDeleteFile>
|
||||||
|
</Menu.Item>,
|
||||||
|
dirFlag &&
|
||||||
|
<Menu.Item key='5'>
|
||||||
|
<CloseDir filePath={key} closeMenu={() => setState("")}/>
|
||||||
|
</Menu.Item>,
|
||||||
|
<Menu.Item key='6' onClick={() => {
|
||||||
|
setState("")
|
||||||
|
}}>关闭菜单</Menu.Item>
|
||||||
|
]
|
||||||
return (
|
return (
|
||||||
<Menu style={tmpStyle}>
|
<Menu style={tmpStyle}>
|
||||||
<Menu.Item key='1'><Icon type='plus-circle'/>{'修改文件名'}</Menu.Item>
|
{menuItem}
|
||||||
<Menu.Item key='2'><Icon type='plus-circle-o'/>{'添加文件'}</Menu.Item>
|
|
||||||
<Menu.Item key='4'><Icon type='edit'/>{'修改'}</Menu.Item>
|
|
||||||
<Menu.Item key='3'><Icon type='minus-circle-o'/>{'删除目录'}</Menu.Item>
|
|
||||||
</Menu>
|
</Menu>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,6 +46,21 @@ export const dirMessageSlice = createSlice({
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
dirRemove:(state,action)=>{
|
||||||
|
console.log("dirMessage:dirRemove", state, action)
|
||||||
|
// 获取当前选中的key
|
||||||
|
let selectDirKey = action.payload.selectDirKey;
|
||||||
|
state.data = state.data.filter(file=>{
|
||||||
|
if (file.filePath === selectDirKey && file.dirFlag) {
|
||||||
|
return false;
|
||||||
|
} else if (file.childList.length > 0 && selectDirKey.startsWith(file.filePath)) {
|
||||||
|
file.childList = filterChild(file.childList, selectDirKey)
|
||||||
|
return true;
|
||||||
|
}else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
nextDirAdd: (state, action) => {
|
nextDirAdd: (state, action) => {
|
||||||
console.log("dirMessage:nextDirAdd", state, action)
|
console.log("dirMessage:nextDirAdd", state, action)
|
||||||
// 获取当前选中的key
|
// 获取当前选中的key
|
||||||
|
@ -59,10 +74,99 @@ export const dirMessageSlice = createSlice({
|
||||||
findChild(file.childList, action, selectDirKey)
|
findChild(file.childList, action, selectDirKey)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
},
|
||||||
|
updateFileName:(state,action)=>{
|
||||||
|
console.log("dirMessage:updateFileName", state, action)
|
||||||
|
let newFilePath = action.payload.newFilePath
|
||||||
|
let oldFilePath = action.payload.oldFilePath
|
||||||
|
// 查找旧文件并且修改文件信息
|
||||||
|
state.data.forEach(file => {
|
||||||
|
if (file.filePath === oldFilePath) {
|
||||||
|
file.filePath = newFilePath
|
||||||
|
file.fileName = newFilePath.substring(newFilePath.lastIndexOf("/")+1)
|
||||||
|
} else if (file.childList.length > 0 && oldFilePath.startsWith(file.filePath)) {
|
||||||
|
updateFileNameChild(file.childList, oldFilePath, newFilePath)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
dirFileAdd:(state,action)=>{
|
||||||
|
console.log("dirMessage:dirFileAdd", state, action)
|
||||||
|
let filePath = action.payload.filePath
|
||||||
|
let fileName = action.payload.fileName
|
||||||
|
let fileMessage = {
|
||||||
|
"fileName": fileName.replace(filePath+"/",""),
|
||||||
|
"filePath": fileName,
|
||||||
|
"dirFlag": false,
|
||||||
|
"childList": []
|
||||||
|
}
|
||||||
|
// 查找旧文件并且修改文件信息
|
||||||
|
state.data.forEach(file => {
|
||||||
|
if (file.filePath === filePath) {
|
||||||
|
if (Array.isArray(file.children)){
|
||||||
|
file.children.push(fileMessage)
|
||||||
|
}else {
|
||||||
|
file.children=[fileMessage]
|
||||||
|
}
|
||||||
|
} else if (file.childList.length > 0 && file.filePath.startsWith(filePath)) {
|
||||||
|
dirFileAddChild(file.childList, filePath, fileMessage)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
dirFileRemove:(state,action)=>{
|
||||||
|
let filePath = action.payload.filePath;
|
||||||
|
state.data = state.data.filter(file=>{
|
||||||
|
if (file.filePath === filePath && !file.dirFlag) {
|
||||||
|
return false;
|
||||||
|
} else if (file.childList.length > 0 && filePath.startsWith(file.filePath)) {
|
||||||
|
file.childList = dirFileRemoveChild(file.childList, filePath)
|
||||||
|
return true;
|
||||||
|
}else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
function dirFileRemoveChild(fileList, selectDirKey) {
|
||||||
|
return fileList.filter(file => {
|
||||||
|
if (file.filePath === selectDirKey && !file.dirFlag) {
|
||||||
|
return false
|
||||||
|
}else if (file.dirFlag && selectDirKey.startsWith(file.filePath) && Array.isArray(file.childList) && file.childList.length > 0) {
|
||||||
|
dirFileRemoveChild(file.childList, selectDirKey)
|
||||||
|
return true
|
||||||
|
}else {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function dirFileAddChild(fileList, filePath, fileMessage){
|
||||||
|
fileList.forEach(file => {
|
||||||
|
if (file.filePath === filePath) {
|
||||||
|
if (Array.isArray(file.children)){
|
||||||
|
file.children.push(fileMessage)
|
||||||
|
}else {
|
||||||
|
file.children=[fileMessage]
|
||||||
|
}
|
||||||
|
} else if (file.childList.length > 0 && file.filePath.startsWith(filePath)) {
|
||||||
|
dirFileAddChild(file.childList, filePath, fileMessage)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
function filterChild(fileList, selectDirKey) {
|
||||||
|
return fileList.filter(file => {
|
||||||
|
if (file.filePath === selectDirKey && file.dirFlag) {
|
||||||
|
return false
|
||||||
|
}else if (file.dirFlag && selectDirKey.startsWith(file.filePath) && Array.isArray(file.childList) && file.childList.length > 0) {
|
||||||
|
filterChild(file.childList, selectDirKey)
|
||||||
|
return true
|
||||||
|
}else {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
function findChild(fileList, action, selectDirKey) {
|
function findChild(fileList, action, selectDirKey) {
|
||||||
fileList.forEach(file => {
|
fileList.forEach(file => {
|
||||||
if (file.filePath === selectDirKey && file.dirFlag &&
|
if (file.filePath === selectDirKey && file.dirFlag &&
|
||||||
|
@ -76,9 +180,25 @@ function findChild(fileList, action, selectDirKey) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function updateFileNameChild(fileList, oldFilePath, newFilePath) {
|
||||||
|
fileList.forEach(file => {
|
||||||
|
if (file.filePath === oldFilePath) {
|
||||||
|
file.filePath = newFilePath
|
||||||
|
file.fileName = newFilePath.substring(newFilePath.lastIndexOf("/")+1)
|
||||||
|
return
|
||||||
|
}else if (Array.isArray(file.childList) && file.childList.length > 0 && oldFilePath.startsWith(file.filePath)) {
|
||||||
|
updateFileNameChild(file.childList, oldFilePath, newFilePath)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
export const {
|
export const {
|
||||||
dirAdd,
|
dirAdd,
|
||||||
nextDirAdd
|
nextDirAdd,
|
||||||
|
dirRemove,
|
||||||
|
updateFileName,
|
||||||
|
dirFileAdd,
|
||||||
|
dirFileRemove,
|
||||||
} = dirMessageSlice.actions
|
} = dirMessageSlice.actions
|
||||||
|
|
||||||
export default dirMessageSlice.reducer
|
export default dirMessageSlice.reducer
|
||||||
|
|
|
@ -40,6 +40,22 @@ export const tableBarItemSlice = createSlice({
|
||||||
state.activeKey=action.payload.activeKey
|
state.activeKey=action.payload.activeKey
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
updateFileName:(state,action)=>{
|
||||||
|
console.log("tableBarItemSlice:updateFileName", state, action)
|
||||||
|
let newFilePath = action.payload.newFilePath
|
||||||
|
let oldFilePath = action.payload.oldFilePath
|
||||||
|
// 查找旧文件并且修改文件信息
|
||||||
|
state.data.forEach(file => {
|
||||||
|
if (file.key === oldFilePath) {
|
||||||
|
file.key = newFilePath
|
||||||
|
file.children= newFilePath
|
||||||
|
file.label = newFilePath.substring(newFilePath.lastIndexOf("/")+1)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if (state.activeKey===oldFilePath){
|
||||||
|
state.activeKey = newFilePath
|
||||||
|
}
|
||||||
|
},
|
||||||
updatedSavedFile:(state, action)=>{
|
updatedSavedFile:(state, action)=>{
|
||||||
console.log("tableBarItemSlice:updatedSavedFile",action.payload)
|
console.log("tableBarItemSlice:updatedSavedFile",action.payload)
|
||||||
// 如果其中包含了相同的key,则是文件覆盖。
|
// 如果其中包含了相同的key,则是文件覆盖。
|
||||||
|
@ -75,6 +91,7 @@ export const { addTableBarItem,
|
||||||
updatedSavedFile,
|
updatedSavedFile,
|
||||||
setExpandedKeys,
|
setExpandedKeys,
|
||||||
removeExpandedKeys,
|
removeExpandedKeys,
|
||||||
addExpandedKeys
|
addExpandedKeys,
|
||||||
|
updateFileName
|
||||||
} = tableBarItemSlice.actions
|
} = tableBarItemSlice.actions
|
||||||
export default tableBarItemSlice.reducer
|
export default tableBarItemSlice.reducer
|
||||||
|
|
|
@ -35,6 +35,28 @@ export async function overWriteFile(filePath,jsonText) {
|
||||||
await fs.writeFile(filePath,jsonText,{"encoding":"utf-8"})
|
await fs.writeFile(filePath,jsonText,{"encoding":"utf-8"})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function newFile(filePath) {
|
||||||
|
await fs.writeFile(filePath,"",{"encoding":"utf-8"})
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function deleteFileAndDir(filePath) {
|
||||||
|
await fs.rm(filePath)
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function updateFileName(oldFileName,newFileName){
|
||||||
|
await fs.rename(oldFileName,newFileName)
|
||||||
|
}
|
||||||
|
|
||||||
export async function saveFileWithName(){
|
export async function saveFileWithName(){
|
||||||
return ipcRenderer.invoke("saveFileWithName" )
|
return ipcRenderer.invoke("saveFileWithName" )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getFileNameByPath(fileName){
|
||||||
|
// 获取文件名
|
||||||
|
let fileFullName = fileName.substring(fileName.lastIndexOf("/")+1);
|
||||||
|
let number = fileFullName.lastIndexOf(".");
|
||||||
|
if (number>0){
|
||||||
|
return fileFullName.substring(0,number);
|
||||||
|
}
|
||||||
|
return fileFullName
|
||||||
|
}
|
Loading…
Reference in New Issue