diff --git a/frontend/src/components/dialog/generate-share-link.js b/frontend/src/components/dialog/generate-share-link.js index 1f6fc7de6b..741d75630b 100644 --- a/frontend/src/components/dialog/generate-share-link.js +++ b/frontend/src/components/dialog/generate-share-link.js @@ -24,6 +24,12 @@ class GenerateShareLink extends React.Component { this.isExpireDaysNoLimit = (parseInt(shareLinkExpireDaysMin) === 0 && parseInt(shareLinkExpireDaysMax) === 0 && shareLinkExpireDaysDefault == 0); this.defaultExpireDays = this.isExpireDaysNoLimit ? '' : shareLinkExpireDaysDefault; + + if (isPro) { + this.editOption = 'edit_download'; + this.permissionOptions = ['preview_download', 'preview_only']; + } + this.state = { isValidate: false, isShowPasswordInput: false, @@ -36,14 +42,9 @@ class GenerateShareLink extends React.Component { sharedLinkInfo: null, isNoticeMessageShow: false, isLoading: true, - fileInfo: null, + currentPermission: isPro ? this.permissionOptions[0] : '', isSendLinkShown: false }; - this.permissions = { - 'can_edit': false, - 'can_download': true - }; - this.isOfficeFile = Utils.isEditableOfficeFile(this.props.itemPath); } componentDidMount() { @@ -63,10 +64,11 @@ class GenerateShareLink extends React.Component { let errMessage = Utils.getErrorMsg(error); toaster.danger(errMessage); }); - if (this.isOfficeFile) { + + if (isPro && Utils.isEditableOfficeFile(path)) { seafileAPI.getFileInfo(repoID, path).then((res) => { - if (res.data) { - this.setState({fileInfo: res.data}); + if (res.data.can_edit) { + this.permissionOptions.push(this.editOption); } }).catch(error => { let errMessage = Utils.getErrorMsg(error); @@ -108,23 +110,8 @@ class GenerateShareLink extends React.Component { this.setState({passwdnew: passwd}); } - setPermission = (permission) => { - if (permission == 'previewAndDownload') { - this.permissions = { - 'can_edit': false, - 'can_download': true - }; - } else if (permission == 'preview') { - this.permissions = { - 'can_edit': false, - 'can_download': false - }; - } else if (permission == 'editOnCloudAndDownload'){ - this.permissions = { - 'can_edit': true, - 'can_download': true - }; - } + setPermission = (e) => { + this.setState({currentPermission: e.target.value}); } generateShareLink = () => { @@ -133,7 +120,11 @@ class GenerateShareLink extends React.Component { this.setState({errorInfo: ''}); let { itemPath, repoID } = this.props; let { password, isExpireChecked, expireDays } = this.state; - let permissions = isPro ? JSON.stringify(this.permissions) : ''; + let permissions; + if (isPro) { + const permissionDetails = Utils.getShareLinkPermissionObject(this.state.currentPermission).permissionDetails; + permissions = JSON.stringify(permissionDetails); + } const expireDaysSent = isExpireChecked ? expireDays : ''; seafileAPI.createShareLink(repoID, itemPath, password, expireDaysSent, permissions).then((res) => { let sharedLinkInfo = new ShareLink(res.data); @@ -172,10 +163,6 @@ class GenerateShareLink extends React.Component { sharedLinkInfo: null, isNoticeMessageShow: false, }); - this.permissions = { - 'can_edit': false, - 'can_download': true - }; }).catch((error) => { let errMessage = Utils.getErrorMsg(error); toaster.danger(errMessage); @@ -340,7 +327,6 @@ class GenerateShareLink extends React.Component { ); } else { - let fileInfo = this.state.fileInfo; return (
@@ -403,28 +389,21 @@ class GenerateShareLink extends React.Component { )} {isPro && ( - - - - - - - - - - {(this.isOfficeFile && fileInfo && fileInfo.can_edit) && - - - - } + + + + {this.permissionOptions.map((item, index) => { + return ( + + + + ); + })} )} {this.state.errorInfo && {gettext(this.state.errorInfo)}} diff --git a/frontend/src/components/index-viewer.js b/frontend/src/components/index-viewer.js index 7549326bd3..a5e86abfd7 100644 --- a/frontend/src/components/index-viewer.js +++ b/frontend/src/components/index-viewer.js @@ -249,12 +249,12 @@ class FolderItem extends React.Component { }); } - renderLink = (node) => { - const className = node.path === this.props.currentPath ? 'wiki-nav-content wiki-nav-content-highlight' : 'wiki-nav-content'; - if (node.href && node.name) { - return
{node.name}
; - } else if (node.name) { - return
{node.name}
; + renderLink = ({ href, name, path }) => { + const className = `wiki-nav-content ${path === this.props.currentPath ? 'wiki-nav-content-highlight' : ''}`; + if (href && name) { + return
{name}
; + } else if (name) { + return
{name}
; } else { return null; } diff --git a/frontend/src/components/main-side-nav.js b/frontend/src/components/main-side-nav.js index 56c59840a8..42ce0ff4a3 100644 --- a/frontend/src/components/main-side-nav.js +++ b/frontend/src/components/main-side-nav.js @@ -54,7 +54,9 @@ class MainSideNav extends React.Component { this.groupsHeight = (groupList.length + 1) * _this.listHeight; _this.setState({ - groupItems: groupList + groupItems: groupList.sort((a, b) => { + return a.name.toLowerCase() < b.name.toLowerCase() ? -1 : 1; + }) }); }).catch(error => { let errMessage = Utils.getErrorMsg(error); diff --git a/frontend/src/components/shared-file-view/shared-file-view-tip.js b/frontend/src/components/shared-file-view/shared-file-view-tip.js index 90170bf150..0c7add7e79 100644 --- a/frontend/src/components/shared-file-view/shared-file-view-tip.js +++ b/frontend/src/components/shared-file-view/shared-file-view-tip.js @@ -2,7 +2,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import { gettext } from '../../utils/constants'; -const { err, trafficOverLimit } = window.shared.pageOptions; +const { err, trafficOverLimit, zipped, filePath } = window.shared.pageOptions; const propTypes = { errorMsg: PropTypes.string @@ -21,7 +21,7 @@ class SharedFileViewTip extends React.Component {
{errorMsg} {!trafficOverLimit && - {gettext('Download')} + {gettext('Download')} }
diff --git a/frontend/src/components/toolbar/dir-operation-toolbar.js b/frontend/src/components/toolbar/dir-operation-toolbar.js index 09a95dd5ed..f313d291e2 100644 --- a/frontend/src/components/toolbar/dir-operation-toolbar.js +++ b/frontend/src/components/toolbar/dir-operation-toolbar.js @@ -1,5 +1,6 @@ import React, { Fragment } from 'react'; import PropTypes from 'prop-types'; +import { Dropdown, DropdownToggle, DropdownMenu, DropdownItem } from 'reactstrap'; import { Utils } from '../../utils/utils'; import { gettext } from '../../utils/constants'; import ModalPortal from '../modal-portal'; @@ -35,6 +36,7 @@ class DirOperationToolbar extends React.Component { isCreateMenuShow: false, isShareDialogShow: false, operationMenuStyle: '', + isMobileOpMenuOpen: false }; } @@ -46,6 +48,10 @@ class DirOperationToolbar extends React.Component { document.removeEventListener('click', this.hideOperationMenu); } + toggleMobileOpMenu = () => { + this.setState({isMobileOpMenuOpen: !this.state.isMobileOpMenuOpen}); + } + hideOperationMenu = () => { this.setState({ isUploadMenuShow: false, @@ -161,17 +167,34 @@ class DirOperationToolbar extends React.Component { let itemType = path === '/' ? 'library' : 'dir'; let itemName = path == '/' ? repoName : Utils.getFolderName(path); + + const content = Utils.isDesktop() ? ( + + {Utils.isSupportUploadFolder() ? + : + } + + {this.props.showShareBtn && + } + + ) : ( + + + + {gettext('Upload')} + {gettext('New Folder')} + {gettext('New File')} + + + ); + return (
- {Utils.isSupportUploadFolder() ? - : - - } - - {this.props.showShareBtn && - - } + {content}
{this.state.isUploadMenuShow && (
    diff --git a/frontend/src/pages/lib-content-view/lib-content-toolbar.js b/frontend/src/pages/lib-content-view/lib-content-toolbar.js index 739211dcf9..c8705bff16 100644 --- a/frontend/src/pages/lib-content-view/lib-content-toolbar.js +++ b/frontend/src/pages/lib-content-view/lib-content-toolbar.js @@ -1,5 +1,6 @@ import React, { Fragment } from 'react'; import PropTypes from 'prop-types'; +import { Utils } from '../../utils/utils'; import { gettext } from '../../utils/constants'; import CommonToolbar from '../../components/toolbar/common-toolbar'; import ViewModeToolbar from '../../components/toolbar/view-mode-toolbar'; @@ -123,7 +124,7 @@ class LibContentToolbar extends React.Component { /> } - + {Utils.isDesktop() && } diff --git a/frontend/src/pages/shared-with-all/public-shared-view.js b/frontend/src/pages/shared-with-all/public-shared-view.js index 9a90c6eef0..5a07910a3b 100644 --- a/frontend/src/pages/shared-with-all/public-shared-view.js +++ b/frontend/src/pages/shared-with-all/public-shared-view.js @@ -2,7 +2,7 @@ import React, { Fragment } from 'react'; import PropTypes from 'prop-types'; import cookie from 'react-cookies'; import MediaQuery from 'react-responsive'; -import { Dropdown, DropdownToggle, DropdownMenu, DropdownItem} from 'reactstrap'; +import { Dropdown, DropdownToggle, DropdownMenu, DropdownItem } from 'reactstrap'; import { seafileAPI } from '../../utils/seafile-api'; import { gettext, loginUrl, canAddPublicRepo } from '../../utils/constants'; import { Utils } from '../../utils/utils'; diff --git a/seahub/auth/views.py b/seahub/auth/views.py index 5b3efb70d3..68c8e56e60 100644 --- a/seahub/auth/views.py +++ b/seahub/auth/views.py @@ -86,15 +86,18 @@ def _handle_login_form_valid(request, user, redirect_to, remember_me): @csrf_protect @never_cache def login(request, template_name='registration/login.html', - redirect_if_logged_in=None, + redirect_if_logged_in='libraries', redirect_field_name=REDIRECT_FIELD_NAME, authentication_form=AuthenticationForm): """Displays the login form and handles the login action.""" - if request.user.is_authenticated() and redirect_if_logged_in: - return HttpResponseRedirect(reverse(redirect_if_logged_in)) - redirect_to = request.GET.get(redirect_field_name, '') + if request.user.is_authenticated(): + if redirect_to: + return HttpResponseRedirect(redirect_to) + else: + return HttpResponseRedirect(reverse(redirect_if_logged_in)) + ip = get_remote_ip(request) if request.method == "POST":