1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-09-21 11:27:18 +00:00
Files
seahub/frontend/src/pages/repo-wiki-mode/main-panel.js

323 lines
12 KiB
JavaScript
Raw Normal View History

import React, { Component, Fragment } from 'react';
2018-10-13 17:07:54 +08:00
import PropTypes from 'prop-types';
import cookie from 'react-cookies';
2018-12-13 14:57:46 +08:00
import { gettext, repoID, siteRoot, permission } from '../../utils/constants';
2018-10-13 17:07:54 +08:00
import { seafileAPI } from '../../utils/seafile-api';
2018-11-14 10:55:11 +08:00
import { Utils } from '../../utils/utils';
2018-12-18 17:21:01 +08:00
import RepoInfo from '../../models/repo-info';
import CommonToolbar from '../../components/toolbar/common-toolbar';
import ViewModeToolbar from '../../components/toolbar/view-mode-toolbar';
import DirOperationToolBar from '../../components/toolbar/dir-operation-toolbar';
import MutipleDirOperationToolbar from '../../components/toolbar/mutilple-dir-operation-toolbar';
import CurDirPath from '../../components/cur-dir-path';
import MarkdownContentViewer from '../../components/markdown-viewer';
2018-10-13 17:07:54 +08:00
import DirentListView from '../../components/dirent-list-view/dirent-list-view';
import DirentDetail from '../../components/dirent-detail/dirent-details';
2018-11-14 10:55:11 +08:00
import FileUploader from '../../components/file-uploader/file-uploader';
import FileTagsViewer from '../../components/filetags-viewer';
2018-10-13 17:07:54 +08:00
const propTypes = {
content: PropTypes.string,
lastModified: PropTypes.string,
latestContributor: PropTypes.string,
permission: PropTypes.string,
2018-12-06 14:10:36 +08:00
hash: PropTypes.string,
2018-11-22 11:26:00 +08:00
path: PropTypes.string.isRequired,
// whether the file or dir corresponding to the path exist
pathExist: PropTypes.bool.isRequired,
2018-10-13 17:07:54 +08:00
isFileLoading: PropTypes.bool.isRequired,
2018-11-22 11:26:00 +08:00
isViewFile: PropTypes.bool.isRequired,
isDirentListLoading: PropTypes.bool.isRequired,
2018-11-23 20:19:42 +08:00
isDirentSelected: PropTypes.bool.isRequired,
isAllDirentSelected: PropTypes.bool.isRequired,
2018-11-22 11:26:00 +08:00
direntList: PropTypes.array.isRequired,
sortBy: PropTypes.string.isRequired,
sortOrder: PropTypes.string.isRequired,
sortItems: PropTypes.func.isRequired,
2018-11-23 20:19:42 +08:00
selectedDirentList: PropTypes.array.isRequired,
2018-11-22 11:26:00 +08:00
updateDirent: PropTypes.func.isRequired,
onSideNavMenuClick: PropTypes.func.isRequired,
2018-10-13 17:07:54 +08:00
onSearchedClick: PropTypes.func.isRequired,
onMainNavBarClick: PropTypes.func.isRequired,
2018-11-22 11:26:00 +08:00
onItemClick: PropTypes.func.isRequired,
2018-11-23 20:19:42 +08:00
onAllDirentSelected: PropTypes.func.isRequired,
onItemSelected: PropTypes.func.isRequired,
2018-11-22 11:26:00 +08:00
onItemDelete: PropTypes.func.isRequired,
onItemRename: PropTypes.func.isRequired,
onItemMove: PropTypes.func.isRequired,
onItemCopy: PropTypes.func.isRequired,
onAddFile: PropTypes.func.isRequired,
onAddFolder: PropTypes.func.isRequired,
onFileTagChanged: PropTypes.func.isRequired,
2018-11-23 20:19:42 +08:00
onItemsMove: PropTypes.func.isRequired,
onItemsCopy: PropTypes.func.isRequired,
onItemsDelete: PropTypes.func.isRequired,
2018-12-12 02:34:58 +00:00
onLinkClick: PropTypes.func.isRequired,
isDraft: PropTypes.bool,
hasDraft: PropTypes.bool,
reviewStatus: PropTypes.any,
goReviewPage: PropTypes.func,
goDraftPage: PropTypes.func,
2018-12-16 12:45:26 +00:00
reviewID: PropTypes.any,
usedRepoTags: PropTypes.array.isRequired,
2018-10-16 18:19:51 +08:00
};
class MainPanel extends Component {
2018-09-18 20:57:17 -05:00
constructor(props) {
super(props);
this.state = {
currentMode: 'wiki',
isDirentDetailShow: false,
currentDirent: null,
2018-11-23 20:19:42 +08:00
direntPath: '',
2018-12-18 17:21:01 +08:00
currentRepoInfo: null,
2018-11-01 18:40:18 +08:00
isRepoOwner: false,
activeTitleIndex: -1,
2018-09-29 15:47:53 +08:00
};
this.titlesInfo = null;
this.pageScroll = false;
2018-09-18 20:57:17 -05:00
}
componentDidMount() {
2018-11-01 18:40:18 +08:00
seafileAPI.getRepoInfo(repoID).then(res => {
2018-12-18 17:21:01 +08:00
let repoInfo = new RepoInfo(res.data);
2018-11-01 18:40:18 +08:00
seafileAPI.getAccountInfo().then(res => {
let user_email = res.data.email;
2018-12-18 17:21:01 +08:00
let isRepoOwner = repoInfo.owner_email === user_email;
2018-11-01 18:40:18 +08:00
this.setState({
2018-12-18 17:21:01 +08:00
currentRepoInfo: repoInfo,
2018-11-01 18:40:18 +08:00
isRepoOwner: isRepoOwner,
});
});
});
2018-12-06 14:10:36 +08:00
if (this.props.hash) {
let hash = this.props.hash;
setTimeout(function() {
window.location.hash = hash;
}, 500);
}
}
switchViewMode = (mode) => {
cookie.save('view_mode', mode, { path: '/' });
let repoName = this.state.currentRepoInfo.repo_name;
let dirPath = this.props.isViewFile ? Utils.getDirName(this.props.path) : this.props.path;
window.location.href = siteRoot + 'library/' + repoID + '/' + repoName + dirPath;
}
2018-11-22 11:26:00 +08:00
onSideNavMenuClick = () => {
this.props.onSideNavMenuClick();
}
onItemClick = (dirent) => {
this.setState({isDirentDetailShow: false});
this.props.onItemClick(dirent);
}
onMainNavBarClick = (path) => {
this.setState({isDirentDetailShow: false});
this.props.onMainNavBarClick(path);
2018-11-22 11:26:00 +08:00
}
2018-11-29 17:55:14 +08:00
onItemDetails = (dirent) => {
this.setState({
currentDirent: dirent,
isDirentDetailShow: true,
});
}
onItemDetailsClose = () => {
this.setState({isDirentDetailShow: false});
}
2018-11-22 11:26:00 +08:00
onFileTagChanged = (dirent, direntPath) => {
this.props.onFileTagChanged(dirent, direntPath);
2018-11-13 16:39:13 +08:00
}
onUploadFile = (e) => {
2018-11-14 10:55:11 +08:00
e.nativeEvent.stopImmediatePropagation();
this.uploader.onFileUpload();
}
onUploadFolder = (e) => {
2018-11-14 10:55:11 +08:00
e.nativeEvent.stopImmediatePropagation();
this.uploader.onFolderUpload();
}
2018-11-29 17:55:14 +08:00
onFileUploadSuccess = (file) => {
// todo
2018-11-14 10:55:11 +08:00
}
2018-12-07 18:24:20 +08:00
handlePageScroll = () => {
if (this.props.pathExist && this.props.isViewFile && !this.pageScroll && this.titlesInfo && this.titlesInfo.length > 0) {
this.pageScroll = true;
let that = this;
setTimeout(function() {
that.pageScroll = false;
}, 100);
const contentScrollTop = this.refs.curViewContent.scrollTop + 180;
let activeTitleIndex;
if (contentScrollTop <= this.titlesInfo[0]) {
activeTitleIndex = 0;
}
else if (contentScrollTop > this.titlesInfo[this.titlesInfo.length - 1]) {
activeTitleIndex = this.titlesInfo.length - 1;
}
else {
for (let i = 0; i < this.titlesInfo.length - 1; i++) {
if (contentScrollTop > this.titlesInfo[i] && this.titlesInfo[i + 1] &&
contentScrollTop < this.titlesInfo[i + 1]) {
activeTitleIndex = i;
break;
}
}
}
this.setState({
activeTitleIndex: activeTitleIndex
});
}
}
2018-12-07 18:24:20 +08:00
onContentRendered = (markdownViewer) => {
this.titlesInfo = markdownViewer.titlesInfo;
}
2018-10-13 17:07:54 +08:00
render() {
2018-11-29 17:55:14 +08:00
const ErrMessage = (<div className="message empty-tip err-message"><h2>{gettext('Folder does not exist.')}</h2></div>);
return (
<div className="main-panel wiki-main-panel o-hidden">
2018-11-29 17:55:14 +08:00
<div className="main-panel-north">
<div className="cur-view-toolbar border-left-show">
2018-11-22 11:26:00 +08:00
<span className="sf2-icon-menu hidden-md-up d-md-none side-nav-toggle" title={gettext('Side Nav Menu')} onClick={this.onSideNavMenuClick}></span>
2018-11-23 20:19:42 +08:00
<div className="dir-operation">
{this.props.isDirentSelected ?
<MutipleDirOperationToolbar
repoID={repoID}
path={this.props.path}
selectedDirentList={this.props.selectedDirentList}
onItemsMove={this.props.onItemsMove}
onItemsCopy={this.props.onItemsCopy}
onItemsDelete={this.props.onItemsDelete}
/> :
<DirOperationToolBar
path={this.props.path}
2018-11-28 12:41:49 +08:00
repoID={repoID}
2018-12-12 02:34:58 +00:00
isDraft={this.props.isDraft}
hasDraft={this.props.hasDraft}
permission={this.props.permission}
isViewFile={this.props.isViewFile}
onAddFile={this.props.onAddFile}
onAddFolder={this.props.onAddFolder}
onUploadFile={this.onUploadFile}
onUploadFolder={this.onUploadFolder}
/>
2018-11-23 20:19:42 +08:00
}
2018-09-18 20:57:17 -05:00
</div>
<ViewModeToolbar currentMode={this.state.currentMode} switchViewMode={this.switchViewMode}/>
</div>
2018-12-21 16:16:45 +08:00
<CommonToolbar repoID={repoID} onSearchedClick={this.props.onSearchedClick} searchPlaceholder={gettext('Search files in this library')}/>
</div>
2018-12-12 15:34:54 +08:00
<div className="main-panel-center flex-row">
<div className="cur-view-container">
<div className="cur-view-path">
2018-12-18 17:21:01 +08:00
{this.state.currentRepoInfo && (
2018-12-13 14:57:46 +08:00
<CurDirPath
repoID={repoID}
2018-12-18 17:21:01 +08:00
repoName={this.state.currentRepoInfo.repo_name}
2018-12-13 14:57:46 +08:00
currentPath={this.props.path}
permission={permission}
onPathClick={this.onMainNavBarClick}
2018-12-14 04:19:24 +00:00
isViewFile={this.props.isViewFile}
2018-12-13 14:57:46 +08:00
/>
)}
</div>
{(this.props.usedRepoTags.length > 0 && this.props.path === '/') && (
<div className="tags-summary-bar">
<FileTagsViewer
repoID={repoID}
currentPath={this.props.path}
usedRepoTags={this.props.usedRepoTags}
/>
</div>
)}
<div className="cur-view-content" onScroll={this.handlePageScroll} ref="curViewContent">
2018-11-29 17:55:14 +08:00
{!this.props.pathExist ?
ErrMessage :
2018-11-14 10:55:11 +08:00
<Fragment>
2018-11-22 11:26:00 +08:00
{ this.props.isViewFile ?
<MarkdownContentViewer
2018-11-22 11:26:00 +08:00
markdownContent={this.props.content}
latestContributor={this.props.latestContributor}
lastModified = {this.props.lastModified}
isFileLoading={this.props.isFileLoading}
activeTitleIndex={this.state.activeTitleIndex}
2018-12-07 18:24:20 +08:00
onContentRendered={this.onContentRendered}
2018-12-12 02:34:58 +00:00
onLinkClick={this.props.onLinkClick}
2018-12-16 12:45:26 +00:00
isDraft={this.props.isDraft}
hasDraft={this.props.hasDraft}
reviewID={this.props.reviewID}
reviewStatus={this.props.reviewStatus}
goDraftPage={this.props.goDraftPage}
goReviewPage={this.props.goReviewPage}
2018-11-22 11:26:00 +08:00
/> :
<Fragment>
<DirentListView
path={this.props.path}
2018-11-28 12:41:49 +08:00
repoID={repoID}
direntList={this.props.direntList}
sortBy={this.props.sortBy}
sortOrder={this.props.sortOrder}
sortItems={this.props.sortItems}
onItemClick={this.onItemClick}
2018-11-22 11:26:00 +08:00
onItemDelete={this.props.onItemDelete}
onItemRename={this.props.onItemRename}
onItemMove={this.props.onItemMove}
onItemCopy={this.props.onItemCopy}
2018-11-22 11:26:00 +08:00
onItemDetails={this.onItemDetails}
isDirentListLoading={this.props.isDirentListLoading}
updateDirent={this.props.updateDirent}
2018-12-18 17:21:01 +08:00
currentRepoInfo={this.state.currentRepoInfo}
2018-11-22 11:26:00 +08:00
isRepoOwner={this.state.isRepoOwner}
2018-11-23 20:19:42 +08:00
isAllItemSelected={this.props.isAllDirentSelected}
onAllItemSelected={this.props.onAllDirentSelected}
onItemSelected={this.props.onItemSelected}
2018-11-22 11:26:00 +08:00
/>
<FileUploader
ref={uploader => this.uploader = uploader}
dragAndDrop={true}
path={this.props.path}
2018-11-28 12:41:49 +08:00
repoID={repoID}
2018-11-29 17:55:14 +08:00
onFileUploadSuccess={this.onFileUploadSuccess}
2018-11-22 11:26:00 +08:00
direntList={this.props.direntList}
/>
</Fragment>
}
2018-11-14 10:55:11 +08:00
</Fragment>
2018-10-13 17:07:54 +08:00
}
</div>
</div>
2018-11-29 17:55:14 +08:00
{this.state.isDirentDetailShow && (
<div className="cur-view-detail">
2018-11-22 11:26:00 +08:00
<DirentDetail
2018-11-28 12:41:49 +08:00
repoID={repoID}
2018-11-29 17:55:14 +08:00
path={this.props.path}
dirent={this.state.currentDirent}
2018-11-23 20:19:42 +08:00
direntPath={this.state.direntPath}
onItemDetailsClose={this.onItemDetailsClose}
2018-11-13 16:39:13 +08:00
onFileTagChanged={this.onFileTagChanged}
2018-09-21 14:16:15 +08:00
/>
</div>
2018-11-29 17:55:14 +08:00
)}
</div>
</div>
);
}
}
2018-10-13 17:07:54 +08:00
MainPanel.propTypes = propTypes;
export default MainPanel;