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 (
+
+
+
+
+
+
+
+
+
+
+
+ );
+ }
+}
+
+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}},
}
};