1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-07-19 01:29:05 +00:00
seahub/frontend/src/components/tree-view/tree-view.js

203 lines
5.6 KiB
JavaScript
Raw Normal View History

2018-08-06 10:29:12 +00:00
import React from 'react';
2018-10-16 10:19:51 +00:00
import PropTypes from 'prop-types';
2018-08-06 10:29:12 +00:00
import TreeNodeView from './tree-node-view';
import TreeViewContextMenu from './tree-view-contextmenu'
2018-10-16 10:19:51 +00:00
const propTypes = {
2019-02-20 03:54:25 +00:00
repoPermission: PropTypes.bool,
2019-01-28 08:48:03 +00:00
isNodeMenuShow: PropTypes.bool.isRequired,
2018-10-16 10:19:51 +00:00
treeData: PropTypes.object.isRequired,
2019-01-28 08:48:03 +00:00
currentPath: PropTypes.string.isRequired,
onMenuItemClick: PropTypes.func,
2018-10-16 10:19:51 +00:00
onNodeClick: PropTypes.func.isRequired,
2019-01-28 08:48:03 +00:00
onNodeExpanded: PropTypes.func.isRequired,
onNodeCollapse: PropTypes.func.isRequired,
2019-03-27 03:25:27 +00:00
onItemMove: PropTypes.func,
currentRepoInfo: PropTypes.object,
switchAnotherMenuToShow: PropTypes.func,
appMenuType: PropTypes.oneOf(['list_view_contextmenu', 'item_contextmenu', 'tree_contextmenu', 'item_op_menu']),
2018-10-16 10:19:51 +00:00
};
const PADDING_LEFT = 20;
2019-01-28 08:48:03 +00:00
class TreeView extends React.Component {
2018-08-06 10:29:12 +00:00
2019-01-28 08:48:03 +00:00
constructor(props) {
super(props);
this.state = {
isItemFreezed: false,
isRightMenuShow: false,
nodeData: null,
fileData: null,
mousePosition: {clientX: '', clientY: ''},
2019-01-28 08:48:03 +00:00
};
2018-08-06 10:29:12 +00:00
}
componentDidMount() {
this.registerHandlers();
}
componentDidUpdate() {
this.registerHandlers();
}
componentWillUnmount() {
this.unregisterHandlers();
}
2019-03-27 03:25:27 +00:00
onItemMove = (repo, dirent, selectedPath, currentPath) => {
this.props.onItemMove(repo, dirent, selectedPath, currentPath);
}
2019-01-28 08:48:03 +00:00
onNodeDragStart = (e, node) => {
2019-03-27 03:25:27 +00:00
let dragStartNodeData = {nodeDirent: node.object, nodeParentPath: node.parentNode.path, nodeRootPath: node.path};
dragStartNodeData = JSON.stringify(dragStartNodeData);
e.dataTransfer.effectAllowed = "move";
e.dataTransfer.setData('applicaiton/drag-item-info', dragStartNodeData);
}
onNodeDragEnter = (e, node) => {
//todo
}
onNodeDragMove = (e) => {
e.preventDefault();
e.dataTransfer.dropEffect = 'move';
}
onNodeDragLeave = (e, node) => {
//todo
}
onNodeDrop = (e, node) => {
if (e.dataTransfer.files.length) { // uploaded files
return;
}
let dragStartNodeData = e.dataTransfer.getData('applicaiton/drag-item-info');
dragStartNodeData = JSON.parse(dragStartNodeData);
let {nodeDirent, nodeParentPath, nodeRootPath} = dragStartNodeData;
let dropNodeData = node;
if (dropNodeData.object.type !== 'dir') {
return;
}
// copy the dirent to itself. eg: A/B -> A/B
if (nodeParentPath === dropNodeData.parentNode.path) {
if (dropNodeData.object.name === nodeDirent.name) {
return;
}
}
// copy the dirent to it's child. eg: A/B -> A/B/C
if (dropNodeData.object.type === 'dir' && nodeDirent.type === 'dir') {
if (dropNodeData.parentNode.path !== nodeParentPath) {
if (dropNodeData.path.indexOf(nodeRootPath) !== -1) {
return;
}
}
}
this.onItemMove(this.props.currentRepoInfo, nodeDirent, dropNodeData.path, nodeParentPath);
2018-08-06 10:29:12 +00:00
}
2019-01-28 08:48:03 +00:00
onFreezedItem = () => {
this.setState({isItemFreezed: true});
this.props.switchAnotherMenuToShow('item_op_menu');
}
2019-01-28 08:48:03 +00:00
onUnFreezedItem = () => {
this.setState({isItemFreezed: false});
}
contextMenu = (e) => {
e.preventDefault();
this.props.switchAnotherMenuToShow('tree_contextmenu');
this.setState({
isRightMenuShow:false,
}, () => {
this.setState({
isRightMenuShow: true,
fileData: this.state.nodeData,
mousePosition: {clientX: e.clientX, clientY: e.clientY}
})
})
}
unregisterHandlers = () => {
let treeView = document.querySelector('.tree-view');
treeView.removeEventListener('contextmenu', this.contextMenu);
}
registerHandlers = () => {
let treeView = document.querySelector('.tree-view');
treeView.addEventListener('contextmenu', this.contextMenu);
}
onNodeChanged = (node) => {
this.setState({
nodeData:node
})
}
closeRightMenu = () => {
this.setState({
isRightMenuShow:false,
})
this.onUnFreezedItem();
}
onMenuItemClick = (operation, node) => {
this.props.onMenuItemClick(operation, node)
}
render() {
return (
<div className="tree-view tree">
2019-01-28 08:48:03 +00:00
<TreeNodeView
2019-02-20 03:54:25 +00:00
repoPermission={this.props.repoPermission}
node={this.props.treeData.root}
2018-11-22 03:26:00 +00:00
currentPath={this.props.currentPath}
2019-01-28 08:48:03 +00:00
paddingLeft={PADDING_LEFT}
isNodeMenuShow={this.props.isNodeMenuShow}
isItemFreezed={this.state.isItemFreezed}
onNodeClick={this.props.onNodeClick}
onMenuItemClick={this.props.onMenuItemClick}
onNodeExpanded={this.props.onNodeExpanded}
onNodeCollapse={this.props.onNodeCollapse}
onNodeDragStart={this.onNodeDragStart}
onFreezedItem={this.onFreezedItem}
onUnFreezedItem={this.onUnFreezedItem}
onNodeChanged={this.onNodeChanged}
registerHandlers={this.registerHandlers}
unregisterHandlers={this.unregisterHandlers}
2019-03-27 03:25:27 +00:00
onNodeDragMove={this.onNodeDragMove}
onNodeDrop={this.onNodeDrop}
onNodeDragEnter={this.onNodeDragEnter}
onNodeDragLeave={this.onNodeDragLeave}
appMenuType={this.props.appMenuType}
/>
{this.state.isRightMenuShow && this.props.appMenuType === 'tree_contextmenu' && (
<TreeViewContextMenu
node={this.state.fileData}
onMenuItemClick={this.onMenuItemClick}
mousePosition={this.state.mousePosition}
closeRightMenu={this.closeRightMenu}
registerHandlers={this.registerHandlers}
unregisterHandlers={this.unregisterHandlers}
/>
)}
</div>
);
2018-08-06 10:29:12 +00:00
}
}
2018-10-16 10:19:51 +00:00
TreeView.propTypes = propTypes;
2018-08-06 10:29:12 +00:00
export default TreeView;