/* eslint-disable react/no-multi-comp */ import React, { Fragment } from 'react'; import PropTypes from 'prop-types'; import { Subscribe } from 'unstated'; import UserGroupTable from './UserGroupTable'; import UserGroupCreateForm from './UserGroupCreateForm'; import UserGroupDeleteModal from './UserGroupDeleteModal'; import { apiErrorHandler, apiSuccessHandler } from '../../../util/apiNotification'; class UserGroupPage extends React.Component { constructor(props) { super(props); this.state = { userGroups: props.userGroups, userGroupRelations: props.userGroupRelations, selectedUserGroup: undefined, // not null but undefined (to use defaultProps in UserGroupDeleteModal) isDeleteModalShow: false, }; this.xss = window.xss; this.showDeleteModal = this.showDeleteModal.bind(this); this.hideDeleteModal = this.hideDeleteModal.bind(this); this.addUserGroup = this.addUserGroup.bind(this); this.deleteUserGroupById = this.deleteUserGroupById.bind(this); } async showDeleteModal(group) { await this.syncUserGroupAndRelations(); this.setState({ selectedUserGroup: group, isDeleteModalShow: true, }); } hideDeleteModal() { this.setState({ selectedUserGroup: undefined, isDeleteModalShow: false, }); } addUserGroup(userGroup, users) { this.setState((prevState) => { const userGroupRelations = Object.assign(prevState.userGroupRelations, { [userGroup._id]: users, }); return { userGroups: [...prevState.userGroups, userGroup], userGroupRelations, }; }); } async deleteUserGroupById({ deleteGroupId, actionName, transferToUserGroupId }) { try { const res = await this.props.crowi.apiv3.post(`/user-groups/${deleteGroupId}/delete`, { actionName, transferToUserGroupId, }); if (res.errors) { return apiErrorHandler(res.errors); } this.setState((prevState) => { const userGroups = prevState.userGroups.filter((userGroup) => { return userGroup._id !== deleteGroupId; }); delete prevState.userGroupRelations[deleteGroupId]; return { userGroups, userGroupRelations: prevState.userGroupRelations, selectedUserGroup: undefined, isDeleteModalShow: false, }; }); apiSuccessHandler(`Deleted a group "${this.xss.process(res.data.userGroup.name)}"`); } catch (err) { apiErrorHandler(new Error('Unable to delete the group')); } } async syncUserGroupAndRelations() { let userGroups = []; let userGroupRelations = []; try { const responses = await Promise.all([ this.props.crowi.apiv3.get('/user-groups'), this.props.crowi.apiv3.get('/user-group-relations'), ]); const isAllOk = responses.reduce((isAllOk, res) => { return isAllOk && !res.errors; }, true); if (isAllOk) { const [userGroupsRes, userGroupRelationsRes] = responses; userGroups = userGroupsRes.data.userGroups; userGroupRelations = userGroupRelationsRes.data.userGroupRelations; } else { throw new Error('Unable to fetch groups from server'); } } catch (err) { apiErrorHandler(err); } this.setState({ userGroups, userGroupRelations, }); } render() { return ( ); } } /** * Wrapper component for using unstated */ class UserGroupPageWrapper extends React.PureComponent { render() { return ( {() => ( // eslint-disable-next-line arrow-body-style )} ); } } UserGroupPage.propTypes = { crowi: PropTypes.object.isRequired, userGroups: PropTypes.arrayOf(PropTypes.object).isRequired, userGroupRelations: PropTypes.object.isRequired, isAclEnabled: PropTypes.bool, }; UserGroupPageWrapper.propTypes = { crowi: PropTypes.object.isRequired, userGroups: PropTypes.arrayOf(PropTypes.object).isRequired, userGroupRelations: PropTypes.object.isRequired, isAclEnabled: PropTypes.bool, }; export default UserGroupPageWrapper;