mirror of
https://github.com/haiwen/seahub.git
synced 2025-09-13 13:50:07 +00:00
Add context menu when no file (#7344)
* dirent none view support create folder * fix permission
This commit is contained in:
@@ -50,6 +50,9 @@ class DirGridView extends React.Component {
|
|||||||
isDirentListLoading={this.props.isDirentListLoading}
|
isDirentListLoading={this.props.isDirentListLoading}
|
||||||
onAddFile={this.props.onAddFile}
|
onAddFile={this.props.onAddFile}
|
||||||
currentRepoInfo={this.props.currentRepoInfo}
|
currentRepoInfo={this.props.currentRepoInfo}
|
||||||
|
userPerm={this.props.userPerm}
|
||||||
|
onAddFolder={this.props.onAddFolder}
|
||||||
|
getMenuContainerSize={this.props.getMenuContainerSize}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@@ -57,6 +57,9 @@ class DirListView extends React.Component {
|
|||||||
isDirentListLoading={this.props.isDirentListLoading}
|
isDirentListLoading={this.props.isDirentListLoading}
|
||||||
onAddFile={this.props.onAddFile}
|
onAddFile={this.props.onAddFile}
|
||||||
currentRepoInfo={this.props.currentRepoInfo}
|
currentRepoInfo={this.props.currentRepoInfo}
|
||||||
|
userPerm={this.props.userPerm}
|
||||||
|
onAddFolder={this.props.onAddFolder}
|
||||||
|
getMenuContainerSize={this.props.getMenuContainerSize}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@@ -1,9 +1,14 @@
|
|||||||
import React, { Fragment } from 'react';
|
import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { enableSeadoc, gettext } from '../../utils/constants';
|
import { enableSeadoc, gettext, enableWhiteboard } from '../../utils/constants';
|
||||||
import Loading from '../loading';
|
import Loading from '../loading';
|
||||||
import ModalPortal from '../modal-portal';
|
import ModalPortal from '../modal-portal';
|
||||||
import CreateFile from '../../components/dialog/create-file-dialog';
|
import CreateFile from '../../components/dialog/create-file-dialog';
|
||||||
|
import CreateFolder from '../dialog/create-folder-dialog';
|
||||||
|
import TextTranslation from '../../utils/text-translation';
|
||||||
|
import { Utils } from '../../utils/utils';
|
||||||
|
import ContextMenu from '../context-menu/context-menu';
|
||||||
|
import { hideMenu, showMenu } from '../context-menu/actions';
|
||||||
|
|
||||||
import '../../css/tip-for-new-file.css';
|
import '../../css/tip-for-new-file.css';
|
||||||
|
|
||||||
@@ -11,7 +16,10 @@ const propTypes = {
|
|||||||
path: PropTypes.string.isRequired,
|
path: PropTypes.string.isRequired,
|
||||||
isDirentListLoading: PropTypes.bool.isRequired,
|
isDirentListLoading: PropTypes.bool.isRequired,
|
||||||
currentRepoInfo: PropTypes.object.isRequired,
|
currentRepoInfo: PropTypes.object.isRequired,
|
||||||
onAddFile: PropTypes.func.isRequired
|
onAddFile: PropTypes.func.isRequired,
|
||||||
|
onAddFolder: PropTypes.func.isRequired,
|
||||||
|
getMenuContainerSize: PropTypes.func.isRequired,
|
||||||
|
userPerm: PropTypes.string,
|
||||||
};
|
};
|
||||||
|
|
||||||
class DirentNoneView extends React.Component {
|
class DirentNoneView extends React.Component {
|
||||||
@@ -21,9 +29,19 @@ class DirentNoneView extends React.Component {
|
|||||||
this.state = {
|
this.state = {
|
||||||
fileType: '',
|
fileType: '',
|
||||||
isCreateFileDialogShow: false,
|
isCreateFileDialogShow: false,
|
||||||
|
isCreateFolderDialogShow: false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onCreateFolderToggle = () => {
|
||||||
|
this.setState({ isCreateFolderDialogShow: !this.state.isCreateFolderDialogShow });
|
||||||
|
};
|
||||||
|
|
||||||
|
onAddFolder = (dirPath) => {
|
||||||
|
this.setState({ isCreateFolderDialogShow: false });
|
||||||
|
this.props.onAddFolder(dirPath);
|
||||||
|
};
|
||||||
|
|
||||||
onCreateNewFile = (type) => {
|
onCreateNewFile = (type) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
fileType: type,
|
fileType: type,
|
||||||
@@ -42,6 +60,104 @@ class DirentNoneView extends React.Component {
|
|||||||
return false; // current repo is null, and unnecessary to check duplicated name
|
return false; // current repo is null, and unnecessary to check duplicated name
|
||||||
};
|
};
|
||||||
|
|
||||||
|
onContainerContextMenu = (event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
let permission = this.props.userPerm;
|
||||||
|
const { isCustomPermission, customPermission } = Utils.getUserPermission(permission);
|
||||||
|
if (permission !== 'admin' && permission !== 'rw' && !isCustomPermission) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const {
|
||||||
|
NEW_FOLDER, NEW_FILE,
|
||||||
|
NEW_MARKDOWN_FILE,
|
||||||
|
NEW_EXCEL_FILE,
|
||||||
|
NEW_POWERPOINT_FILE,
|
||||||
|
NEW_WORD_FILE,
|
||||||
|
NEW_SEADOC_FILE,
|
||||||
|
NEW_TLDRAW_FILE
|
||||||
|
} = TextTranslation;
|
||||||
|
const direntsContainerMenuList = [
|
||||||
|
NEW_FOLDER, NEW_FILE, 'Divider',
|
||||||
|
];
|
||||||
|
const { currentRepoInfo } = this.props;
|
||||||
|
if (enableSeadoc && !currentRepoInfo.encrypted) {
|
||||||
|
direntsContainerMenuList.push(NEW_SEADOC_FILE);
|
||||||
|
}
|
||||||
|
direntsContainerMenuList.push(
|
||||||
|
NEW_MARKDOWN_FILE,
|
||||||
|
NEW_EXCEL_FILE,
|
||||||
|
NEW_POWERPOINT_FILE,
|
||||||
|
NEW_WORD_FILE,
|
||||||
|
);
|
||||||
|
if (enableWhiteboard) {
|
||||||
|
direntsContainerMenuList.push(NEW_TLDRAW_FILE);
|
||||||
|
}
|
||||||
|
let id = 'dirent-container-menu';
|
||||||
|
if (isCustomPermission) {
|
||||||
|
const { create: canCreate } = customPermission.permission;
|
||||||
|
if (!canCreate) return;
|
||||||
|
}
|
||||||
|
let menuList = direntsContainerMenuList;
|
||||||
|
this.handleContextClick(event, id, menuList);
|
||||||
|
};
|
||||||
|
|
||||||
|
handleContextClick = (event, id, menuList, currentObject = null) => {
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
let x = event.clientX || (event.touches && event.touches[0].pageX);
|
||||||
|
let y = event.clientY || (event.touches && event.touches[0].pageY);
|
||||||
|
if (this.props.posX) {
|
||||||
|
x -= this.props.posX;
|
||||||
|
}
|
||||||
|
if (this.props.posY) {
|
||||||
|
y -= this.props.posY;
|
||||||
|
}
|
||||||
|
hideMenu();
|
||||||
|
let showMenuConfig = {
|
||||||
|
id: id,
|
||||||
|
position: { x, y },
|
||||||
|
target: event.target,
|
||||||
|
currentObject: currentObject,
|
||||||
|
menuList: menuList,
|
||||||
|
};
|
||||||
|
if (menuList.length === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
showMenu(showMenuConfig);
|
||||||
|
};
|
||||||
|
|
||||||
|
onContainerMenuItemClick = (operation) => {
|
||||||
|
switch (operation) {
|
||||||
|
case 'New Folder':
|
||||||
|
this.onCreateFolderToggle();
|
||||||
|
break;
|
||||||
|
case 'New File':
|
||||||
|
this.onCreateNewFile('');
|
||||||
|
break;
|
||||||
|
case 'New Markdown File':
|
||||||
|
this.onCreateNewFile('.md');
|
||||||
|
break;
|
||||||
|
case 'New Excel File':
|
||||||
|
this.onCreateNewFile('.xlsx');
|
||||||
|
break;
|
||||||
|
case 'New PowerPoint File':
|
||||||
|
this.onCreateNewFile('.pptx');
|
||||||
|
break;
|
||||||
|
case 'New Word File':
|
||||||
|
this.onCreateNewFile('.docx');
|
||||||
|
break;
|
||||||
|
case 'New Whiteboard File':
|
||||||
|
this.onCreateNewFile('.draw');
|
||||||
|
break;
|
||||||
|
case 'New SeaDoc File':
|
||||||
|
this.onCreateNewFile('.sdoc');
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
hideMenu();
|
||||||
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
if (this.props.isDirentListLoading) {
|
if (this.props.isDirentListLoading) {
|
||||||
return (<Loading />);
|
return (<Loading />);
|
||||||
@@ -49,7 +165,7 @@ class DirentNoneView extends React.Component {
|
|||||||
const { currentRepoInfo } = this.props;
|
const { currentRepoInfo } = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Fragment>
|
<div className="tip-for-new-file-container" onContextMenu={this.onContainerContextMenu}>
|
||||||
<div className="tip-for-new-file">
|
<div className="tip-for-new-file">
|
||||||
<p className="text-secondary text-center">{gettext('This folder has no content at this time.')}</p>
|
<p className="text-secondary text-center">{gettext('This folder has no content at this time.')}</p>
|
||||||
<p className="text-secondary text-center">{gettext('You can create files quickly')}{' +'}</p>
|
<p className="text-secondary text-center">{gettext('You can create files quickly')}{' +'}</p>
|
||||||
@@ -83,7 +199,22 @@ class DirentNoneView extends React.Component {
|
|||||||
/>
|
/>
|
||||||
</ModalPortal>
|
</ModalPortal>
|
||||||
)}
|
)}
|
||||||
</Fragment>
|
{this.state.isCreateFolderDialogShow &&
|
||||||
|
<ModalPortal>
|
||||||
|
<CreateFolder
|
||||||
|
parentPath={this.props.path}
|
||||||
|
onAddFolder={this.onAddFolder}
|
||||||
|
checkDuplicatedName={this.checkDuplicatedName}
|
||||||
|
addFolderCancel={this.onCreateFolderToggle}
|
||||||
|
/>
|
||||||
|
</ModalPortal>
|
||||||
|
}
|
||||||
|
<ContextMenu
|
||||||
|
id={'dirent-container-menu'}
|
||||||
|
onMenuItemClick={this.onContainerMenuItemClick}
|
||||||
|
getMenuContainerSize={this.props.getMenuContainerSize}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,3 +1,9 @@
|
|||||||
|
.tip-for-new-file-container {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
.tip-for-new-file {
|
.tip-for-new-file {
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
padding: 2em 1em;
|
padding: 2em 1em;
|
||||||
|
Reference in New Issue
Block a user