1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-08-02 07:47:32 +00:00

Add nav others (#6313)

This commit is contained in:
Michael An 2024-07-09 09:45:50 +08:00 committed by GitHub
parent 739a12ada4
commit e7eb77b9c6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 119 additions and 48 deletions

View File

@ -1,7 +1,7 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Dropdown, DropdownMenu, DropdownToggle, DropdownItem } from 'reactstrap';
import { gettext, siteRoot } from '../../utils/constants';
import { gettext } from '../../utils/constants';
import { Utils } from '../../utils/utils';
import TextTranslation from '../../utils/text-translation';
import SeahubPopover from '../common/seahub-popover';
@ -52,41 +52,21 @@ class DirTool extends React.Component {
getMenu = () => {
const list = [];
const { repoID, userPerm, currentPath } = this.props;
const { TAGS, TRASH, HISTORY } = TextTranslation;
if (userPerm !== 'rw') {
const { userPerm, currentPath } = this.props;
if (userPerm !== 'rw' || Utils.isMarkdownFile(currentPath)) {
return list;
}
if (Utils.isMarkdownFile(currentPath)) {
return list;
}
const { TAGS } = TextTranslation;
list.push(TAGS);
if (Utils.getFileName(currentPath)) {
let trashUrl = siteRoot + 'repo/' + repoID + '/trash/?path=' + encodeURIComponent(currentPath);
list.push({...TRASH, href: trashUrl});
} else {
let trashUrl = siteRoot + 'repo/' + repoID + '/trash/';
list.push({...TRASH, href: trashUrl});
let historyUrl = siteRoot + 'repo/history/' + repoID + '/';
list.push({...HISTORY, href: historyUrl});
}
return list;
};
onMenuItemClick = (item) => {
const { key, href } = item;
const { key } = item;
switch (key) {
case 'Tags':
this.setState({isRepoTagDialogOpen: !this.state.isRepoTagDialogOpen});
break;
case 'Trash':
location.href = href;
break;
case 'History':
location.href = href;
break;
}
};

View File

@ -0,0 +1,20 @@
.dir-content-nav .tree-section:first-child {
margin-top: 12px;
}
.dir-content-nav .tree-section:last-child {
margin-bottom: 28px;
}
.dir-others .tree-node-inner:hover {
background-color: #f0f0f0;
border-radius: 0.25rem;
}
.dir-others .tree-node-inner .tree-node-text {
padding-left: 2rem;
}
.dir-others .tree-node-inner .left-icon {
padding-left: 10px;
}

View File

@ -14,6 +14,9 @@ import { gettext } from '../../utils/constants';
import { Utils } from '../../utils/utils';
import TreeSection from '../../components/tree-section';
import DirViews from './dir-views';
import DirOthers from './dir-others';
import './dir-column-nav.css';
const propTypes = {
currentPath: PropTypes.string.isRequired,
@ -268,7 +271,17 @@ class DirColumnNav extends React.Component {
repoID={this.props.repoID}
/>
</TreeSection>
<DirViews repoID={this.props.repoID} currentPath={this.props.currentPath} userPerm={this.props.userPerm} onNodeClick={this.onNodeClick}/>
<DirViews
repoID={this.props.repoID}
currentPath={this.props.currentPath}
userPerm={this.props.userPerm}
onNodeClick={this.onNodeClick}
/>
<DirOthers
repoID={this.props.repoID}
currentPath={this.props.currentPath}
userPerm={this.props.userPerm}
/>
</>
);
};

View File

@ -0,0 +1,52 @@
import React from 'react';
import PropTypes from 'prop-types';
import { gettext, siteRoot } from '../../utils/constants';
import { Utils } from '../../utils/utils';
import TreeSection from '../tree-section';
const DirOthers = ({ userPerm, repoID, currentPath }) => {
let trashUrl = null;
let historyUrl = null;
if (userPerm === 'rw' && !Utils.isMarkdownFile(currentPath)) {
if (Utils.getFileName(currentPath)) {
trashUrl = siteRoot + 'repo/' + repoID + '/trash/?path=' + encodeURIComponent(currentPath);
} else {
trashUrl = siteRoot + 'repo/' + repoID + '/trash/';
historyUrl = siteRoot + 'repo/history/' + repoID + '/';
}
}
return (
<TreeSection title={gettext('Others')} className="dir-others">
{trashUrl &&
<div className='tree-node-inner text-nowrap' title={gettext('Trash')} onClick={() => location.href = trashUrl}>
<div className="tree-node-text">{gettext('Trash')}</div>
<div className="left-icon">
<div className="tree-node-icon">
<span className="sf3-font-recycle1 sf3-font"></span>
</div>
</div>
</div>
}
{historyUrl &&
<div className='tree-node-inner text-nowrap' title={gettext('History')} onClick={() => location.href = historyUrl}>
<div className="tree-node-text">{gettext('History')}</div>
<div className="left-icon">
<div className="tree-node-icon">
<span className="sf3-font-history sf3-font"></span>
</div>
</div>
</div>
}
</TreeSection>
);
};
DirOthers.propTypes = {
userPerm: PropTypes.string,
repoID: PropTypes.string,
currentPath: PropTypes.string,
};
export default DirOthers;

View File

@ -1,13 +1,11 @@
import React, { useCallback, useEffect, useMemo, useState } from 'react';
import PropTypes from 'prop-types';
import { gettext } from '../../../utils/constants';
import { Utils } from '../../../utils/utils';
import TreeSection from '../../tree-section';
import { MetadataStatusManagementDialog, MetadataTreeView } from '../../../metadata';
import metadataAPI from '../../../metadata/api';
import toaster from '../../toast';
import './index.css';
import { gettext } from '../../utils/constants';
import { Utils } from '../../utils/utils';
import TreeSection from '../tree-section';
import { MetadataStatusManagementDialog, MetadataTreeView } from '../../metadata';
import metadataAPI from '../../metadata/api';
import toaster from '../toast';
const DirViews = ({ userPerm, repoID, currentPath, onNodeClick }) => {
const enableMetadataManagement = useMemo(() => {
@ -63,11 +61,21 @@ const DirViews = ({ userPerm, repoID, currentPath, onNodeClick }) => {
return (
<>
<TreeSection title={gettext('Views')} moreKey={{ name: 'views' }} moreOperations={moreOperations} moreOperationClick={moreOperationClick}>
<TreeSection
title={gettext('Views')}
moreKey={{ name: 'views' }}
moreOperations={moreOperations}
moreOperationClick={moreOperationClick}
>
{!loading && metadataStatus && (<MetadataTreeView repoID={repoID} currentPath={currentPath} onNodeClick={onNodeClick} />)}
</TreeSection>
{showMetadataStatusManagementDialog && (
<MetadataStatusManagementDialog value={metadataStatus} repoID={repoID} toggle={closeMetadataManagementDialog} submit={toggleMetadataStatus} />
<MetadataStatusManagementDialog
value={metadataStatus}
repoID={repoID}
toggle={closeMetadataManagementDialog}
submit={toggleMetadataStatus}
/>
)}
</>
);

View File

@ -1,7 +0,0 @@
.dir-content-nav .tree-section:first-child {
margin-top: 12px;
}
.dir-content-nav .tree-section:last-child {
margin-bottom: 28px;
}

View File

@ -1,10 +1,11 @@
import React, { useCallback, useMemo, useState } from 'react';
import PropTypes from 'prop-types';
import classnames from 'classnames';
import ItemDropdownMenu from '../dropdown-menu/item-dropdown-menu';
import './index.css';
const TreeSection = ({ title, children, moreKey, moreOperations, moreOperationClick }) => {
const TreeSection = ({ title, children, moreKey, moreOperations, moreOperationClick, className }) => {
const [showChildren, setShowChildren] = useState(true);
const [highlight, setHighlight] = useState(false);
const [freeze, setFreeze] = useState(false);
@ -43,8 +44,13 @@ const TreeSection = ({ title, children, moreKey, moreOperations, moreOperationCl
}, []);
return (
<div className="tree-section">
<div className={`tree-section-header${highlight ? ' tree-section-header-hover' : ''}`} onMouseEnter={onMouseEnter} onMouseOver={onMouseOver} onMouseLeave={onMouseLeave}>
<div className={classnames('tree-section', {[className]: className})}>
<div
className={classnames('tree-section-header', {'tree-section-header-hover': highlight})}
onMouseEnter={onMouseEnter}
onMouseOver={onMouseOver}
onMouseLeave={onMouseLeave}
>
<div className="tree-section-header-title">{title}</div>
<div className="tree-section-header-operations">
{validMoreOperations.length > 0 && (
@ -81,6 +87,7 @@ TreeSection.propTypes = {
children: PropTypes.any,
moreKey: PropTypes.object,
moreOperationClick: PropTypes.func,
className: PropTypes.string,
};
export default TreeSection;

View File

@ -55,8 +55,6 @@ class MainPanel extends Component {
return { ...props, docUuid: window.seafile.docUuid, currentPageConfig };
}
render() {
const { permission, pathExist, isDataLoading, isViewFile, config, onUpdatePage } = this.props;
const { currentPageConfig = {}, } = this.state;