mirror of
https://github.com/haiwen/seahub.git
synced 2025-08-31 22:54:11 +00:00
[dir view] redesigned the toolbar for the current folder (#6117)
* [dir view] redesigned the toolbar for the current folder * [dir view] toolbar for the current folder: code cleanup * [dir view] toolbar for the current folder: updated the 'upload' icon; modified UI details
This commit is contained in:
@@ -22,8 +22,7 @@ const propTypes = {
|
||||
onUploadFile: PropTypes.func.isRequired,
|
||||
onUploadFolder: PropTypes.func.isRequired,
|
||||
direntList: PropTypes.array.isRequired,
|
||||
currentMode: PropTypes.string.isRequired,
|
||||
switchViewMode: PropTypes.func.isRequired,
|
||||
children: PropTypes.object
|
||||
};
|
||||
|
||||
class DirOperationToolbar extends React.Component {
|
||||
@@ -34,68 +33,29 @@ class DirOperationToolbar extends React.Component {
|
||||
fileType: '.md',
|
||||
isCreateFileDialogShow: false,
|
||||
isCreateFolderDialogShow: false,
|
||||
isUploadMenuShow: false,
|
||||
isCreateMenuShow: false,
|
||||
isShareDialogShow: false,
|
||||
operationMenuStyle: '',
|
||||
isDesktopMenuOpen: false,
|
||||
isMobileOpMenuOpen: false
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
document.addEventListener('click', this.hideOperationMenu);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
document.removeEventListener('click', this.hideOperationMenu);
|
||||
}
|
||||
toggleDesktopOpMenu = () => {
|
||||
this.setState({isDesktopMenuOpen: !this.state.isDesktopMenuOpen});
|
||||
};
|
||||
|
||||
toggleMobileOpMenu = () => {
|
||||
this.setState({isMobileOpMenuOpen: !this.state.isMobileOpMenuOpen});
|
||||
};
|
||||
|
||||
hideOperationMenu = () => {
|
||||
this.setState({
|
||||
isUploadMenuShow: false,
|
||||
isCreateMenuShow: false,
|
||||
});
|
||||
};
|
||||
|
||||
toggleOperationMenu = (e) => {
|
||||
e.nativeEvent.stopImmediatePropagation();
|
||||
let targetRect = e.target.getBoundingClientRect();
|
||||
let left = targetRect.left;
|
||||
let top = targetRect.bottom;
|
||||
let style = {position: 'fixed', display: 'block', left: left, top: top};
|
||||
this.setState({operationMenuStyle: style});
|
||||
};
|
||||
|
||||
onUploadClick = (e) => {
|
||||
this.toggleOperationMenu(e);
|
||||
this.setState({
|
||||
isUploadMenuShow: !this.state.isUploadMenuShow,
|
||||
isCreateMenuShow: false,
|
||||
});
|
||||
};
|
||||
|
||||
onUploadFile = (e) => {
|
||||
this.setState({isUploadMenuShow: false});
|
||||
this.props.onUploadFile(e);
|
||||
};
|
||||
|
||||
onUploadFolder = (e) => {
|
||||
this.setState({isUploadMenuShow: false});
|
||||
this.props.onUploadFolder(e);
|
||||
};
|
||||
|
||||
onCreateClick = (e) => {
|
||||
this.toggleOperationMenu(e);
|
||||
this.setState({
|
||||
isCreateMenuShow: !this.state.isCreateMenuShow,
|
||||
isUploadMenuShow: false,
|
||||
});
|
||||
};
|
||||
|
||||
onShareClick = () => {
|
||||
this.setState({
|
||||
isShareDialogShow: !this.state.isShareDialogShow
|
||||
@@ -161,6 +121,41 @@ class DirOperationToolbar extends React.Component {
|
||||
return isDuplicated;
|
||||
};
|
||||
|
||||
onDropdownToggleKeyDown = (e) => {
|
||||
if (e.key == 'Enter' || e.key == 'Space') {
|
||||
this.toggleDesktopOpMenu();
|
||||
}
|
||||
};
|
||||
|
||||
onDropDownMouseMove = (e) => {
|
||||
if (this.state.isSubMenuShown && e.target && e.target.className === 'dropdown-item') {
|
||||
this.setState({
|
||||
isSubMenuShown: false
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
toggleSubMenu = (e) => {
|
||||
e.stopPropagation();
|
||||
this.setState({
|
||||
isSubMenuShown: !this.state.isSubMenuShown}, () => {
|
||||
this.toggleDesktopOpMenu();
|
||||
});
|
||||
};
|
||||
|
||||
toggleSubMenuShown = (item) => {
|
||||
this.setState({
|
||||
isSubMenuShown: true,
|
||||
currentItem: item.text
|
||||
});
|
||||
};
|
||||
|
||||
onMenuItemKeyDown = (item, e) => {
|
||||
if (e.key == 'Enter' || e.key == 'Space') {
|
||||
item.onClick();
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
let { path, repoName, userPerm } = this.props;
|
||||
|
||||
@@ -179,42 +174,108 @@ class DirOperationToolbar extends React.Component {
|
||||
let content = null;
|
||||
if (Utils.isDesktop()) {
|
||||
const { showShareBtn, repoEncrypted } = this.props;
|
||||
let opList = [];
|
||||
if (canUpload) {
|
||||
if (Utils.isSupportUploadFolder()) {
|
||||
opList.push({
|
||||
'icon': 'upload-files',
|
||||
'text': gettext('Upload'),
|
||||
subOpList: [
|
||||
{'text': gettext('Upload Files'), 'onClick': this.onUploadFile},
|
||||
{'text': gettext('Upload Folder'), 'onClick': this.onUploadFolder}
|
||||
]
|
||||
});
|
||||
} else {
|
||||
opList.push({'text': gettext('Upload'), 'onClick': this.onUploadFile});
|
||||
}
|
||||
}
|
||||
|
||||
if (canCreate) {
|
||||
let newSubOpList = [
|
||||
{'text': gettext('New Folder'), 'onClick': this.onCreateFolderToggle},
|
||||
{'text': gettext('New File'), 'onClick': this.onCreateFileToggle},
|
||||
'Divider',
|
||||
{'text': gettext('New Markdown File'), 'onClick': this.onCreateMarkdownToggle},
|
||||
{'text': gettext('New Excel File'), 'onClick': this.onCreateExcelToggle},
|
||||
{'text': gettext('New PowerPoint File'), 'onClick': this.onCreatePPTToggle},
|
||||
{'text': gettext('New Word File'), 'onClick': this.onCreateWordToggle}
|
||||
];
|
||||
if (enableSeadoc && !repoEncrypted) {
|
||||
newSubOpList.push({'text': gettext('New SeaDoc File'), 'onClick': this.onCreateSeaDocToggle});
|
||||
}
|
||||
opList.push({
|
||||
'icon': 'new',
|
||||
'text': gettext('New'),
|
||||
subOpList: newSubOpList
|
||||
});
|
||||
}
|
||||
|
||||
if (showShareBtn) {
|
||||
opList.push({
|
||||
'icon': 'share',
|
||||
'text': gettext('Share'),
|
||||
'onClick': this.onShareClick
|
||||
});
|
||||
}
|
||||
|
||||
content = (
|
||||
<Fragment>
|
||||
{canUpload && (
|
||||
<Fragment>
|
||||
{Utils.isSupportUploadFolder() ?
|
||||
<Fragment>
|
||||
<button className="btn btn-secondary operation-item" onClick={this.onUploadClick} aria-haspopup="true" aria-expanded={this.state.isUploadMenuShow} aria-controls="upload-menu">{gettext('Upload')}</button>
|
||||
{this.state.isUploadMenuShow && (
|
||||
<div className="menu dropdown-menu" style={this.state.operationMenuStyle} role="menu" id="upload-menu">
|
||||
<button type="button" className="dropdown-item" onClick={this.onUploadFile} role="menuitem">{gettext('Upload Files')}</button>
|
||||
<button type="button" className="dropdown-item" onClick={this.onUploadFolder} role="menuitem">{gettext('Upload Folder')}</button>
|
||||
</div>
|
||||
)}
|
||||
</Fragment>
|
||||
:
|
||||
<button className="btn btn-secondary operation-item" title={gettext('Upload')} onClick={this.onUploadFile}>{gettext('Upload')}</button>}
|
||||
</Fragment>
|
||||
)}
|
||||
{canCreate &&
|
||||
<Fragment>
|
||||
<button className="btn btn-secondary operation-item" onClick={this.onCreateClick} aria-haspopup="true" aria-expanded={this.state.isUploadMenuShow} aria-controls="new-menu">{gettext('New')}</button>
|
||||
{this.state.isCreateMenuShow && (
|
||||
<div className="menu dropdown-menu" style={this.state.operationMenuStyle} role="menu" id="new-menu">
|
||||
<button className="dropdown-item" onClick={this.onCreateFolderToggle} role="menuitem">{gettext('New Folder')}</button>
|
||||
<button className="dropdown-item" onClick={this.onCreateFileToggle}>{gettext('New File')}</button>
|
||||
<div className="dropdown-divider"></div>
|
||||
<button className="dropdown-item" onClick={this.onCreateMarkdownToggle} role="menuitem">{gettext('New Markdown File')}</button>
|
||||
<button className="dropdown-item" onClick={this.onCreateExcelToggle} role="menuitem">{gettext('New Excel File')}</button>
|
||||
<button className="dropdown-item" onClick={this.onCreatePPTToggle} role="menuitem">{gettext('New PowerPoint File')}</button>
|
||||
<button className="dropdown-item" onClick={this.onCreateWordToggle} role="menuitem">{gettext('New Word File')}</button>
|
||||
{enableSeadoc && !repoEncrypted && <button className="dropdown-item" onClick={this.onCreateSeaDocToggle} role="menuitem">{gettext('New SeaDoc File')} (beta)</button>}
|
||||
</div>
|
||||
)}
|
||||
</Fragment>
|
||||
}
|
||||
{showShareBtn && <button className="btn btn-secondary operation-item" title={gettext('Share')} onClick={this.onShareClick}>{gettext('Share')}</button>}
|
||||
<Dropdown isOpen={this.state.isDesktopMenuOpen} toggle={this.toggleDesktopOpMenu}>
|
||||
<DropdownToggle
|
||||
tag="div"
|
||||
role="button"
|
||||
className="path-item"
|
||||
title={gettext('More operations')}
|
||||
aria-label={gettext('More operations')}
|
||||
onClick={this.toggleDesktopOpMenu}
|
||||
onKeyDown={this.onDropdownToggleKeyDown}
|
||||
data-toggle="dropdown"
|
||||
>
|
||||
{this.props.children}
|
||||
<i className="sf3-font-drop-down sf3-font ml-1 path-item-dropdown-toggle"></i>
|
||||
</DropdownToggle>
|
||||
<DropdownMenu onMouseMove={this.onDropDownMouseMove} style={{'width': '200px'}}>
|
||||
{opList.map((item, index)=> {
|
||||
if (item == 'Divider') {
|
||||
return <DropdownItem key={index} divider />;
|
||||
} else if (item.subOpList) {
|
||||
return (
|
||||
<Dropdown
|
||||
key={index}
|
||||
direction="right"
|
||||
className="w-100"
|
||||
isOpen={this.state.isSubMenuShown && this.state.currentItem == item.text}
|
||||
toggle={this.toggleSubMenu}
|
||||
onMouseMove={(e) => {e.stopPropagation();}}
|
||||
>
|
||||
<DropdownToggle
|
||||
caret
|
||||
className="dropdown-item font-weight-normal rounded-0 d-flex align-items-center pr-2"
|
||||
onMouseEnter={this.toggleSubMenuShown.bind(this, item)}
|
||||
>
|
||||
<i className={`sf3-font-${item.icon} sf3-font mr-2 dropdown-item-icon`}></i>
|
||||
<span className="mr-auto">{item.text}</span>
|
||||
</DropdownToggle>
|
||||
<DropdownMenu>
|
||||
{item.subOpList.map((item, index)=> {
|
||||
if (item == 'Divider') {
|
||||
return <DropdownItem key={index} divider />;
|
||||
} else {
|
||||
return (<DropdownItem key={index} onClick={item.onClick} onKeyDown={this.onMenuItemKeyDown.bind(this, item)}>{item.text}</DropdownItem>);
|
||||
}
|
||||
})}
|
||||
</DropdownMenu>
|
||||
</Dropdown>
|
||||
);
|
||||
} else {
|
||||
return (<DropdownItem key={index} onClick={item.onClick} onKeyDown={this.onMenuItemKeyDown.bind(this, item)}>
|
||||
<i className={`sf3-font-${item.icon} sf3-font mr-2 dropdown-item-icon`}></i>
|
||||
{item.text}
|
||||
</DropdownItem>);
|
||||
}
|
||||
})}
|
||||
</DropdownMenu>
|
||||
</Dropdown>
|
||||
</Fragment>
|
||||
);
|
||||
} else {
|
||||
|
Reference in New Issue
Block a user