From 02055139b548f5d76cdda6708877192921f09296 Mon Sep 17 00:00:00 2001 From: Michael An <2331806369@qq.com> Date: Fri, 10 Jan 2025 15:48:34 +0800 Subject: [PATCH] Add context menu when no file (#7344) * dirent none view support create folder * fix permission --- .../components/dir-view-mode/dir-grid-view.js | 3 + .../components/dir-view-mode/dir-list-view.js | 3 + .../dirent-list-view/dirent-none-view.js | 141 +++++++++++++++++- frontend/src/css/tip-for-new-file.css | 6 + 4 files changed, 148 insertions(+), 5 deletions(-) diff --git a/frontend/src/components/dir-view-mode/dir-grid-view.js b/frontend/src/components/dir-view-mode/dir-grid-view.js index 7bf333fb92b..d0e82eec029 100644 --- a/frontend/src/components/dir-view-mode/dir-grid-view.js +++ b/frontend/src/components/dir-view-mode/dir-grid-view.js @@ -50,6 +50,9 @@ class DirGridView extends React.Component { isDirentListLoading={this.props.isDirentListLoading} onAddFile={this.props.onAddFile} currentRepoInfo={this.props.currentRepoInfo} + userPerm={this.props.userPerm} + onAddFolder={this.props.onAddFolder} + getMenuContainerSize={this.props.getMenuContainerSize} /> ); } diff --git a/frontend/src/components/dir-view-mode/dir-list-view.js b/frontend/src/components/dir-view-mode/dir-list-view.js index 0d8439cf04f..cc879dce205 100644 --- a/frontend/src/components/dir-view-mode/dir-list-view.js +++ b/frontend/src/components/dir-view-mode/dir-list-view.js @@ -57,6 +57,9 @@ class DirListView extends React.Component { isDirentListLoading={this.props.isDirentListLoading} onAddFile={this.props.onAddFile} currentRepoInfo={this.props.currentRepoInfo} + userPerm={this.props.userPerm} + onAddFolder={this.props.onAddFolder} + getMenuContainerSize={this.props.getMenuContainerSize} /> ); } diff --git a/frontend/src/components/dirent-list-view/dirent-none-view.js b/frontend/src/components/dirent-list-view/dirent-none-view.js index 9c7a5015008..28c20e6f0ea 100644 --- a/frontend/src/components/dirent-list-view/dirent-none-view.js +++ b/frontend/src/components/dirent-list-view/dirent-none-view.js @@ -1,9 +1,14 @@ -import React, { Fragment } from 'react'; +import React from 'react'; import PropTypes from 'prop-types'; -import { enableSeadoc, gettext } from '../../utils/constants'; +import { enableSeadoc, gettext, enableWhiteboard } from '../../utils/constants'; import Loading from '../loading'; import ModalPortal from '../modal-portal'; 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'; @@ -11,7 +16,10 @@ const propTypes = { path: PropTypes.string.isRequired, isDirentListLoading: PropTypes.bool.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 { @@ -21,9 +29,19 @@ class DirentNoneView extends React.Component { this.state = { fileType: '', isCreateFileDialogShow: false, + isCreateFolderDialogShow: false, }; } + onCreateFolderToggle = () => { + this.setState({ isCreateFolderDialogShow: !this.state.isCreateFolderDialogShow }); + }; + + onAddFolder = (dirPath) => { + this.setState({ isCreateFolderDialogShow: false }); + this.props.onAddFolder(dirPath); + }; + onCreateNewFile = (type) => { this.setState({ fileType: type, @@ -42,6 +60,104 @@ class DirentNoneView extends React.Component { 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() { if (this.props.isDirentListLoading) { return (); @@ -49,7 +165,7 @@ class DirentNoneView extends React.Component { const { currentRepoInfo } = this.props; return ( - +

{gettext('This folder has no content at this time.')}

{gettext('You can create files quickly')}{' +'}

@@ -83,7 +199,22 @@ class DirentNoneView extends React.Component { /> )} - + {this.state.isCreateFolderDialogShow && + + + + } + +
); } } diff --git a/frontend/src/css/tip-for-new-file.css b/frontend/src/css/tip-for-new-file.css index 8fd6762e512..156f448813b 100644 --- a/frontend/src/css/tip-for-new-file.css +++ b/frontend/src/css/tip-for-new-file.css @@ -1,3 +1,9 @@ +.tip-for-new-file-container { + display: flex; + justify-content: center; + height: 100%; +} + .tip-for-new-file { margin: 0 auto; padding: 2em 1em;