1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-09-03 07:55:36 +00:00

Add option to only show folder in nav side panel (#6541)

* fix conflict

* remove redundant code

* add space at the end of css

* update ui
This commit is contained in:
Aries
2024-08-16 11:59:07 +08:00
committed by GitHub
parent 7543f195f3
commit 0d740cf138
9 changed files with 95 additions and 10 deletions

View File

@@ -58,6 +58,7 @@ class DirColumnNav extends React.Component {
isMoveDialogShow: false, isMoveDialogShow: false,
isMultipleOperation: false, isMultipleOperation: false,
operationList: [], operationList: [],
isDisplayFiles: false,
}; };
this.isNodeMenuShow = true; this.isNodeMenuShow = true;
} }
@@ -75,6 +76,7 @@ class DirColumnNav extends React.Component {
let menuList = []; let menuList = [];
menuList.push(TextTranslation.NEW_FOLDER); menuList.push(TextTranslation.NEW_FOLDER);
menuList.push(TextTranslation.NEW_FILE); menuList.push(TextTranslation.NEW_FILE);
menuList.push(TextTranslation.DISPLAY_FILES);
return menuList; return menuList;
}; };
@@ -127,6 +129,9 @@ class DirColumnNav extends React.Component {
case 'Open in New Tab': case 'Open in New Tab':
this.onOpenFile(node); this.onOpenFile(node);
break; break;
case 'Display files':
this.onDisplayFilesToggle();
break;
} }
}; };
@@ -186,6 +191,10 @@ class DirColumnNav extends React.Component {
window.open(newUrl, '_blank'); window.open(newUrl, '_blank');
}; };
onDisplayFilesToggle = () => {
this.setState({ isDisplayFiles: !this.state.isDisplayFiles });
};
checkDuplicatedName = (newName) => { checkDuplicatedName = (newName) => {
let node = this.state.opNode; let node = this.state.opNode;
// root node to new node conditions: parentNode is null, // root node to new node conditions: parentNode is null,
@@ -292,7 +301,7 @@ class DirColumnNav extends React.Component {
<Loading /> <Loading />
) : ( ) : (
<> <>
<TreeSection title={gettext('Files')} moreKey={{ name: 'files' }} moreOperations={this.state.operationList} moreOperationClick={this.onMoreOperationClick}> <TreeSection title={gettext('Files')} moreKey={{ name: 'files' }} moreOperations={this.state.operationList} moreOperationClick={this.onMoreOperationClick} isDisplayFiles={this.state.isDisplayFiles}>
<TreeView <TreeView
userPerm={userPerm} userPerm={userPerm}
isNodeMenuShow={this.isNodeMenuShow} isNodeMenuShow={this.isNodeMenuShow}
@@ -310,6 +319,7 @@ class DirColumnNav extends React.Component {
onItemsMove={onItemsMove} onItemsMove={onItemsMove}
repoID={repoID} repoID={repoID}
getMenuContainerSize={getMenuContainerSize} getMenuContainerSize={getMenuContainerSize}
isDisplayFiles={this.state.isDisplayFiles}
/> />
</TreeSection> </TreeSection>
<DirViews repoID={repoID} currentPath={currentPath} userPerm={userPerm} /> <DirViews repoID={repoID} currentPath={currentPath} userPerm={userPerm} />

View File

@@ -6,6 +6,8 @@ import { gettext } from '../../utils/constants';
import { Utils } from '../../utils/utils'; import { Utils } from '../../utils/utils';
import ModalPortal from '../modal-portal'; import ModalPortal from '../modal-portal';
import '../../css/item-dropdown-menu.css';
const propTypes = { const propTypes = {
tagName: PropTypes.string, tagName: PropTypes.string,
item: PropTypes.object.isRequired, item: PropTypes.object.isRequired,
@@ -17,6 +19,7 @@ const propTypes = {
freezeItem: PropTypes.func, freezeItem: PropTypes.func,
unfreezeItem: PropTypes.func, unfreezeItem: PropTypes.func,
menuStyle: PropTypes.object, menuStyle: PropTypes.object,
isDisplayFiles: PropTypes.bool,
}; };
class ItemDropdownMenu extends React.Component { class ItemDropdownMenu extends React.Component {
@@ -104,7 +107,7 @@ class ItemDropdownMenu extends React.Component {
}; };
onMenuItemClick = (event) => { onMenuItemClick = (event) => {
let operation = Utils.getEventData(event, 'toggle'); let operation = Utils.getEventData(event, 'toggle') ?? event.currentTarget.getAttribute('data-toggle');
let item = this.props.item; let item = this.props.item;
this.props.onMenuItemClick(operation, event, item); this.props.onMenuItemClick(operation, event, item);
}; };
@@ -168,7 +171,16 @@ class ItemDropdownMenu extends React.Component {
return <DropdownItem key={index} divider />; return <DropdownItem key={index} divider />;
} else { } else {
return ( return (
<DropdownItem key={index} data-toggle={menuItem.key} onClick={this.onMenuItemClick} onKeyDown={this.onMenuItemKeyDown}>{menuItem.value}</DropdownItem> <DropdownItem className='p-0' key={index} data-toggle={menuItem.key} onClick={this.onMenuItemClick} onKeyDown={this.onMenuItemKeyDown}>
<div className='dropdown-item-wrapper'>
<span className='dropdown-item-tick'>
{menuItem.value === 'Display files' && this.props.isDisplayFiles && (
<i className="sf2-icon-tick"></i>
)}
</span>
<span className='dropdown-item-content'>{menuItem.value}</span>
</div>
</DropdownItem>
); );
} }
})} })}

