diff --git a/frontend/src/components/cur-dir-path/dir-tool.js b/frontend/src/components/cur-dir-path/dir-tool.js index 3f71a3854c..219ab77b90 100644 --- a/frontend/src/components/cur-dir-path/dir-tool.js +++ b/frontend/src/components/cur-dir-path/dir-tool.js @@ -1,8 +1,9 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { v4 as uuidv4 } from 'uuid'; +import { Dropdown, DropdownMenu, DropdownToggle, DropdownItem } from 'reactstrap'; import { gettext, siteRoot } from '../../utils/constants'; import { Utils } from '../../utils/utils'; +import TextTranslation from '../../utils/text-translation'; import SeahubPopover from '../common/seahub-popover'; import ListTagPopover from '../popover/list-tag-popover'; @@ -12,6 +13,9 @@ const propTypes = { currentPath: PropTypes.string.isRequired, updateUsedRepoTags: PropTypes.func.isRequired, onDeleteRepoTag: PropTypes.func.isRequired, + currentMode: PropTypes.string.isRequired, + switchViewMode: PropTypes.func.isRequired, + isCustomPermission: PropTypes.bool, }; class DirTool extends React.Component { @@ -19,20 +23,21 @@ class DirTool extends React.Component { constructor(props) { super(props); this.state = { - isListRepoTagShow: false, + isRepoTagDialogOpen: false, + isDropdownMenuOpen: false }; - this.tagsIconID = `tags-icon-${uuidv4()}`; } + toggleDropdownMenu = () => { + this.setState({ + isDropdownMenuOpen: !this.state.isDropdownMenuOpen + }); + }; + onMouseDown = (e) => { e.stopPropagation(); }; - toggleRepoTag = (e) => { - e.stopPropagation(); - this.setState({ isListRepoTagShow: !this.state.isListRepoTagShow }); - }; - hidePopover = (e) => { if (e) { let dom = e.target; @@ -41,95 +46,136 @@ class DirTool extends React.Component { dom = dom.parentNode; } } - this.setState({ isListRepoTagShow: false }); + this.setState({isRepoTagDialogOpen: false}); }; toggleCancel = () => { - this.setState({ isListRepoTagShow: false }); + this.setState({isRepoTagDialogOpen: false}); }; isMarkdownFile(filePath) { return Utils.getFileName(filePath).includes('.md'); } - render() { - let { repoID, userPerm, currentPath } = this.props; + getList2 = () => { + const list = []; + const { repoID, userPerm, currentPath } = this.props; + const { TAGS, TRASH, HISTORY } = TextTranslation; if (userPerm !== 'rw') { - return ''; + return list; } if (this.isMarkdownFile(currentPath)) { - return ''; + return list; } - let toolbarDom = null; - if (Utils.getFileName(currentPath)) { // name not '' is not root path + + list.push(TAGS); + + if (Utils.getFileName(currentPath)) { let trashUrl = siteRoot + 'repo/' + repoID + '/trash/?path=' + encodeURIComponent(currentPath); - toolbarDom = ( - - ); - } else { // currentPath === '/' is root path + list.push({...TRASH, href: trashUrl}); + } else { let trashUrl = siteRoot + 'repo/' + repoID + '/trash/'; + list.push({...TRASH, href: trashUrl}); + let historyUrl = siteRoot + 'repo/history/' + repoID + '/'; - toolbarDom = ( - - ); + list.push({...HISTORY, href: historyUrl}); } + + return list; + }; + + onMenuItemClick = (item) => { + const { key: operation, href } = item; + switch (operation) { + case 'Properties': + this.props.switchViewMode('detail'); + break; + case 'Tags': + this.setState({ isRepoTagDialogOpen: !this.state.isRepoTagDialogOpen }); + break; + case 'Trash': + location.href = href; + break; + case 'History': + location.href = href; + break; + } + }; + + getMenuList = () => { + const list = []; + const list2 = this.getList2(); + const { PROPERTIES, } = TextTranslation; + if (!this.props.isCustomPermission) { + list.push(PROPERTIES); + } + return list.concat(list2); + }; + + onMenuItemKeyDown = (e) => { + if (e.key == 'Enter' || e.key == 'Space') { + this.onMenuItemClick(e); + } + }; + + render() { + let baseClass = 'btn btn-secondary btn-icon sf-view-mode-btn '; + const menuItems = this.getMenuList(); + const { isDropdownMenuOpen } = this.state; + const { repoID } = this.props; return ( - <> - {toolbarDom} - {this.state.isListRepoTagShow && - - - + +
+
+ + +
+ {menuItems.length > 0 && + + + + + {menuItems.map((menuItem, index) => { + if (menuItem === 'Divider') { + return ; + } else { + return ( + {menuItem.value} + ); + } + })} + + + } +
+ {this.state.isRepoTagDialogOpen && + + + } - +
); } + } DirTool.propTypes = propTypes; diff --git a/frontend/src/components/cur-dir-path/index.js b/frontend/src/components/cur-dir-path/index.js index 2cc7d26ee6..ecd9154eea 100644 --- a/frontend/src/components/cur-dir-path/index.js +++ b/frontend/src/components/cur-dir-path/index.js @@ -22,6 +22,9 @@ const propTypes = { sortBy: PropTypes.string, sortOrder: PropTypes.string, sortItems: PropTypes.func, + currentMode: PropTypes.string.isRequired, + switchViewMode: PropTypes.func.isRequired, + isCustomPermission: PropTypes.bool, }; class CurDirPath extends React.Component { @@ -62,6 +65,9 @@ class CurDirPath extends React.Component { currentPath={this.props.currentPath} updateUsedRepoTags={this.props.updateUsedRepoTags} onDeleteRepoTag={this.props.onDeleteRepoTag} + currentMode={this.props.currentMode} + switchViewMode={this.props.switchViewMode} + isCustomPermission={this.props.isCustomPermission} />} {!isDesktop && this.props.direntList.length > 0 && } diff --git a/frontend/src/components/toolbar/dir-operation-toolbar.js b/frontend/src/components/toolbar/dir-operation-toolbar.js index bcf692c5c2..148ea8ddcb 100644 --- a/frontend/src/components/toolbar/dir-operation-toolbar.js +++ b/frontend/src/components/toolbar/dir-operation-toolbar.js @@ -7,7 +7,6 @@ import ModalPortal from '../modal-portal'; import CreateFolder from '../../components/dialog/create-folder-dialog'; import CreateFile from '../../components/dialog/create-file-dialog'; import ShareDialog from '../../components/dialog/share-dialog'; -import ViewModeToolbar from './view-mode-toolbar'; const propTypes = { path: PropTypes.string.isRequired, @@ -244,7 +243,6 @@ class DirOperationToolbar extends React.Component { {content} )} - {Utils.isDesktop() && } {this.state.isCreateFileDialogShow && ( - {Utils.isDesktop() && } {this.state.isMoveDialogShow && { - e.preventDefault(); - let id = e.target.id; - if (id === this.props.currentMode) { - return; - } - this.props.switchViewMode(id); - }; - - render() { - let baseClass = 'btn btn-secondary btn-icon sf-view-mode-btn '; - return ( - -
- - -
- {!this.props.isCustomPermission && ( -
- -
- )} -
- ); - } -} - -ViewModeToolbar.propTypes = propTypes; - -export default ViewModeToolbar; diff --git a/frontend/src/css/toolbar.css b/frontend/src/css/toolbar.css index 892a6c4b2d..8fbdcd5346 100644 --- a/frontend/src/css/toolbar.css +++ b/frontend/src/css/toolbar.css @@ -51,30 +51,36 @@ /* end file-operation toolbar */ /* begin view-mode toolbar */ -.detail-btn button, .sf-view-mode-btn { + width: 44px; + height: 32px; padding: 0; - height: 30px; - min-width: 2rem; - color: #aaa; - background-color: #fff; + background-color: #e5e6e7; + color: #444; + font-size: 14px; + line-height: 30px; border: 1px solid #ccc; - line-height: 29px; - font-size: 18px; - border-radius: 2px; + border-radius: 3px; } -.detail-btn button { - font-size: 15px; - padding-top: 1px; +.sf-view-mode-btn:hover { + background-color: #d2d3d3; } .sf-view-mode-btn.current-mode { - background-color: #ccc !important; - color: #fff !important; + background-color: #fff; } /* end view-mode toolbar */ +#cur-folder-more-op-toggle { + color: #444; + font-size: 14px; + height: 32px; + padding: 0; + line-height: 30px; + margin-left: 10px; +} + /* begin common-toolbar */ .common-toolbar { display: flex; diff --git a/frontend/src/pages/lib-content-view/lib-content-container.js b/frontend/src/pages/lib-content-view/lib-content-container.js index 958cad10d5..15a4906c15 100644 --- a/frontend/src/pages/lib-content-view/lib-content-container.js +++ b/frontend/src/pages/lib-content-view/lib-content-container.js @@ -9,6 +9,9 @@ import DirColumnView from '../../components/dir-view-mode/dir-column-view'; import '../../css/lib-content-view.css'; const propTypes = { + switchViewMode: PropTypes.func.isRequired, + isCustomPermission: PropTypes.bool, + pathPrefix: PropTypes.array.isRequired, isTreePanelShown: PropTypes.bool.isRequired, toggleTreePanel: PropTypes.func.isRequired, @@ -188,6 +191,9 @@ class LibContentContainer extends React.Component { sortOrder={this.props.sortOrder} sortItems={this.props.sortItems} toggleTreePanel={this.props.toggleTreePanel} + currentMode={this.props.currentMode} + switchViewMode={this.props.switchViewMode} + isCustomPermission={this.props.isCustomPermission} />
diff --git a/frontend/src/pages/lib-content-view/lib-content-toolbar.js b/frontend/src/pages/lib-content-view/lib-content-toolbar.js index 25ebedffc2..3c1203b127 100644 --- a/frontend/src/pages/lib-content-view/lib-content-toolbar.js +++ b/frontend/src/pages/lib-content-view/lib-content-toolbar.js @@ -2,11 +2,9 @@ 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 MultipleDirOperationToolbar from '../../components/toolbar/multiple-dir-operation-toolbar'; import ViewFileToolbar from '../../components/toolbar/view-file-toolbar'; -import { Utils } from '../../utils/utils'; const propTypes = { isViewFile: PropTypes.bool.isRequired, @@ -55,9 +53,6 @@ class LibContentToolbar extends React.Component { render() { - const { userPerm } = this.props; - const { isCustomPermission } = Utils.getUserPermission(userPerm); - if (this.props.isViewFile) { return ( @@ -76,7 +71,6 @@ class LibContentToolbar extends React.Component { showShareBtn={this.props.showShareBtn} repoTags={this.props.repoTags} /> -