| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445 |
- import React, { PureComponent as Component } from 'react';
- import {
- Table,
- Card,
- Badge,
- Select,
- Button,
- Modal,
- Row,
- Col,
- message,
- Popconfirm,
- Switch,
- Tooltip
- } from 'antd';
- import PropTypes from 'prop-types';
- import { fetchGroupMsg } from '../../../../reducer/modules/group';
- import { connect } from 'react-redux';
- import ErrMsg from '../../../../components/ErrMsg/ErrMsg.js';
- import { fetchGroupMemberList } from '../../../../reducer/modules/group.js';
- import {
- fetchProjectList,
- getProjectMemberList,
- getProject,
- addMember,
- delMember,
- changeMemberRole,
- changeMemberEmailNotice
- } from '../../../../reducer/modules/project.js';
- import UsernameAutoComplete from '../../../../components/UsernameAutoComplete/UsernameAutoComplete.js';
- import '../Setting.scss';
- const Option = Select.Option;
- const arrayAddKey = arr => {
- return arr.map((item, index) => {
- return {
- ...item,
- key: index
- };
- });
- };
- @connect(
- state => {
- return {
- projectMsg: state.project.currProject,
- uid: state.user.uid,
- projectList: state.project.projectList
- };
- },
- {
- fetchGroupMemberList,
- getProjectMemberList,
- addMember,
- delMember,
- fetchGroupMsg,
- changeMemberRole,
- getProject,
- fetchProjectList,
- changeMemberEmailNotice
- }
- )
- class ProjectMember extends Component {
- constructor(props) {
- super(props);
- this.state = {
- groupMemberList: [],
- projectMemberList: [],
- groupName: '',
- role: '',
- visible: false,
- dataSource: [],
- inputUids: [],
- inputRole: 'dev',
- modalVisible: false,
- selectProjectId: 0
- };
- }
- static propTypes = {
- match: PropTypes.object,
- projectId: PropTypes.number,
- projectMsg: PropTypes.object,
- uid: PropTypes.number,
- addMember: PropTypes.func,
- delMember: PropTypes.func,
- changeMemberRole: PropTypes.func,
- getProject: PropTypes.func,
- fetchGroupMemberList: PropTypes.func,
- fetchGroupMsg: PropTypes.func,
- getProjectMemberList: PropTypes.func,
- fetchProjectList: PropTypes.func,
- projectList: PropTypes.array,
- changeMemberEmailNotice: PropTypes.func
- };
- showAddMemberModal = () => {
- this.setState({
- visible: true
- });
- };
- showImportMemberModal = async () => {
- await this.props.fetchProjectList(this.props.projectMsg.group_id);
- this.setState({
- modalVisible: true
- });
- };
- // 重新获取列表
- reFetchList = () => {
- this.props.getProjectMemberList(this.props.match.params.id).then(res => {
- this.setState({
- projectMemberList: arrayAddKey(res.payload.data.data),
- visible: false,
- modalVisible: false
- });
- });
- };
- handleOk = () => {
- this.addMembers(this.state.inputUids);
- };
- // 增 - 添加成员
- addMembers = memberUids => {
- this.props
- .addMember({
- id: this.props.match.params.id,
- member_uids: memberUids,
- role: this.state.inputRole
- })
- .then(res => {
- if (!res.payload.data.errcode) {
- const { add_members, exist_members } = res.payload.data.data;
- const addLength = add_members.length;
- const existLength = exist_members.length;
- this.setState({
- inputRole: 'dev',
- inputUids: []
- });
- message.success(`添加成功! 已成功添加 ${addLength} 人,其中 ${existLength} 人已存在`);
- this.reFetchList(); // 添加成功后重新获取分组成员列表
- }
- });
- };
- // 添加成员时 选择新增成员权限
- changeNewMemberRole = value => {
- this.setState({
- inputRole: value
- });
- };
- // 删 - 删除分组成员
- deleteConfirm = member_uid => {
- return () => {
- const id = this.props.match.params.id;
- this.props.delMember({ id, member_uid }).then(res => {
- if (!res.payload.data.errcode) {
- message.success(res.payload.data.errmsg);
- this.reFetchList(); // 添加成功后重新获取分组成员列表
- }
- });
- };
- };
- // 改 - 修改成员权限
- changeUserRole = e => {
- const id = this.props.match.params.id;
- const role = e.split('-')[0];
- const member_uid = e.split('-')[1];
- this.props.changeMemberRole({ id, member_uid, role }).then(res => {
- if (!res.payload.data.errcode) {
- message.success(res.payload.data.errmsg);
- this.reFetchList(); // 添加成功后重新获取分组成员列表
- }
- });
- };
- // 修改用户是否接收消息通知
- changeEmailNotice = async (notice, member_uid) => {
- const id = this.props.match.params.id;
- await this.props.changeMemberEmailNotice({ id, member_uid, notice });
- this.reFetchList(); // 添加成功后重新获取项目成员列表
- };
- // 关闭模态框
- handleCancel = () => {
- this.setState({
- visible: false
- });
- };
- // 关闭批量导入模态框
- handleModalCancel = () => {
- this.setState({
- modalVisible: false
- });
- };
- // 处理选择项目
- handleChange = key => {
- this.setState({
- selectProjectId: key
- });
- };
- // 确定批量导入模态框
- handleModalOk = async () => {
- // 获取项目中的成员列表
- const menberList = await this.props.getProjectMemberList(this.state.selectProjectId);
- const memberUidList = menberList.payload.data.data.map(item => {
- return item.uid;
- });
- this.addMembers(memberUidList);
- };
- onUserSelect = uids => {
- this.setState({
- inputUids: uids
- });
- };
- async componentWillMount() {
- const groupMemberList = await this.props.fetchGroupMemberList(this.props.projectMsg.group_id);
- const groupMsg = await this.props.fetchGroupMsg(this.props.projectMsg.group_id);
- const projectMemberList = await this.props.getProjectMemberList(this.props.match.params.id);
- this.setState({
- groupMemberList: groupMemberList.payload.data.data,
- groupName: groupMsg.payload.data.data.group_name,
- projectMemberList: arrayAddKey(projectMemberList.payload.data.data),
- role: this.props.projectMsg.role
- });
- }
- render() {
- const isEmailChangeEable = this.state.role === 'owner' || this.state.role === 'admin';
- const columns = [
- {
- title:
- this.props.projectMsg.name + ' 项目成员 (' + this.state.projectMemberList.length + ') 人',
- dataIndex: 'username',
- key: 'username',
- render: (text, record) => {
- return (
- <div className="m-user">
- <img src={'/api/user/avatar?uid=' + record.uid} className="m-user-img" />
- <p className="m-user-name">{text}</p>
- <Tooltip placement="top" title="消息通知">
- <span>
- <Switch
- size="small"
- checkedChildren="开"
- unCheckedChildren="关"
- checked={record.email_notice}
- disabled={!(isEmailChangeEable || record.uid === this.props.uid)}
- onChange={e => this.changeEmailNotice(e, record.uid)}
- />
- </span>
- </Tooltip>
- </div>
- );
- }
- },
- {
- title:
- this.state.role === 'owner' || this.state.role === 'admin' ? (
- <div className="btn-container">
- <Button className="btn" type="primary" icon="plus" onClick={this.showAddMemberModal}>
- 添加成员
- </Button>
- <Button className="btn" icon="plus" onClick={this.showImportMemberModal}>
- 批量导入成员
- </Button>
- </div>
- ) : (
- ''
- ),
- key: 'action',
- className: 'member-opration',
- render: (text, record) => {
- if (this.state.role === 'owner' || this.state.role === 'admin') {
- return (
- <div>
- <Select
- value={record.role + '-' + record.uid}
- className="select"
- onChange={this.changeUserRole}
- >
- <Option value={'owner-' + record.uid}>组长</Option>
- <Option value={'dev-' + record.uid}>开发者</Option>
- <Option value={'guest-' + record.uid}>访客</Option>
- </Select>
- <Popconfirm
- placement="topRight"
- title="你确定要删除吗? "
- onConfirm={this.deleteConfirm(record.uid)}
- okText="确定"
- cancelText=""
- >
- <Button type="danger" icon="delete" className="btn-danger" />
- </Popconfirm>
- </div>
- );
- } else {
- // 非管理员可以看到权限 但无法修改
- if (record.role === 'owner') {
- return '组长';
- } else if (record.role === 'dev') {
- return '开发者';
- } else if (record.role === 'guest') {
- return '访客';
- } else {
- return '';
- }
- }
- }
- }
- ];
- // 获取当前分组下的所有项目名称
- const children = this.props.projectList.map((item, index) => (
- <Option key={index} value={'' + item._id}>
- {item.name}
- </Option>
- ));
- return (
- <div className="g-row">
- <div className="m-panel">
- {this.state.visible ? (
- <Modal
- title="添加成员"
- visible={this.state.visible}
- onOk={this.handleOk}
- onCancel={this.handleCancel}
- >
- <Row gutter={6} className="modal-input">
- <Col span="5">
- <div className="label usernamelabel">用户名: </div>
- </Col>
- <Col span="15">
- <UsernameAutoComplete callbackState={this.onUserSelect} />
- </Col>
- </Row>
- <Row gutter={6} className="modal-input">
- <Col span="5">
- <div className="label usernamelabel">权限: </div>
- </Col>
- <Col span="15">
- <Select defaultValue="dev" className="select" onChange={this.changeNewMemberRole}>
- <Option value="owner">组长</Option>
- <Option value="dev">开发者</Option>
- <Option value="guest">访客</Option>
- </Select>
- </Col>
- </Row>
- </Modal>
- ) : (
- ''
- )}
- <Modal
- title="批量导入成员"
- visible={this.state.modalVisible}
- onOk={this.handleModalOk}
- onCancel={this.handleModalCancel}
- >
- <Row gutter={6} className="modal-input">
- <Col span="5">
- <div className="label usernamelabel">项目名: </div>
- </Col>
- <Col span="15">
- <Select
- showSearch
- style={{ width: 200 }}
- placeholder="请选择项目名称"
- optionFilterProp="children"
- onChange={this.handleChange}
- >
- {children}
- </Select>
- </Col>
- </Row>
- </Modal>
- <Table
- columns={columns}
- dataSource={this.state.projectMemberList}
- pagination={false}
- locale={{ emptyText: <ErrMsg type="noMemberInProject" /> }}
- className="setting-project-member"
- />
- <Card
- bordered={false}
- title={
- this.state.groupName + ' 分组成员 ' + '(' + this.state.groupMemberList.length + ') 人'
- }
- hoverable={true}
- className="setting-group"
- >
- {this.state.groupMemberList.length ? (
- this.state.groupMemberList.map((item, index) => {
- return (
- <div key={index} className="card-item">
- <img
- src={
- location.protocol +
- '//' +
- location.host +
- '/api/user/avatar?uid=' +
- item.uid
- }
- className="item-img"
- />
- <p className="item-name">
- {item.username}
- {item.uid === this.props.uid ? (
- <Badge
- count={'我'}
- style={{
- backgroundColor: '#689bd0',
- fontSize: '13px',
- marginLeft: '8px',
- borderRadius: '4px'
- }}
- />
- ) : null}
- </p>
- {item.role === 'owner' ? <p className="item-role">组长</p> : null}
- {item.role === 'dev' ? <p className="item-role">开发者</p> : null}
- {item.role === 'guest' ? <p className="item-role">访客</p> : null}
- </div>
- );
- })
- ) : (
- <ErrMsg type="noMemberInGroup" />
- )}
- </Card>
- </div>
- </div>
- );
- }
- }
- export default ProjectMember;
|