UserGroupPage.jsx 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  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 { createSubscribedElement } 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. };
  21. this.xss = window.xss;
  22. this.handlePage = this.handlePage.bind(this);
  23. this.showDeleteModal = this.showDeleteModal.bind(this);
  24. this.hideDeleteModal = this.hideDeleteModal.bind(this);
  25. this.addUserGroup = this.addUserGroup.bind(this);
  26. this.deleteUserGroupById = this.deleteUserGroupById.bind(this);
  27. }
  28. async componentDidMount() {
  29. await this.syncUserGroupAndRelations();
  30. }
  31. async showDeleteModal(group) {
  32. try {
  33. await this.syncUserGroupAndRelations();
  34. this.setState({
  35. selectedUserGroup: group,
  36. isDeleteModalShow: true,
  37. });
  38. }
  39. catch (err) {
  40. toastError(err);
  41. }
  42. }
  43. hideDeleteModal() {
  44. this.setState({
  45. selectedUserGroup: undefined,
  46. isDeleteModalShow: false,
  47. });
  48. }
  49. addUserGroup(userGroup, users) {
  50. this.setState((prevState) => {
  51. const userGroupRelations = Object.assign(prevState.userGroupRelations, {
  52. [userGroup._id]: users,
  53. });
  54. return {
  55. userGroups: [...prevState.userGroups, userGroup],
  56. userGroupRelations,
  57. };
  58. });
  59. }
  60. async deleteUserGroupById({ deleteGroupId, actionName, transferToUserGroupId }) {
  61. try {
  62. const res = await this.props.appContainer.apiv3.delete(`/user-groups/${deleteGroupId}`, {
  63. actionName,
  64. transferToUserGroupId,
  65. });
  66. this.setState((prevState) => {
  67. const userGroups = prevState.userGroups.filter((userGroup) => {
  68. return userGroup._id !== deleteGroupId;
  69. });
  70. delete prevState.userGroupRelations[deleteGroupId];
  71. return {
  72. userGroups,
  73. userGroupRelations: prevState.userGroupRelations,
  74. selectedUserGroup: undefined,
  75. isDeleteModalShow: false,
  76. };
  77. });
  78. toastSuccess(`Deleted a group "${this.xss.process(res.data.userGroup.name)}"`);
  79. }
  80. catch (err) {
  81. toastError(new Error('Unable to delete the group'));
  82. }
  83. }
  84. async handlePage(selectedPage) {
  85. await this.setState({ activePage: selectedPage });
  86. await this.syncUserGroupAndRelations();
  87. }
  88. async syncUserGroupAndRelations() {
  89. let userGroups = [];
  90. let userGroupRelations = {};
  91. let totalUserGroups = 0;
  92. try {
  93. const params = { page: this.state.activePage };
  94. const responses = await Promise.all([
  95. this.props.appContainer.apiv3.get('/user-groups', params),
  96. this.props.appContainer.apiv3.get('/user-group-relations', params),
  97. ]);
  98. const [userGroupsRes, userGroupRelationsRes] = responses;
  99. userGroups = userGroupsRes.data.userGroups;
  100. totalUserGroups = userGroupsRes.data.totalUserGroups;
  101. userGroupRelations = userGroupRelationsRes.data.userGroupRelations;
  102. this.setState({
  103. userGroups,
  104. userGroupRelations,
  105. totalUserGroups,
  106. });
  107. }
  108. catch (err) {
  109. toastError(err);
  110. }
  111. }
  112. render() {
  113. return (
  114. <Fragment>
  115. <UserGroupCreateForm
  116. isAclEnabled={this.props.isAclEnabled}
  117. onCreate={this.addUserGroup}
  118. />
  119. <PaginationWrapper
  120. activePage={this.state.activePage}
  121. changePage={this.handlePage}
  122. totalItemsCount={this.state.totalUserGroups}
  123. >
  124. <UserGroupTable
  125. userGroups={this.state.userGroups}
  126. isAclEnabled={this.props.isAclEnabled}
  127. onDelete={this.showDeleteModal}
  128. userGroupRelations={this.state.userGroupRelations}
  129. />
  130. </PaginationWrapper>
  131. <UserGroupDeleteModal
  132. userGroups={this.state.userGroups}
  133. deleteUserGroup={this.state.selectedUserGroup}
  134. onDelete={this.deleteUserGroupById}
  135. isShow={this.state.isDeleteModalShow}
  136. onShow={this.showDeleteModal}
  137. onHide={this.hideDeleteModal}
  138. />
  139. </Fragment>
  140. );
  141. }
  142. }
  143. /**
  144. * Wrapper component for using unstated
  145. */
  146. const UserGroupPageWrapper = (props) => {
  147. return createSubscribedElement(UserGroupPage, props, [AppContainer]);
  148. };
  149. UserGroupPage.propTypes = {
  150. appContainer: PropTypes.instanceOf(AppContainer).isRequired,
  151. isAclEnabled: PropTypes.bool,
  152. };
  153. export default UserGroupPageWrapper;