UserGroupDetailContainer.js 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. import { Container } from 'unstated';
  2. import loggerFactory from '@alias/logger';
  3. import { toastError } from '../util/apiNotification';
  4. // eslint-disable-next-line no-unused-vars
  5. const logger = loggerFactory('growi:services:UserGroupDetailContainer');
  6. /**
  7. * Service container for admin user group detail page (UserGroupDetailPage.jsx)
  8. * @extends {Container} unstated Container
  9. */
  10. export default class UserGroupDetailContainer extends Container {
  11. constructor(appContainer) {
  12. super();
  13. this.appContainer = appContainer;
  14. this.state = {
  15. // TODO: [SPA] get userGroup from props
  16. userGroup: JSON.parse(document.getElementById('admin-user-group-detail').getAttribute('data-user-group')),
  17. userGroupRelations: [],
  18. relatedPages: [],
  19. isUserGroupUserModalOpen: false,
  20. searchType: 'partial',
  21. isAlsoMailSearched: false,
  22. isAlsoNameSearched: false,
  23. };
  24. this.init();
  25. this.switchIsAlsoMailSearched = this.switchIsAlsoMailSearched.bind(this);
  26. this.switchIsAlsoNameSearched = this.switchIsAlsoNameSearched.bind(this);
  27. this.openUserGroupUserModal = this.openUserGroupUserModal.bind(this);
  28. this.closeUserGroupUserModal = this.closeUserGroupUserModal.bind(this);
  29. this.addUserByUsername = this.addUserByUsername.bind(this);
  30. this.removeUserByUsername = this.removeUserByUsername.bind(this);
  31. }
  32. /**
  33. * Workaround for the mangling in production build to break constructor.name
  34. */
  35. static getClassName() {
  36. return 'UserGroupDetailContainer';
  37. }
  38. /**
  39. * retrieve user group data
  40. */
  41. async init() {
  42. try {
  43. const [
  44. userGroupRelations,
  45. relatedPages,
  46. ] = await Promise.all([
  47. this.appContainer.apiv3.get(`/user-groups/${this.state.userGroup._id}/user-group-relations`).then((res) => { return res.data.userGroupRelations }),
  48. this.appContainer.apiv3.get(`/user-groups/${this.state.userGroup._id}/pages`).then((res) => { return res.data.pages }),
  49. ]);
  50. await this.setState({
  51. userGroupRelations,
  52. relatedPages,
  53. });
  54. }
  55. catch (err) {
  56. logger.error(err);
  57. toastError(new Error('Failed to fetch data'));
  58. }
  59. }
  60. /**
  61. * switch isAlsoMailSearched
  62. */
  63. switchIsAlsoMailSearched() {
  64. this.setState({ isAlsoMailSearched: !this.state.isAlsoMailSearched });
  65. }
  66. /**
  67. * switch isAlsoNameSearched
  68. */
  69. switchIsAlsoNameSearched() {
  70. this.setState({ isAlsoNameSearched: !this.state.isAlsoNameSearched });
  71. }
  72. /**
  73. * switch searchType
  74. */
  75. switchSearchType(searchType) {
  76. this.setState({ searchType });
  77. }
  78. /**
  79. * update user group
  80. *
  81. * @memberOf UserGroupDetailContainer
  82. * @param {object} param update param for user group
  83. * @return {object} response object
  84. */
  85. async updateUserGroup(param) {
  86. const res = await this.appContainer.apiv3.put(`/user-groups/${this.state.userGroup._id}`, param);
  87. const { userGroup } = res.data;
  88. await this.setState({ userGroup });
  89. return res;
  90. }
  91. /**
  92. * open a modal
  93. *
  94. * @memberOf UserGroupDetailContainer
  95. */
  96. async openUserGroupUserModal() {
  97. await this.setState({ isUserGroupUserModalOpen: true });
  98. }
  99. /**
  100. * close a modal
  101. *
  102. * @memberOf UserGroupDetailContainer
  103. */
  104. async closeUserGroupUserModal() {
  105. await this.setState({ isUserGroupUserModalOpen: false });
  106. }
  107. /**
  108. * search user for invitation
  109. * @param {string} username username of the user to be searched
  110. */
  111. async fetchApplicableUsers(searchWord) {
  112. const res = await this.appContainer.apiv3.get(`/user-groups/${this.state.userGroup._id}/unrelated-users`, {
  113. searchWord,
  114. searchType: this.state.searchType,
  115. isAlsoMailSearched: this.state.isAlsoMailSearched,
  116. isAlsoNameSearched: this.state.isAlsoNameSearched,
  117. });
  118. const { users } = res.data;
  119. return users;
  120. }
  121. /**
  122. * update user group
  123. *
  124. * @memberOf UserGroupDetailContainer
  125. * @param {string} username username of the user to be added to the group
  126. */
  127. async addUserByUsername(username) {
  128. const res = await this.appContainer.apiv3.post(`/user-groups/${this.state.userGroup._id}/users/${username}`);
  129. // do not add users for ducaplicate
  130. if (res.data.userGroupRelation == null) { return }
  131. const { userGroupRelation } = res.data;
  132. this.setState((prevState) => {
  133. return {
  134. userGroupRelations: [...prevState.userGroupRelations, userGroupRelation],
  135. };
  136. });
  137. }
  138. /**
  139. * update user group
  140. *
  141. * @memberOf UserGroupDetailContainer
  142. * @param {string} username username of the user to be removed from the group
  143. */
  144. async removeUserByUsername(username) {
  145. const res = await this.appContainer.apiv3.delete(`/user-groups/${this.state.userGroup._id}/users/${username}`);
  146. this.setState((prevState) => {
  147. return {
  148. userGroupRelations: prevState.userGroupRelations.filter((u) => { return u._id !== res.data.userGroupRelation._id }),
  149. };
  150. });
  151. }
  152. }