diff --git a/frontend/src/components/dialog/manage-members-dialog.js b/frontend/src/components/dialog/manage-members-dialog.js index 54cf991617..bebe4b0557 100644 --- a/frontend/src/components/dialog/manage-members-dialog.js +++ b/frontend/src/components/dialog/manage-members-dialog.js @@ -5,6 +5,7 @@ import { gettext } from '../../utils/constants'; import { Button, Modal, ModalHeader, ModalBody, ModalFooter, Table } from 'reactstrap'; import { seafileAPI } from '../../utils/seafile-api.js'; import PermissionEditor from '../permission-editor'; +import UserSelect from '../../models/user-select'; import '../../css/manage-members-dialog.css'; const propTypes = { @@ -21,56 +22,36 @@ class ManageMembersDialog extends React.Component { this.state = { groupMembers: [], selectedOption: null, - errMessage: '', + errMessage: [], + clearSelect: false, }; - this.options = []; } - handleSelectChange = (option) => { + onSelectChange = (option) => { this.setState({ selectedOption: option, - errMessage: '', + errMessage: [], + clearSelect: false, }); - this.options = []; - } - - loadOptions = (value, callback) => { - if (value.trim().length > 0) { - seafileAPI.searchUsers(value.trim()).then((res) => { - this.options = []; - for (let i = 0 ; i < res.data.users.length; i++) { - let obj = {}; - obj.value = res.data.users[i].name; - obj.email = res.data.users[i].email; - obj.label = - - - {res.data.users[i].name} - ; - this.options.push(obj); - } - callback(this.options); - }); - } } addGroupMember = () => { - if (this.state.selectedOption && this.state.selectedOption.email) { - this.refs.memberSelect.select.onChange([], { action: 'clear' }); - seafileAPI.addGroupMember(this.props.groupID, this.state.selectedOption.email).then((res) => { - this.onGroupMembersChange(); - this.options = []; - this.setState({ - selectedOption: null, - }); - }).catch((error) => { - if (error.response) { - this.setState({ - errMessage: error.response.data.error_msg - }); - } - }); + 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) => { + this.onGroupMembersChange(); + this.setState({ + selectedOption: null, + clearSelect: true, + }); + if (res.data.failed.length > 0) { + this.setState({ + errMessage: res.data.failed + }); + } + }); } listGroupMembers = () => { @@ -100,17 +81,26 @@ class ManageMembersDialog extends React.Component {

{gettext('Add group member')}

- - + {this.state.selectedOption ? + : + + }
- {this.state.errMessage} + { + this.state.errMessage.length > 0 && + this.state.errMessage.map((item, index = 0) => { + return ( +
{item.error_msg}
+ ); + }) + }
diff --git a/frontend/src/css/manage-members-dialog.css b/frontend/src/css/manage-members-dialog.css index 0cf2193a9f..0b0daca86a 100644 --- a/frontend/src/css/manage-members-dialog.css +++ b/frontend/src/css/manage-members-dialog.css @@ -41,4 +41,7 @@ } .group-transfer .btn { width: 75px; +} +.group-error { + margin-top: 10px; } \ No newline at end of file diff --git a/frontend/src/models/user-select.js b/frontend/src/models/user-select.js new file mode 100644 index 0000000000..fd5570fc29 --- /dev/null +++ b/frontend/src/models/user-select.js @@ -0,0 +1,73 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import AsyncSelect from 'react-select/lib/Async'; +import { seafileAPI } from '../utils/seafile-api.js'; +import { gettext } from '../utils/constants'; + +const propTypes = { + placeholder: PropTypes.string.isRequired, + onSelectChange: PropTypes.func.isRequired, + clearSelect: PropTypes.bool.isRequired, + isMulti: PropTypes.bool.isRequired, + className: PropTypes.string.isRequired, +}; + +class UserSelect extends React.Component { + + constructor(props) { + super(props); + this.options = []; + } + + handleSelectChange = (option) => { + this.options = []; + this.props.onSelectChange(option); + } + + loadOptions = (input, callback) => { + const value = input.trim(); + if (value.length > 0) { + seafileAPI.searchUsers(value).then((res) => { + this.options = []; + for (let i = 0 ; i < res.data.users.length; i++) { + const item = res.data.users[i]; + let obj = {}; + obj.value = item.name; + obj.email = item.email; + obj.label = + + + {item.name} + ; + this.options.push(obj); + } + callback(this.options); + }); + } + } + + componentWillReceiveProps(nextProps) { + if (nextProps.clearSelect === true && this.props.clearSelect === false) { + this.refs.userSelect.select.onChange([], { action: 'clear' }); + } + } + + render() { + return ( + + ); + } +} + +UserSelect.propTypes = propTypes; + +export default UserSelect; \ No newline at end of file