|
@@ -2,119 +2,33 @@ import React, { Fragment } from 'react';
|
|
|
import PropTypes from 'prop-types';
|
|
import PropTypes from 'prop-types';
|
|
|
import { withTranslation } from 'react-i18next';
|
|
import { withTranslation } from 'react-i18next';
|
|
|
|
|
|
|
|
|
|
+import StatusActivateForm from './StatusActivateForm';
|
|
|
|
|
+import StatusSuspendedForm from './StatusSuspendedForm';
|
|
|
|
|
+import RemoveUserForm from './UserRemoveForm';
|
|
|
|
|
+import RemoveAdminForm from './RemoveAdminForm';
|
|
|
|
|
+import GiveAdminForm from './GiveAdminForm';
|
|
|
|
|
+
|
|
|
import { createSubscribedElement } from '../../UnstatedUtils';
|
|
import { createSubscribedElement } from '../../UnstatedUtils';
|
|
|
import AppContainer from '../../../services/AppContainer';
|
|
import AppContainer from '../../../services/AppContainer';
|
|
|
|
|
|
|
|
class UserMenu extends React.Component {
|
|
class UserMenu extends React.Component {
|
|
|
|
|
|
|
|
|
|
+ constructor(props) {
|
|
|
|
|
+ super(props);
|
|
|
|
|
|
|
|
- activateUser() {
|
|
|
|
|
- const { appContainer } = this.props;
|
|
|
|
|
-
|
|
|
|
|
- appContainer.apiPost('/admin/user/{userId}/activate');
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- susupendUser() {
|
|
|
|
|
- const { appContainer } = this.props;
|
|
|
|
|
-
|
|
|
|
|
- appContainer.apiPost('/admin/user/{userId}/suspend');
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- removeUser() {
|
|
|
|
|
- const { appContainer } = this.props;
|
|
|
|
|
-
|
|
|
|
|
- appContainer.apiPost('/admin/user/{user._id}/removeCompletely');
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ this.state = {
|
|
|
|
|
|
|
|
- removeFromAdmin() {
|
|
|
|
|
- const { appContainer } = this.props;
|
|
|
|
|
|
|
+ };
|
|
|
|
|
|
|
|
- appContainer.apiPost('/admin/user/{user._id}/removeFromAdmin');
|
|
|
|
|
|
|
+ this.onPasswordResetClicked = this.onPasswordResetClicked.bind(this);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- giveAdminAccess() {
|
|
|
|
|
- const { appContainer } = this.props;
|
|
|
|
|
-
|
|
|
|
|
- appContainer.apiPost('/admin/user/{user._id}/makeAdmin');
|
|
|
|
|
|
|
+ onPasswordResetClicked() {
|
|
|
|
|
+ this.props.onPasswordResetClicked(this.props.user);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-
|
|
|
|
|
render() {
|
|
render() {
|
|
|
const { t, user } = this.props;
|
|
const { t, user } = this.props;
|
|
|
- const me = this.props.appContainer.me;
|
|
|
|
|
-
|
|
|
|
|
- let contentOfStatus;
|
|
|
|
|
- let adminMenu;
|
|
|
|
|
-
|
|
|
|
|
- if (user.status === 1) {
|
|
|
|
|
- contentOfStatus = (
|
|
|
|
|
- <a className="mx-4" onClick={this.activateUser}>
|
|
|
|
|
- <i className="icon-fw icon-user-following"></i> { t('user_management.accept') }
|
|
|
|
|
- </a>
|
|
|
|
|
- );
|
|
|
|
|
- }
|
|
|
|
|
- if (user.status === 2) {
|
|
|
|
|
- contentOfStatus = (
|
|
|
|
|
- user.username !== me
|
|
|
|
|
- ? (
|
|
|
|
|
- <a onClick={this.susupendUser}>
|
|
|
|
|
- <i className="icon-fw icon-ban"></i>{ t('user_management.deactivate_account') }
|
|
|
|
|
- </a>
|
|
|
|
|
- )
|
|
|
|
|
- : (
|
|
|
|
|
- <div className="mx-4">
|
|
|
|
|
- <i className="icon-fw icon-ban mb-2"></i>{ t('user_management.deactivate_account') }
|
|
|
|
|
- <p className="alert alert-danger">{ t('user_management.your_own') }</p>
|
|
|
|
|
- </div>
|
|
|
|
|
- )
|
|
|
|
|
- );
|
|
|
|
|
- }
|
|
|
|
|
- if (user.status === 3) {
|
|
|
|
|
- contentOfStatus = (
|
|
|
|
|
- <div>
|
|
|
|
|
- <a className="mx-4" onClick={this.activateUser}>
|
|
|
|
|
- <i className="icon-fw icon-action-redo"></i> { t('Undo') }
|
|
|
|
|
- </a>
|
|
|
|
|
- {/* label は同じだけど、こっちは論理削除 */}
|
|
|
|
|
- <a className="mx-4" onClick={this.removeUser}>
|
|
|
|
|
- <i className="icon-fw icon-fire text-danger"></i> { t('Delete') }
|
|
|
|
|
- </a>
|
|
|
|
|
- </div>
|
|
|
|
|
- );
|
|
|
|
|
- }
|
|
|
|
|
- if (user.status === 1 || user.status === 5) {
|
|
|
|
|
- contentOfStatus = (
|
|
|
|
|
- <li className="dropdown-button">
|
|
|
|
|
- <a className="mx-4" onClick={this.removeUser}>
|
|
|
|
|
- <i className="icon-fw icon-fire text-danger"></i> { t('Delete') }
|
|
|
|
|
- </a>
|
|
|
|
|
- </li>
|
|
|
|
|
- );
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- if (user.admin === true && user.status === 2) {
|
|
|
|
|
- adminMenu = (
|
|
|
|
|
- user.username !== me
|
|
|
|
|
- ? (
|
|
|
|
|
- <a onClick={this.removeFromAdmin}>
|
|
|
|
|
- <i className="icon-fw icon-user-unfollow mb-2"></i> { t('user_management.remove_admin_access') }
|
|
|
|
|
- </a>
|
|
|
|
|
- )
|
|
|
|
|
- : (
|
|
|
|
|
- <div className="mx-4">
|
|
|
|
|
- <i className="icon-fw icon-user-unfollow mb-2"></i>{ t('user_management.remove_admin_access') }
|
|
|
|
|
- <p className="alert alert-danger">{ t('user_management.cannot_remove') }</p>
|
|
|
|
|
- </div>
|
|
|
|
|
- )
|
|
|
|
|
- );
|
|
|
|
|
- }
|
|
|
|
|
- if (user.admin === false && user.status === 2) {
|
|
|
|
|
- adminMenu = (
|
|
|
|
|
- <a onClick={this.giveAdminAccess}>
|
|
|
|
|
- <i className="icon-fw icon-magic-wand"></i>{ t('user_management.give_admin_access') }
|
|
|
|
|
- </a>
|
|
|
|
|
- );
|
|
|
|
|
- }
|
|
|
|
|
|
|
|
|
|
return (
|
|
return (
|
|
|
<Fragment>
|
|
<Fragment>
|
|
@@ -124,75 +38,26 @@ class UserMenu extends React.Component {
|
|
|
</button>
|
|
</button>
|
|
|
<ul className="dropdown-menu" role="menu">
|
|
<ul className="dropdown-menu" role="menu">
|
|
|
<li className="dropdown-header">{ t('user_management.edit_menu') }</li>
|
|
<li className="dropdown-header">{ t('user_management.edit_menu') }</li>
|
|
|
- <li>
|
|
|
|
|
- <a
|
|
|
|
|
- href="#"
|
|
|
|
|
- data-user-id="{{ userId }}"
|
|
|
|
|
- data-target="#admin-password-reset-modal"
|
|
|
|
|
- data-toggle="modal"
|
|
|
|
|
- >
|
|
|
|
|
- <i className="icon-fw icon-key"></i>
|
|
|
|
|
- { t('user_management.reset_password') }
|
|
|
|
|
|
|
+ <li onClick={this.onPasswordResetClicked}>
|
|
|
|
|
+ <a>
|
|
|
|
|
+ <i className="icon-fw icon-key"></i>{ t('user_management.reset_password') }
|
|
|
</a>
|
|
</a>
|
|
|
</li>
|
|
</li>
|
|
|
<li className="divider"></li>
|
|
<li className="divider"></li>
|
|
|
<li className="dropdown-header">{ t('status') }</li>
|
|
<li className="dropdown-header">{ t('status') }</li>
|
|
|
<li>
|
|
<li>
|
|
|
- {contentOfStatus}
|
|
|
|
|
|
|
+ {(user.status === 1 || user.status === 3) && <StatusActivateForm user={user} />}
|
|
|
|
|
+ {user.status === 2 && <StatusSuspendedForm user={user} />}
|
|
|
|
|
+ {(user.status === 1 || user.status === 3 || user.status === 5) && <RemoveUserForm user={user} />}
|
|
|
</li>
|
|
</li>
|
|
|
<li className="divider pl-0"></li>
|
|
<li className="divider pl-0"></li>
|
|
|
<li className="dropdown-header">{ t('user_management.administrator_menu') }</li>
|
|
<li className="dropdown-header">{ t('user_management.administrator_menu') }</li>
|
|
|
- <li>{adminMenu}</li>
|
|
|
|
|
|
|
+ <li>
|
|
|
|
|
+ {user.status === 2 && user.admin === true && <RemoveAdminForm user={user} />}
|
|
|
|
|
+ {user.status === 2 && user.admin === false && <GiveAdminForm user={user} />}
|
|
|
|
|
+ </li>
|
|
|
</ul>
|
|
</ul>
|
|
|
</div>
|
|
</div>
|
|
|
- {/* password reset modal */}
|
|
|
|
|
- <div className="modal fade" id="admin-password-reset-modal">
|
|
|
|
|
- <div className="modal-dialog">
|
|
|
|
|
- <div className="modal-content">
|
|
|
|
|
- <div className="modal-header">
|
|
|
|
|
- <button type="button" className="close" data-dismiss="modal" aria-hidden="true">×</button>
|
|
|
|
|
- <div className="modal-title">{ t('user_management.reset_password')}</div>
|
|
|
|
|
- </div>
|
|
|
|
|
-
|
|
|
|
|
- <div className="modal-body">
|
|
|
|
|
- <p>
|
|
|
|
|
- { t('user_management.password_never_seen') }<br />
|
|
|
|
|
- <span className="text-danger">{ t('user_management.send_new_password') }</span>
|
|
|
|
|
- </p>
|
|
|
|
|
- <p>
|
|
|
|
|
- { t('user_management.target_user') }: <code>{ user.email }</code>
|
|
|
|
|
- </p>
|
|
|
|
|
- <button type="submit" value="" className="btn btn-primary">
|
|
|
|
|
- { t('user_management.reset_password')}
|
|
|
|
|
- </button>
|
|
|
|
|
- </div>
|
|
|
|
|
- </div>
|
|
|
|
|
- </div>
|
|
|
|
|
- </div>
|
|
|
|
|
- <div className="modal fade" id="admin-password-reset-modal-done">
|
|
|
|
|
- <div className="modal-dialog">
|
|
|
|
|
- <div className="modal-content">
|
|
|
|
|
-
|
|
|
|
|
- <div className="modal-header">
|
|
|
|
|
- <button type="button" className="close" data-dismiss="modal" aria-hidden="true">×</button>
|
|
|
|
|
- <div className="modal-title">{ t('user_management.reset_password') }</div>
|
|
|
|
|
- </div>
|
|
|
|
|
-
|
|
|
|
|
- <div className="modal-body">
|
|
|
|
|
- <p className="alert alert-danger">Let the user know the new password below and strongly recommend to change another one immediately. </p>
|
|
|
|
|
- <p>
|
|
|
|
|
- Reset user: <code id="admin-password-reset-done-user"></code>
|
|
|
|
|
- </p>
|
|
|
|
|
- <p>
|
|
|
|
|
- New password: <code id="admin-password-reset-done-password"></code>
|
|
|
|
|
- </p>
|
|
|
|
|
- </div>
|
|
|
|
|
- <div className="modal-footer">
|
|
|
|
|
- <button type="submit" className="btn btn-primary" data-dismiss="modal">OK</button>
|
|
|
|
|
- </div>
|
|
|
|
|
- </div>
|
|
|
|
|
- </div>
|
|
|
|
|
- </div>
|
|
|
|
|
</Fragment>
|
|
</Fragment>
|
|
|
);
|
|
);
|
|
|
}
|
|
}
|
|
@@ -207,7 +72,8 @@ UserMenu.propTypes = {
|
|
|
t: PropTypes.func.isRequired, // i18next
|
|
t: PropTypes.func.isRequired, // i18next
|
|
|
appContainer: PropTypes.instanceOf(AppContainer).isRequired,
|
|
appContainer: PropTypes.instanceOf(AppContainer).isRequired,
|
|
|
|
|
|
|
|
- user: PropTypes.array,
|
|
|
|
|
|
|
+ user: PropTypes.object.isRequired,
|
|
|
|
|
+ onPasswordResetClicked: PropTypes.func.isRequired,
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
export default withTranslation()(UserMenuWrapper);
|
|
export default withTranslation()(UserMenuWrapper);
|