1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-09-03 16:10:26 +00:00

[refactor] lib container view (#6766)

* [refactor] lib container view

* optimize codes
This commit is contained in:
Michael An
2024-09-13 20:28:20 +08:00
committed by GitHub
parent 3dae590dfc
commit 453c84f46f
7 changed files with 266 additions and 515 deletions

View File

@@ -5,7 +5,7 @@ import DirentDetail from './dirent-details';
import ObjectUtils from '../../metadata/metadata-view/utils/object-utils';
import { MetadataContext } from '../../metadata';
const Index = React.memo(({ repoID, path, dirent, currentRepoInfo, repoTags, fileTags, onClose, onFileTagChanged }) => {
const DetailContainer = React.memo(({ repoID, path, dirent, currentRepoInfo, repoTags, fileTags, onClose, onFileTagChanged }) => {
useEffect(() => {
// init context
@@ -45,7 +45,7 @@ const Index = React.memo(({ repoID, path, dirent, currentRepoInfo, repoTags, fil
return !isChanged;
});
Index.propTypes = {
DetailContainer.propTypes = {
repoID: PropTypes.string,
path: PropTypes.string,
dirent: PropTypes.object,
@@ -56,4 +56,4 @@ Index.propTypes = {
onFileTagChanged: PropTypes.func,
};
export default Index;
export default DetailContainer;

View File

@@ -101,7 +101,7 @@ class DirentDetails extends React.Component {
{this.renderImage()}
{dirent && direntDetail && (
<div className="detail-content">
{dirent.type !== 'file' ? (
{dirent.type !== 'file' ?
<DirDetails
repoID={repoID}
repoInfo={this.props.currentRepoInfo}
@@ -109,7 +109,7 @@ class DirentDetails extends React.Component {
direntDetail={direntDetail}
path={this.props.dirent ? path + '/' + dirent.name : path}
/>
) : (
:
<FileDetails
repoID={repoID}
repoInfo={this.props.currentRepoInfo}
@@ -120,7 +120,7 @@ class DirentDetails extends React.Component {
fileTagList={dirent ? dirent.file_tags : fileTags}
onFileTagChanged={this.props.onFileTagChanged}
/>
)}
}
</div>
)}
</Body>

View File

@@ -1,15 +1,15 @@
import React, { useEffect, useMemo, useState } from 'react';
import PropTypes from 'prop-types';
import { Formatter } from '@seafile/sf-metadata-ui-component';
import { Utils } from '../../../utils/utils';
import { gettext } from '../../../utils/constants';
import { seafileAPI } from '../../../utils/seafile-api';
import toaster from '../../toast';
import { Detail, Header, Body } from '../detail';
import Repo from '../../../models/repo';
import Loading from '../../loading';
import DetailItem from '../detail-item';
import { CellType } from '../../../metadata/metadata-view/_basic';
import { Utils } from '../../utils/utils';
import { gettext } from '../../utils/constants';
import { seafileAPI } from '../../utils/seafile-api';
import toaster from '../toast';
import { Detail, Header, Body } from './detail';
import Repo from '../../models/repo';
import Loading from '../loading';
import DetailItem from './detail-item';
import { CellType } from '../../metadata/metadata-view/_basic';
const LibDetail = React.memo(({ currentRepoInfo, onClose }) => {
const [isLoading, setLoading] = useState(true);
@@ -36,9 +36,9 @@ const LibDetail = React.memo(({ currentRepoInfo, onClose }) => {
<Detail>
<Header title={currentRepoInfo.repo_name} icon={smallIconUrl} onClose={onClose} />
<Body>
{isLoading ? (
{isLoading ?
<div className="w-100 h-100 d-flex algin-items-center justify-content-center"><Loading /></div>
) : (
:
<div className="detail-content">
<DetailItem field={filesField} value={repo.file_count || 0} className="sf-metadata-property-detail-formatter">
<Formatter field={filesField} value={repo.file_count || 0} />
@@ -62,7 +62,7 @@ const LibDetail = React.memo(({ currentRepoInfo, onClose }) => {
<Formatter field={mtimeField} value={repo.last_modified} />
</DetailItem>
</div>
)}
}
</Body>
</Detail>
);

View File

@@ -42,7 +42,7 @@ const propTypes = {
isGroupOwnedRepo: PropTypes.bool.isRequired,
};
class MultipleDirOperationToolbar extends React.Component {
class SelectedDirentsToolbar extends React.Component {
constructor(props) {
super(props);
@@ -471,6 +471,6 @@ class MultipleDirOperationToolbar extends React.Component {
}
}
MultipleDirOperationToolbar.propTypes = propTypes;
SelectedDirentsToolbar.propTypes = propTypes;
export default MultipleDirOperationToolbar;
export default SelectedDirentsToolbar;

View File

@@ -0,0 +1,6 @@
import Dirent from './dirent';
import FileTag from './file-tag';
import RepoTag from './repo-tag';
import RepoInfo from './repo-info';
export { Dirent, FileTag, RepoTag, RepoInfo };

View File

@@ -1,370 +0,0 @@
import React from 'react';
import PropTypes from 'prop-types';
import classnames from 'classnames';
import { Utils } from '../../utils/utils';
import { gettext } from '../../utils/constants';
import CurDirPath from '../../components/cur-dir-path';
import DirTool from '../../components/cur-dir-path/dir-tool';
import Detail from '../../components/dirent-detail';
import DirColumnView from '../../components/dir-view-mode/dir-column-view';
import ToolbarForSelectedDirents from '../../components/toolbar/selected-dirents-toolbar';
import '../../css/lib-content-view.css';
const propTypes = {
isSidePanelFolded: PropTypes.bool,
switchViewMode: PropTypes.func.isRequired,
isCustomPermission: PropTypes.bool,
pathPrefix: PropTypes.array.isRequired,
isTreePanelShown: PropTypes.bool.isRequired,
toggleTreePanel: PropTypes.func.isRequired,
currentMode: PropTypes.string.isRequired,
path: PropTypes.string.isRequired,
pathExist: PropTypes.bool.isRequired,
// repoinfo
repoEncrypted: PropTypes.bool.isRequired,
currentRepoInfo: PropTypes.object.isRequired,
repoID: PropTypes.string.isRequired,
enableDirPrivateShare: PropTypes.bool.isRequired,
isGroupOwnedRepo: PropTypes.bool.isRequired,
userPerm: PropTypes.string,
isRepoOwner: PropTypes.bool.isRequired,
// path func
onTabNavClick: PropTypes.func.isRequired,
onMainNavBarClick: PropTypes.func.isRequired,
// file
isViewFile: PropTypes.bool.isRequired,
fileTags: PropTypes.array.isRequired,
isFileLoading: PropTypes.bool.isRequired,
filePermission: PropTypes.string,
content: PropTypes.string,
viewId: PropTypes.string,
lastModified: PropTypes.string,
latestContributor: PropTypes.string,
currentDirent: PropTypes.object,
onLinkClick: PropTypes.func.isRequired,
onCloseMarkdownViewDialog: PropTypes.func,
// 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
repoTags: PropTypes.array.isRequired,
usedRepoTags: PropTypes.array.isRequired,
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,
onItemConvert: PropTypes.func.isRequired,
onFileTagChanged: PropTypes.func.isRequired,
isDirentSelected: PropTypes.bool.isRequired,
isAllDirentSelected: PropTypes.bool.isRequired,
onAllDirentSelected: PropTypes.func.isRequired,
isDirentDetailShow: PropTypes.bool.isRequired,
selectedDirent: PropTypes.object,
selectedDirentList: PropTypes.array.isRequired,
onSelectedDirentListUpdate: PropTypes.func.isRequired,
onItemsMove: PropTypes.func.isRequired,
onItemsCopy: PropTypes.func.isRequired,
onItemsDelete: PropTypes.func.isRequired,
closeDirentDetail: PropTypes.func.isRequired,
showDirentDetail: PropTypes.func.isRequired,
onDeleteRepoTag: PropTypes.func.isRequired,
updateDetail: PropTypes.bool.isRequired,
onListContainerScroll: PropTypes.func.isRequired,
onDirentClick: PropTypes.func.isRequired,
direntDetailPanelTab: PropTypes.string,
loadDirentList: PropTypes.func,
fullDirentList: PropTypes.array,
unSelectDirent: PropTypes.func,
onFilesTagChanged: PropTypes.func.isRequired,
showShareBtn: PropTypes.bool.isRequired,
onUploadFile: PropTypes.func.isRequired,
onUploadFolder: PropTypes.func.isRequired,
onToolbarFileTagChanged: PropTypes.func.isRequired,
eventBus: PropTypes.object,
};
class LibContentContainer extends React.Component {
constructor(props) {
super(props);
this.state = {
currentDirent: null,
hasSelectedFile: false,
};
this.errMessage = (<div className="message err-tip">{gettext('Folder does not exist.')}</div>);
}
UNSAFE_componentWillReceiveProps(nextProps) {
if (nextProps.path !== this.props.path || nextProps.updateDetail !== this.props.updateDetail) {
this.setState({ currentDirent: null });
}
if (!this.state.hasSelectedFile) {
const { isDirentSelected } = nextProps;
if (isDirentSelected) {
this.setState({ hasSelectedFile: true });
}
}
}
onPathClick = (path) => {
this.props.onMainNavBarClick(path);
};
onItemClick = (dirent) => {
this.props.onItemClick(dirent);
};
onDirentClick = (dirent, event) => {
this.setState({ currentDirent: dirent && dirent.isActive ? null : dirent });
this.props.onDirentClick(dirent, event);
};
onItemSelected = (dirent) => {
this.setState({ currentDirent: dirent && dirent.isActive ? null : dirent });
this.props.onItemSelected(dirent);
};
onItemDelete = (dirent) => {
this.checkCurrentDirent(dirent);
this.props.onItemDelete(dirent);
};
onItemMove = (destRepo, dirent, selectedPath, currentPath) => {
this.checkCurrentDirent(dirent);
this.props.onItemMove(destRepo, dirent, selectedPath, currentPath);
};
checkCurrentDirent = (deletedDirent) => {
let { currentDirent } = this.state;
if (currentDirent && deletedDirent.name === currentDirent.name) {
this.setState({ currentDirent: null });
}
};
onItemsScroll = (e) => {
let target = e.target;
if (target.scrollTop === 0) {
return;
}
if (target.scrollTop + target.clientHeight + 1 >= target.scrollHeight) {
this.props.onListContainerScroll();
}
};
render() {
const isDesktop = Utils.isDesktop();
const { path, repoID, usedRepoTags, isDirentSelected } = this.props;
const { hasSelectedFile } = this.state;
let isRepoInfoBarShow = false;
if (path === '/') {
if (isDesktop && usedRepoTags.length !== 0) {
isRepoInfoBarShow = true;
}
}
return (
<div className="cur-view-container">
{this.props.currentRepoInfo.status === 'read-only' &&
<div className="readonly-tip-message">
{gettext('This library has been set to read-only by admin and cannot be updated.')}
</div>
}
<div className="cur-view-path lib-cur-view-path">
<div className={classnames('cur-view-path-left', { 'w-100': !isDesktop, 'animation-children': hasSelectedFile })}>
{isDirentSelected ? (
<ToolbarForSelectedDirents
repoID={this.props.repoID}
path={this.props.path}
userPerm={this.props.userPerm}
repoEncrypted={this.props.repoEncrypted}
repoTags={this.props.repoTags}
selectedDirentList={this.props.selectedDirentList}
direntList={this.props.direntList}
onItemsMove={this.props.onItemsMove}
onItemsCopy={this.props.onItemsCopy}
onItemsDelete={this.props.onItemsDelete}
onItemRename={this.props.onItemRename}
isRepoOwner={this.props.isRepoOwner}
currentRepoInfo={this.props.currentRepoInfo}
enableDirPrivateShare={this.props.enableDirPrivateShare}
updateDirent={this.props.updateDirent}
unSelectDirent={this.props.unSelectDirent}
onFilesTagChanged={this.props.onFilesTagChanged}
showShareBtn={this.props.showShareBtn}
isGroupOwnedRepo={this.props.isGroupOwnedRepo}
showDirentDetail={this.props.showDirentDetail}
currentMode={this.props.currentMode}
switchViewMode={this.props.switchViewMode}
/>
) : (
<CurDirPath
currentRepoInfo={this.props.currentRepoInfo}
repoID={repoID}
repoName={this.props.currentRepoInfo.repo_name}
repoEncrypted={this.props.repoEncrypted}
isGroupOwnedRepo={this.props.isGroupOwnedRepo}
pathPrefix={this.props.pathPrefix}
currentPath={this.props.path}
userPerm={this.props.userPerm}
onTabNavClick={this.props.onTabNavClick}
onPathClick={this.onPathClick}
fileTags={this.props.fileTags}
direntList={this.props.direntList}
sortBy={this.props.sortBy}
sortOrder={this.props.sortOrder}
sortItems={this.props.sortItems}
toggleTreePanel={this.props.toggleTreePanel}
enableDirPrivateShare={this.props.enableDirPrivateShare}
showShareBtn={this.props.showShareBtn}
onAddFolder={this.props.onAddFolder}
onAddFile={this.props.onAddFile}
onUploadFile={this.props.onUploadFile}
onUploadFolder={this.props.onUploadFolder}
fullDirentList={this.props.fullDirentList}
filePermission={this.props.filePermission}
onFileTagChanged={this.props.onToolbarFileTagChanged}
repoTags={this.props.repoTags}
onItemMove={this.props.onItemMove}
isDesktop={isDesktop}
loadDirentList={this.props.loadDirentList}
/>
)}
</div>
{isDesktop &&
<div className="cur-view-path-right py-1">
<DirTool
repoID={repoID}
repoName={this.props.currentRepoInfo.repo_name}
userPerm={this.props.userPerm}
currentPath={path}
updateUsedRepoTags={this.props.updateUsedRepoTags}
onDeleteRepoTag={this.props.onDeleteRepoTag}
currentMode={this.props.currentMode}
switchViewMode={this.props.switchViewMode}
isCustomPermission={this.props.isCustomPermission}
sortBy={this.props.sortBy}
sortOrder={this.props.sortOrder}
sortItems={this.props.sortItems}
viewId={this.props.viewId}
viewType={this.props.viewType}
/>
</div>
}
</div>
<div className='cur-view-content lib-content-container' onScroll={this.onItemsScroll}>
{!this.props.pathExist && this.errMessage}
{this.props.pathExist && (
<DirColumnView
isSidePanelFolded={this.props.isSidePanelFolded}
isTreePanelShown={this.props.isTreePanelShown}
currentMode={this.props.currentMode}
currentDirent={this.props.currentDirent}
path={this.props.path}
repoID={repoID}
currentRepoInfo={this.props.currentRepoInfo}
isGroupOwnedRepo={this.props.isGroupOwnedRepo}
userPerm={this.props.userPerm}
enableDirPrivateShare={this.props.enableDirPrivateShare}
isTreeDataLoading={this.props.isTreeDataLoading}
treeData={this.props.treeData}
currentNode={this.props.currentNode}
onNodeClick={this.props.onNodeClick}
onNodeCollapse={this.props.onNodeCollapse}
onNodeExpanded={this.props.onNodeExpanded}
onAddFolderNode={this.props.onAddFolder}
onAddFileNode={this.props.onAddFile}
onRenameNode={this.props.onRenameNode}
onDeleteNode={this.props.onDeleteNode}
isViewFile={this.props.isViewFile}
isFileLoading={this.props.isFileLoading}
filePermission={this.props.filePermission}
content={this.props.content}
viewId={this.props.viewId}
lastModified={this.props.lastModified}
latestContributor={this.props.latestContributor}
onLinkClick={this.props.onLinkClick}
isRepoInfoBarShow={isRepoInfoBarShow}
repoTags={this.props.repoTags}
usedRepoTags={this.props.usedRepoTags}
updateUsedRepoTags={this.props.updateUsedRepoTags}
isDirentListLoading={this.props.isDirentListLoading}
direntList={this.props.direntList}
fullDirentList={this.props.fullDirentList}
sortBy={this.props.sortBy}
sortOrder={this.props.sortOrder}
sortItems={this.props.sortItems}
onAddFolder={this.props.onAddFolder}
onAddFile={this.props.onAddFile}
onItemClick={this.onItemClick}
onItemSelected={this.onItemSelected}
onItemDelete={this.onItemDelete}
onItemRename={this.props.onItemRename}
onItemMove={this.onItemMove}
onItemCopy={this.props.onItemCopy}
onItemConvert={this.props.onItemConvert}
onDirentClick={this.onDirentClick}
updateDirent={this.props.updateDirent}
isAllItemSelected={this.props.isAllDirentSelected}
onAllItemSelected={this.props.onAllDirentSelected}
selectedDirentList={this.props.selectedDirentList}
onSelectedDirentListUpdate={this.props.onSelectedDirentListUpdate}
onItemsMove={this.props.onItemsMove}
onItemsCopy={this.props.onItemsCopy}
onItemsDelete={this.props.onItemsDelete}
onFileTagChanged={this.props.onFileTagChanged}
showDirentDetail={this.props.showDirentDetail}
onItemsScroll={this.onItemsScroll}
isDirentDetailShow={this.props.isDirentDetailShow}
eventBus={this.props.eventBus}
onCloseMarkdownViewDialog={this.props.onCloseMarkdownViewDialog}
getMarkDownFilePath={this.props.getMarkDownFilePath}
getMarkDownFileName={this.props.getMarkDownFileName}
openMarkdownFile={this.props.openMarkdownFile}
/>
)}
{this.props.isDirentDetailShow && (
<Detail
path={path}
repoID={repoID}
currentRepoInfo={this.props.currentRepoInfo}
dirent={this.state.currentDirent}
repoTags={this.props.repoTags}
fileTags={this.props.isViewFile ? this.props.fileTags : []}
onFileTagChanged={this.props.onFileTagChanged}
onClose={this.props.closeDirentDetail}
/>
)}
</div>
</div>
);
}
}
LibContentContainer.propTypes = propTypes;
export default LibContentContainer;

View File

@@ -1,7 +1,8 @@
import React, { Fragment } from 'react';
import React from 'react';
import PropTypes from 'prop-types';
import cookie from 'react-cookies';
import moment from 'moment';
import classnames from 'classnames';
import MediaQuery from 'react-responsive';
import { Modal } from 'reactstrap';
import { navigate } from '@gatsbyjs/reach-router';
@@ -9,16 +10,12 @@ import { gettext, siteRoot, username, enableVideoThumbnail, enablePDFThumbnail,
import { seafileAPI } from '../../utils/seafile-api';
import { Utils } from '../../utils/utils';
import collabServer from '../../utils/collab-server';
import Dirent from '../../models/dirent';
import FileTag from '../../models/file-tag';
import RepoTag from '../../models/repo-tag';
import RepoInfo from '../../models/repo-info';
import { Dirent, FileTag, RepoTag, RepoInfo } from '../../models';
import TreeNode from '../../components/tree-view/tree-node';
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 LibContentContainer from './lib-content-container';
import FileUploader from '../../components/file-uploader/file-uploader';
import CopyMoveDirentProgressDialog from '../../components/dialog/copy-move-dirent-progress-dialog';
import DeleteFolderDialog from '../../components/dialog/delete-folder-dialog';
@@ -26,6 +23,13 @@ import { EVENT_BUS_TYPE } from '../../components/common/event-bus-type';
import { PRIVATE_FILE_TYPE } from '../../constants';
import { MetadataProvider, CollaboratorsProvider } from '../../metadata/hooks';
import { LIST_MODE, METADATA_MODE } from '../../components/dir-view-mode/constants';
import CurDirPath from '../../components/cur-dir-path';
import DirTool from '../../components/cur-dir-path/dir-tool';
import DetailContainer from '../../components/dirent-detail/detail-container';
import DirColumnView from '../../components/dir-view-mode/dir-column-view';
import SelectedDirentsToolbar from '../../components/toolbar/selected-dirents-toolbar';
import '../../css/lib-content-view.css';
const propTypes = {
eventBus: PropTypes.object,
@@ -80,7 +84,6 @@ class LibContentView extends React.Component {
errorMsg: '',
isDirentDetailShow: false,
direntDetailPanelTab: '',
updateDetail: false,
itemsShowLength: 100,
isSessionExpired: false,
isCopyMoveProgressDialogShow: false,
@@ -104,6 +107,23 @@ class LibContentView extends React.Component {
this.unsubscribeEventBus = null;
}
updateCurrentDirent = (deletedDirent) => {
let { currentDirent } = this.state;
if (currentDirent && deletedDirent.name === currentDirent.name) {
this.setState({ currentDirent: null });
}
};
onItemsScroll = (e) => {
let target = e.target;
if (target.scrollTop === 0) {
return;
}
if (target.scrollTop + target.clientHeight + 1 >= target.scrollHeight) {
this.onListContainerScroll();
}
};
showDirentDetail = (direntDetailPanelTab) => {
if (direntDetailPanelTab) {
this.setState({ direntDetailPanelTab: direntDetailPanelTab }, () => {
@@ -241,7 +261,10 @@ class LibContentView extends React.Component {
});
}
componentDidUpdate() {
componentDidUpdate(prevProps, prevState) {
if (prevState.path !== this.state.path) {
this.setState({ currentDirent: null });
}
this.lastModifyTime = new Date();
this.props.eventBus.dispatch(EVENT_BUS_TYPE.CURRENT_LIBRARY_CHANGED, {
repoID: this.props.repoID,
@@ -386,23 +409,15 @@ class LibContentView extends React.Component {
};
handleMarkdownFile = (path) => {
seafileAPI.getFileInfo(this.props.repoID, path)
.then(() => {
/*
if (this.state.currentMode !== 'column') {
cookie.save('seafile_view_mode', 'column');
this.setState({currentMode: 'column'});
}
*/
seafileAPI.getFileInfo(this.props.repoID, path).then(() => {
this.loadSidePanel(path);
this.showFile(path);
}).catch(() => {
if (this.state.isTreePanelShown) {
this.loadSidePanel(path);
this.showFile(path);
})
.catch(() => {
if (this.state.isTreePanelShown) {
this.loadSidePanel(path);
}
this.showDir(path);
});
}
this.showDir(path);
});
};
handleNonMarkdownFile = (path) => {
@@ -950,7 +965,7 @@ class LibContentView extends React.Component {
let direntPaths = this.getSelectedDirentPaths();
let dirNames = this.getSelectedDirentNames();
this.setState({ updateDetail: !this.state.updateDetail });
this.setState({ currentDirent: null });
seafileAPI.deleteMutipleDirents(repoID, this.state.path, dirNames).then(res => {
if (this.state.isTreePanelShown) {
this.deleteTreeNodes(direntPaths);
@@ -1143,6 +1158,7 @@ class LibContentView extends React.Component {
};
onMainPanelItemDelete = (dirent) => {
this.updateCurrentDirent(dirent);
let path = Utils.joinPath(this.state.path, dirent.name);
this.deleteItem(path, dirent.isDir());
};
@@ -1260,6 +1276,7 @@ class LibContentView extends React.Component {
// list operations
onMoveItem = (destRepo, dirent, moveToDirentPath, nodeParentPath) => {
this.updateCurrentDirent(dirent);
let repoID = this.props.repoID;
// just for view list state
let dirName = dirent.name;
@@ -1412,6 +1429,9 @@ class LibContentView extends React.Component {
};
onDirentClick = (clickedDirent, event) => {
this.setState({
currentDirent: clickedDirent && clickedDirent.isActive ? null : clickedDirent
});
const { direntList, selectedDirentList, lastSelectedIndex } = this.state;
if (clickedDirent) {
const clickedIndex = direntList.findIndex(dirent => dirent.name === clickedDirent.name);
@@ -1527,6 +1547,9 @@ class LibContentView extends React.Component {
};
onDirentSelected = (dirent) => {
this.setState({
currentDirent: dirent && dirent.isActive ? null : dirent
});
let direntList = this.state.direntList.map(item => {
if (item.name === dirent.name) {
item.isSelected = !item.isSelected;
@@ -2170,17 +2193,15 @@ class LibContentView extends React.Component {
};
render() {
let { currentRepoInfo, userPerm, isCopyMoveProgressDialogShow, isDeleteFolderDialogOpen, currentDirent,
path, usedRepoTags } = this.state;
if (this.state.libNeedDecrypt) {
return (
<ModalPortal>
<LibDecryptDialog
repoID={this.props.repoID}
onLibDecryptDialog={this.onLibDecryptDialog}
/>
<LibDecryptDialog repoID={this.props.repoID} onLibDecryptDialog={this.onLibDecryptDialog} />
</ModalPortal>
);
}
if (this.state.libNeedDecryptWhenCopy || this.state.libNeedDecryptWhenMove) {
return (
<ModalPortal>
@@ -2191,22 +2212,19 @@ class LibContentView extends React.Component {
</ModalPortal>
);
}
if (this.state.errorMsg) {
return (
<Fragment>
<>
<p className="error mt-6 text-center">{this.state.errorMsg}</p>
<button type="submit" className="btn btn-primary submit" onClick={this.handleSubmit}>{gettext('Leave Share')}</button>
</Fragment>
</>
);
}
if (!this.state.currentRepoInfo) {
return '';
}
let enableDirPrivateShare = false;
let { currentRepoInfo, userPerm, isCopyMoveProgressDialogShow, isDeleteFolderDialogOpen, currentDirent } = this.state;
let showShareBtn = Utils.isHasPermissionToShare(currentRepoInfo, userPerm);
let isRepoOwner = currentRepoInfo.owner_email === username;
let isVirtual = currentRepoInfo.is_virtual;
@@ -2225,6 +2243,14 @@ class LibContentView extends React.Component {
canUpload = upload;
}
const isDesktop = Utils.isDesktop();
let isRepoInfoBarShow = false;
if (path === '/') {
if (isDesktop && usedRepoTags.length !== 0) {
isRepoInfoBarShow = true;
}
}
return (
<MetadataProvider
repoID={this.props.repoID}
@@ -2233,95 +2259,184 @@ class LibContentView extends React.Component {
>
<CollaboratorsProvider repoID={this.props.repoID}>
<div className="main-panel-center flex-row">
<LibContentContainer
isSidePanelFolded={this.props.isSidePanelFolded}
repoEncrypted={this.state.repoEncrypted}
isRepoOwner={isRepoOwner}
onFilesTagChanged={this.onFileTagChanged}
unSelectDirent={this.unSelectDirent}
pathPrefix={this.props.pathPrefix}
isTreePanelShown={this.state.isTreePanelShown}
toggleTreePanel={this.toggleTreePanel}
currentMode={this.state.currentMode}
switchViewMode={this.switchViewMode}
isCustomPermission={isCustomPermission}
path={this.state.path}
pathExist={this.state.pathExist}
currentRepoInfo={this.state.currentRepoInfo}
repoID={this.props.repoID}
enableDirPrivateShare={enableDirPrivateShare}
userPerm={userPerm}
isGroupOwnedRepo={this.state.isGroupOwnedRepo}
onTabNavClick={this.props.onTabNavClick}
onMainNavBarClick={this.onMainNavBarClick}
isViewFile={this.state.isViewFile}
fileTags={this.state.fileTags}
isFileLoading={this.state.isFileLoading}
filePermission={this.state.filePermission}
content={this.state.content}
viewId={this.state.viewId}
lastModified={this.state.lastModified}
latestContributor={this.state.latestContributor}
onLinkClick={this.onLinkClick}
isTreeDataLoading={this.state.isTreeDataLoading}
treeData={this.state.treeData}
currentNode={this.state.currentNode}
onNodeClick={this.onTreeNodeClick}
onNodeCollapse={this.onTreeNodeCollapse}
onNodeExpanded={this.onTreeNodeExpanded}
onAddFolderNode={this.onAddFolder}
onAddFileNode={this.onAddFile}
onRenameNode={this.onRenameTreeNode}
onDeleteNode={this.onDeleteTreeNode}
repoTags={this.state.repoTags}
usedRepoTags={this.state.usedRepoTags}
updateUsedRepoTags={this.updateUsedRepoTags}
isDirentListLoading={this.state.isDirentListLoading}
direntList={direntItemsList}
fullDirentList={this.state.direntList}
sortBy={this.state.sortBy}
sortOrder={this.state.sortOrder}
currentDirent={currentDirent}
sortItems={this.sortItems}
updateDirent={this.updateDirent}
onDirentClick={this.onDirentClick}
onItemClick={this.onItemClick}
onItemSelected={this.onDirentSelected}
onItemDelete={this.onMainPanelItemDelete}
onItemRename={this.onMainPanelItemRename}
onItemMove={this.onMoveItem}
onItemCopy={this.onCopyItem}
onItemConvert={this.onConvertItem}
onAddFolder={this.onAddFolder}
onAddFile={this.onAddFile}
onFileTagChanged={this.onFileTagChanged}
isDirentSelected={this.state.isDirentSelected}
isAllDirentSelected={this.state.isAllDirentSelected}
onAllDirentSelected={this.onAllDirentSelected}
isDirentDetailShow={this.state.isDirentDetailShow}
selectedDirent={this.state.selectedDirentList && this.state.selectedDirentList[0]}
selectedDirentList={this.state.selectedDirentList}
onSelectedDirentListUpdate={this.onSelectedDirentListUpdate}
onItemsMove={this.onMoveItems}
onItemsCopy={this.onCopyItems}
onItemsDelete={this.onDeleteItems}
closeDirentDetail={this.closeDirentDetail}
showDirentDetail={this.showDirentDetail}
direntDetailPanelTab={this.state.direntDetailPanelTab}
onDeleteRepoTag={this.onDeleteRepoTag}
onToolbarFileTagChanged={this.onToolbarFileTagChanged}
updateDetail={this.state.updateDetail}
onListContainerScroll={this.onListContainerScroll}
loadDirentList={this.loadDirentList}
showShareBtn={showShareBtn}
onUploadFile={this.onUploadFile}
onUploadFolder={this.onUploadFolder}
eventBus={this.props.eventBus}
onCloseMarkdownViewDialog={this.onCloseMarkdownViewDialog}
getMarkDownFilePath={this.getMarkDownFilePath}
getMarkDownFileName={this.getMarkDownFileName}
openMarkdownFile={this.openMarkdownFile}
/>
<div className="cur-view-container">
{this.state.currentRepoInfo.status === 'read-only' &&
<div className="readonly-tip-message">
{gettext('This library has been set to read-only by admin and cannot be updated.')}
</div>
}
<div className="cur-view-path lib-cur-view-path">
<div className={classnames(
'cur-view-path-left', {
'w-100': !isDesktop,
'animation-children': this.state.isDirentSelected
})}>
{this.state.isDirentSelected ?
<SelectedDirentsToolbar
repoID={this.props.repoID}
path={this.state.path}
userPerm={userPerm}
repoEncrypted={this.state.repoEncrypted}
repoTags={this.state.repoTags}
selectedDirentList={this.state.selectedDirentList}
direntList={direntItemsList}
onItemsMove={this.onMoveItems}
onItemsCopy={this.onCopyItems}
onItemsDelete={this.onDeleteItems}
onItemRename={this.onMainPanelItemRename}
isRepoOwner={isRepoOwner}
currentRepoInfo={this.state.currentRepoInfo}
enableDirPrivateShare={enableDirPrivateShare}
updateDirent={this.updateDirent}
unSelectDirent={this.unSelectDirent}
onFilesTagChanged={this.onFileTagChanged}
showShareBtn={showShareBtn}
isGroupOwnedRepo={this.state.isGroupOwnedRepo}
showDirentDetail={this.showDirentDetail}
currentMode={this.state.currentMode}
switchViewMode={this.switchViewMode}
/>
:
<CurDirPath
currentRepoInfo={this.state.currentRepoInfo}
repoID={this.props.repoID}
repoName={this.state.currentRepoInfo.repo_name}
repoEncrypted={this.state.repoEncrypted}
isGroupOwnedRepo={this.state.isGroupOwnedRepo}
pathPrefix={this.props.pathPrefix}
currentPath={this.state.path}
userPerm={userPerm}
onTabNavClick={this.props.onTabNavClick}
onPathClick={this.onMainNavBarClick}
fileTags={this.state.fileTags}
direntList={direntItemsList}
sortBy={this.state.sortBy}
sortOrder={this.state.sortOrder}
sortItems={this.sortItems}
toggleTreePanel={this.toggleTreePanel}
enableDirPrivateShare={enableDirPrivateShare}
showShareBtn={showShareBtn}
onAddFolder={this.onAddFolder}
onAddFile={this.onAddFile}
onUploadFile={this.onUploadFile}
onUploadFolder={this.onUploadFolder}
fullDirentList={this.state.direntList}
filePermission={this.state.filePermission}
onFileTagChanged={this.onToolbarFileTagChanged}
repoTags={this.state.repoTags}
onItemMove={this.onMoveItem}
isDesktop={isDesktop}
loadDirentList={this.loadDirentList}
/>
}
</div>
{isDesktop &&
<div className="cur-view-path-right py-1">
<DirTool
repoID={this.props.repoID}
repoName={this.state.currentRepoInfo.repo_name}
userPerm={userPerm}
currentPath={path}
updateUsedRepoTags={this.updateUsedRepoTags}
onDeleteRepoTag={this.onDeleteRepoTag}
currentMode={this.state.currentMode}
switchViewMode={this.switchViewMode}
isCustomPermission={isCustomPermission}
sortBy={this.state.sortBy}
sortOrder={this.state.sortOrder}
sortItems={this.sortItems}
viewId={this.state.viewId}
viewType={this.props.viewType}
/>
</div>
}
</div>
<div className='cur-view-content lib-content-container' onScroll={this.onItemsScroll}>
{this.state.pathExist ?
<DirColumnView
isSidePanelFolded={this.props.isSidePanelFolded}
isTreePanelShown={this.state.isTreePanelShown}
currentMode={this.state.currentMode}
currentDirent={currentDirent}
path={this.state.path}
repoID={this.props.repoID}
currentRepoInfo={this.state.currentRepoInfo}
isGroupOwnedRepo={this.state.isGroupOwnedRepo}
userPerm={userPerm}
enableDirPrivateShare={enableDirPrivateShare}
isTreeDataLoading={this.state.isTreeDataLoading}
treeData={this.state.treeData}
currentNode={this.state.currentNode}
onNodeClick={this.onTreeNodeClick}
onNodeCollapse={this.onTreeNodeCollapse}
onNodeExpanded={this.onTreeNodeExpanded}
onAddFolderNode={this.onAddFolder}
onAddFileNode={this.onAddFile}
onRenameNode={this.onRenameTreeNode}
onDeleteNode={this.onDeleteTreeNode}
isViewFile={this.state.isViewFile}
isFileLoading={this.state.isFileLoading}
filePermission={this.state.filePermission}
content={this.state.content}
viewId={this.state.viewId}
lastModified={this.state.lastModified}
latestContributor={this.state.latestContributor}
onLinkClick={this.onLinkClick}
isRepoInfoBarShow={isRepoInfoBarShow}
repoTags={this.state.repoTags}
usedRepoTags={this.state.usedRepoTags}
updateUsedRepoTags={this.updateUsedRepoTags}
isDirentListLoading={this.state.isDirentListLoading}
direntList={direntItemsList}
fullDirentList={this.state.direntList}
sortBy={this.state.sortBy}
sortOrder={this.state.sortOrder}
sortItems={this.sortItems}
onAddFolder={this.onAddFolder}
onAddFile={this.onAddFile}
onItemClick={this.onItemClick}
onItemSelected={this.onDirentSelected}
onItemDelete={this.onMainPanelItemDelete}
onItemRename={this.onMainPanelItemRename}
onItemMove={this.onMoveItem}
onItemCopy={this.onCopyItem}
onItemConvert={this.onConvertItem}
onDirentClick={this.onDirentClick}
updateDirent={this.updateDirent}
isAllItemSelected={this.state.isAllDirentSelected}
onAllItemSelected={this.onAllDirentSelected}
selectedDirentList={this.state.selectedDirentList}
onSelectedDirentListUpdate={this.onSelectedDirentListUpdate}
onItemsMove={this.onMoveItems}
onItemsCopy={this.onCopyItems}
onItemsDelete={this.onDeleteItems}
onFileTagChanged={this.onFileTagChanged}
showDirentDetail={this.showDirentDetail}
onItemsScroll={this.onItemsScroll}
isDirentDetailShow={this.state.isDirentDetailShow}
eventBus={this.props.eventBus}
onCloseMarkdownViewDialog={this.onCloseMarkdownViewDialog}
getMarkDownFilePath={this.getMarkDownFilePath}
getMarkDownFileName={this.getMarkDownFileName}
openMarkdownFile={this.openMarkdownFile}
/>
:
<div className="message err-tip">{gettext('Folder does not exist.')}</div>
}
{this.state.isDirentDetailShow && (
<DetailContainer
path={this.state.path}
repoID={this.props.repoID}
currentRepoInfo={this.state.currentRepoInfo}
dirent={this.state.currentDirent}
repoTags={this.state.repoTags}
fileTags={this.state.isViewFile ? this.state.fileTags : []}
onFileTagChanged={this.onFileTagChanged}
onClose={this.closeDirentDetail}
/>
)}
</div>
</div>
{canUpload && this.state.pathExist && !this.state.isViewFile && this.state.currentMode !== METADATA_MODE && (
<FileUploader
ref={uploader => this.uploader = uploader}