diff --git a/frontend/src/components/dialog/change-repo-password-dialog.js b/frontend/src/components/dialog/change-repo-password-dialog.js new file mode 100644 index 0000000000..34c0fcfb3c --- /dev/null +++ b/frontend/src/components/dialog/change-repo-password-dialog.js @@ -0,0 +1,133 @@ +import React, { Fragment } from 'react'; +import PropTypes from 'prop-types'; +import { Modal, ModalHeader, ModalBody, ModalFooter } from 'reactstrap'; +import { gettext, repoPasswordMinLength } from '../../utils/constants'; +import { Utils } from '../../utils/utils'; +import { seafileAPI } from '../../utils/seafile-api'; +import toaster from '../toast'; + +const propTypes = { + repoID: PropTypes.string.isRequired, + repoName: PropTypes.string.isRequired, + toggleDialog: PropTypes.func.isRequired +}; + +class ChangeRepoPasswordDialog extends React.Component { + constructor(props) { + super(props); + this.state = { + oldPassword: '', + newPassword: '', + newPasswordAgain: '', + submitBtnDisabled: false, + errorMsg: '' + }; + } + + handleOldPasswordInputChange = (e) => { + this.setState({ + oldPassword: e.target.value + }); + } + + handleNewPasswordInputChange = (e) => { + this.setState({ + newPassword: e.target.value + }); + } + + handleNewPasswordAgainInputChange = (e) => { + this.setState({ + newPasswordAgain: e.target.value + }); + } + + formSubmit = (e) => { + const { oldPassword, newPassword, newPasswordAgain } = this.state; + if (!oldPassword) { + this.setState({ + errorMsg: gettext('Please enter the old password') + }); + return false; + } + if (!newPassword) { + this.setState({ + errorMsg: gettext('Please enter a new password') + }); + return false; + } + if (newPassword.length < repoPasswordMinLength) { + this.setState({ + errorMsg: gettext('New password is too short') + }); + return false; + } + if (!newPasswordAgain) { + this.setState({ + errorMsg: gettext('Please enter the new password again') + }); + return false; + } + if (newPassword != newPasswordAgain) { + this.setState({ + errorMsg: gettext('New passwords don\'t match') + }); + return false; + } + + this.setState({ + submitBtnDisabled: true + }); + seafileAPI.changeEncryptedRepoPassword(this.props.repoID, oldPassword, newPassword) + .then(() => { + this.props.toggleDialog(); + toaster.success(gettext('Successfully changed library password.')); + }).catch((error) => { + let errorMsg = ''; + if (error.response) { + if (error.response.data) { + errorMsg = error.response.data.error_msg; + } else { + errorMsg = gettext('Error'); + } + } else { + errorMsg = gettext('Please check the network.'); + } + this.setState({ + errorMsg: errorMsg, + submitBtnDisabled: false + }); + }); + } + + + render() { + const { repoID, repoName, toggleDialog } = this.props; + + return ( + + + + + +
+
+
+ {gettext('(at least {placeholder} characters)').replace('{placeholder}', repoPasswordMinLength)}
+
+
+
+ {this.state.errorMsg &&

{this.state.errorMsg}

} +
+
+ + + +
+ ); + } +} + +ChangeRepoPasswordDialog.propTypes = propTypes; + +export default ChangeRepoPasswordDialog; diff --git a/frontend/src/pages/my-libs/item.js b/frontend/src/pages/my-libs/item.js index 8921f2af79..8267675519 100644 --- a/frontend/src/pages/my-libs/item.js +++ b/frontend/src/pages/my-libs/item.js @@ -9,6 +9,7 @@ import { seafileAPI } from '../../utils/seafile-api'; import Rename from '../../components/rename'; import ModalPotal from '../../components/modal-portal'; import ShareDialog from '../../components/dialog/share-dialog'; +import ChangeRepoPasswordDialog from '../../components/dialog/change-repo-password-dialog'; const propTypes = { data: PropTypes.object.isRequired, @@ -33,6 +34,7 @@ class Item extends Component { showChangeLibName: false, isShowSharedDialog: false, highlight: false, + isChangeRepoPasswordDialogOpen: false }; } @@ -141,6 +143,11 @@ class Item extends Component { } changePassword = () => { + this.setState({isChangeRepoPasswordDialogOpen: true}); + } + + toggleChangePasswordDialog = () => { + this.setState({isChangeRepoPasswordDialogOpen: !this.state.isChangeRepoPasswordDialogOpen}); } folderPerm = () => { @@ -264,6 +271,15 @@ class Item extends Component { /> )} + {this.state.isChangeRepoPasswordDialogOpen && ( + + + + )} ); @@ -295,6 +311,15 @@ class Item extends Component { /> )} + {this.state.isChangeRepoPasswordDialogOpen && ( + + + + )} ); diff --git a/frontend/src/utils/constants.js b/frontend/src/utils/constants.js index f9744d1a04..3a6c820995 100644 --- a/frontend/src/utils/constants.js +++ b/frontend/src/utils/constants.js @@ -39,6 +39,7 @@ export const enableEncryptedLibrary = window.app.pageOptions.enableEncryptedLibr export const enableRepoHistorySetting = window.app.pageOptions.enableRepoHistorySetting === '1'; export const isSystemStaff = window.app.pageOptions.isSystemStaff; export const thumbnailSizeForOriginal = window.app.pageOptions.thumbnailSizeForOriginal; +export const repoPasswordMinLength = window.app.pageOptions.repoPasswordMinLength; // wiki export const slug = window.wiki ? window.wiki.config.slug : ''; diff --git a/frontend/src/utils/utils.js b/frontend/src/utils/utils.js index d3fac9e1c2..43d2b6ee90 100644 --- a/frontend/src/utils/utils.js +++ b/frontend/src/utils/utils.js @@ -144,6 +144,15 @@ export const Utils = { .innerHTML; }, + generateDialogTitle: function(title, operationTarget) { + /* + * @param title: gettext('...{placeholder}...') + */ + const targetStr = this.HTMLescape(operationTarget); + const str = `${targetStr}`; + return title.replace('{placeholder}', str); + }, + getFileName: function(filePath) { let lastIndex = filePath.lastIndexOf('/'); return filePath.slice(lastIndex+1); diff --git a/media/css/seahub_react.css b/media/css/seahub_react.css index b5245cb1ef..895a3af6cf 100644 --- a/media/css/seahub_react.css +++ b/media/css/seahub_react.css @@ -111,6 +111,10 @@ a:hover { color:#eb8205; } overflow:hidden; text-overflow:ellipsis; } +.op-target { + color: #ee8204; + word-wrap: break-word; +} .left-zero { left: 0px !important; } diff --git a/seahub/templates/base_for_react.html b/seahub/templates/base_for_react.html index 94348046fd..79469c17b8 100644 --- a/seahub/templates/base_for_react.html +++ b/seahub/templates/base_for_react.html @@ -73,6 +73,7 @@ enableRepoHistorySetting: '{{ enable_repo_history_setting }}', isSystemStaff: {% if request.user.is_staff %} true {% else %} false {% endif %}, thumbnailSizeForOriginal: {{ thumbnail_size_for_original }}, + repoPasswordMinLength: {{repo_password_min_length}}, } };