-
-
{gettext('Files')}
-
- {(this.props.repoPermission) && (
-
-
-
- {gettext('New Folder')}
- {gettext('New File')}
-
-
- )}
-
-
-
- {this.props.isTreeDataLoading ?
- () :
- ()
- }
-
+
+ {this.props.isTreeDataLoading ?
+ () :
+ ()
+ }
{this.state.isAddFolderDialogShow && (
@@ -229,6 +195,6 @@ class LibContentNav extends React.Component {
}
}
-LibContentNav.propTypes = propTypes;
+DirColumnNav.propTypes = propTypes;
-export default LibContentNav;
\ No newline at end of file
+export default DirColumnNav;
diff --git a/frontend/src/components/dir-view-mode/dir-column-view.js b/frontend/src/components/dir-view-mode/dir-column-view.js
new file mode 100644
index 0000000000..f1996381db
--- /dev/null
+++ b/frontend/src/components/dir-view-mode/dir-column-view.js
@@ -0,0 +1,155 @@
+import React, { Fragment } from 'react';
+import PropTypes from 'prop-types';
+import DirColumnNav from './dir-column-nav';
+import DirColumnFile from './dir-column-file';
+import DirListMode from './dir-list-view';
+
+import '../../css/lib-content-view.css';
+
+const propTypes = {
+ path: PropTypes.string.isRequired,
+ repoID: PropTypes.string.isRequired,
+ // repoinfo
+ currentRepoInfo: PropTypes.object.isRequired,
+ repoPermission: PropTypes.bool.isRequired,
+ repoEncrypted: PropTypes.bool.isRequired,
+ enableDirPrivateShare: PropTypes.bool.isRequired,
+ userPrem: PropTypes.bool,
+ isAdmin: PropTypes.bool.isRequired,
+ isRepoOwner: PropTypes.bool.isRequired,
+ isGroupOwnedRepo: PropTypes.bool.isRequired,
+ // tree
+ isTreeDataLoading: PropTypes.bool.isRequired,
+ treeData: PropTypes.object.isRequired,
+ currentNode: PropTypes.object,
+ onNodeClick: PropTypes.func.isRequired,
+ onNodeCollapse: PropTypes.func.isRequired,
+ onNodeExpanded: PropTypes.func.isRequired,
+ onRenameNode: PropTypes.func.isRequired,
+ onDeleteNode: PropTypes.func.isRequired,
+ onAddFileNode: PropTypes.func.isRequired,
+ onAddFolderNode: PropTypes.func.isRequired,
+ // file
+ isViewFile: PropTypes.bool.isRequired,
+ isFileLoading: PropTypes.bool.isRequired,
+ isFileLoadedErr: PropTypes.bool.isRequired,
+ hash: PropTypes.string,
+ isDraft: PropTypes.bool.isRequired,
+ hasDraft: PropTypes.bool.isRequired,
+ goDraftPage: PropTypes.func.isRequired,
+ reviewStatus: PropTypes.string,
+ goReviewPage: PropTypes.func.isRequired,
+ filePermission: PropTypes.bool.isRequired,
+ content: PropTypes.string,
+ lastModified: PropTypes.string,
+ latestContributor: PropTypes.string,
+ onLinkClick: PropTypes.func.isRequired,
+ // repo content
+ isRepoInfoBarShow: PropTypes.bool.isRequired,
+ draftCounts: PropTypes.number.isRequired,
+ reviewCounts: PropTypes.number.isRequired,
+ usedRepoTags: PropTypes.array.isRequired,
+ readmeMarkdown: PropTypes.object,
+ updateUsedRepoTags: PropTypes.func.isRequired,
+ // list
+ isDirentListLoading: PropTypes.bool.isRequired,
+ direntList: PropTypes.array.isRequired,
+ sortBy: PropTypes.string.isRequired,
+ sortOrder: PropTypes.string.isRequired,
+ sortItems: PropTypes.func.isRequired,
+ onAddFile: PropTypes.func.isRequired,
+ updateDirent: PropTypes.func.isRequired,
+ onItemClick: PropTypes.func.isRequired,
+ onItemSelected: PropTypes.func.isRequired,
+ onItemDelete: PropTypes.func.isRequired,
+ onItemRename: PropTypes.func.isRequired,
+ onItemMove: PropTypes.func.isRequired,
+ onItemCopy: PropTypes.func.isRequired,
+ onItemDetails: PropTypes.func.isRequired,
+ onDirentClick: PropTypes.func.isRequired,
+ isAllItemSelected: PropTypes.bool.isRequired,
+ onAllItemSelected: PropTypes.func.isRequired,
+};
+
+class DirColumnView extends React.Component {
+
+ render() {
+ return (
+
+
+
+ {this.props.isViewFile ? (
+
+ ) : (
+
+ )}
+
+
+ );
+ }
+}
+
+DirColumnView.propTypes = propTypes;
+
+export default DirColumnView;
diff --git a/frontend/src/components/dir-view-mode/dir-grid-view.js b/frontend/src/components/dir-view-mode/dir-grid-view.js
new file mode 100644
index 0000000000..bb0863f5ad
--- /dev/null
+++ b/frontend/src/components/dir-view-mode/dir-grid-view.js
@@ -0,0 +1,19 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+
+const propTypes = {
+
+};
+
+class DirGridView extends React.Component {
+
+ render() {
+ return (
+ 表格布局
+ );
+ }
+}
+
+DirGridView.propTypes = propTypes;
+
+export default DirGridView;
diff --git a/frontend/src/components/dir-view-mode/dir-list-view.js b/frontend/src/components/dir-view-mode/dir-list-view.js
new file mode 100644
index 0000000000..ac8cdf31da
--- /dev/null
+++ b/frontend/src/components/dir-view-mode/dir-list-view.js
@@ -0,0 +1,90 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import RepoInfoBar from '../../components/repo-info-bar';
+import DirentListView from '../../components/dirent-list-view/dirent-list-view';
+
+const propTypes = {
+ path: PropTypes.string.isRequired,
+ repoID: PropTypes.string.isRequired,
+ currentRepoInfo: PropTypes.object.isRequired,
+ repoEncrypted: PropTypes.bool.isRequired,
+ isRepoOwner: PropTypes.bool.isRequired,
+ isAdmin: PropTypes.bool.isRequired,
+ isGroupOwnedRepo: PropTypes.bool.isRequired,
+ enableDirPrivateShare: PropTypes.bool.isRequired,
+ isRepoInfoBarShow: PropTypes.bool.isRequired,
+ usedRepoTags: PropTypes.array.isRequired,
+ readmeMarkdown: PropTypes.object,
+ draftCounts: PropTypes.number,
+ reviewCounts: PropTypes.number,
+ updateUsedRepoTags: PropTypes.func.isRequired,
+ isDirentListLoading: PropTypes.bool.isRequired,
+ direntList: PropTypes.array.isRequired,
+ sortBy: PropTypes.string.isRequired,
+ sortOrder: PropTypes.string.isRequired,
+ sortItems: PropTypes.func.isRequired,
+ onAddFile: PropTypes.func.isRequired,
+ onItemClick: PropTypes.func.isRequired,
+ onItemSelected: PropTypes.func.isRequired,
+ onItemDelete: PropTypes.func.isRequired,
+ onItemRename: PropTypes.func.isRequired,
+ onItemMove: PropTypes.func.isRequired,
+ onItemCopy: PropTypes.func.isRequired,
+ onDirentClick: PropTypes.func.isRequired,
+ onItemDetails: PropTypes.func.isRequired,
+ updateDirent: PropTypes.func.isRequired,
+ isAllItemSelected: PropTypes.bool.isRequired,
+ onAllItemSelected: PropTypes.func.isRequired,
+};
+
+class DirListView extends React.Component {
+
+ render() {
+ return (
+
+ {this.props.isRepoInfoBarShow && (
+
+ )}
+
+
+ );
+ }
+}
+
+DirListView.propTypes = propTypes;
+
+export default DirListView;
diff --git a/frontend/src/components/dirent-detail/detail-list-view.js b/frontend/src/components/dirent-detail/detail-list-view.js
index b368f7a0d8..20f61dec84 100644
--- a/frontend/src/components/dirent-detail/detail-list-view.js
+++ b/frontend/src/components/dirent-detail/detail-list-view.js
@@ -112,7 +112,7 @@ class DetailListView extends React.Component {
);
})}
-
+
@@ -128,7 +128,7 @@ class DetailListView extends React.Component {
);
})}
-
+
diff --git a/frontend/src/components/file-chooser/dirent-list-item.js b/frontend/src/components/file-chooser/dirent-list-item.js
index 69bab4defb..5387b0714b 100644
--- a/frontend/src/components/file-chooser/dirent-list-item.js
+++ b/frontend/src/components/file-chooser/dirent-list-item.js
@@ -88,6 +88,7 @@ class DirentListItem extends React.Component {
filePath={this.state.filePath}
onItemClick={this.onItemClick}
selectedPath={this.props.selectedPath}
+ selectedRepo={this.props.selectedRepo}
onDirentItemClick={this.props.onDirentItemClick}
isShowFile={this.props.isShowFile}
/>
@@ -98,10 +99,7 @@ class DirentListItem extends React.Component {
}
render() {
- let isCurrentRepo = false;
- if (this.props.selectedRepo) {
- isCurrentRepo = this.props.selectedRepo.repo_id === this.props.repo.repo_id;
- }
+ let isCurrentRepo = this.props.selectedRepo.repo_id === this.props.repo.repo_id;
let isCurrentPath = this.props.selectedPath === this.state.filePath;
return (
diff --git a/frontend/src/components/file-chooser/file-chooser.js b/frontend/src/components/file-chooser/file-chooser.js
index db8f876efa..cbd2d2103a 100644
--- a/frontend/src/components/file-chooser/file-chooser.js
+++ b/frontend/src/components/file-chooser/file-chooser.js
@@ -39,6 +39,7 @@ class FileChooser extends React.Component {
let repoInfo = new RepoInfo(res.data);
this.setState({
currentRepoInfo: repoInfo,
+ selectedRepo: repoInfo
});
});
}
@@ -100,6 +101,9 @@ class FileChooser extends React.Component {
}
render() {
+ if (!this.state.selectedRepo) {
+ return '';
+ }
const mode = this.props.mode;
let libName = mode === 'current_repo_and_other_repos' ? gettext('Other Libraries') : gettext('Libraries');
return (
diff --git a/frontend/src/components/select-editor/select-editor.js b/frontend/src/components/select-editor/select-editor.js
index cff52ff2a5..3282b94508 100644
--- a/frontend/src/components/select-editor/select-editor.js
+++ b/frontend/src/components/select-editor/select-editor.js
@@ -88,7 +88,7 @@ class SelectEditor extends React.Component {
{this.props.isEditIconShow && (
)}
diff --git a/frontend/src/components/toolbar/dir-operation-toolbar.js b/frontend/src/components/toolbar/dir-operation-toolbar.js
index f61136ef0f..2f77a08cef 100644
--- a/frontend/src/components/toolbar/dir-operation-toolbar.js
+++ b/frontend/src/components/toolbar/dir-operation-toolbar.js
@@ -10,6 +10,12 @@ import ShareDialog from '../../components/dialog/share-dialog';
const propTypes = {
path: PropTypes.string.isRequired,
repoID: PropTypes.string.isRequired,
+ repoName: PropTypes.string.isRequired,
+ repoEncrypted: PropTypes.bool.isRequired,
+ enableDirPrivateShare: PropTypes.bool.isRequired,
+ userPerm: PropTypes.string.isRequired,
+ isAdmin: PropTypes.bool.isRequired,
+ isGroupOwnedRepo: PropTypes.bool.isRequired,
showShareBtn: PropTypes.bool.isRequired,
onAddFile: PropTypes.func.isRequired,
onAddFolder: PropTypes.func.isRequired,
@@ -139,14 +145,6 @@ class DirOperationToolbar extends React.Component {
this.props.onAddFolder(dirPath);
}
- onViewReview = () => {
- this.props.goReviewPage();
- }
-
- onViewDraft = () => {
- this.props.goDraftPage();
- }
-
checkDuplicatedName = (newName) => {
let direntList = this.props.direntList;
let isDuplicated = direntList.some(object => {
diff --git a/frontend/src/components/tree-view/tree-node.js b/frontend/src/components/tree-view/tree-node.js
index a4d062cf18..d8e5bc3957 100644
--- a/frontend/src/components/tree-view/tree-node.js
+++ b/frontend/src/components/tree-view/tree-node.js
@@ -79,8 +79,9 @@ class TreeNode {
this.path = this.generatePath(this.parentNode);
if (this.isExpanded) {
this.updateChildrenPath(this);
+ } else {
+ this.isLoaded = false;
}
- // this.isLoaded = false;
}
updateChildrenPath(node) {
diff --git a/frontend/src/css/layout.css b/frontend/src/css/layout.css
index cd90edcc9b..583fbaf5c7 100644
--- a/frontend/src/css/layout.css
+++ b/frontend/src/css/layout.css
@@ -107,7 +107,6 @@
.cur-view-content {
padding: 0.625rem 1rem 1.25rem;
- height: calc(100% - 40px);
flex: 1;
min-height: 0;
overflow: auto;
diff --git a/frontend/src/css/lib-content-view.css b/frontend/src/css/lib-content-view.css
index 925b402dba..c367b38a29 100644
--- a/frontend/src/css/lib-content-view.css
+++ b/frontend/src/css/lib-content-view.css
@@ -2,56 +2,31 @@
.view-mode-container {
display: flex;
flex-direction: row !important;
+ overflow: hidden !important;
+ min-height: 0;
}
-.dir-side-nav {
+.dir-content-nav {
flex: 0 0 25%;
display: flex;
flex-direction: column;
+ overflow: hidden;
background-color: #fff;
- overflow: hidden;
-}
-
-.dir-main-content {
- flex: 1 0 75% !important;
- display: flex;
- flex-direction: column;
-}
-
-.dir-nav-heading {
- position: relative;
- display: flex;
- align-items: center;
- justify-content: center;
- background: #f4f4f7;
- border-bottom: solid 1px #e8e8e8;
- font-size: 1rem;
- font-weight: normal;
- height: 49px;
- margin: 0;
-}
-
-.dir-nav-container {
- flex: 1 1;
- overflow: hidden;
- padding: 12px 0;
border-right: 1px solid #eee;
+ margin-left: -0.75rem;
}
-.dir-nav-container:hover {
+.dir-content-nav:hover {
overflow: auto;
}
-.heading-icon {
- position: absolute;
- right: 1rem;
- top: 30%;
- color: #888;
- font-size: 0.8125rem;
-}
-
-.heading-icon .action-icon {
- font-size: 1.125rem;
+.dir-content-main {
+ flex: 1 0 75% !important;
+ display: flex;
+ flex-direction: column;
+ margin-right: -0.75rem;
+ padding:0 0.75rem;
+ overflow: auto;
}
/*tree view */
@@ -170,20 +145,19 @@
}
.cur-view-content .wiki-page-content {
- /* width: calc(100% - 160px); */
flex: 1;
padding-right: 40px;
}
-.dir-main-content .wiki-page-content .article {
+.dir-content-main .wiki-page-content .article {
padding: 0 10px;
}
-.dir-main-content .wiki-page-content .ml-2 {
+.dir-content-main .wiki-page-content .ml-2 {
text-decoration: underline;
}
-.dir-main-content .wiki-page-content .ml-2:hover {
+.dir-content-main .wiki-page-content .ml-2:hover {
text-decoration: underline;
color:#eb8205;
}
diff --git a/frontend/src/pages/lib-content-view/lib-content-container.js b/frontend/src/pages/lib-content-view/lib-content-container.js
new file mode 100644
index 0000000000..194f62ce43
--- /dev/null
+++ b/frontend/src/pages/lib-content-view/lib-content-container.js
@@ -0,0 +1,270 @@
+import React, { Fragment } from 'react';
+import PropTypes from 'prop-types';
+import { gettext } from '../../utils/constants';
+import CurDirPath from '../../components/cur-dir-path';
+import DirentDetail from '../../components/dirent-detail/dirent-details';
+import DirListView from '../../components/dir-view-mode/dir-list-view';
+import DirGridView from '../../components/dir-view-mode/dir-grid-view';
+import DirColumnView from '../../components/dir-view-mode/dir-column-view';
+
+const propTypes = {
+ pathPrefix: PropTypes.array.isRequired,
+ currentMode: PropTypes.string.isRequired,
+ path: PropTypes.string.isRequired,
+ pathExist: PropTypes.bool.isRequired,
+ // repoinfo
+ currentRepoInfo: PropTypes.object.isRequired,
+ repoID: PropTypes.string.isRequired,
+ repoName: PropTypes.string.isRequired,
+ repoPermission: PropTypes.bool.isRequired,
+ repoEncrypted: PropTypes.bool.isRequired,
+ enableDirPrivateShare: PropTypes.bool.isRequired,
+ userPrem: PropTypes.bool,
+ isAdmin: PropTypes.bool.isRequired,
+ isRepoOwner: PropTypes.bool.isRequired,
+ isGroupOwnedRepo: PropTypes.bool.isRequired,
+ // path func
+ onTabNavClick: PropTypes.func.isRequired,
+ onMainNavBarClick: PropTypes.func.isRequired,
+ // file
+ isViewFile: PropTypes.bool.isRequired,
+ isFileLoadedErr: PropTypes.bool.isRequired,
+ hash: PropTypes.string,
+ isDraft: PropTypes.bool.isRequired,
+ hasDraft: PropTypes.bool.isRequired,
+ goDraftPage: PropTypes.func.isRequired,
+ reviewStatus: PropTypes.string,
+ goReviewPage: PropTypes.func.isRequired,
+ isFileLoading: PropTypes.bool.isRequired,
+ filePermission: PropTypes.bool.isRequired,
+ content: PropTypes.string,
+ lastModified: PropTypes.string,
+ latestContributor: PropTypes.string,
+ onLinkClick: PropTypes.func.isRequired,
+ // tree
+ isTreeDataLoading: PropTypes.bool.isRequired,
+ treeData: PropTypes.object.isRequired,
+ currentNode: PropTypes.object,
+ onNodeClick: PropTypes.func.isRequired,
+ onNodeCollapse: PropTypes.func.isRequired,
+ onNodeExpanded: PropTypes.func.isRequired,
+ onRenameNode: PropTypes.func.isRequired,
+ onDeleteNode: PropTypes.func.isRequired,
+ onAddFileNode: PropTypes.func.isRequired,
+ onAddFolderNode: PropTypes.func.isRequired,
+ // repo content
+ draftCounts: PropTypes.number,
+ reviewCounts: PropTypes.number,
+ usedRepoTags: PropTypes.array.isRequired,
+ readmeMarkdown: PropTypes.object,
+ updateUsedRepoTags: PropTypes.func.isRequired,
+ // list
+ isDirentListLoading: PropTypes.bool.isRequired,
+ direntList: PropTypes.array.isRequired,
+ sortBy: PropTypes.string.isRequired,
+ sortOrder: PropTypes.string.isRequired,
+ sortItems: PropTypes.func.isRequired,
+ updateDirent: PropTypes.func.isRequired,
+ onItemClick: PropTypes.func.isRequired,
+ onItemSelected: PropTypes.func.isRequired,
+ onItemDelete: PropTypes.func.isRequired,
+ onItemRename: PropTypes.func.isRequired,
+ onItemMove: PropTypes.func.isRequired,
+ onItemCopy: PropTypes.func.isRequired,
+ onAddFolder: PropTypes.func.isRequired,
+ onAddFile: PropTypes.func.isRequired,
+ onFileTagChanged: PropTypes.func.isRequired,
+ isDirentSelected: PropTypes.bool.isRequired,
+ isAllDirentSelected: PropTypes.bool.isRequired,
+ onAllDirentSelected: PropTypes.func.isRequired,
+};
+
+class LibContentContainer extends React.Component {
+
+ constructor(props) {
+ super(props);
+ this.state = {
+ currentDirent: null,
+ isDirentDetailShow: false,
+ };
+
+ this.errMessage = ({gettext('Folder does not exist.')}
);
+ }
+
+ onPathClick = (path) => {
+ this.setState({isDirentDetailShow: false});
+ this.props.onMainNavBarClick(path);
+ }
+
+ onItemClick = (dirent) => {
+ this.setState({isDirentDetailShow: false});
+ this.props.onItemClick(dirent);
+ }
+
+ // on ''
+ onDirentClick = (dirent) => {
+ if (this.state.isDirentDetailShow) {
+ this.onItemDetails(dirent);
+ }
+ }
+
+ onItemDetails = (dirent) => {
+ this.setState({
+ currentDirent: dirent,
+ isDirentDetailShow: true,
+ });
+ }
+
+ onItemDetailsClose = () => {
+ this.setState({isDirentDetailShow: false});
+ }
+
+ render() {
+ let { path, repoID, usedRepoTags, readmeMarkdown, draftCounts, reviewCounts } = this.props;
+ let isRepoInfoBarShow = false;
+ if (path === '/') {
+ if (usedRepoTags.length !== 0 || readmeMarkdown !== null || draftCounts !== 0 || reviewCounts !== 0) {
+ isRepoInfoBarShow = true;
+ }
+ }
+
+ return (
+
+
+
+
+
+
+ {!this.props.pathExist && this.errMessage}
+ {this.props.pathExist && (
+
+ {this.props.currentMode === 'list' && (
+
+ )}
+ {this.props.currentMode === 'grid' && (
+
+ )}
+ {this.props.currentMode === 'column' && (
+
+ )}
+
+ )}
+
+
+ {this.state.isDirentDetailShow && (
+
+
+
+ )}
+
+ );
+ }
+}
+
+LibContentContainer.propTypes = propTypes;
+
+export default LibContentContainer;
diff --git a/frontend/src/pages/lib-content-view/lib-content-main.js b/frontend/src/pages/lib-content-view/lib-content-main.js
deleted file mode 100644
index 4a4791a439..0000000000
--- a/frontend/src/pages/lib-content-view/lib-content-main.js
+++ /dev/null
@@ -1,285 +0,0 @@
-import React, { Fragment } from 'react';
-import PropTypes from 'prop-types';
-import { gettext } from '../../utils/constants';
-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 DirentListView from '../../components/dirent-list-view/dirent-list-view';
-import DirentDetail from '../../components/dirent-detail/dirent-details';
-import FileUploader from '../../components/file-uploader/file-uploader';
-import RepoInfoBar from '../../components/repo-info-bar';
-
-const propTypes = {
- pathPrefix: PropTypes.array.isRequired,
- currentMode: PropTypes.string.isRequired,
- path: PropTypes.string.isRequired,
- pathExist: PropTypes.bool.isRequired,
- // repo
- currentRepoInfo: PropTypes.object, // Initially not loaded
- repoID: PropTypes.string.isRequired,
- repoName: PropTypes.string.isRequired,
- repoPermission: PropTypes.bool.isRequired,
- repoEncrypted: PropTypes.bool.isRequired,
- isAdmin: PropTypes.bool.isRequired,
- userPerm: PropTypes.string.isRequired,
- showShareBtn: PropTypes.bool.isRequired,
- enableDirPrivateShare: PropTypes.bool.isRequired,
- isRepoOwner: PropTypes.bool.isRequired,
- isGroupOwnedRepo: PropTypes.bool.isRequired,
- // toolbar
- onTabNavClick: PropTypes.func.isRequired,
- onSideNavMenuClick: PropTypes.func.isRequired,
- selectedDirentList: PropTypes.array.isRequired,
- onItemsMove: PropTypes.func.isRequired,
- onItemsCopy: PropTypes.func.isRequired,
- onItemsDelete: PropTypes.func.isRequired,
- switchViewMode: PropTypes.func.isRequired,
- onSearchedClick: PropTypes.func.isRequired,
- onMainNavBarClick: PropTypes.func.isRequired,
- // repo content
- draftCounts: PropTypes.number,
- reviewCounts: PropTypes.number,
- usedRepoTags: PropTypes.array.isRequired,
- readmeMarkdown: PropTypes.object,
- updateUsedRepoTags: PropTypes.func.isRequired,
- // dirent list
- isDirentListLoading: PropTypes.bool.isRequired,
- direntList: PropTypes.array.isRequired,
- sortBy: PropTypes.string.isRequired,
- sortOrder: PropTypes.string.isRequired,
- sortItems: PropTypes.func.isRequired,
- updateDirent: PropTypes.func.isRequired,
- onItemClick: PropTypes.func.isRequired,
- onItemSelected: PropTypes.func.isRequired,
- onItemDelete: PropTypes.func.isRequired,
- onItemRename: PropTypes.func.isRequired,
- onItemMove: PropTypes.func.isRequired,
- onItemCopy: PropTypes.func.isRequired,
- onAddFolder: PropTypes.func.isRequired,
- onAddFile: PropTypes.func.isRequired,
- onFileTagChanged: PropTypes.func.isRequired,
- isDirentSelected: PropTypes.bool.isRequired,
- isAllDirentSelected: PropTypes.bool.isRequired,
- onAllDirentSelected: PropTypes.func.isRequired,
- onFileUploadSuccess: PropTypes.func.isRequired,
-};
-
-class LibContentMain extends React.Component {
-
- constructor(props) {
- super(props);
- this.state = {
- currentDirent: null,
- isDirentDetailShow: false,
- };
- }
-
- onSideNavMenuClick = () => {
- this.props.onSideNavMenuClick();
- }
-
- onPathClick = (path) => {
- this.setState({isDirentDetailShow: false});
- this.props.onPathClick(path);
- }
-
- onItemClick = (dirent) => {
- this.setState({isDirentDetailShow: false});
- this.props.onItemClick(dirent);
- }
-
- // on '
'
- onDirentClick = (dirent) => {
- if (this.state.isDirentDetailShow) {
- this.onItemDetails(dirent);
- }
- }
-
- onItemDetails = (dirent) => {
- this.setState({
- currentDirent: dirent,
- isDirentDetailShow: true,
- });
- }
-
- onItemDetailsClose = () => {
- this.setState({isDirentDetailShow: false});
- }
-
- onUploadFile = (e) => {
- e.nativeEvent.stopImmediatePropagation();
- this.uploader.onFileUpload();
- }
-
- onUploadFolder = (e) => {
- e.nativeEvent.stopImmediatePropagation();
- this.uploader.onFolderUpload();
- }
-
- switchViewMode = (mode) => {
- this.props.switchViewMode(mode);
- }
-
- onFileUploadSuccess = (direntObject) => {
- this.props.onFileUploadSuccess(direntObject);
- }
-
- renderListView = () => {
- let repoID = this.props.repoID;
- const showRepoInfoBar = this.props.path === '/' && (
- this.props.usedRepoTags.length != 0 || this.props.readmeMarkdown != null ||
- this.props.draftCounts != 0 || this.props.reviewCounts != 0);
- return (
-
- {showRepoInfoBar && (
-
- )}
-
-
- );
- }
-
- renderGridView = () => {
- // todo
- return (
- grid-mode
- )
- }
-
- renderColumnView = () => {
- return (
- this.renderListView()
- )
- }
-
- render() {
- let repoID = this.props.repoID;
- const errMessage = ({gettext('Folder does not exist.')}
);
- return (
-
-
-
-
-
- {this.props.isDirentSelected ?
- :
-
- }
-
-
-
-
-
-
-
-
- {this.props.currentRepoInfo && (
-
- )}
-
-
- {!this.props.pathExist && errMessage }
- {(this.props.pathExist && (
-
- {this.props.currentMode === 'list' && this.renderListView()}
- {this.props.currentMode === 'grid' && this.renderGridView()}
- {this.props.currentMode === 'column' && this.renderColumnView()}
- this.uploader = uploader}
- dragAndDrop={true}
- path={this.props.path}
- repoID={repoID}
- direntList={this.props.direntList}
- onFileUploadSuccess={this.onFileUploadSuccess}
- />
-
- ))}
-
-
- {this.state.isDirentDetailShow && (
-
-
-
- )}
-
-
- );
- }
-}
-
-LibContentMain.propTypes = propTypes;
-
-export default LibContentMain;
diff --git a/frontend/src/pages/lib-content-view/lib-content-toolbar.js b/frontend/src/pages/lib-content-view/lib-content-toolbar.js
new file mode 100644
index 0000000000..134f5b2282
--- /dev/null
+++ b/frontend/src/pages/lib-content-view/lib-content-toolbar.js
@@ -0,0 +1,130 @@
+import React, { Fragment } from 'react';
+import PropTypes from 'prop-types';
+import { Utils } from '../../utils/utils';
+import { gettext, siteRoot } from '../../utils/constants';
+import { seafileAPI } from '../../utils/seafile-api';
+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';
+
+const propTypes = {
+ isViewFile: PropTypes.bool.isRequired,
+ filePermission: PropTypes.bool.isRequired, // ture = 'rw'
+ isDraft: PropTypes.bool.isRequired,
+ hasDraft: PropTypes.bool.isRequired,
+ // side-panel
+ onSideNavMenuClick: PropTypes.func.isRequired,
+ // mutiple-dir
+ isDirentSelected: PropTypes.bool.isRequired,
+ repoID: PropTypes.string.isRequired,
+ path: PropTypes.string.isRequired,
+ selectedDirentList: PropTypes.array.isRequired,
+ onItemsMove: PropTypes.func.isRequired,
+ onItemsCopy: PropTypes.func.isRequired,
+ onItemsDelete: PropTypes.func.isRequired,
+ // dir
+ direntList: PropTypes.array.isRequired,
+ repoName: PropTypes.string.isRequired,
+ repoEncrypted: PropTypes.bool.isRequired,
+ isAdmin: PropTypes.bool.isRequired,
+ isGroupOwnedRepo: PropTypes.bool.isRequired,
+ userPerm: PropTypes.string.isRequired,
+ showShareBtn: PropTypes.bool.isRequired,
+ enableDirPrivateShare: PropTypes.bool.isRequired,
+ onAddFile: PropTypes.func.isRequired,
+ onAddFolder: PropTypes.func.isRequired,
+ onUploadFile: PropTypes.func.isRequired,
+ onUploadFolder: PropTypes.func.isRequired,
+ // view-mode
+ currentMode: PropTypes.string.isRequired,
+ switchViewMode: PropTypes.func.isRequired,
+ // search
+ onSearchedClick: PropTypes.func.isRequired,
+};
+
+class LibContentToolbar extends React.Component {
+
+ onEditClick = (e) => {
+ e.preventDefault();
+ let { path, repoID } = this.props;
+ let url = siteRoot + 'lib/' + repoID + '/file' + Utils.encodePath(path) + '?mode=edit';
+ window.open(url);
+ }
+
+ onNewDraft = (e) => {
+ e.preventDefault();
+ let { path, repoID } = this.props;
+ seafileAPI.createDraft(repoID, path).then(res => {
+ window.location.href = siteRoot + 'lib/' + res.data.origin_repo_id + '/file' + res.data.draft_file_path + '?mode=edit';
+ });
+ }
+
+ render() {
+
+ if (this.props.isViewFile) {
+ return (
+
+
+
+
+ {(this.props.filePermission && !this.props.hasDraft) && (
+
+
+
+ )}
+ {/* default have read priv */}
+ {(!this.props.isDraft && !this.props.hasDraft) && (
+
+ )}
+
+
+
+
+
+ );
+ }
+
+ return (
+
+
+
+
+ {this.props.isDirentSelected ?
+ :
+
+ }
+
+
+
+
+
+ );
+ }
+}
+
+LibContentToolbar.propTypes = propTypes;
+
+export default LibContentToolbar;
diff --git a/frontend/src/pages/lib-content-view/lib-content-view.js b/frontend/src/pages/lib-content-view/lib-content-view.js
index 37f8d91a8e..19ec68a74e 100644
--- a/frontend/src/pages/lib-content-view/lib-content-view.js
+++ b/frontend/src/pages/lib-content-view/lib-content-view.js
@@ -15,16 +15,15 @@ import treeHelper from '../../components/tree-view/tree-helper';
import toaster from '../../components/toast';
import ModalPortal from '../../components/modal-portal';
import LibDecryptDialog from '../../components/dialog/lib-decrypt-dialog';
-import FileContentView from '../../components/file-content-view';
-import LibContentNav from './lib-content-nav';
-import LibContentMain from './lib-content-main';
-
-import '../../css/lib-content-view.css';
+import LibContentToolbar from './lib-content-toolbar';
+import LibContentContainer from './lib-content-container';
+import FileUploader from '../../components/file-uploader/file-uploader';
const propTypes = {
pathPrefix: PropTypes.array.isRequired,
onTabNavClick: PropTypes.func.isRequired,
onMenuClick: PropTypes.func.isRequired,
+ repoID: PropTypes.string,
};
class LibContentView extends React.Component {
@@ -62,6 +61,7 @@ class LibContentView extends React.Component {
treeData: treeHelper.buildTree(),
currentNode: null,
isFileLoading: true,
+ isFileLoadedErr: false,
filePermission: true,
content: '',
lastModified: '',
@@ -72,7 +72,7 @@ class LibContentView extends React.Component {
sortBy: 'name', // 'name' or 'time'
sortOrder: 'asc', // 'asc' or 'desc'
isAllDirentSelected: false,
- dirID: '',
+ dirID: '', // for update dir list
errorMsg: '',
};
@@ -83,7 +83,7 @@ class LibContentView extends React.Component {
componentWillMount() {
const hash = window.location.hash;
if (hash.slice(0, 1) === '#') {
- this.state.hash = hash;
+ this.setState({hash: hash});
}
}
@@ -316,6 +316,7 @@ class LibContentView extends React.Component {
latestContributor: last_modifier_name,
lastModified: moment.unix(mtime).fromNow(),
isFileLoading: false,
+ isFileLoadedErr: false,
isDraft: is_draft,
hasDraft: has_draft,
reviewStatus: review_status,
@@ -324,6 +325,11 @@ class LibContentView extends React.Component {
});
});
});
+ }).catch(() => {
+ this.setState({
+ isFileLoading: false,
+ isFileLoadedErr: true,
+ });
});
// update location
@@ -980,6 +986,7 @@ class LibContentView extends React.Component {
}
if (node.object.isDir()) {
+ let isLoaded = node.isLoaded;
if (!node.isLoaded) {
let tree = this.state.treeData.clone();
node = tree.getNodeByPath(node.path);
@@ -989,7 +996,7 @@ class LibContentView extends React.Component {
this.setState({treeData: tree});
});
}
- if (node.path === this.state.path) {
+ if (isLoaded && node.path === this.state.path) {
if (node.isExpanded) {
let tree = treeHelper.collapseNode(this.state.treeData, node);
this.setState({treeData: tree});
@@ -1147,7 +1154,18 @@ class LibContentView extends React.Component {
});
}
+ onUploadFile = (e) => {
+ e.nativeEvent.stopImmediatePropagation();
+ this.uploader.onFileUpload();
+ }
+
+ onUploadFolder = (e) => {
+ e.nativeEvent.stopImmediatePropagation();
+ this.uploader.onFolderUpload();
+ }
+
render() {
+
if (this.state.libNeedDecrypt) {
return (
@@ -1159,6 +1177,10 @@ class LibContentView extends React.Component {
);
}
+ if (!this.state.currentRepoInfo) {
+ return '';
+ }
+
let showShareBtn = false;
let enableDirPrivateShare = false;
const { repoEncrypted, isAdmin, ownerEmail, userPerm, isVirtual, isDepartmentAdmin } = this.state;
@@ -1173,12 +1195,70 @@ class LibContentView extends React.Component {
}
return (
-
- {this.state.currentMode === 'column' &&
-
+
+
+
+
+
- }
- {this.state.isViewFile &&
-
- }
- {!this.state.isViewFile && (
-
- )}
+ {this.state.pathExist && !this.state.isViewFile && (
+ this.uploader = uploader}
+ dragAndDrop={true}
+ path={this.state.path}
+ repoID={this.props.repoID}
+ direntList={this.state.direntList}
+ onFileUploadSuccess={this.onFileUploadSuccess}
+ />
+ )}
+
);
}
@@ -1276,4 +1311,4 @@ class LibContentView extends React.Component {
LibContentView.propTypes = propTypes;
-export default LibContentView;
\ No newline at end of file
+export default LibContentView;