UserGroupPage.jsx 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. import React, { Fragment } from 'react';
  2. import PropTypes from 'prop-types';
  3. import PaginationWrapper from '../../PaginationWrapper';
  4. import UserGroupTable from './UserGroupTable';
  5. import UserGroupCreateForm from './UserGroupCreateForm';
  6. import UserGroupDeleteModal from './UserGroupDeleteModal';
  7. import { withUnstatedContainers } from '../../UnstatedUtils';
  8. import AppContainer from '../../../services/AppContainer';
  9. import { toastSuccess, toastError } from '../../../util/apiNotification';
  10. class UserGroupPage extends React.Component {
  11. constructor(props) {
  12. super(props);
  13. this.state = {
  14. userGroups: [],
  15. userGroupRelations: {},
  16. selectedUserGroup: undefined, // not null but undefined (to use defaultProps in UserGroupDeleteModal)
  17. isDeleteModalShow: false,
  18. activePage: 1,
  19. totalUserGroups: 0,
  20. pagingLimit: Infinity,
  21. };
  22. this.xss = window.xss;
  23. this.handlePage = this.handlePage.bind(this);
  24. this.showDeleteModal = this.showDeleteModal.bind(this);
  25. this.hideDeleteModal = this.hideDeleteModal.bind(this);
  26. this.addUserGroup = this.addUserGroup.bind(this);
  27. this.deleteUserGroupById = this.deleteUserGroupById.bind(this);
  28. }
  29. async componentDidMount() {
  30. await this.syncUserGroupAndRelations();
  31. }
  32. async showDeleteModal(group) {
  33. try {
  34. await this.syncUserGroupAndRelations();
  35. this.setState({
  36. selectedUserGroup: group,
  37. isDeleteModalShow: true,
  38. });
  39. }
  40. catch (err) {
  41. toastError(err);
  42. }
  43. }
  44. hideDeleteModal() {
  45. this.setState({
  46. selectedUserGroup: undefined,
  47. isDeleteModalShow: false,
  48. });
  49. }
  50. addUserGroup(userGroup, users) {
  51. this.setState((prevState) => {
  52. const userGroupRelations = Object.assign(prevState.userGroupRelations, {
  53. [userGroup._id]: users,
  54. });
  55. return {
  56. userGroups: [...prevState.userGroups, userGroup],
  57. userGroupRelations,
  58. };
  59. });
  60. }
  61. async deleteUserGroupById({ deleteGroupId, actionName, transferToUserGroupId }) {
  62. try {
  63. const res = await this.props.appContainer.apiv3.delete(`/user-groups/${deleteGroupId}`, {
  64. actionName,
  65. transferToUserGroupId,
  66. });
  67. this.setState((prevState) => {
  68. const userGroups = prevState.userGroups.filter((userGroup) => {
  69. return userGroup._id !== deleteGroupId;
  70. });
  71. delete prevState.userGroupRelations[deleteGroupId];
  72. return {
  73. userGroups,
  74. userGroupRelations: prevState.userGroupRelations,
  75. selectedUserGroup: undefined,
  76. isDeleteModalShow: false,
  77. };
  78. });
  79. toastSuccess(`Deleted a group "${this.xss.process(res.data.userGroup.name)}"`);
  80. }
  81. catch (err) {
  82. toastError(new Error('Unable to delete the group'));
  83. }
  84. }
  85. async handlePage(selectedPage) {
  86. await this.setState({ activePage: selectedPage });
  87. await this.syncUserGroupAndRelations();
  88. }
  89. async syncUserGroupAndRelations() {
  90. let userGroups = [];
  91. let userGroupRelations = {};
  92. let totalUserGroups = 0;
  93. let pagingLimit = Infinity;
  94. try {
  95. const params = { page: this.state.activePage };
  96. const responses = await Promise.all([
  97. this.props.appContainer.apiv3.get('/user-groups', params),
  98. this.props.appContainer.apiv3.get('/user-group-relations', params),
  99. ]);
  100. const [userGroupsRes, userGroupRelationsRes] = responses;
  101. userGroups = userGroupsRes.data.userGroups;
  102. totalUserGroups = userGroupsRes.data.totalUserGroups;
  103. pagingLimit = userGroupsRes.data.pagingLimit;
  104. userGroupRelations = userGroupRelationsRes.data.userGroupRelations;
  105. this.setState({
  106. userGroups,
  107. userGroupRelations,
  108. totalUserGroups,
  109. pagingLimit,
  110. });
  111. }
  112. catch (err) {
  113. toastError(err);
  114. }
  115. }
  116. render() {
  117. const { isAclEnabled } = this.props.appContainer.config;
  118. return (
  119. <Fragment>
  120. <UserGroupCreateForm
  121. isAclEnabled={isAclEnabled}
  122. onCreate={this.addUserGroup}
  123. />
  124. <UserGroupTable
  125. userGroups={this.state.userGroups}
  126. isAclEnabled={isAclEnabled}
  127. onDelete={this.showDeleteModal}
  128. userGroupRelations={this.state.userGroupRelations}
  129. />
  130. {this.state.userGroups.length === 0
  131. ? <p>No groups yet</p> : (
  132. <PaginationWrapper
  133. activePage={this.state.activePage}
  134. changePage={this.handlePage}
  135. totalItemsCount={this.state.totalUserGroups}
  136. pagingLimit={this.state.pagingLimit}
  137. align="center"
  138. size="sm"
  139. />
  140. )}
  141. <UserGroupDeleteModal
  142. userGroups={this.state.userGroups}
  143. deleteUserGroup={this.state.selectedUserGroup}
  144. onDelete={this.deleteUserGroupById}
  145. isShow={this.state.isDeleteModalShow}
  146. onShow={this.showDeleteModal}
  147. onHide={this.hideDeleteModal}
  148. />
  149. </Fragment>
  150. );
  151. }
  152. }
  153. /**
  154. * Wrapper component for using unstated
  155. */
  156. const UserGroupPageWrapper = withUnstatedContainers(UserGroupPage, [AppContainer]);
  157. UserGroupPage.propTypes = {
  158. appContainer: PropTypes.instanceOf(AppContainer).isRequired,
  159. };
  160. export default UserGroupPageWrapper;