1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-09-02 07:27:04 +00:00

Repo mode optimized (#2850)

* optimized repo-wiki-mode side-panel.js

* optimized main-panel code

* repair bug
This commit is contained in:
杨顺强
2019-01-18 16:41:26 +08:00
committed by Daniel Pan
parent 6155c81522
commit 620029ad9d
4 changed files with 181 additions and 176 deletions

View File

@@ -5282,7 +5282,7 @@
}, },
"git-up": { "git-up": {
"version": "1.2.1", "version": "1.2.1",
"resolved": "http://registry.npmjs.org/git-up/-/git-up-1.2.1.tgz", "resolved": "https://registry.npmjs.org/git-up/-/git-up-1.2.1.tgz",
"integrity": "sha1-JkSAoAax2EJhrB/gmjpRacV+oZ0=", "integrity": "sha1-JkSAoAax2EJhrB/gmjpRacV+oZ0=",
"requires": { "requires": {
"is-ssh": "^1.0.0", "is-ssh": "^1.0.0",
@@ -5291,7 +5291,7 @@
}, },
"git-url-parse": { "git-url-parse": {
"version": "5.0.1", "version": "5.0.1",
"resolved": "http://registry.npmjs.org/git-url-parse/-/git-url-parse-5.0.1.tgz", "resolved": "https://registry.npmjs.org/git-url-parse/-/git-url-parse-5.0.1.tgz",
"integrity": "sha1-/j15xnRq4FBIz6UIyB553du6OEM=", "integrity": "sha1-/j15xnRq4FBIz6UIyB553du6OEM=",
"requires": { "requires": {
"git-up": "^1.0.0" "git-up": "^1.0.0"
@@ -7844,7 +7844,7 @@
}, },
"node-status-codes": { "node-status-codes": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "http://registry.npmjs.org/node-status-codes/-/node-status-codes-1.0.0.tgz", "resolved": "https://registry.npmjs.org/node-status-codes/-/node-status-codes-1.0.0.tgz",
"integrity": "sha1-WuVUHQJGRdMqWPzdyc7s6nrjrC8=" "integrity": "sha1-WuVUHQJGRdMqWPzdyc7s6nrjrC8="
}, },
"noop6": { "noop6": {
@@ -8151,7 +8151,7 @@
}, },
"package.json": { "package.json": {
"version": "2.0.1", "version": "2.0.1",
"resolved": "http://registry.npmjs.org/package.json/-/package.json-2.0.1.tgz", "resolved": "https://registry.npmjs.org/package.json/-/package.json-2.0.1.tgz",
"integrity": "sha1-+IYFnSpJ7QduZIg2ldc7K0bSHW0=", "integrity": "sha1-+IYFnSpJ7QduZIg2ldc7K0bSHW0=",
"requires": { "requires": {
"git-package-json": "^1.4.0", "git-package-json": "^1.4.0",
@@ -8161,7 +8161,7 @@
"dependencies": { "dependencies": {
"got": { "got": {
"version": "5.7.1", "version": "5.7.1",
"resolved": "http://registry.npmjs.org/got/-/got-5.7.1.tgz", "resolved": "https://registry.npmjs.org/got/-/got-5.7.1.tgz",
"integrity": "sha1-X4FjWmHkplifGAVp6k44FoClHzU=", "integrity": "sha1-X4FjWmHkplifGAVp6k44FoClHzU=",
"requires": { "requires": {
"create-error-class": "^3.0.1", "create-error-class": "^3.0.1",
@@ -8183,7 +8183,7 @@
}, },
"package-json": { "package-json": {
"version": "2.4.0", "version": "2.4.0",
"resolved": "http://registry.npmjs.org/package-json/-/package-json-2.4.0.tgz", "resolved": "https://registry.npmjs.org/package-json/-/package-json-2.4.0.tgz",
"integrity": "sha1-DRW9Z9HLvduyyiIv8u24a8sxqLs=", "integrity": "sha1-DRW9Z9HLvduyyiIv8u24a8sxqLs=",
"requires": { "requires": {
"got": "^5.0.0", "got": "^5.0.0",
@@ -10819,9 +10819,9 @@
} }
}, },
"seafile-js": { "seafile-js": {
"version": "0.2.57", "version": "0.2.58",
"resolved": "https://registry.npmjs.org/seafile-js/-/seafile-js-0.2.57.tgz", "resolved": "https://registry.npmjs.org/seafile-js/-/seafile-js-0.2.58.tgz",
"integrity": "sha512-LVZ63u9rp5UnKuifzlGb3DfHv9F5C/AANgii53cwHfcAJPI3Fws/dHQaWZU9c1kTjgf4e15lltQI+6ch4MKw0A==", "integrity": "sha512-4/H5SLSZo4qBE3D9sdHyZqBtt3NZLEOhL+xSFcivE3lnCpITTaPaQZUl7Icx/PXHjD6CqIlM6EDKJgJz9m0BRA==",
"requires": { "requires": {
"axios": "^0.18.0", "axios": "^0.18.0",
"form-data": "^2.3.2", "form-data": "^2.3.2",

View File

@@ -32,7 +32,7 @@
"react-moment": "^0.7.9", "react-moment": "^0.7.9",
"react-select": "^2.1.1", "react-select": "^2.1.1",
"reactstrap": "^6.4.0", "reactstrap": "^6.4.0",
"seafile-js": "^0.2.57", "seafile-js": "^0.2.58",
"socket.io-client": "^2.2.0", "socket.io-client": "^2.2.0",
"sw-precache-webpack-plugin": "0.11.4", "sw-precache-webpack-plugin": "0.11.4",
"unified": "^7.0.0", "unified": "^7.0.0",

View File

@@ -214,83 +214,81 @@ class MainPanel extends Component {
)} )}
</div> </div>
<div className="cur-view-content"> <div className="cur-view-content">
{!this.props.pathExist ? {!this.props.pathExist && ErrMessage }
ErrMessage : {(this.props.pathExist && this.props.isViewFile) && (
<WikiMarkdownViewer
isFileLoading={this.props.isFileLoading}
markdownContent={this.props.content}
latestContributor={this.props.latestContributor}
lastModified = {this.props.lastModified}
onLinkClick={this.props.onLinkClick}
>
<Fragment>
{this.props.reviewStatus === 'open' &&
<div className='seafile-btn-view-review text-center'>
<div className='tag tag-green'>
{gettext('This file is in review stage')}
<a className="ml-2" onMouseDown={this.props.goReviewPage}>{gettext('View Review')}</a>
</div>
</div>
}
{(!this.props.isDraft && this.props.hasDraft && this.props.reviewStatus !== 'open') &&
<div className='seafile-btn-view-review text-center'>
<div className='tag tag-green'>
{gettext('This file is in draft stage.')}
<a className="ml-2" onMouseDown={this.props.goDraftPage}>{gettext('Edit Draft')}</a>
</div>
</div>
}
</Fragment>
</WikiMarkdownViewer>
)}
{(this.props.pathExist && !this.props.isViewFile) && (
<Fragment> <Fragment>
{this.props.isViewFile ? {showRepoInfoBar && (
<WikiMarkdownViewer <RepoInfoBar
isFileLoading={this.props.isFileLoading} repoID={repoID}
markdownContent={this.props.content} currentPath={this.props.path}
latestContributor={this.props.latestContributor} usedRepoTags={this.props.usedRepoTags}
lastModified = {this.props.lastModified} readmeMarkdown={this.props.readmeMarkdown}
onLinkClick={this.props.onLinkClick} draftCounts={this.props.draftCounts}
> reviewCounts={this.props.reviewCounts}
<Fragment> />
{this.props.reviewStatus === 'open' && )}
<div className='seafile-btn-view-review text-center'> <DirentListView
<div className='tag tag-green'> path={this.props.path}
{gettext('This file is in review stage')} repoID={repoID}
<a className="ml-2" onMouseDown={this.props.goReviewPage}>{gettext('View Review')}</a> repoEncrypted={this.props.repoEncrypted}
</div> direntList={this.props.direntList}
</div> sortBy={this.props.sortBy}
} sortOrder={this.props.sortOrder}
{(!this.props.isDraft && this.props.hasDraft && this.props.reviewStatus !== 'open') && sortItems={this.props.sortItems}
<div className='seafile-btn-view-review text-center'> onAddFile={this.props.onAddFile}
<div className='tag tag-green'> onItemClick={this.onItemClick}
{gettext('This file is in draft stage.')} onItemDelete={this.props.onItemDelete}
<a className="ml-2" onMouseDown={this.props.goDraftPage}>{gettext('Edit Draft')}</a> onItemRename={this.props.onItemRename}
</div> onItemMove={this.props.onItemMove}
</div> onItemCopy={this.props.onItemCopy}
} onDirentClick={this.onDirentClick}
</Fragment> onItemDetails={this.onItemDetails}
</WikiMarkdownViewer> : isDirentListLoading={this.props.isDirentListLoading}
<Fragment> updateDirent={this.props.updateDirent}
{showRepoInfoBar && ( currentRepoInfo={this.state.currentRepoInfo}
<RepoInfoBar isRepoOwner={this.state.isRepoOwner}
repoID={repoID} isAllItemSelected={this.props.isAllDirentSelected}
currentPath={this.props.path} onAllItemSelected={this.props.onAllDirentSelected}
usedRepoTags={this.props.usedRepoTags} onItemSelected={this.props.onItemSelected}
readmeMarkdown={this.props.readmeMarkdown} />
draftCounts={this.props.draftCounts} <FileUploader
reviewCounts={this.props.reviewCounts} ref={uploader => this.uploader = uploader}
/> dragAndDrop={true}
)} path={this.props.path}
<DirentListView repoID={repoID}
path={this.props.path} direntList={this.props.direntList}
repoID={repoID} onFileUploadSuccess={this.onFileUploadSuccess}
repoEncrypted={this.props.repoEncrypted} />
direntList={this.props.direntList}
sortBy={this.props.sortBy}
sortOrder={this.props.sortOrder}
sortItems={this.props.sortItems}
onAddFile={this.props.onAddFile}
onItemClick={this.onItemClick}
onItemDelete={this.props.onItemDelete}
onItemRename={this.props.onItemRename}
onItemMove={this.props.onItemMove}
onItemCopy={this.props.onItemCopy}
onDirentClick={this.onDirentClick}
onItemDetails={this.onItemDetails}
isDirentListLoading={this.props.isDirentListLoading}
updateDirent={this.props.updateDirent}
currentRepoInfo={this.state.currentRepoInfo}
isRepoOwner={this.state.isRepoOwner}
isAllItemSelected={this.props.isAllDirentSelected}
onAllItemSelected={this.props.onAllDirentSelected}
onItemSelected={this.props.onItemSelected}
/>
<FileUploader
ref={uploader => this.uploader = uploader}
dragAndDrop={true}
path={this.props.path}
repoID={repoID}
direntList={this.props.direntList}
onFileUploadSuccess={this.onFileUploadSuccess}
/>
</Fragment>
}
</Fragment> </Fragment>
} )}
</div> </div>
</div> </div>
{this.state.isDirentDetailShow && ( {this.state.isDirentDetailShow && (

View File

@@ -1,9 +1,11 @@
import React, { Component } from 'react'; import React, { Component } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { gettext, siteRoot, logoPath, mediaUrl, siteTitle, logoWidth, logoHeight } from '../../utils/constants'; import { gettext } from '../../utils/constants';
import { Dropdown, DropdownMenu, DropdownToggle, DropdownItem } from 'reactstrap';
import TreeView from '../../components/tree-view/tree-view'; import TreeView from '../../components/tree-view/tree-view';
import NodeMenu from '../../components/tree-view/node-menu'; import NodeMenu from '../../components/tree-view/node-menu';
import MenuControl from '../../components/menu-control'; import Logo from '../../components/logo';
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';
import CreateFolder from '../../components/dialog/create-folder-dialog'; import CreateFolder from '../../components/dialog/create-folder-dialog';
@@ -37,29 +39,29 @@ class SidePanel extends Component {
}, },
isLoadFailed: false, isLoadFailed: false,
isMenuIconShow: false, isMenuIconShow: false,
showDelete: false, isHeaderMenuShow: false,
showFile: false, isDeleteDialogShow: false,
showFolder: false, isAddFileDialogShow: false,
showRename: false, isAddFolderDialogShow: false,
isFile: false isRenameDialogShow: false,
}; };
this.searchedPath = null;
}
closeSide = () => {
this.props.onCloseSide();
} }
onMouseEnter = () => { onMouseEnter = () => {
this.setState({ this.setState({isMenuIconShow: true});
isMenuIconShow: true
});
} }
onMouseLeave = () => { onMouseLeave = () => {
this.setState({ this.setState({isMenuIconShow: false});
isMenuIconShow: false }
});
onDropdownToggleClick = (e) => {
e.preventDefault();
this.toggleOperationMenu();
}
toggleOperationMenu = () => {
this.setState({isHeaderMenuShow: !this.state.isHeaderMenuShow});
} }
onNodeClick = (node) => { onNodeClick = (node) => {
@@ -79,19 +81,6 @@ class SidePanel extends Component {
}); });
} }
onHeadingMenuClick = (e) => {
e.nativeEvent.stopImmediatePropagation();
let node = this.props.treeData.root;
let left = e.clientX - 8*16;
let top = e.clientY + 10;
let position = Object.assign({},this.state.menuPosition, {left: left, top: top});
this.setState({
isShowMenu: !this.state.isShowMenu,
currentNode: node,
menuPosition: position
});
}
onHideContextMenu = () => { onHideContextMenu = () => {
if (!this.state.isShowMenu) { if (!this.state.isShowMenu) {
return; return;
@@ -102,44 +91,50 @@ class SidePanel extends Component {
}); });
} }
toggleAddFile = () => { onAddFileToggle = () => {
this.setState({showFile: !this.state.showFile}); this.setState({
isMenuIconShow: false,
isAddFileDialogShow: !this.state.isAddFileDialogShow
});
this.onHideContextMenu(); this.onHideContextMenu();
} }
toggleAddFolder = () => { onAddFolderToggle = () => {
this.setState({showFolder: !this.state.showFolder}); this.setState({
isMenuIconShow: false,
isAddFolderDialogShow: !this.state.isAddFolderDialogShow
});
this.onHideContextMenu(); this.onHideContextMenu();
} }
toggleRename = () => { onRenameToggle = () => {
this.setState({showRename: !this.state.showRename}); this.setState({isRenameDialogShow: !this.state.isRenameDialogShow});
this.onHideContextMenu(); this.onHideContextMenu();
} }
toggleDelete = () => { onDeleteToggle = () => {
this.setState({showDelete: !this.state.showDelete}); this.setState({isDeleteDialogShow: !this.state.isDeleteDialogShow});
this.onHideContextMenu(); this.onHideContextMenu();
} }
onAddFolderNode = (dirPath) => { onAddFolderNode = (dirPath) => {
this.setState({showFolder: !this.state.showFolder}); this.setState({isAddFolderDialogShow: !this.state.isAddFolderDialogShow});
this.props.onAddFolderNode(dirPath); this.props.onAddFolderNode(dirPath);
} }
onAddFileNode = (filePath, isDraft) => { onAddFileNode = (filePath, isDraft) => {
this.setState({showFile: !this.state.showFile}); this.setState({isAddFileDialogShow: !this.state.isAddFileDialogShow});
this.props.onAddFileNode(filePath, isDraft); this.props.onAddFileNode(filePath, isDraft);
} }
onRenameNode = (newName) => { onRenameNode = (newName) => {
this.setState({showRename: !this.state.showRename}); this.setState({isRenameDialogShow: !this.state.isRenameDialogShow});
let node = this.state.currentNode; let node = this.state.currentNode;
this.props.onRenameNode(node, newName); this.props.onRenameNode(node, newName);
} }
onDeleteNode = () => { onDeleteNode = () => {
this.setState({showDelete: !this.state.showDelete}); this.setState({isDeleteDialogShow: !this.state.isDeleteDialogShow});
let node = this.state.currentNode; let node = this.state.currentNode;
this.props.onDeleteNode(node); this.props.onDeleteNode(node);
} }
@@ -157,97 +152,109 @@ class SidePanel extends Component {
} }
addFolderCancel = () => { addFolderCancel = () => {
this.setState({showFolder: !this.state.showFolder}); this.setState({isAddFolderDialogShow: !this.state.isAddFolderDialogShow});
} }
addFileCancel = () => { addFileCancel = () => {
this.setState({showFile: !this.state.showFile}); this.setState({isAddFileDialogShow: !this.state.isAddFileDialogShow});
} }
deleteCancel = () => { deleteCancel = () => {
this.setState({showDelete: !this.state.showDelete}); this.setState({isDeleteDialogShow: !this.state.isDeleteDialogShow});
} }
renameCancel = () => { renameCancel = () => {
this.setState({showRename: !this.state.showRename}); this.setState({isRenameDialogShow: !this.state.isRenameDialogShow});
} }
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'}`}>
<div className="side-panel-top panel-top"> <div className="side-panel-top panel-top">
<a href={siteRoot} id="logo"> <Logo onCloseSidePanel={this.props.onCloseSide} />
<img src={mediaUrl + logoPath} title={siteTitle} alt="logo" width={logoWidth} height={logoHeight} />
</a>
<a title="Close" aria-label="Close" onClick={this.closeSide} className="sf2-icon-x1 sf-popover-close side-panel-close action-icon d-md-none "></a>
</div> </div>
<div id="side-nav" className="wiki-side-nav" role="navigation"> <div id="side-nav" className="wiki-side-nav" role="navigation">
<h3 <h3 className="wiki-pages-heading" onMouseEnter={this.onMouseEnter} onMouseLeave={this.onMouseLeave}>
className="wiki-pages-heading"
onMouseEnter={this.onMouseEnter}
onMouseLeave={this.onMouseLeave}
>
{gettext('Files')} {gettext('Files')}
<div className="heading-icon"> <div className="heading-icon">
<MenuControl {this.state.isMenuIconShow && (
isShow={this.state.isMenuIconShow} <Dropdown isOpen={this.state.isHeaderMenuShow} toggle={this.toggleOperationMenu}>
onClick={this.onHeadingMenuClick} <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>
<DropdownItem onClick={this.onAddFolderToggle}>{gettext('New Folder')}</DropdownItem>
<DropdownItem onClick={this.onAddFileToggle}>{gettext('New File')}</DropdownItem>
</DropdownMenu>
</Dropdown>
)}
</div> </div>
</h3> </h3>
<div className="wiki-pages-container"> <div className="wiki-pages-container">
{this.props.treeData && {this.props.treeData && (
<TreeView <TreeView
currentPath={this.props.currentPath} treeData={this.props.treeData}
treeData={this.props.treeData} currentPath={this.props.currentPath}
currentNode={this.state.currentNode} isNodeItemFrezee={this.state.isNodeItemFrezee}
isNodeItemFrezee={this.state.isNodeItemFrezee} onShowContextMenu={this.onShowContextMenu}
onNodeClick={this.onNodeClick} onNodeClick={this.onNodeClick}
onShowContextMenu={this.onShowContextMenu} onDirCollapse={this.props.onDirCollapse}
onDirCollapse={this.props.onDirCollapse} />
/> )}
} {this.state.isShowMenu && (
{this.state.isShowMenu && <NodeMenu
<NodeMenu menuPosition={this.state.menuPosition}
menuPosition={this.state.menuPosition} currentNode={this.state.currentNode}
currentNode={this.state.currentNode} toggleAddFile={this.onAddFileToggle}
toggleAddFile={this.toggleAddFile} toggleAddFolder={this.onAddFolderToggle}
toggleAddFolder={this.toggleAddFolder} toggleRename={this.onRenameToggle}
toggleRename={this.toggleRename} toggleDelete={this.onDeleteToggle}
toggleDelete={this.toggleDelete} />
/> )}
} </div>
{this.state.showDelete && </div>
{this.state.isDeleteDialogShow && (
<ModalPortal>
<Delete <Delete
currentNode={this.state.currentNode} currentNode={this.state.currentNode}
handleSubmit={this.onDeleteNode} handleSubmit={this.onDeleteNode}
toggleCancel={this.deleteCancel} toggleCancel={this.deleteCancel}
/> />
} </ModalPortal>
{this.state.showFile && )}
{this.state.isAddFileDialogShow && (
<ModalPortal>
<CreateFile <CreateFile
fileType={'.md'} fileType={'.md'}
parentPath={this.state.currentNode.path} parentPath={this.state.currentNode.path}
onAddFile={this.onAddFileNode} onAddFile={this.onAddFileNode}
addFileCancel={this.addFileCancel} addFileCancel={this.addFileCancel}
/> />
} </ModalPortal>
{this.state.showFolder && )}
{this.state.isAddFolderDialogShow && (
<ModalPortal>
<CreateFolder <CreateFolder
parentPath={this.state.currentNode.path} parentPath={this.state.currentNode.path}
onAddFolder={this.onAddFolderNode} onAddFolder={this.onAddFolderNode}
addFolderCancel={this.addFolderCancel} addFolderCancel={this.addFolderCancel}
/> />
} </ModalPortal>
{this.state.showRename && )}
{this.state.isRenameDialogShow && (
<ModalPortal>
<Rename <Rename
currentNode={this.state.currentNode} currentNode={this.state.currentNode}
onRename={this.onRenameNode} onRename={this.onRenameNode}
toggleCancel={this.renameCancel} toggleCancel={this.renameCancel}
/> />
} </ModalPortal>
</div> )}
</div>
</div> </div>
); );
} }