2019-02-13 14:21:39 +08:00
|
|
|
import React from 'react';
|
|
|
|
import PropTypes from 'prop-types';
|
|
|
|
import { Dropdown, DropdownMenu, DropdownToggle, DropdownItem } from 'reactstrap';
|
2025-01-02 11:22:25 +08:00
|
|
|
import { gettext, isPro, folderPermEnabled, enableRepoSnapshotLabel, enableResetEncryptedRepoPassword, isEmailConfigured, enableMultipleOfficeSuite } from '../../utils/constants';
|
2019-06-04 16:18:32 +08:00
|
|
|
import { Utils } from '../../utils/utils';
|
2025-03-14 17:09:04 +08:00
|
|
|
import MobileItemMenu from '../../components/mobile-item-menu';
|
2019-02-13 14:21:39 +08:00
|
|
|
|
|
|
|
const propTypes = {
|
|
|
|
isPC: PropTypes.bool,
|
|
|
|
repo: PropTypes.object.isRequired,
|
2019-07-16 07:55:55 +08:00
|
|
|
isStarred: PropTypes.bool,
|
2025-05-12 16:54:52 +08:00
|
|
|
onFreezedItem: PropTypes.func,
|
|
|
|
onUnfreezedItem: PropTypes.func,
|
2019-02-13 14:21:39 +08:00
|
|
|
onMenuItemClick: PropTypes.func.isRequired,
|
|
|
|
};
|
|
|
|
|
|
|
|
class MylibRepoMenu extends React.Component {
|
|
|
|
|
|
|
|
constructor(props) {
|
|
|
|
super(props);
|
|
|
|
this.state = {
|
|
|
|
isItemMenuShow: false,
|
2023-10-13 22:47:38 +08:00
|
|
|
isAdvancedMenuShown: false
|
2019-02-13 14:21:39 +08:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
onMenuItemClick = (e) => {
|
2025-05-12 16:54:52 +08:00
|
|
|
const operation = Utils.getEventData(e, 'toggle');
|
2019-02-13 14:21:39 +08:00
|
|
|
this.props.onMenuItemClick(operation);
|
2023-09-13 08:40:50 +08:00
|
|
|
};
|
2019-02-13 14:21:39 +08:00
|
|
|
|
2021-09-22 10:48:25 +08:00
|
|
|
onMenuItemKeyDown = (e) => {
|
|
|
|
if (e.key == 'Enter' || e.key == 'Space') {
|
|
|
|
this.onMenuItemClick(e);
|
|
|
|
}
|
2023-09-13 08:40:50 +08:00
|
|
|
};
|
2021-09-22 10:48:25 +08:00
|
|
|
|
2019-02-13 14:21:39 +08:00
|
|
|
onDropdownToggleClick = (e) => {
|
|
|
|
this.toggleOperationMenu(e);
|
2023-09-13 08:40:50 +08:00
|
|
|
};
|
2019-02-13 14:21:39 +08:00
|
|
|
|
2021-09-22 10:48:25 +08:00
|
|
|
onDropdownToggleKeyDown = (e) => {
|
|
|
|
if (e.key == 'Enter' || e.key == 'Space') {
|
|
|
|
this.onDropdownToggleClick(e);
|
|
|
|
}
|
2023-09-13 08:40:50 +08:00
|
|
|
};
|
2021-09-22 10:48:25 +08:00
|
|
|
|
2019-02-13 14:21:39 +08:00
|
|
|
toggleOperationMenu = (e) => {
|
2025-05-12 16:54:52 +08:00
|
|
|
const { isLibView } = this.props;
|
|
|
|
if (isLibView) {
|
|
|
|
this.setState({ isItemMenuShow: !this.state.isItemMenuShow });
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-02-13 14:21:39 +08:00
|
|
|
let dataset = e.target ? e.target.dataset : null;
|
|
|
|
if (dataset && dataset.toggle && dataset.toggle === 'Rename') {
|
2024-07-18 11:58:42 +08:00
|
|
|
this.setState({ isItemMenuShow: !this.state.isItemMenuShow });
|
2019-02-13 14:21:39 +08:00
|
|
|
return;
|
|
|
|
}
|
2020-11-02 13:56:35 +08:00
|
|
|
|
2019-02-13 14:21:39 +08:00
|
|
|
this.setState(
|
2024-07-18 11:58:42 +08:00
|
|
|
{ isItemMenuShow: !this.state.isItemMenuShow },
|
2019-02-13 14:21:39 +08:00
|
|
|
() => {
|
|
|
|
if (this.state.isItemMenuShow) {
|
|
|
|
this.props.onFreezedItem();
|
|
|
|
} else {
|
|
|
|
this.props.onUnfreezedItem();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
);
|
2023-09-13 08:40:50 +08:00
|
|
|
};
|
2019-02-13 14:21:39 +08:00
|
|
|
|
2023-10-13 22:47:38 +08:00
|
|
|
toggleAdvancedMenuShown = (e) => {
|
|
|
|
this.setState({ isAdvancedMenuShown: true });
|
|
|
|
};
|
|
|
|
|
|
|
|
toggleAdvancedMenu = (e) => {
|
|
|
|
e.stopPropagation();
|
|
|
|
this.setState({ isAdvancedMenuShown: !this.state.isAdvancedMenuShown }, () => {
|
|
|
|
this.toggleOperationMenu(e);
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
onDropDownMouseMove = (e) => {
|
|
|
|
if (this.state.isAdvancedMenuShown && e.target && e.target.className === 'dropdown-item') {
|
|
|
|
this.setState({
|
|
|
|
isAdvancedMenuShown: false
|
|
|
|
});
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2019-02-13 14:21:39 +08:00
|
|
|
generatorOperations = () => {
|
|
|
|
let repo = this.props.repo;
|
2020-03-20 13:29:00 +08:00
|
|
|
let showResetPasswordMenuItem = isPro && repo.encrypted && enableResetEncryptedRepoPassword && isEmailConfigured;
|
2020-11-02 13:56:35 +08:00
|
|
|
let operations = ['Rename', 'Transfer'];
|
2020-03-09 21:13:16 +08:00
|
|
|
if (folderPermEnabled) {
|
|
|
|
operations.push('Folder Permission');
|
|
|
|
}
|
2023-08-24 10:18:40 +08:00
|
|
|
operations.push('Share Admin', 'Divider');
|
2023-02-03 09:51:18 +08:00
|
|
|
|
2019-02-13 14:21:39 +08:00
|
|
|
if (repo.encrypted) {
|
|
|
|
operations.push('Change Password');
|
|
|
|
}
|
|
|
|
if (showResetPasswordMenuItem) {
|
2019-05-15 14:56:46 +08:00
|
|
|
operations.push('Reset Password');
|
2019-02-13 14:21:39 +08:00
|
|
|
}
|
2023-02-03 09:51:18 +08:00
|
|
|
|
2024-11-06 20:12:39 +08:00
|
|
|
operations.push('Divider', 'Advanced');
|
2023-10-19 13:43:53 +08:00
|
|
|
// Remove adjacent excess 'Divider'
|
|
|
|
for (let i = 0; i < operations.length; i++) {
|
|
|
|
if (operations[i] === 'Divider' && operations[i + 1] === 'Divider') {
|
|
|
|
operations.splice(i, 1);
|
|
|
|
i--;
|
|
|
|
}
|
|
|
|
}
|
2023-10-13 22:47:38 +08:00
|
|
|
return operations;
|
|
|
|
};
|
|
|
|
|
|
|
|
getAdvancedOperations = () => {
|
|
|
|
const operations = [];
|
2023-07-11 15:19:39 +08:00
|
|
|
operations.push('API Token');
|
2019-02-13 14:21:39 +08:00
|
|
|
if (this.props.isPC && enableRepoSnapshotLabel) {
|
2019-06-27 15:35:01 +08:00
|
|
|
operations.push('Label Current State');
|
2019-02-13 14:21:39 +08:00
|
|
|
}
|
2025-01-02 11:22:25 +08:00
|
|
|
if (enableMultipleOfficeSuite && isPro) {
|
|
|
|
operations.push('Office Suite');
|
|
|
|
}
|
2019-02-13 14:21:39 +08:00
|
|
|
return operations;
|
2023-09-13 08:40:50 +08:00
|
|
|
};
|
2019-02-13 14:21:39 +08:00
|
|
|
|
|
|
|
translateOperations = (item) => {
|
|
|
|
let translateResult = '';
|
2024-07-18 11:58:42 +08:00
|
|
|
switch (item) {
|
2019-07-16 07:55:55 +08:00
|
|
|
case 'Star':
|
|
|
|
translateResult = gettext('Star');
|
|
|
|
break;
|
|
|
|
case 'Unstar':
|
|
|
|
translateResult = gettext('Unstar');
|
|
|
|
break;
|
2019-02-13 14:21:39 +08:00
|
|
|
case 'Share':
|
|
|
|
translateResult = gettext('Share');
|
|
|
|
break;
|
|
|
|
case 'Delete':
|
|
|
|
translateResult = gettext('Delete');
|
|
|
|
break;
|
|
|
|
case 'Rename':
|
|
|
|
translateResult = gettext('Rename');
|
|
|
|
break;
|
|
|
|
case 'Transfer':
|
|
|
|
translateResult = gettext('Transfer');
|
|
|
|
break;
|
|
|
|
case 'Change Password':
|
|
|
|
translateResult = gettext('Change Password');
|
|
|
|
break;
|
|
|
|
case 'Reset Password':
|
|
|
|
translateResult = gettext('Reset Password');
|
|
|
|
break;
|
|
|
|
case 'Folder Permission':
|
|
|
|
translateResult = gettext('Folder Permission');
|
|
|
|
break;
|
2019-06-27 15:35:01 +08:00
|
|
|
case 'Label Current State':
|
|
|
|
translateResult = gettext('Label Current State');
|
2019-02-13 14:21:39 +08:00
|
|
|
break;
|
2019-11-04 15:47:20 +08:00
|
|
|
case 'API Token':
|
2019-11-29 15:17:00 +08:00
|
|
|
translateResult = 'API Token'; // translation is not needed here
|
2019-11-04 15:47:20 +08:00
|
|
|
break;
|
2023-08-24 10:18:40 +08:00
|
|
|
case 'Share Admin':
|
|
|
|
translateResult = gettext('Share Admin');
|
2020-03-09 16:30:27 +08:00
|
|
|
break;
|
2023-10-13 22:47:38 +08:00
|
|
|
case 'Advanced':
|
|
|
|
translateResult = gettext('Advanced');
|
|
|
|
break;
|
2025-01-02 11:22:25 +08:00
|
|
|
case 'Office Suite':
|
|
|
|
translateResult = gettext('Office Suite');
|
|
|
|
break;
|
2019-02-13 14:21:39 +08:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return translateResult;
|
2023-09-13 08:40:50 +08:00
|
|
|
};
|
2019-02-13 14:21:39 +08:00
|
|
|
|
|
|
|
render() {
|
|
|
|
let operations = this.generatorOperations();
|
2023-10-13 22:47:38 +08:00
|
|
|
const advancedOperations = this.getAdvancedOperations();
|
2019-02-13 14:21:39 +08:00
|
|
|
|
2025-05-12 16:54:52 +08:00
|
|
|
const { children, isLibView } = this.props;
|
|
|
|
|
2019-02-13 14:21:39 +08:00
|
|
|
// pc menu
|
|
|
|
if (this.props.isPC) {
|
|
|
|
return (
|
2025-05-12 16:54:52 +08:00
|
|
|
<Dropdown
|
|
|
|
isOpen={this.state.isItemMenuShow}
|
|
|
|
toggle={this.toggleOperationMenu}
|
|
|
|
direction={isLibView ? 'end' : 'down'}
|
|
|
|
className={isLibView ? 'd-block' : ''}
|
|
|
|
>
|
2020-11-02 13:56:35 +08:00
|
|
|
<DropdownToggle
|
2025-05-31 12:01:08 +08:00
|
|
|
tag={isLibView ? 'div' : 'i'}
|
|
|
|
className={isLibView ? 'dir-others-item' : 'op-icon sf3-font-more sf3-font'}
|
2021-09-29 15:23:02 +08:00
|
|
|
role="button"
|
|
|
|
tabIndex="0"
|
2025-05-12 16:54:52 +08:00
|
|
|
title={isLibView ? gettext('More') : gettext('More operations')}
|
2024-01-03 18:08:24 +08:00
|
|
|
aria-label={gettext('More operations')}
|
2021-09-22 10:48:25 +08:00
|
|
|
onClick={this.onDropdownToggleClick}
|
|
|
|
onKeyDown={this.onDropdownToggleKeyDown}
|
2020-11-02 13:56:35 +08:00
|
|
|
data-toggle="dropdown"
|
2025-05-12 16:54:52 +08:00
|
|
|
>
|
2025-05-31 12:01:08 +08:00
|
|
|
{children}
|
2025-05-12 16:54:52 +08:00
|
|
|
</DropdownToggle>
|
|
|
|
<DropdownMenu onMouseMove={this.onDropDownMouseMove} container={isLibView ? 'body' : ''}>
|
2024-07-18 11:58:42 +08:00
|
|
|
{operations.map((item, index) => {
|
2020-03-09 21:13:16 +08:00
|
|
|
if (item == 'Divider') {
|
2020-11-02 13:56:35 +08:00
|
|
|
return <DropdownItem key={index} divider />;
|
2023-10-13 22:47:38 +08:00
|
|
|
} else if (item == 'Advanced') {
|
|
|
|
return (
|
|
|
|
<Dropdown
|
|
|
|
key={index}
|
|
|
|
direction="right"
|
|
|
|
className="w-100"
|
|
|
|
isOpen={this.state.isAdvancedMenuShown}
|
|
|
|
toggle={this.toggleAdvancedMenu}
|
|
|
|
onMouseMove={(e) => {e.stopPropagation();}}
|
|
|
|
>
|
|
|
|
<DropdownToggle
|
2025-02-14 14:04:25 +08:00
|
|
|
tag="span"
|
2023-10-18 16:58:10 +08:00
|
|
|
className="dropdown-item font-weight-normal rounded-0 d-flex justify-content-between align-items-center pr-2"
|
2023-10-13 22:47:38 +08:00
|
|
|
onMouseEnter={this.toggleAdvancedMenuShown}
|
|
|
|
>
|
|
|
|
{this.translateOperations(item)}
|
2024-06-21 12:07:58 +08:00
|
|
|
<i className="sf3-font-down sf3-font rotate-270"></i>
|
2023-10-13 22:47:38 +08:00
|
|
|
</DropdownToggle>
|
|
|
|
<DropdownMenu>
|
2024-07-18 11:58:42 +08:00
|
|
|
{advancedOperations.map((item, index) => {
|
2023-10-13 22:47:38 +08:00
|
|
|
return (<DropdownItem key={index} data-toggle={item} onClick={this.onMenuItemClick} onKeyDown={this.onMenuItemKeyDown}>{this.translateOperations(item)}</DropdownItem>);
|
|
|
|
})}
|
|
|
|
</DropdownMenu>
|
|
|
|
</Dropdown>
|
|
|
|
);
|
2020-03-09 21:13:16 +08:00
|
|
|
} else {
|
2021-09-22 10:48:25 +08:00
|
|
|
return (<DropdownItem key={index} data-toggle={item} onClick={this.onMenuItemClick} onKeyDown={this.onMenuItemKeyDown}>{this.translateOperations(item)}</DropdownItem>);
|
2020-03-09 21:13:16 +08:00
|
|
|
}
|
2019-02-13 14:21:39 +08:00
|
|
|
})}
|
|
|
|
</DropdownMenu>
|
|
|
|
</Dropdown>
|
2019-05-15 14:56:46 +08:00
|
|
|
);
|
2019-02-13 14:21:39 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// mobile menu
|
2023-10-13 22:47:38 +08:00
|
|
|
operations.pop(); // removed the last item 'Advanced'
|
2019-02-13 14:21:39 +08:00
|
|
|
operations.unshift('Delete');
|
2019-07-16 07:55:55 +08:00
|
|
|
operations.unshift('Share');
|
|
|
|
this.props.isStarred ? operations.unshift('Unstar') : operations.unshift('Star');
|
2019-02-13 14:21:39 +08:00
|
|
|
|
|
|
|
return (
|
2025-03-14 17:09:04 +08:00
|
|
|
<MobileItemMenu isOpen={this.state.isItemMenuShow} toggle={this.toggleOperationMenu}>
|
|
|
|
{operations.filter(item => item != 'Divider').map((item, index) => {
|
|
|
|
return (<DropdownItem key={index} className="mobile-menu-item" data-toggle={item} onClick={this.onMenuItemClick}>{this.translateOperations(item)}</DropdownItem>);
|
|
|
|
})}
|
|
|
|
</MobileItemMenu>
|
2019-02-13 14:21:39 +08:00
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
MylibRepoMenu.propTypes = propTypes;
|
|
|
|
|
|
|
|
export default MylibRepoMenu;
|