2018-09-12 02:32:31 +00:00
|
|
|
import React, { Component } from 'react';
|
2018-10-16 10:19:51 +00:00
|
|
|
import PropTypes from 'prop-types';
|
2019-01-18 08:41:26 +00:00
|
|
|
import { gettext } from '../../utils/constants';
|
|
|
|
import { Dropdown, DropdownMenu, DropdownToggle, DropdownItem } from 'reactstrap';
|
2019-01-23 08:25:14 +00:00
|
|
|
import TreeView from '../../components/tree-view-2/tree-view';
|
2019-01-18 08:41:26 +00:00
|
|
|
import Logo from '../../components/logo';
|
2019-01-23 08:25:14 +00:00
|
|
|
import Loading from '../../components/loading';
|
2019-01-18 08:41:26 +00:00
|
|
|
import ModalPortal from '../../components/modal-portal';
|
2018-10-16 06:27:21 +00:00
|
|
|
import Delete from '../../components/dialog/delete-dialog';
|
|
|
|
import Rename from '../../components/dialog/rename-dialog';
|
|
|
|
import CreateFolder from '../../components/dialog/create-folder-dialog';
|
|
|
|
import CreateFile from '../../components/dialog/create-file-dialog';
|
2018-09-12 02:32:31 +00:00
|
|
|
|
2018-10-16 10:19:51 +00:00
|
|
|
const propTypes = {
|
2018-11-22 03:26:00 +00:00
|
|
|
currentNode: PropTypes.object,
|
2019-01-23 08:25:14 +00:00
|
|
|
isTreeDataLoading: PropTypes.bool.isRequired,
|
2018-10-16 10:19:51 +00:00
|
|
|
treeData: PropTypes.object.isRequired,
|
2018-11-22 03:26:00 +00:00
|
|
|
currentPath: PropTypes.string.isRequired,
|
2018-10-16 10:19:51 +00:00
|
|
|
closeSideBar: PropTypes.bool.isRequired,
|
|
|
|
onCloseSide: PropTypes.func.isRequired,
|
|
|
|
onNodeClick: PropTypes.func.isRequired,
|
2019-01-23 08:25:14 +00:00
|
|
|
onNodeCollapse: PropTypes.func.isRequired,
|
|
|
|
onNodeExpanded: PropTypes.func.isRequired,
|
2018-10-16 10:19:51 +00:00
|
|
|
onRenameNode: PropTypes.func.isRequired,
|
|
|
|
onDeleteNode: PropTypes.func.isRequired,
|
|
|
|
onAddFileNode: PropTypes.func.isRequired,
|
|
|
|
onAddFolderNode: PropTypes.func.isRequired,
|
|
|
|
};
|
|
|
|
|
2018-09-12 02:32:31 +00:00
|
|
|
class SidePanel extends Component {
|
|
|
|
|
|
|
|
constructor(props) {
|
|
|
|
super(props);
|
|
|
|
this.state = {
|
2019-01-23 08:25:14 +00:00
|
|
|
opNode: null,
|
2018-09-12 02:32:31 +00:00
|
|
|
isLoadFailed: false,
|
2018-09-12 06:15:27 +00:00
|
|
|
isMenuIconShow: false,
|
2019-01-18 08:41:26 +00:00
|
|
|
isHeaderMenuShow: false,
|
|
|
|
isDeleteDialogShow: false,
|
|
|
|
isAddFileDialogShow: false,
|
|
|
|
isAddFolderDialogShow: false,
|
|
|
|
isRenameDialogShow: false,
|
2018-09-29 10:32:53 +00:00
|
|
|
};
|
2018-09-12 02:32:31 +00:00
|
|
|
}
|
|
|
|
|
2019-01-23 08:25:14 +00:00
|
|
|
componentWillReceiveProps(nextProps) {
|
|
|
|
this.setState({opNode: nextProps.currentNode});
|
|
|
|
}
|
|
|
|
|
2018-09-12 02:32:31 +00:00
|
|
|
onMouseEnter = () => {
|
2019-01-18 08:41:26 +00:00
|
|
|
this.setState({isMenuIconShow: true});
|
2018-09-12 02:32:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
onMouseLeave = () => {
|
2019-01-18 08:41:26 +00:00
|
|
|
this.setState({isMenuIconShow: false});
|
|
|
|
}
|
|
|
|
|
|
|
|
onDropdownToggleClick = (e) => {
|
|
|
|
e.preventDefault();
|
|
|
|
this.toggleOperationMenu();
|
|
|
|
}
|
|
|
|
|
|
|
|
toggleOperationMenu = () => {
|
|
|
|
this.setState({isHeaderMenuShow: !this.state.isHeaderMenuShow});
|
2018-09-12 02:32:31 +00:00
|
|
|
}
|
|
|
|
|
2018-11-22 03:26:00 +00:00
|
|
|
onNodeClick = (node) => {
|
2019-01-23 08:25:14 +00:00
|
|
|
this.setState({opNode: node});
|
2018-11-22 03:26:00 +00:00
|
|
|
this.props.onNodeClick(node);
|
2018-09-12 02:32:31 +00:00
|
|
|
}
|
|
|
|
|
2019-01-23 08:25:14 +00:00
|
|
|
onMenuItemClick = (operation, node) => {
|
|
|
|
this.setState({opNode: node});
|
|
|
|
switch (operation) {
|
|
|
|
case 'New Folder':
|
|
|
|
this.onAddFolderToggle();
|
|
|
|
break;
|
|
|
|
case 'New File':
|
|
|
|
this.onAddFileToggle();
|
|
|
|
break;
|
|
|
|
case 'Rename':
|
|
|
|
this.onRenameToggle();
|
|
|
|
break;
|
|
|
|
case 'Delete':
|
|
|
|
this.onDeleteToggle();
|
|
|
|
break;
|
2018-09-12 06:15:27 +00:00
|
|
|
}
|
2018-09-12 02:32:31 +00:00
|
|
|
}
|
|
|
|
|
2019-01-23 08:25:14 +00:00
|
|
|
onAddFileToggle = (type) => {
|
|
|
|
if (type === 'root') {
|
|
|
|
let root = this.props.treeData.root;
|
|
|
|
this.setState({
|
|
|
|
isAddFileDialogShow: !this.state.isAddFileDialogShow,
|
|
|
|
opNode: root,
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
this.setState({isAddFileDialogShow: !this.state.isAddFileDialogShow});
|
|
|
|
}
|
2018-10-16 06:27:21 +00:00
|
|
|
}
|
2019-01-23 08:25:14 +00:00
|
|
|
|
|
|
|
onAddFolderToggle = (type) => {
|
|
|
|
if (type === 'root') {
|
|
|
|
let root = this.props.treeData.root;
|
|
|
|
this.setState({
|
|
|
|
isAddFolderDialogShow: !this.state.isAddFolderDialogShow,
|
|
|
|
opNode: root,
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
this.setState({isAddFolderDialogShow: !this.state.isAddFolderDialogShow});
|
|
|
|
}
|
2018-09-12 06:15:27 +00:00
|
|
|
}
|
2018-11-22 03:26:00 +00:00
|
|
|
|
2019-01-18 08:41:26 +00:00
|
|
|
onRenameToggle = () => {
|
|
|
|
this.setState({isRenameDialogShow: !this.state.isRenameDialogShow});
|
2018-09-12 06:15:27 +00:00
|
|
|
}
|
2018-11-22 03:26:00 +00:00
|
|
|
|
2019-01-18 08:41:26 +00:00
|
|
|
onDeleteToggle = () => {
|
|
|
|
this.setState({isDeleteDialogShow: !this.state.isDeleteDialogShow});
|
2018-09-12 06:15:27 +00:00
|
|
|
}
|
|
|
|
|
2018-09-12 02:32:31 +00:00
|
|
|
onAddFolderNode = (dirPath) => {
|
2019-01-18 08:41:26 +00:00
|
|
|
this.setState({isAddFolderDialogShow: !this.state.isAddFolderDialogShow});
|
2018-09-12 02:32:31 +00:00
|
|
|
this.props.onAddFolderNode(dirPath);
|
|
|
|
}
|
2018-11-22 03:26:00 +00:00
|
|
|
|
2018-10-24 06:37:41 +00:00
|
|
|
onAddFileNode = (filePath, isDraft) => {
|
2019-01-18 08:41:26 +00:00
|
|
|
this.setState({isAddFileDialogShow: !this.state.isAddFileDialogShow});
|
2018-10-24 06:37:41 +00:00
|
|
|
this.props.onAddFileNode(filePath, isDraft);
|
2018-09-12 02:32:31 +00:00
|
|
|
}
|
2018-11-22 03:26:00 +00:00
|
|
|
|
2018-09-12 02:32:31 +00:00
|
|
|
onRenameNode = (newName) => {
|
2019-01-18 08:41:26 +00:00
|
|
|
this.setState({isRenameDialogShow: !this.state.isRenameDialogShow});
|
2019-01-23 08:25:14 +00:00
|
|
|
let node = this.state.opNode;
|
2018-09-29 10:32:53 +00:00
|
|
|
this.props.onRenameNode(node, newName);
|
2018-09-12 02:32:31 +00:00
|
|
|
}
|
2018-11-22 03:26:00 +00:00
|
|
|
|
2018-09-12 02:32:31 +00:00
|
|
|
onDeleteNode = () => {
|
2019-01-18 08:41:26 +00:00
|
|
|
this.setState({isDeleteDialogShow: !this.state.isDeleteDialogShow});
|
2019-01-23 08:25:14 +00:00
|
|
|
let node = this.state.opNode;
|
2018-09-12 02:32:31 +00:00
|
|
|
this.props.onDeleteNode(node);
|
|
|
|
}
|
|
|
|
|
|
|
|
render() {
|
|
|
|
return (
|
2018-09-29 10:32:53 +00:00
|
|
|
<div className={`side-panel wiki-side-panel ${this.props.closeSideBar ? '': 'left-zero'}`}>
|
2018-09-12 02:32:31 +00:00
|
|
|
<div className="side-panel-top panel-top">
|
2019-01-18 08:41:26 +00:00
|
|
|
<Logo onCloseSidePanel={this.props.onCloseSide} />
|
2018-09-12 02:32:31 +00:00
|
|
|
</div>
|
|
|
|
<div id="side-nav" className="wiki-side-nav" role="navigation">
|
2019-01-18 08:41:26 +00:00
|
|
|
<h3 className="wiki-pages-heading" onMouseEnter={this.onMouseEnter} onMouseLeave={this.onMouseLeave}>
|
2018-09-29 10:32:53 +00:00
|
|
|
{gettext('Files')}
|
2018-09-12 02:32:31 +00:00
|
|
|
<div className="heading-icon">
|
2019-01-18 08:41:26 +00:00
|
|
|
{this.state.isMenuIconShow && (
|
|
|
|
<Dropdown isOpen={this.state.isHeaderMenuShow} toggle={this.toggleOperationMenu}>
|
|
|
|
<DropdownToggle
|
|
|
|
tag="i"
|
|
|
|
className="fas fa-ellipsis-v"
|
|
|
|
title={gettext('More Operations')}
|
|
|
|
data-toggle="dropdown"
|
|
|
|
aria-expanded={this.state.isHeaderMenuShow}
|
|
|
|
onClick={this.onDropdownToggleClick}
|
|
|
|
/>
|
|
|
|
<DropdownMenu right>
|
2019-01-23 08:25:14 +00:00
|
|
|
<DropdownItem onClick={this.onAddFolderToggle.bind(this, 'root')}>{gettext('New Folder')}</DropdownItem>
|
|
|
|
<DropdownItem onClick={this.onAddFileToggle.bind(this, 'root')}>{gettext('New File')}</DropdownItem>
|
2019-01-18 08:41:26 +00:00
|
|
|
</DropdownMenu>
|
|
|
|
</Dropdown>
|
|
|
|
)}
|
2018-09-12 02:32:31 +00:00
|
|
|
</div>
|
|
|
|
</h3>
|
|
|
|
<div className="wiki-pages-container">
|
2019-01-23 08:25:14 +00:00
|
|
|
{this.props.isTreeDataLoading ?
|
|
|
|
(<Loading/>) :
|
|
|
|
(<TreeView
|
2019-01-18 08:41:26 +00:00
|
|
|
treeData={this.props.treeData}
|
|
|
|
currentPath={this.props.currentPath}
|
|
|
|
onNodeClick={this.onNodeClick}
|
2019-01-23 08:25:14 +00:00
|
|
|
onNodeExpanded={this.props.onNodeExpanded}
|
|
|
|
onNodeCollapse={this.props.onNodeCollapse}
|
|
|
|
onMenuItemClick={this.onMenuItemClick}
|
|
|
|
onFreezedItem={this.onFreezedItem}
|
|
|
|
onUnFreezedItem={this.onUnFreezedItem}
|
2019-01-18 08:41:26 +00:00
|
|
|
/>
|
|
|
|
)}
|
|
|
|
</div>
|
|
|
|
</div>
|
2019-01-23 08:25:14 +00:00
|
|
|
{this.state.isAddFolderDialogShow && (
|
2019-01-18 08:41:26 +00:00
|
|
|
<ModalPortal>
|
2019-01-23 08:25:14 +00:00
|
|
|
<CreateFolder
|
|
|
|
parentPath={this.state.opNode.path}
|
|
|
|
onAddFolder={this.onAddFolderNode}
|
|
|
|
addFolderCancel={this.onAddFolderToggle}
|
|
|
|
/>
|
2019-01-18 08:41:26 +00:00
|
|
|
</ModalPortal>
|
|
|
|
)}
|
|
|
|
{this.state.isAddFileDialogShow && (
|
|
|
|
<ModalPortal>
|
2018-10-16 06:27:21 +00:00
|
|
|
<CreateFile
|
|
|
|
fileType={'.md'}
|
2019-01-23 08:25:14 +00:00
|
|
|
parentPath={this.state.opNode.path}
|
2018-09-12 06:15:27 +00:00
|
|
|
onAddFile={this.onAddFileNode}
|
2019-01-23 08:25:14 +00:00
|
|
|
addFileCancel={this.onAddFileToggle}
|
|
|
|
/>
|
2019-01-18 08:41:26 +00:00
|
|
|
</ModalPortal>
|
|
|
|
)}
|
|
|
|
{this.state.isRenameDialogShow && (
|
|
|
|
<ModalPortal>
|
2018-11-22 03:26:00 +00:00
|
|
|
<Rename
|
2019-01-23 08:25:14 +00:00
|
|
|
currentNode={this.state.opNode}
|
2018-11-22 03:26:00 +00:00
|
|
|
onRename={this.onRenameNode}
|
2019-01-23 08:25:14 +00:00
|
|
|
toggleCancel={this.onRenameToggle}
|
|
|
|
/>
|
|
|
|
</ModalPortal>
|
|
|
|
)}
|
|
|
|
{this.state.isDeleteDialogShow && (
|
|
|
|
<ModalPortal>
|
|
|
|
<Delete
|
|
|
|
currentNode={this.state.opNode}
|
|
|
|
handleSubmit={this.onDeleteNode}
|
|
|
|
toggleCancel={this.onDeleteToggle}
|
2018-09-12 06:15:27 +00:00
|
|
|
/>
|
2019-01-18 08:41:26 +00:00
|
|
|
</ModalPortal>
|
|
|
|
)}
|
2018-09-12 02:32:31 +00:00
|
|
|
</div>
|
2018-09-29 10:32:53 +00:00
|
|
|
);
|
2018-09-12 02:32:31 +00:00
|
|
|
}
|
|
|
|
}
|
2018-10-16 10:19:51 +00:00
|
|
|
|
|
|
|
SidePanel.propTypes = propTypes;
|
|
|
|
|
2019-01-23 08:25:14 +00:00
|
|
|
export default SidePanel;
|