2
0

UserMenu.jsx 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. import React, { Fragment } from 'react';
  2. import PropTypes from 'prop-types';
  3. import { withTranslation } from 'react-i18next';
  4. import { createSubscribedElement } from '../../UnstatedUtils';
  5. import AppContainer from '../../../services/AppContainer';
  6. class UserMenu extends React.Component {
  7. activateUser() {
  8. const { appContainer } = this.props;
  9. appContainer.apiPost('/admin/user/{userId}/activate');
  10. }
  11. susupendUser() {
  12. const { appContainer } = this.props;
  13. appContainer.apiPost('/admin/user/{userId}/suspend');
  14. }
  15. removeUser() {
  16. const { appContainer } = this.props;
  17. appContainer.apiPost('/admin/user/{user._id}/removeCompletely');
  18. }
  19. removeFromAdmin() {
  20. const { appContainer } = this.props;
  21. appContainer.apiPost('/admin/user/{user._id}/removeFromAdmin');
  22. }
  23. giveAdminAccess() {
  24. const { appContainer } = this.props;
  25. appContainer.apiPost('/admin/user/{user._id}/makeAdmin');
  26. }
  27. render() {
  28. const { t, user } = this.props;
  29. const me = this.props.appContainer.me;
  30. let contentOfStatus;
  31. let adminMenu;
  32. if (user.status === 1) {
  33. contentOfStatus = (
  34. <a className="mx-4" onClick={this.activateUser}>
  35. <i className="icon-fw icon-user-following"></i> { t('user_management.accept') }
  36. </a>
  37. );
  38. }
  39. if (user.status === 2) {
  40. contentOfStatus = (
  41. user.username !== me
  42. ? (
  43. <a onClick={this.susupendUser}>
  44. <i className="icon-fw icon-ban"></i>{ t('user_management.deactivate_account') }
  45. </a>
  46. )
  47. : (
  48. <div className="mx-4">
  49. <i className="icon-fw icon-ban mb-2"></i>{ t('user_management.deactivate_account') }
  50. <p className="alert alert-danger">{ t('user_management.your_own') }</p>
  51. </div>
  52. )
  53. );
  54. }
  55. if (user.status === 3) {
  56. contentOfStatus = (
  57. <div>
  58. <a className="mx-4" onClick={this.activateUser}>
  59. <i className="icon-fw icon-action-redo"></i> { t('Undo') }
  60. </a>
  61. {/* label は同じだけど、こっちは論理削除 */}
  62. <a className="mx-4" onClick={this.removeUser}>
  63. <i className="icon-fw icon-fire text-danger"></i> { t('Delete') }
  64. </a>
  65. </div>
  66. );
  67. }
  68. if (user.status === 1 || user.status === 5) {
  69. contentOfStatus = (
  70. <li className="dropdown-button">
  71. <a className="mx-4" onClick={this.removeUser}>
  72. <i className="icon-fw icon-fire text-danger"></i> { t('Delete') }
  73. </a>
  74. </li>
  75. );
  76. }
  77. if (user.admin === true && user.status === 2) {
  78. adminMenu = (
  79. user.username !== me
  80. ? (
  81. <a onClick={this.removeFromAdmin}>
  82. <i className="icon-fw icon-user-unfollow mb-2"></i> { t('user_management.remove_admin_access') }
  83. </a>
  84. )
  85. : (
  86. <div className="mx-4">
  87. <i className="icon-fw icon-user-unfollow mb-2"></i>{ t('user_management.remove_admin_access') }
  88. <p className="alert alert-danger">{ t('user_management.cannot_remove') }</p>
  89. </div>
  90. )
  91. );
  92. }
  93. if (user.admin === false && user.status === 2) {
  94. adminMenu = (
  95. <a onClick={this.giveAdminAccess}>
  96. <i className="icon-fw icon-magic-wand"></i>{ t('user_management.give_admin_access') }
  97. </a>
  98. );
  99. }
  100. return (
  101. <Fragment>
  102. <div className="btn-group admin-user-menu">
  103. <button type="button" className="btn btn-sm btn-default dropdown-toggle" data-toggle="dropdown">
  104. <i className="icon-settings"></i> <span className="caret"></span>
  105. </button>
  106. <ul className="dropdown-menu" role="menu">
  107. <li className="dropdown-header">{ t('user_management.edit_menu') }</li>
  108. <li>
  109. <a
  110. href="#"
  111. data-user-id="{{ userId }}"
  112. data-target="#admin-password-reset-modal"
  113. data-toggle="modal"
  114. >
  115. <i className="icon-fw icon-key"></i>
  116. { t('user_management.reset_password') }
  117. </a>
  118. </li>
  119. <li className="divider"></li>
  120. <li className="dropdown-header">{ t('status') }</li>
  121. <li>
  122. {contentOfStatus}
  123. </li>
  124. <li className="divider pl-0"></li>
  125. <li className="dropdown-header">{ t('user_management.administrator_menu') }</li>
  126. <li>{adminMenu}</li>
  127. </ul>
  128. </div>
  129. {/* password reset modal */}
  130. <div className="modal fade" id="admin-password-reset-modal">
  131. <div className="modal-dialog">
  132. <div className="modal-content">
  133. <div className="modal-header">
  134. <button type="button" className="close" data-dismiss="modal" aria-hidden="true">&times;</button>
  135. <div className="modal-title">{ t('user_management.reset_password')}</div>
  136. </div>
  137. <div className="modal-body">
  138. <p>
  139. { t('user_management.password_never_seen') }<br />
  140. <span className="text-danger">{ t('user_management.send_new_password') }</span>
  141. </p>
  142. <p>
  143. { t('user_management.target_user') }: <code>{ user.email }</code>
  144. </p>
  145. <button type="submit" value="" className="btn btn-primary">
  146. { t('user_management.reset_password')}
  147. </button>
  148. </div>
  149. </div>
  150. </div>
  151. </div>
  152. <div className="modal fade" id="admin-password-reset-modal-done">
  153. <div className="modal-dialog">
  154. <div className="modal-content">
  155. <div className="modal-header">
  156. <button type="button" className="close" data-dismiss="modal" aria-hidden="true">&times;</button>
  157. <div className="modal-title">{ t('user_management.reset_password') }</div>
  158. </div>
  159. <div className="modal-body">
  160. <p className="alert alert-danger">Let the user know the new password below and strongly recommend to change another one immediately. </p>
  161. <p>
  162. Reset user: <code id="admin-password-reset-done-user"></code>
  163. </p>
  164. <p>
  165. New password: <code id="admin-password-reset-done-password"></code>
  166. </p>
  167. </div>
  168. <div className="modal-footer">
  169. <button type="submit" className="btn btn-primary" data-dismiss="modal">OK</button>
  170. </div>
  171. </div>
  172. </div>
  173. </div>
  174. </Fragment>
  175. );
  176. }
  177. }
  178. const UserMenuWrapper = (props) => {
  179. return createSubscribedElement(UserMenu, props, [AppContainer]);
  180. };
  181. UserMenu.propTypes = {
  182. t: PropTypes.func.isRequired, // i18next
  183. appContainer: PropTypes.instanceOf(AppContainer).isRequired,
  184. user: PropTypes.array,
  185. };
  186. export default withTranslation()(UserMenuWrapper);