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:
@@ -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;
|
@@ -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>
|
||||
|
@@ -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>
|
||||
);
|
@@ -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;
|
||||
|
6
frontend/src/models/index.js
Normal file
6
frontend/src/models/index.js
Normal 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 };
|
@@ -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;
|
@@ -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}
|
||||
|
Reference in New Issue
Block a user