import React, { Fragment } from 'react'; import PropTypes from 'prop-types'; import { Button, Modal, ModalHeader, ModalBody, ModalFooter, Table, Input, Label, FormGroup } from 'reactstrap'; import { Utils } from '../../utils/utils'; import { gettext } from '../../utils/constants'; import { seafileAPI } from '../../utils/seafile-api'; import RoleEditor from '../select-editor/role-editor'; import UserSelect from '../user-select'; import toaster from '../toast'; import Loading from '../loading'; import '../../css/manage-members-dialog.css'; const propTypes = { groupID: PropTypes.string.isRequired, toggleManageMembersDialog: PropTypes.func.isRequired, onGroupChanged: PropTypes.func.isRequired, isOwner: PropTypes.bool.isRequired, }; class ManageMembersDialog extends React.Component { constructor(props) { super(props); this.state = { isLoading: true, // first loading isLoadingMore: false, groupMembers: [], page: 1, perPage: 100, hasNextPage: false, selectedOption: null, errMessage: [], isItemFreezed: false, searchGroupMemberInputValue: '', }; } componentDidMount() { this.listGroupMembers(this.state.page); } listGroupMembers = (page) => { const { groupID } = this.props; const { perPage, groupMembers } = this.state; seafileAPI.listGroupMembers(groupID, page, perPage).then((res) => { const members = res.data; this.setState({ isLoading: false, isLoadingMore: false, page: page, hasNextPage: members.length < perPage ? false : true, groupMembers: groupMembers.concat(members) }); }).catch(error => { let errMessage = Utils.getErrorMsg(error); toaster.danger(errMessage); this.setState({ isLoading: false, isLoadingMore: false, hasNextPage: false }); }); } onSelectChange = (option) => { this.setState({ selectedOption: option, errMessage: [], }); } addGroupMember = () => { let emails = []; for (let i = 0; i < this.state.selectedOption.length; i++) { emails.push(this.state.selectedOption[i].email); } seafileAPI.addGroupMembers(this.props.groupID, emails).then((res) => { const newMembers = res.data.success; this.setState({ groupMembers: [].concat(newMembers, this.state.groupMembers), selectedOption: null, }); this.refs.userSelect.clearSelect(); if (res.data.failed.length > 0) { this.setState({ errMessage: res.data.failed }); } }).catch(error => { let errMessage = Utils.getErrorMsg(error); toaster.danger(errMessage); }); } handleSearchGroupMemberInputChange = (e) => { this.setState({ searchGroupMemberInputValue: e.target.value }); } searchGroupMember = () => { seafileAPI.searchGroupMember(this.props.groupID, this.state.searchGroupMemberInputValue).then((res) => { this.setState({ groupMembers: res.data, }); }).catch(error => { let errMessage = Utils.getErrorMsg(error); toaster.danger(errMessage); }); } toggleItemFreezed = (isFreezed) => { this.setState({ isItemFreezed: isFreezed }); } toggle = () => { this.props.toggleManageMembersDialog(); } handleScroll = (event) => { // isLoadingMore: to avoid repeated request const { page, hasNextPage, isLoadingMore } = this.state; if (hasNextPage && !isLoadingMore) { const clientHeight = event.target.clientHeight; const scrollHeight = event.target.scrollHeight; const scrollTop = event.target.scrollTop; const isBottom = (clientHeight + scrollTop + 1 >= scrollHeight); if (isBottom) { // scroll to the bottom this.setState({isLoadingMore: true}, () => { this.listGroupMembers(page + 1); }); } } } changeMember = (targetMember) => { this.setState({ groupMembers: this.state.groupMembers.map((item) => { if (item.email == targetMember.email) { item = targetMember; } return item; }) }); } deleteMember = (targetMember) => { const groupMembers = this.state.groupMembers; groupMembers.splice(groupMembers.indexOf(targetMember), 1); this.setState({ groupMembers: groupMembers }); } render() { const { isLoading, hasNextPage } = this.state; return ( {gettext('Manage group members')}

{gettext('Add group member')}

{this.state.selectedOption ? : }

{gettext('Search group member')}

{this.state.searchGroupMemberInputValue ? : }
{ this.state.errMessage.length > 0 && this.state.errMessage.map((item, index = 0) => { return (
{item.error_msg}
); }) }
{isLoading ? : ( { this.state.groupMembers.length > 0 && this.state.groupMembers.map((item, index) => { return ( ); }) }
{gettext('Name')} {gettext('Role')}
{hasNextPage && }
)}
); } } ManageMembersDialog.propTypes = propTypes; const MemberPropTypes = { item: PropTypes.object.isRequired, changeMember: PropTypes.func.isRequired, deleteMember: PropTypes.func.isRequired, groupID: PropTypes.string.isRequired, isOwner: PropTypes.bool.isRequired, }; class Member extends React.PureComponent { constructor(props) { super(props); this.roles = ['Admin', 'Member']; this.state = ({ highlight: false, }); } onChangeUserRole = (role) => { let isAdmin = role === 'Admin' ? 'True' : 'False'; seafileAPI.setGroupAdmin(this.props.groupID, this.props.item.email, isAdmin).then((res) => { this.props.changeMember(res.data); }).catch(error => { let errMessage = Utils.getErrorMsg(error); toaster.danger(errMessage); }); } deleteMember = () => { const { item } = this.props; seafileAPI.deleteGroupMember(this.props.groupID, item.email).then((res) => { this.props.deleteMember(item); toaster.success(gettext('Successfully deleted {name}.').replace('{name}', item.name)); }).catch(error => { let errMessage = Utils.getErrorMsg(error); toaster.danger(errMessage); }); } handleMouseOver = () => { if (this.props.isItemFreezed) return; this.setState({ highlight: true, }); } handleMouseLeave = () => { if (this.props.isItemFreezed) return; this.setState({ highlight: false, }); } translateRole = (role) => { if (role === 'Admin') { return gettext('Admin'); } else if (role === 'Member') { return gettext('Member'); } else if (role === 'Owner') { return gettext('Owner'); } } render() { const { item, isOwner } = this.props; const deleteAuthority = (item.role !== 'Owner' && isOwner === true) || (item.role === 'Member' && isOwner === false); return( {item.name} {((isOwner === false) || (isOwner === true && item.role === 'Owner')) && {this.translateRole(item.role)} } {(isOwner === true && item.role !== 'Owner') && } {(deleteAuthority && !this.props.isItemFreezed) && } ); } } Member.propTypes = MemberPropTypes; export default ManageMembersDialog;