AdminUsersContainer.js 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. import { isServer } from '@growi/core';
  2. import { debounce } from 'throttle-debounce';
  3. import { Container } from 'unstated';
  4. import loggerFactory from '~/utils/logger';
  5. import {
  6. apiv3Delete, apiv3Get, apiv3Post, apiv3Put,
  7. } from '../util/apiv3-client';
  8. // eslint-disable-next-line no-unused-vars
  9. const logger = loggerFactory('growi:services:AdminUserGroupDetailContainer');
  10. /**
  11. * Service container for admin users page (Users.jsx)
  12. * @extends {Container} unstated Container
  13. */
  14. export default class AdminUsersContainer extends Container {
  15. constructor(appContainer) {
  16. super();
  17. if (isServer()) {
  18. return;
  19. }
  20. this.appContainer = appContainer;
  21. this.state = {
  22. users: [],
  23. sort: 'id',
  24. sortOrder: 'asc',
  25. isPasswordResetModalShown: false,
  26. isUserInviteModalShown: false,
  27. userForPasswordResetModal: null,
  28. totalUsers: 0,
  29. activePage: 1,
  30. pagingLimit: Infinity,
  31. selectedStatusList: new Set(['all']),
  32. searchText: '',
  33. };
  34. this.showPasswordResetModal = this.showPasswordResetModal.bind(this);
  35. this.hidePasswordResetModal = this.hidePasswordResetModal.bind(this);
  36. this.toggleUserInviteModal = this.toggleUserInviteModal.bind(this);
  37. this.handleChangeSearchTextDebouce = debounce(3000, () => this.retrieveUsersByPagingNum(1));
  38. }
  39. /**
  40. * Workaround for the mangling in production build to break constructor.name
  41. */
  42. static getClassName() {
  43. return 'AdminUsersContainer';
  44. }
  45. /**
  46. * Workaround for status list
  47. */
  48. isSelected(statusType) {
  49. return this.state.selectedStatusList.has(statusType);
  50. }
  51. handleClick(statusType) {
  52. const all = 'all';
  53. if (this.isSelected(statusType)) {
  54. this.deleteStatusFromList(statusType);
  55. }
  56. else {
  57. if (statusType === all) {
  58. this.clearStatusList();
  59. }
  60. else {
  61. this.deleteStatusFromList(all);
  62. }
  63. this.addStatusToList(statusType);
  64. }
  65. }
  66. async clearStatusList() {
  67. const { selectedStatusList } = this.state;
  68. selectedStatusList.clear();
  69. await this.setState({ selectedStatusList });
  70. }
  71. async addStatusToList(statusType) {
  72. const { selectedStatusList } = this.state;
  73. selectedStatusList.add(statusType);
  74. await this.setState({ selectedStatusList });
  75. this.retrieveUsersByPagingNum(1);
  76. }
  77. async deleteStatusFromList(statusType) {
  78. const { selectedStatusList } = this.state;
  79. selectedStatusList.delete(statusType);
  80. await this.setState({ selectedStatusList });
  81. this.retrieveUsersByPagingNum(1);
  82. }
  83. /**
  84. * Workaround for Increment Search Text Input
  85. */
  86. async handleChangeSearchText(searchText) {
  87. await this.setState({ searchText });
  88. this.handleChangeSearchTextDebouce();
  89. }
  90. async clearSearchText() {
  91. await this.setState({ searchText: '' });
  92. this.retrieveUsersByPagingNum(1);
  93. }
  94. /**
  95. * Workaround for Sorting
  96. */
  97. async sort(sort, isAsc) {
  98. const sortOrder = isAsc ? 'asc' : 'desc';
  99. await this.setState({ sort, sortOrder });
  100. this.retrieveUsersByPagingNum(1);
  101. }
  102. async resetAllChanges() {
  103. await this.setState({
  104. sort: 'id',
  105. sortOrder: 'asc',
  106. searchText: '',
  107. selectedStatusList: new Set(['all']),
  108. });
  109. this.retrieveUsersByPagingNum(1);
  110. }
  111. /**
  112. * syncUsers of selectedPage
  113. * @memberOf AdminUsersContainer
  114. * @param {number} selectedPage
  115. */
  116. async retrieveUsersByPagingNum(selectedPage) {
  117. const params = {
  118. page: selectedPage,
  119. sort: this.state.sort,
  120. sortOrder: this.state.sortOrder,
  121. selectedStatusList: Array.from(this.state.selectedStatusList),
  122. searchText: this.state.searchText,
  123. // Even if email is hidden, it will be displayed on admin page.
  124. forceIncludeAttributes: ['email'],
  125. };
  126. const { data } = await apiv3Get('/users', params);
  127. if (data.paginateResult == null) {
  128. throw new Error('data must conclude \'paginateResult\' property.');
  129. }
  130. const { docs: users, totalDocs: totalUsers, limit: pagingLimit } = data.paginateResult;
  131. this.setState({
  132. users,
  133. totalUsers,
  134. pagingLimit,
  135. activePage: selectedPage,
  136. });
  137. }
  138. /**
  139. * create user invited
  140. * @memberOf AdminUsersContainer
  141. * @param {object} shapedEmailList
  142. * @param {bool} sendEmail
  143. */
  144. async createUserInvited(shapedEmailList, sendEmail) {
  145. const response = await apiv3Post('/users/invite', {
  146. shapedEmailList,
  147. sendEmail,
  148. });
  149. await this.retrieveUsersByPagingNum(this.state.activePage);
  150. return response.data;
  151. }
  152. /**
  153. * open reset password modal, and props user
  154. * @memberOf AdminUsersContainer
  155. * @param {object} user
  156. */
  157. async showPasswordResetModal(user) {
  158. await this.setState({
  159. isPasswordResetModalShown: true,
  160. userForPasswordResetModal: user,
  161. });
  162. }
  163. /**
  164. * close reset password modal
  165. * @memberOf AdminUsersContainer
  166. */
  167. async hidePasswordResetModal() {
  168. await this.setState({
  169. isPasswordResetModalShown: false,
  170. userForPasswordResetModal: null,
  171. });
  172. }
  173. /**
  174. * toggle user invite modal
  175. * @memberOf AdminUsersContainer
  176. */
  177. async toggleUserInviteModal() {
  178. await this.setState({ isUserInviteModalShown: !this.state.isUserInviteModalShown });
  179. }
  180. /**
  181. * Give user admin
  182. * @memberOf AdminUsersContainer
  183. * @param {string} userId
  184. * @return {string} username
  185. */
  186. async giveUserAdmin(userId) {
  187. const response = await apiv3Put(`/users/${userId}/giveAdmin`);
  188. const { username } = response.data.userData;
  189. await this.retrieveUsersByPagingNum(this.state.activePage);
  190. return username;
  191. }
  192. /**
  193. * Remove user admin
  194. * @memberOf AdminUsersContainer
  195. * @param {string} userId
  196. * @return {string} username
  197. */
  198. async removeUserAdmin(userId) {
  199. const response = await apiv3Put(`/users/${userId}/removeAdmin`);
  200. const { username } = response.data.userData;
  201. await this.retrieveUsersByPagingNum(this.state.activePage);
  202. return username;
  203. }
  204. /**
  205. * Activate user
  206. * @memberOf AdminUsersContainer
  207. * @param {string} userId
  208. * @return {string} username
  209. */
  210. async activateUser(userId) {
  211. const response = await apiv3Put(`/users/${userId}/activate`);
  212. const { username } = response.data.userData;
  213. await this.retrieveUsersByPagingNum(this.state.activePage);
  214. return username;
  215. }
  216. /**
  217. * Deactivate user
  218. * @memberOf AdminUsersContainer
  219. * @param {string} userId
  220. * @return {string} username
  221. */
  222. async deactivateUser(userId) {
  223. const response = await apiv3Put(`/users/${userId}/deactivate`);
  224. const { username } = response.data.userData;
  225. await this.retrieveUsersByPagingNum(this.state.activePage);
  226. return username;
  227. }
  228. /**
  229. * remove user
  230. * @memberOf AdminUsersContainer
  231. * @param {string} userId
  232. * @return {object} removedUserData
  233. */
  234. async removeUser(userId) {
  235. const response = await apiv3Delete(`/users/${userId}/remove`);
  236. const removedUserData = response.data.userData;
  237. await this.retrieveUsersByPagingNum(this.state.activePage);
  238. return removedUserData;
  239. }
  240. }