View File

@@ -6,7 +6,7 @@ import { isMobile } from '../../utils/utils';
import './index.css'; import './index.css';
const TreeSection = ({ title, children, moreKey, moreOperations, moreOperationClick, className }) => { const TreeSection = ({ title, children, moreKey, moreOperations, moreOperationClick, className, isDisplayFiles }) => {
const [showChildren, setShowChildren] = useState(true); const [showChildren, setShowChildren] = useState(true);
const [highlight, setHighlight] = useState(false); const [highlight, setHighlight] = useState(false);
const [freeze, setFreeze] = useState(false); const [freeze, setFreeze] = useState(false);
@@ -65,6 +65,7 @@ const TreeSection = ({ title, children, moreKey, moreOperations, moreOperationCl
getMenuList={() => validMoreOperations} getMenuList={() => validMoreOperations}
onMenuItemClick={moreOperationClick} onMenuItemClick={moreOperationClick}
menuStyle={isMobile ? { zIndex: 1050 } : {}} menuStyle={isMobile ? { zIndex: 1050 } : {}}
isDisplayFiles={isDisplayFiles}
/> />
</div> </div>
</> </>
@@ -90,6 +91,7 @@ TreeSection.propTypes = {
moreKey: PropTypes.object, moreKey: PropTypes.object,
moreOperationClick: PropTypes.func, moreOperationClick: PropTypes.func,
className: PropTypes.string, className: PropTypes.string,
isDisplayFiles: PropTypes.bool,
}; };
export default TreeSection; export default TreeSection;

View File

@@ -26,6 +26,7 @@ const propTypes = {
handleContextClick: PropTypes.func.isRequired, handleContextClick: PropTypes.func.isRequired,
onNodeDragEnter: PropTypes.func.isRequired, onNodeDragEnter: PropTypes.func.isRequired,
onNodeDragLeave: PropTypes.func.isRequired, onNodeDragLeave: PropTypes.func.isRequired,
isDisplayFiles: PropTypes.bool,
}; };
class TreeNodeView extends React.Component { class TreeNodeView extends React.Component {
@@ -264,6 +265,7 @@ class TreeNodeView extends React.Component {
onNodeDragEnter={this.props.onNodeDragEnter} onNodeDragEnter={this.props.onNodeDragEnter}
onNodeDragLeave={this.props.onNodeDragLeave} onNodeDragLeave={this.props.onNodeDragLeave}
handleContextClick={this.props.handleContextClick} handleContextClick={this.props.handleContextClick}
isDisplayFiles={this.props.isDisplayFiles}
/> />
); );
})} })}
@@ -279,6 +281,10 @@ class TreeNodeView extends React.Component {
hlClass = 'tree-node-hight-light'; hlClass = 'tree-node-hight-light';
} }
if (node.path !== '/' && type !== 'dir' && !this.props.isDisplayFiles) {
return '';
}
const { isCustomPermission } = Utils.getUserPermission(userPerm); const { isCustomPermission } = Utils.getUserPermission(userPerm);
return ( return (
<div className="tree-node"> <div className="tree-node">

View File

@@ -23,6 +23,7 @@ const propTypes = {
posX: PropTypes.number, posX: PropTypes.number,
posY: PropTypes.number, posY: PropTypes.number,
getMenuContainerSize: PropTypes.func, getMenuContainerSize: PropTypes.func,
isDisplayFiles: PropTypes.bool,
}; };
const LEFT_INDENT = 20; const LEFT_INDENT = 20;
@@ -343,6 +344,7 @@ class TreeView extends React.Component {
onNodeDragEnter={this.onNodeDragEnter} onNodeDragEnter={this.onNodeDragEnter}
onNodeDragLeave={this.onNodeDragLeave} onNodeDragLeave={this.onNodeDragLeave}
handleContextClick={this.handleContextClick} handleContextClick={this.handleContextClick}
isDisplayFiles={this.props.isDisplayFiles}
/> />
<ContextMenu <ContextMenu
id={'tree-node-contextmenu'} id={'tree-node-contextmenu'}

View File

@@ -3,6 +3,8 @@ import PropTypes from 'prop-types';
import { Dropdown, DropdownMenu, DropdownToggle, DropdownItem } from 'reactstrap'; import { Dropdown, DropdownMenu, DropdownToggle, DropdownItem } from 'reactstrap';
import { gettext } from '../utils/constants'; import { gettext } from '../utils/constants';
import '../css/view-modes.css';
const propTypes = { const propTypes = {
currentViewMode: PropTypes.string.isRequired, currentViewMode: PropTypes.string.isRequired,
switchViewMode: PropTypes.func.isRequired switchViewMode: PropTypes.func.isRequired
@@ -51,15 +53,15 @@ class ViewModes extends React.Component {
<DropdownMenu right={true} className="mt-1"> <DropdownMenu right={true} className="mt-1">
{options.map((item, index) => { {options.map((item, index) => {
return ( return (
<DropdownItem key={index} onClick={this.props.switchViewMode.bind(this, item.value)}> <DropdownItem className='p-0' key={index} onClick={this.props.switchViewMode.bind(this, item.value)}>
<div className="d-flex justify-content-between align-items-center"> <div className="view-modes-dropdown-wrapper">
<span className="mr-8 d-flex justify-content-between align-items-center"> <span className='view-modes-dropdown-tick'>
{currentViewMode === item.value && <i className="sf2-icon-tick"></i>}
</span>
<span className="view-modes-dropdown-content">
<span className={`sf3-font-${item.icon} sf3-font mr-2`}></span> <span className={`sf3-font-${item.icon} sf3-font mr-2`}></span>
<span>{item.text}</span> <span>{item.text}</span>
</span> </span>
<span>
{currentViewMode === item.value && <i className="sf2-icon-tick"></i>}
</span>
</div> </div>
</DropdownItem> </DropdownItem>
); );

View File

@@ -0,0 +1,25 @@
.dropdown-item-wrapper {
height: 100%;
display: flex;
align-items: center;
position: relative;
padding-left: 1.5rem;
padding-right: 1rem;
}
.dropdown-item-wrapper .dropdown-item-tick {
width: 1.5rem;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
position: absolute;
top: 0;
left: 0;
text-align: center;
color: #666666;
}
.dropdown-item:hover .dropdown-item-tick {
color: #fff;
}

View File

@@ -0,0 +1,25 @@
.view-modes-dropdown-wrapper {
position: relative;
display: flex;
justify-content: space-between;
align-items: center;
padding-left: 1.5rem;
padding-right: 1rem;
text-align: center;
}
.view-modes-dropdown-tick {
width: 1.5rem;
height: 1.5rem;
position: absolute;
top: 0;
left: 0;
display: flex;
justify-content: center;
align-items: center;
}
.view-modes-dropdown-content {
display: flex;
align-items: center;
}

View File

@@ -35,6 +35,7 @@ const TextTranslation = {
'TAGS': { key: 'Tags', value: gettext('Tags') }, 'TAGS': { key: 'Tags', value: gettext('Tags') },
'TRASH': { key: 'Trash', value: gettext('Trash') }, 'TRASH': { key: 'Trash', value: gettext('Trash') },
'ONLYOFFICE_CONVERT': { key: 'Convert with ONLYOFFICE', value: gettext('Convert with ONLYOFFICE') }, 'ONLYOFFICE_CONVERT': { key: 'Convert with ONLYOFFICE', value: gettext('Convert with ONLYOFFICE') },
'DISPLAY_FILES': { key: 'Display files', value: gettext('Display files') },
}; };
export default TextTranslation; export default TextTranslation;