1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-09-01 15:09:14 +00:00

Double name bug repair (#2879)

This commit is contained in:
杨顺强
2019-01-25 15:44:04 +08:00
committed by Daniel Pan
parent 9ddcf06225
commit 69b4db2afa
12 changed files with 222 additions and 91 deletions

View File

@@ -1,12 +1,14 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { Button, Modal, ModalHeader, Input, ModalBody, ModalFooter, Form, FormGroup, Label } from 'reactstrap'; import { Button, Modal, ModalHeader, Input, ModalBody, ModalFooter, Form, FormGroup, Label, Alert } from 'reactstrap';
import { gettext } from '../../utils/constants'; import { gettext } from '../../utils/constants';
import { Utils } from '../../utils/utils';
const propTypes = { const propTypes = {
fileType: PropTypes.string, fileType: PropTypes.string,
parentPath: PropTypes.string.isRequired, parentPath: PropTypes.string.isRequired,
onAddFile: PropTypes.func.isRequired, onAddFile: PropTypes.func.isRequired,
checkDuplicatedName: PropTypes.func.isRequired,
addFileCancel: PropTypes.func.isRequired, addFileCancel: PropTypes.func.isRequired,
}; };
@@ -17,10 +19,22 @@ class CreateFile extends React.Component {
parentPath: '', parentPath: '',
childName: props.fileType, childName: props.fileType,
isDraft: false, isDraft: false,
errMessage: '',
}; };
this.newInput = React.createRef(); this.newInput = React.createRef();
} }
componentDidMount() {
let parentPath = this.props.parentPath;
if (parentPath[parentPath.length - 1] === '/') { // mainPanel
this.setState({parentPath: parentPath});
} else {
this.setState({parentPath: parentPath + '/'}); // sidePanel
}
this.newInput.focus();
this.newInput.setSelectionRange(0,0);
}
handleChange = (e) => { handleChange = (e) => {
this.setState({ this.setState({
childName: e.target.value, childName: e.target.value,
@@ -28,14 +42,23 @@ class CreateFile extends React.Component {
} }
handleSubmit = () => { handleSubmit = () => {
let path = this.state.parentPath + this.state.childName; let isDuplicated = this.checkDuplicatedName();
let isDraft = this.state.isDraft; let newName = this.state.childName
this.props.onAddFile(path, isDraft); if (isDuplicated) {
let errMessage = gettext('The name \'{name}\' is already occupied, please choose another name.');
errMessage = errMessage.replace('{name}', Utils.HTMLescape(newName));
this.setState({errMessage: errMessage});
} else {
let path = this.state.parentPath + newName;
let isDraft = this.state.isDraft;
this.props.onAddFile(path, isDraft);
}
} }
handleKeyPress = (e) => { handleKeyPress = (e) => {
if (e.key === 'Enter') { if (e.key === 'Enter') {
this.handleSubmit(); this.handleSubmit();
e.preventDefault();
} }
} }
@@ -92,15 +115,9 @@ class CreateFile extends React.Component {
this.props.addFileCancel(); this.props.addFileCancel();
} }
componentDidMount() { checkDuplicatedName = () => {
let parentPath = this.props.parentPath; let isDuplicated = this.props.checkDuplicatedName(this.state.childName);
if (parentPath[parentPath.length - 1] === '/') { // mainPanel return isDuplicated;
this.setState({parentPath: parentPath});
} else {
this.setState({parentPath: parentPath + '/'}); // sidePanel
}
this.newInput.focus();
this.newInput.setSelectionRange(0,0);
} }
render() { render() {
@@ -127,6 +144,7 @@ class CreateFile extends React.Component {
</FormGroup> </FormGroup>
)} )}
</Form> </Form>
{this.state.errMessage && <Alert color="danger" className="mt-2">{this.state.errMessage}</Alert>}
</ModalBody> </ModalBody>
<ModalFooter> <ModalFooter>
<Button color="secondary" onClick={this.toggle}>{gettext('Cancel')}</Button> <Button color="secondary" onClick={this.toggle}>{gettext('Cancel')}</Button>

View File

@@ -1,12 +1,14 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { Button, Modal, ModalHeader, Input, ModalBody, ModalFooter, Form, FormGroup, Label } from 'reactstrap'; import { Button, Modal, ModalHeader, Input, ModalBody, ModalFooter, Form, FormGroup, Label, Alert } from 'reactstrap';
import { gettext } from '../../utils/constants'; import { gettext } from '../../utils/constants';
import { Utils } from '../../utils/utils';
const propTypes = { const propTypes = {
fileType: PropTypes.string, fileType: PropTypes.string,
parentPath: PropTypes.string.isRequired, parentPath: PropTypes.string.isRequired,
onAddFolder: PropTypes.func.isRequired, onAddFolder: PropTypes.func.isRequired,
checkDuplicatedName: PropTypes.func.isRequired,
addFolderCancel: PropTypes.func.isRequired, addFolderCancel: PropTypes.func.isRequired,
}; };
@@ -15,32 +17,12 @@ class CreateForder extends React.Component {
super(props); super(props);
this.state = { this.state = {
parentPath: '', parentPath: '',
childName: '' childName: '',
errMessage: ''
}; };
this.newInput = React.createRef(); this.newInput = React.createRef();
} }
handleChange = (e) => {
this.setState({
childName: e.target.value,
});
}
handleSubmit = () => {
let path = this.state.parentPath + this.state.childName;
this.props.onAddFolder(path);
}
handleKeyPress = (e) => {
if (e.key === 'Enter') {
this.handleSubmit();
}
}
toggle = () => {
this.props.addFolderCancel();
}
componentDidMount() { componentDidMount() {
let parentPath = this.props.parentPath; let parentPath = this.props.parentPath;
if (parentPath[parentPath.length - 1] === '/') { // mainPanel if (parentPath[parentPath.length - 1] === '/') { // mainPanel
@@ -52,6 +34,39 @@ class CreateForder extends React.Component {
this.newInput.setSelectionRange(0,0); this.newInput.setSelectionRange(0,0);
} }
handleChange = (e) => {
this.setState({childName: e.target.value});
}
handleSubmit = () => {
let newName = this.state.childName;
let isDuplicated = this.checkDuplicatedName();
if (isDuplicated) {
let errMessage = gettext('The name \'{name}\' is already occupied, please choose another name.');
errMessage = errMessage.replace('{name}', Utils.HTMLescape(newName));
this.setState({errMessage: errMessage});
} else {
let path = this.state.parentPath + newName;
this.props.onAddFolder(path);
}
}
handleKeyPress = (e) => {
if (e.key === 'Enter') {
this.handleSubmit();
e.preventDefault();
}
}
toggle = () => {
this.props.addFolderCancel();
}
checkDuplicatedName = () => {
let isDuplicated = this.props.checkDuplicatedName(this.state.childName);
return isDuplicated;
}
render() { render() {
return ( return (
<Modal isOpen={true} toggle={this.toggle}> <Modal isOpen={true} toggle={this.toggle}>
@@ -69,6 +84,7 @@ class CreateForder extends React.Component {
/> />
</FormGroup> </FormGroup>
</Form> </Form>
{this.state.errMessage && <Alert color="danger" className="mt-2">{this.state.errMessage}</Alert>}
</ModalBody> </ModalBody>
<ModalFooter> <ModalFooter>
<Button color="secondary" onClick={this.toggle}>{gettext('Cancel')}</Button> <Button color="secondary" onClick={this.toggle}>{gettext('Cancel')}</Button>

View File

@@ -1,12 +1,14 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { gettext } from '../../utils/constants'; import { gettext } from '../../utils/constants';
import { Button, Modal, ModalHeader, Input, ModalBody, ModalFooter } from 'reactstrap'; import { Utils } from '../../utils/utils';
import { Button, Modal, ModalHeader, Input, ModalBody, ModalFooter, Alert } from 'reactstrap';
const propTypes = { const propTypes = {
currentNode: PropTypes.object, currentNode: PropTypes.object,
onRename: PropTypes.func.isRequired, onRename: PropTypes.func.isRequired,
toggleCancel: PropTypes.func.isRequired, toggleCancel: PropTypes.func.isRequired,
checkDuplicatedName: PropTypes.func.isRequired,
}; };
class Rename extends React.Component { class Rename extends React.Component {
@@ -14,34 +16,13 @@ class Rename extends React.Component {
super(props); super(props);
this.state = { this.state = {
newName: '', newName: '',
errMessage: '',
}; };
this.newInput = React.createRef(); this.newInput = React.createRef();
} }
handleChange = (e) => {
this.setState({
newName: e.target.value,
});
}
handleSubmit = () => {
this.props.onRename(this.state.newName);
}
handleKeyPress = (e) => {
if (e.key === 'Enter') {
this.handleSubmit();
}
}
toggle = () => {
this.props.toggleCancel();
}
componentWillMount() { componentWillMount() {
this.setState({ this.setState({newName: this.props.currentNode.object.name});
newName: this.props.currentNode.object.name
});
} }
componentDidMount() { componentDidMount() {
@@ -60,12 +41,66 @@ class Rename extends React.Component {
componentWillReceiveProps(nextProps) { componentWillReceiveProps(nextProps) {
this.changeState(nextProps.currentNode); this.changeState(nextProps.currentNode);
} }
handleChange = (e) => {
this.setState({newName: e.target.value});
}
changeState(currentNode) { handleSubmit = () => {
let { isValid, errMessage } = this.validateInput();
if (!isValid) {
this.setState({errMessage : errMessage});
} else {
let isDuplicated = this.checkDuplicatedName();
if (isDuplicated) {
let errMessage = gettext('The name \'{name}\' is already occupied, please choose another name.');
errMessage = errMessage.replace('{name}', Utils.HTMLescape(this.state.newName));
this.setState({errMessage: errMessage});
} else {
this.props.onRename(this.state.newName);
}
}
}
handleKeyPress = (e) => {
if (e.key === 'Enter') {
this.handleSubmit();
}
}
toggle = () => {
this.props.toggleCancel();
}
changeState = (currentNode) => {
let name = currentNode.object.name; let name = currentNode.object.name;
this.setState({newName: name}); this.setState({newName: name});
} }
validateInput = () => {
let newName = this.state.newName.trim();
let isValid = true;
let errMessage = '';
if (!newName) {
isValid = false;
errMessage = gettext('Name is required.');
return { isValid, errMessage };
}
if (newName.indexOf('/') > -1) {
isValid = false;
errMessage = gettext('Name should not include ' + '\'/\'' + '.');
return { isValid, errMessage };
}
return { isValid, errMessage };
}
checkDuplicatedName = () => {
let isDuplicated = this.props.checkDuplicatedName(this.state.newName);
return isDuplicated;
}
render() { render() {
let type = this.props.currentNode.object.type; let type = this.props.currentNode.object.type;
return ( return (
@@ -74,6 +109,7 @@ class Rename extends React.Component {
<ModalBody> <ModalBody>
<p>{type === 'file' ? gettext('Enter the new file name:'): gettext('Enter the new folder name:')}</p> <p>{type === 'file' ? gettext('Enter the new file name:'): gettext('Enter the new folder name:')}</p>
<Input onKeyPress={this.handleKeyPress} innerRef={input => {this.newInput = input;}} placeholder="newName" value={this.state.newName} onChange={this.handleChange} /> <Input onKeyPress={this.handleKeyPress} innerRef={input => {this.newInput = input;}} placeholder="newName" value={this.state.newName} onChange={this.handleChange} />
{this.state.errMessage && <Alert color="danger" className="mt-2">{this.state.errMessage}</Alert>}
</ModalBody> </ModalBody>
<ModalFooter> <ModalFooter>
<Button color="primary" onClick={this.handleSubmit}>{gettext('Submit')}</Button> <Button color="primary" onClick={this.handleSubmit}>{gettext('Submit')}</Button>

View File

@@ -157,6 +157,7 @@ class DirPanel extends React.Component {
path={this.props.path} path={this.props.path}
repoID={this.props.repoID} repoID={this.props.repoID}
showShareBtn={this.props.showShareBtn} showShareBtn={this.props.showShareBtn}
direntList={this.props.direntList}
onAddFile={this.props.onAddFile} onAddFile={this.props.onAddFile}
onAddFolder={this.props.onAddFolder} onAddFolder={this.props.onAddFolder}
onUploadFile={this.onUploadFile} onUploadFile={this.onUploadFile}

View File

@@ -11,6 +11,7 @@ import Lightbox from 'react-image-lightbox';
import 'react-image-lightbox/style.css'; import 'react-image-lightbox/style.css';
import '../../css/tip-for-new-md.css'; import '../../css/tip-for-new-md.css';
import toaster from '../toast';
const propTypes = { const propTypes = {
path: PropTypes.string.isRequired, path: PropTypes.string.isRequired,
@@ -61,6 +62,19 @@ class DirentListView extends React.Component {
this.setState({isItemFreezed: false}); this.setState({isItemFreezed: false});
} }
onItemRename = (dirent, newName) => {
let isDuplicated = this.props.direntList.some(item => {
return item.name === newName;
});
if (isDuplicated) {
let errMessage = gettext('The name {name} is already occupied, please choose another name.');
errMessage = errMessage.replace('{name}', Utils.HTMLescape(newName));
toaster.danger(errMessage);
return false;
}
this.props.onItemRename(dirent, newName);
}
onItemRenameToggle = () => { onItemRenameToggle = () => {
this.onFreezedItem(); this.onFreezedItem();
} }
@@ -238,11 +252,12 @@ class DirentListView extends React.Component {
repoID={this.props.repoID} repoID={this.props.repoID}
currentRepoInfo={this.props.currentRepoInfo} currentRepoInfo={this.props.currentRepoInfo}
isRepoOwner={this.props.isRepoOwner} isRepoOwner={this.props.isRepoOwner}
direntList={this.props.direntList}
onItemClick={this.props.onItemClick} onItemClick={this.props.onItemClick}
onItemRenameToggle={this.onItemRenameToggle} onItemRenameToggle={this.onItemRenameToggle}
onItemSelected={this.props.onItemSelected} onItemSelected={this.props.onItemSelected}
onItemDelete={this.props.onItemDelete} onItemDelete={this.props.onItemDelete}
onItemRename={this.props.onItemRename} onItemRename={this.onItemRename}
onItemMove={this.props.onItemMove} onItemMove={this.props.onItemMove}
onItemCopy={this.props.onItemCopy} onItemCopy={this.props.onItemCopy}
updateDirent={this.props.updateDirent} updateDirent={this.props.updateDirent}

View File

@@ -20,6 +20,7 @@ const propTypes = {
onUploadFolder: PropTypes.func.isRequired, onUploadFolder: PropTypes.func.isRequired,
isDraft: PropTypes.bool, isDraft: PropTypes.bool,
hasDraft: PropTypes.bool, hasDraft: PropTypes.bool,
direntList: PropTypes.array.isRequired,
}; };
class DirOperationToolbar extends React.Component { class DirOperationToolbar extends React.Component {
@@ -167,6 +168,14 @@ class DirOperationToolbar extends React.Component {
this.props.goDraftPage(); this.props.goDraftPage();
} }
checkDuplicatedName = (newName) => {
let direntList = this.props.direntList;
let isDuplicated = direntList.some(object => {
return object.name === newName;
});
return isDuplicated;
}
render() { render() {
let { path, isViewFile } = this.props; let { path, isViewFile } = this.props;
let itemType = isViewFile ? 'file' : 'dir'; let itemType = isViewFile ? 'file' : 'dir';
@@ -220,8 +229,9 @@ class DirOperationToolbar extends React.Component {
parentPath={this.props.path} parentPath={this.props.path}
fileType={this.state.fileType} fileType={this.state.fileType}
onAddFile={this.onAddFile} onAddFile={this.onAddFile}
checkDuplicatedName={this.checkDuplicatedName}
addFileCancel={this.onCreateFileToggle} addFileCancel={this.onCreateFileToggle}
/> />
</ModalPortal> </ModalPortal>
)} )}
{this.state.isCreateFolderDialogShow && ( {this.state.isCreateFolderDialogShow && (
@@ -229,6 +239,7 @@ class DirOperationToolbar extends React.Component {
<CreateFolder <CreateFolder
parentPath={this.props.path} parentPath={this.props.path}
onAddFolder={this.onAddFolder} onAddFolder={this.onAddFolder}
checkDuplicatedName={this.checkDuplicatedName}
addFolderCancel={this.onCreateFolderToggle} addFolderCancel={this.onCreateFolderToggle}
/> />
</ModalPortal> </ModalPortal>

View File

@@ -1,6 +1,7 @@
import { Utils } from '../../utils/utils'; import { Utils } from '../../utils/utils';
import Tree from './tree'; import Tree from './tree';
import TreeNode from './tree-node'; import TreeNode from './tree-node';
import Dirent from '../../models/dirent';
class TreeHelper { class TreeHelper {
@@ -74,11 +75,12 @@ class TreeHelper {
return treeCopy; return treeCopy;
} }
moveNodeByPath(tree, nodePath, destPath) { moveNodeByPath(tree, nodePath, destPath, nodeName) {
let treeCopy = tree.clone(); let treeCopy = tree.clone();
let node = treeCopy.getNodeByPath(nodePath); let node = treeCopy.getNodeByPath(nodePath);
let destNode = treeCopy.getNodeByPath(destPath); let destNode = treeCopy.getNodeByPath(destPath);
if (destNode && node) { // node has loaded if (destNode && node) { // node has loaded
node.object.name = nodeName; // need not update path
treeCopy.moveNode(node, destNode); treeCopy.moveNode(node, destNode);
} }
if (!destNode && node){ if (!destNode && node){
@@ -94,7 +96,7 @@ class TreeHelper {
nodePaths.forEach(nodePath => { nodePaths.forEach(nodePath => {
let node = treeCopy.getNodeByPath(nodePath); let node = treeCopy.getNodeByPath(nodePath);
treeCopy.moveNode(node, destNode); treeCopy.moveNode(node, destNode);
}) });
} else { } else {
nodePaths.forEach(nodePath=> { nodePaths.forEach(nodePath=> {
let node = treeCopy.getNodeByPath(nodePath); let node = treeCopy.getNodeByPath(nodePath);
@@ -104,12 +106,13 @@ class TreeHelper {
return treeCopy; return treeCopy;
} }
copyNodeByPath(tree, nodePath, destPath) { copyNodeByPath(tree, nodePath, destPath, nodeName) {
let treeCopy = tree.clone(); let treeCopy = tree.clone();
let node = treeCopy.getNodeByPath(nodePath);
node = node.clone(); // need a dup
let destNode = treeCopy.getNodeByPath(destPath); let destNode = treeCopy.getNodeByPath(destPath);
let treeNode = treeCopy.getNodeByPath(nodePath);
if (destNode) { if (destNode) {
let node = treeNode.clone(); // need a dup
node.object.name = nodeName; // need not update path
treeCopy.copyNode(node, destNode); treeCopy.copyNode(node, destNode);
} }
return treeCopy; return treeCopy;
@@ -129,7 +132,7 @@ class TreeHelper {
buildTree() { buildTree() {
let tree = new Tree(); let tree = new Tree();
let object = {name: '/'}; let object = new Dirent({name: '/'});
let root = new TreeNode({object, isLoaded: false, isExpanded: true}); let root = new TreeNode({object, isLoaded: false, isExpanded: true});
tree.setRoot(root); tree.setRoot(root);
return tree; return tree;

View File

@@ -2,7 +2,7 @@ class TreeNode {
constructor({ path, object, isLoaded, isPreload, isExpanded, parentNode }) { constructor({ path, object, isLoaded, isPreload, isExpanded, parentNode }) {
this.path = path || object.name, // The default setting is the object name, which is set to a relative path when the father is set. this.path = path || object.name, // The default setting is the object name, which is set to a relative path when the father is set.
this.object = object; this.object = object.clone();
this.isLoaded = isLoaded || false; this.isLoaded = isLoaded || false;
this.isPreload = isPreload || false; this.isPreload = isPreload || false;
this.isExpanded = isExpanded || false; this.isExpanded = isExpanded || false;
@@ -13,7 +13,7 @@ class TreeNode {
clone() { clone() {
let treeNode = new TreeNode({ let treeNode = new TreeNode({
path: this.path, path: this.path,
object: this.object, object: this.object.clone(),
isLoaded: this.isLoaded, isLoaded: this.isLoaded,
isPreload: this.isPreload, isPreload: this.isPreload,
isExpanded: this.isExpanded, isExpanded: this.isExpanded,
@@ -102,7 +102,7 @@ class TreeNode {
const treeNode = { const treeNode = {
path: this.path, path: this.path,
object: this.object, object: this.object.clone(),
isLoaded: this.isLoaded, isLoaded: this.isLoaded,
isPreload: this.isPreload, isPreload: this.isPreload,
isExpanded: this.isExpanded, isExpanded: this.isExpanded,
@@ -115,6 +115,7 @@ class TreeNode {
static deserializefromJson(json) { static deserializefromJson(json) {
let { path, object, isLoaded, isPreload, isExpanded, parentNode, children = [] } = json; let { path, object, isLoaded, isPreload, isExpanded, parentNode, children = [] } = json;
object = object.clone();
const treeNode = new TreeNode({ const treeNode = new TreeNode({
path, path,

View File

@@ -34,6 +34,10 @@ class Dirent {
} }
} }
clone() {
return new Dirent(this);
}
isDir() { isDir() {
return this.type !== 'file'; return this.type !== 'file';
} }

View File

@@ -187,6 +187,7 @@ class MainPanel extends Component {
repoID={repoID} repoID={repoID}
isDraft={this.props.isDraft} isDraft={this.props.isDraft}
hasDraft={this.props.hasDraft} hasDraft={this.props.hasDraft}
direntList={this.props.direntList}
permission={this.props.permission} permission={this.props.permission}
isViewFile={this.props.isViewFile} isViewFile={this.props.isViewFile}
showShareBtn={this.props.showShareBtn} showShareBtn={this.props.showShareBtn}

View File

@@ -1,10 +1,12 @@
import React, { Component } from 'react'; import React, { Component } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { gettext } from '../../utils/constants';
import { Dropdown, DropdownMenu, DropdownToggle, DropdownItem } from 'reactstrap'; import { Dropdown, DropdownMenu, DropdownToggle, DropdownItem } from 'reactstrap';
import { gettext } from '../../utils/constants';
import { Utils } from '../../utils/utils';
import TreeView from '../../components/tree-view-2/tree-view'; import TreeView from '../../components/tree-view-2/tree-view';
import Logo from '../../components/logo'; import Logo from '../../components/logo';
import Loading from '../../components/loading'; import Loading from '../../components/loading';
import toaster from '../../components/toast';
import ModalPortal from '../../components/modal-portal'; import ModalPortal from '../../components/modal-portal';
import Delete from '../../components/dialog/delete-dialog'; import Delete from '../../components/dialog/delete-dialog';
import Rename from '../../components/dialog/rename-dialog'; import Rename from '../../components/dialog/rename-dialog';
@@ -141,6 +143,19 @@ class SidePanel extends Component {
this.props.onDeleteNode(node); this.props.onDeleteNode(node);
} }
checkDuplicatedName = (newName) => {
let node = this.state.opNode;
// root node to new node conditions: parentNode is null,
let parentNode = node.parentNode ? node.parentNode : node;
let childrenObject = parentNode.children.map(item => {
return item.object;
});
let isDuplicated = childrenObject.some(object => {
return object.name === newName;
});
return isDuplicated;
}
render() { render() {
return ( return (
<div className={`side-panel wiki-side-panel ${this.props.closeSideBar ? '': 'left-zero'}`}> <div className={`side-panel wiki-side-panel ${this.props.closeSideBar ? '': 'left-zero'}`}>
@@ -190,8 +205,9 @@ class SidePanel extends Component {
<CreateFolder <CreateFolder
parentPath={this.state.opNode.path} parentPath={this.state.opNode.path}
onAddFolder={this.onAddFolderNode} onAddFolder={this.onAddFolderNode}
checkDuplicatedName={this.checkDuplicatedName}
addFolderCancel={this.onAddFolderToggle} addFolderCancel={this.onAddFolderToggle}
/> />
</ModalPortal> </ModalPortal>
)} )}
{this.state.isAddFileDialogShow && ( {this.state.isAddFileDialogShow && (
@@ -200,8 +216,9 @@ class SidePanel extends Component {
fileType={'.md'} fileType={'.md'}
parentPath={this.state.opNode.path} parentPath={this.state.opNode.path}
onAddFile={this.onAddFileNode} onAddFile={this.onAddFileNode}
checkDuplicatedName={this.checkDuplicatedName}
addFileCancel={this.onAddFileToggle} addFileCancel={this.onAddFileToggle}
/> />
</ModalPortal> </ModalPortal>
)} )}
{this.state.isRenameDialogShow && ( {this.state.isRenameDialogShow && (
@@ -209,6 +226,7 @@ class SidePanel extends Component {
<Rename <Rename
currentNode={this.state.opNode} currentNode={this.state.opNode}
onRename={this.onRenameNode} onRename={this.onRenameNode}
checkDuplicatedName={this.checkDuplicatedName}
toggleCancel={this.onRenameToggle} toggleCancel={this.onRenameToggle}
/> />
</ModalPortal> </ModalPortal>

View File

@@ -473,9 +473,9 @@ class Wiki extends Component {
//just for view list state //just for view list state
let dirName = dirent.name let dirName = dirent.name
let direntPath = Utils.joinPath(this.state.path, dirName); let direntPath = Utils.joinPath(this.state.path, dirName);
seafileAPI.moveDir(repoID, destRepo.repo_id,moveToDirentPath, this.state.path, dirName).then(() => { seafileAPI.moveDir(repoID, destRepo.repo_id,moveToDirentPath, this.state.path, dirName).then(res => {
let nodeName = res.data[0].obj_name;
this.moveTreeNode(direntPath, moveToDirentPath, destRepo); this.moveTreeNode(direntPath, moveToDirentPath, destRepo, nodeName);
this.moveDirent(direntPath); this.moveDirent(direntPath);
let message = gettext('Successfully moved %(name)s.'); let message = gettext('Successfully moved %(name)s.');
@@ -492,8 +492,9 @@ class Wiki extends Component {
//just for view list state //just for view list state
let dirName = dirent.name; let dirName = dirent.name;
let direntPath = Utils.joinPath(this.state.path, dirName); let direntPath = Utils.joinPath(this.state.path, dirName);
seafileAPI.copyDir(repoID, destRepo.repo_id, copyToDirentPath, this.state.path, dirName).then(() => { seafileAPI.copyDir(repoID, destRepo.repo_id, copyToDirentPath, this.state.path, dirName).then(res => {
this.copyTreeNode(direntPath, copyToDirentPath, destRepo); let nodeName = res.data[0].obj_name;
this.copyTreeNode(direntPath, copyToDirentPath, destRepo, nodeName);
let message = gettext('Successfully copied %(name)s.'); let message = gettext('Successfully copied %(name)s.');
message = message.replace('%(name)s', dirName); message = message.replace('%(name)s', dirName);
toaster.success(message); toaster.success(message);
@@ -508,9 +509,12 @@ class Wiki extends Component {
let direntPaths = this.getSelectedDirentPaths(); let direntPaths = this.getSelectedDirentPaths();
let dirNames = this.getSelectedDirentNames(); let dirNames = this.getSelectedDirentNames();
seafileAPI.moveDir(repoID, destRepo.repo_id, destDirentPath, this.state.path, dirNames).then(() => { seafileAPI.moveDir(repoID, destRepo.repo_id, destDirentPath, this.state.path, dirNames).then(res => {
direntPaths.forEach(direntPath => { let names = res.data.map(item => {
this.moveTreeNode(direntPath, destDirentPath, destRepo); return item.obj_name;
});
direntPaths.forEach((direntPath, index) => {
this.moveTreeNode(direntPath, destDirentPath, destRepo, names[index]);
this.moveDirent(direntPath); this.moveDirent(direntPath);
}); });
let message = gettext('Successfully moved %(name)s.'); let message = gettext('Successfully moved %(name)s.');
@@ -527,9 +531,12 @@ class Wiki extends Component {
let direntPaths = this.getSelectedDirentPaths(); let direntPaths = this.getSelectedDirentPaths();
let dirNames = this.getSelectedDirentNames(); let dirNames = this.getSelectedDirentNames();
seafileAPI.copyDir(repoID, destRepo.repo_id, destDirentPath, this.state.path, dirNames).then(() => { seafileAPI.copyDir(repoID, destRepo.repo_id, destDirentPath, this.state.path, dirNames).then(res => {
direntPaths.forEach(direntPath => { let names = res.data.map(item => {
this.copyTreeNode(direntPath, destDirentPath, destRepo); return item.obj_name;
});
direntPaths.forEach((direntPath, index) => {
this.copyTreeNode(direntPath, destDirentPath, destRepo, names[index]);
}); });
let message = gettext('Successfully copied %(name)s.'); let message = gettext('Successfully copied %(name)s.');
message = message.replace('%(name)s', dirNames); message = message.replace('%(name)s', dirNames);
@@ -911,21 +918,21 @@ class Wiki extends Component {
this.setState({treeData: tree}); this.setState({treeData: tree});
} }
moveTreeNode = (nodePath, moveToPath, moveToRepo) => { moveTreeNode = (nodePath, moveToPath, moveToRepo, nodeName) => {
if (repoID !== moveToRepo.repo_id) { if (repoID !== moveToRepo.repo_id) {
let tree = treeHelper.deleteNodeByPath(this.state.treeData, nodePath); let tree = treeHelper.deleteNodeByPath(this.state.treeData, nodePath);
this.setState({treeData: tree}); this.setState({treeData: tree});
return return
} }
let tree = treeHelper.moveNodeByPath(this.state.treeData, nodePath, moveToPath); let tree = treeHelper.moveNodeByPath(this.state.treeData, nodePath, moveToPath, nodeName);
this.setState({treeData: tree}); this.setState({treeData: tree});
} }
copyTreeNode = (nodePath, copyToPath, destRepo) => { copyTreeNode = (nodePath, copyToPath, destRepo, nodeName) => {
if (repoID !== destRepo.repo_id) { if (repoID !== destRepo.repo_id) {
return; return;
} }
let tree = treeHelper.copyNodeByPath(this.state.treeData, nodePath, copyToPath); let tree = treeHelper.copyNodeByPath(this.state.treeData, nodePath, copyToPath, nodeName);
this.setState({treeData: tree}); this.setState({treeData: tree});
} }