2017-07-12 11:43:10 +08:00
|
|
|
|
import React, { Component } from 'react'
|
|
|
|
|
import PropTypes from 'prop-types'
|
|
|
|
|
import { connect } from 'react-redux'
|
2017-08-16 17:13:14 +08:00
|
|
|
|
import { Button, Icon, Modal,Alert, Input, message, Menu, Row, Col } from 'antd'
|
2017-07-12 15:41:11 +08:00
|
|
|
|
import { autobind } from 'core-decorators';
|
2017-07-18 15:06:12 +08:00
|
|
|
|
import axios from 'axios';
|
2017-07-25 13:17:54 +08:00
|
|
|
|
import { withRouter } from 'react-router';
|
2017-07-25 10:31:19 +08:00
|
|
|
|
const { TextArea } = Input;
|
2017-07-18 18:23:38 +08:00
|
|
|
|
const Search = Input.Search;
|
2017-07-19 14:53:51 +08:00
|
|
|
|
const TYPE_EDIT = 'edit';
|
2017-08-16 17:13:14 +08:00
|
|
|
|
const confirm = Modal.confirm;
|
|
|
|
|
import UsernameAutoComplete from '../../../components/UsernameAutoComplete/UsernameAutoComplete.js';
|
2017-07-12 11:43:10 +08:00
|
|
|
|
import {
|
|
|
|
|
fetchGroupList,
|
2017-07-17 10:17:29 +08:00
|
|
|
|
setCurrGroup,
|
2017-07-19 17:17:07 +08:00
|
|
|
|
setGroupList
|
2017-08-08 10:07:55 +08:00
|
|
|
|
} from '../../../reducer/modules/group.js'
|
2017-07-12 11:43:10 +08:00
|
|
|
|
|
|
|
|
|
import './GroupList.scss'
|
|
|
|
|
|
|
|
|
|
@connect(
|
|
|
|
|
state => ({
|
|
|
|
|
groupList: state.group.groupList,
|
2017-08-01 15:03:34 +08:00
|
|
|
|
currGroup: state.group.currGroup,
|
2017-08-10 21:20:57 +08:00
|
|
|
|
curUserRole: state.user.role
|
2017-07-12 11:43:10 +08:00
|
|
|
|
}),
|
|
|
|
|
{
|
|
|
|
|
fetchGroupList,
|
2017-07-17 10:17:29 +08:00
|
|
|
|
setCurrGroup,
|
2017-07-19 17:17:07 +08:00
|
|
|
|
setGroupList
|
2017-07-12 11:43:10 +08:00
|
|
|
|
}
|
|
|
|
|
)
|
2017-07-25 13:17:54 +08:00
|
|
|
|
@withRouter
|
2017-07-12 11:43:10 +08:00
|
|
|
|
export default class GroupList extends Component {
|
|
|
|
|
|
|
|
|
|
static propTypes = {
|
|
|
|
|
groupList: PropTypes.array,
|
2017-07-17 10:17:29 +08:00
|
|
|
|
currGroup: PropTypes.object,
|
|
|
|
|
fetchGroupList: PropTypes.func,
|
2017-07-19 10:39:59 +08:00
|
|
|
|
setCurrGroup: PropTypes.func,
|
2017-07-25 13:17:54 +08:00
|
|
|
|
setGroupList: PropTypes.func,
|
|
|
|
|
match: PropTypes.object,
|
2017-08-01 15:03:34 +08:00
|
|
|
|
history: PropTypes.object,
|
|
|
|
|
curUserRole: PropTypes.string
|
2017-07-12 16:38:42 +08:00
|
|
|
|
}
|
|
|
|
|
|
2017-07-18 15:06:12 +08:00
|
|
|
|
state = {
|
|
|
|
|
addGroupModalVisible: false,
|
2017-07-19 14:53:51 +08:00
|
|
|
|
editGroupModalVisible: false,
|
2017-07-18 15:06:12 +08:00
|
|
|
|
newGroupName: '',
|
2017-07-19 17:17:07 +08:00
|
|
|
|
newGroupDesc: '',
|
|
|
|
|
currGroupName: '',
|
|
|
|
|
currGroupDesc: '',
|
2017-08-16 17:13:14 +08:00
|
|
|
|
groupList: [],
|
|
|
|
|
owner_uid: 0
|
2017-07-18 15:06:12 +08:00
|
|
|
|
}
|
|
|
|
|
|
2017-07-12 16:38:42 +08:00
|
|
|
|
constructor(props) {
|
|
|
|
|
super(props)
|
|
|
|
|
}
|
|
|
|
|
|
2017-08-09 13:48:06 +08:00
|
|
|
|
async componentWillMount() {
|
2017-07-25 13:17:54 +08:00
|
|
|
|
const groupName = this.props.match.params.groupName;
|
2017-08-09 13:48:06 +08:00
|
|
|
|
await this.props.fetchGroupList();
|
|
|
|
|
let currGroup = this.props.groupList[0] || { group_name: '', group_desc: '' };
|
|
|
|
|
if(this.props.groupList.length && groupName){
|
|
|
|
|
for(let i = 0;i<this.props.groupList.length;i++){
|
|
|
|
|
if(this.props.groupList[i].group_name === groupName){
|
|
|
|
|
currGroup = this.props.groupList[i];
|
|
|
|
|
}else{
|
|
|
|
|
this.props.history.replace(`${currGroup._id}`);
|
2017-07-25 13:17:54 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
2017-08-09 13:48:06 +08:00
|
|
|
|
}else if(!groupName && this.props.groupList.length){
|
|
|
|
|
this.props.history.push(`/group/${this.props.groupList[0]._id}`);
|
|
|
|
|
}
|
|
|
|
|
this.setState({groupList: this.props.groupList});
|
|
|
|
|
this.props.setCurrGroup(currGroup)
|
2017-07-12 15:41:11 +08:00
|
|
|
|
}
|
|
|
|
|
|
2017-07-18 15:06:12 +08:00
|
|
|
|
@autobind
|
2017-07-19 14:53:51 +08:00
|
|
|
|
showModal(type) {
|
|
|
|
|
if (type === 'edit') {
|
|
|
|
|
const { currGroup } = this.props;
|
|
|
|
|
this.setState({
|
|
|
|
|
currGroupName: currGroup.group_name,
|
|
|
|
|
currGroupDesc: currGroup.group_desc,
|
|
|
|
|
editGroupModalVisible: true
|
|
|
|
|
});
|
|
|
|
|
} else {
|
|
|
|
|
this.setState({
|
|
|
|
|
addGroupModalVisible: true
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@autobind
|
|
|
|
|
hideModal(type) {
|
|
|
|
|
if (type === TYPE_EDIT) {
|
|
|
|
|
this.setState({
|
|
|
|
|
editGroupModalVisible: false
|
|
|
|
|
});
|
|
|
|
|
} else {
|
|
|
|
|
this.setState({
|
|
|
|
|
addGroupModalVisible: false
|
|
|
|
|
});
|
|
|
|
|
}
|
2017-07-18 15:06:12 +08:00
|
|
|
|
}
|
2017-07-12 15:41:11 +08:00
|
|
|
|
@autobind
|
2017-08-09 13:48:06 +08:00
|
|
|
|
async addGroup() {
|
2017-08-16 17:13:14 +08:00
|
|
|
|
const { newGroupName: group_name, newGroupDesc: group_desc, owner_uid } = this.state;
|
|
|
|
|
const res = await axios.post('/api/group/add', { group_name, group_desc, owner_uid })
|
2017-08-09 13:48:06 +08:00
|
|
|
|
if (!res.data.errcode) {
|
|
|
|
|
this.setState({
|
|
|
|
|
addGroupModalVisible: false
|
|
|
|
|
});
|
|
|
|
|
await this.props.fetchGroupList();
|
|
|
|
|
this.setState({groupList: this.props.groupList});
|
|
|
|
|
this.props.setCurrGroup(res.data.data)
|
|
|
|
|
}
|
2017-07-18 15:06:12 +08:00
|
|
|
|
}
|
|
|
|
|
@autobind
|
2017-08-09 13:48:06 +08:00
|
|
|
|
async editGroup() {
|
2017-07-19 14:53:51 +08:00
|
|
|
|
const { currGroupName: group_name, currGroupDesc: group_desc } = this.state;
|
|
|
|
|
const id = this.props.currGroup._id;
|
2017-08-11 10:25:19 +08:00
|
|
|
|
const res = axios.post('/api/group/up', { group_name, group_desc, id });
|
2017-08-09 13:48:06 +08:00
|
|
|
|
if (res.data.errcode) {
|
|
|
|
|
message.error(res.data.errmsg);
|
|
|
|
|
} else {
|
|
|
|
|
this.setState({
|
|
|
|
|
editGroupModalVisible: false
|
|
|
|
|
});
|
|
|
|
|
this.props.setCurrGroup({ group_name, group_desc, _id: id });
|
|
|
|
|
}
|
2017-07-18 15:06:12 +08:00
|
|
|
|
}
|
|
|
|
|
@autobind
|
2017-07-19 14:53:51 +08:00
|
|
|
|
inputNewGroupName(e, type) {
|
|
|
|
|
if (type === TYPE_EDIT) {
|
|
|
|
|
this.setState({ currGroupName: e.target.value})
|
|
|
|
|
} else {
|
|
|
|
|
this.setState({newGroupName: e.target.value});
|
|
|
|
|
}
|
2017-07-18 15:06:12 +08:00
|
|
|
|
}
|
|
|
|
|
@autobind
|
2017-07-19 14:53:51 +08:00
|
|
|
|
inputNewGroupDesc(e, type) {
|
|
|
|
|
if (type === TYPE_EDIT) {
|
|
|
|
|
this.setState({ currGroupDesc: e.target.value})
|
|
|
|
|
} else {
|
|
|
|
|
this.setState({newGroupDesc: e.target.value});
|
|
|
|
|
}
|
2017-07-12 11:43:10 +08:00
|
|
|
|
}
|
|
|
|
|
|
2017-07-19 10:39:59 +08:00
|
|
|
|
@autobind
|
|
|
|
|
selectGroup(e) {
|
|
|
|
|
const groupId = e.key;
|
2017-07-19 11:05:22 +08:00
|
|
|
|
const currGroup = this.props.groupList.find((group) => { return +group._id === +groupId });
|
|
|
|
|
this.props.setCurrGroup(currGroup);
|
2017-07-30 15:06:03 +08:00
|
|
|
|
this.props.history.replace(`${currGroup._id}`);
|
2017-07-19 10:39:59 +08:00
|
|
|
|
}
|
|
|
|
|
|
2017-08-16 17:13:14 +08:00
|
|
|
|
@autobind
|
|
|
|
|
onUserSelect(childState) {
|
|
|
|
|
this.setState({
|
|
|
|
|
owner_uid: childState.uid
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
showConfirm =()=> {
|
|
|
|
|
let that = this;
|
|
|
|
|
confirm({
|
2017-08-18 19:47:02 +08:00
|
|
|
|
title: "确认删除 "+that.props.currGroup.group_name+" 分组吗?",
|
2017-08-16 17:13:14 +08:00
|
|
|
|
content: <div style={{marginTop:'10px', fontSize: '12px', lineHeight: '25px'}}>
|
|
|
|
|
<Alert message="警告:此操作非常危险,会删除该分组下面所有项目和接口,并且无法恢复!" type="warning" />
|
2017-08-18 19:47:02 +08:00
|
|
|
|
<div style={{marginTop: '15px'}}>
|
|
|
|
|
<p><b>请输入分组名称确认此操作:</b></p>
|
|
|
|
|
<Input id="group_name" />
|
|
|
|
|
</div>
|
2017-08-16 17:13:14 +08:00
|
|
|
|
</div>,
|
|
|
|
|
onOk() {
|
|
|
|
|
let groupName = document.getElementById('group_name').value;
|
|
|
|
|
if(that.props.currGroup.group_name !== groupName){
|
|
|
|
|
message.error('分组名称有误')
|
|
|
|
|
return new Promise((resolve, reject)=>{
|
|
|
|
|
reject('error')
|
|
|
|
|
})
|
|
|
|
|
}else{
|
|
|
|
|
that.deleteGroup()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
},
|
|
|
|
|
iconType: 'delete',
|
|
|
|
|
onCancel() { }
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2017-07-19 15:32:51 +08:00
|
|
|
|
@autobind
|
2017-08-09 13:48:06 +08:00
|
|
|
|
async deleteGroup() {
|
2017-07-19 15:32:51 +08:00
|
|
|
|
const self = this;
|
|
|
|
|
const { currGroup } = self.props;
|
2017-08-11 10:25:19 +08:00
|
|
|
|
const res = await axios.post('/api/group/del', {id: currGroup._id})
|
2017-08-09 13:48:06 +08:00
|
|
|
|
if (res.data.errcode) {
|
|
|
|
|
message.error(res.data.errmsg);
|
|
|
|
|
} else {
|
2017-08-16 17:13:14 +08:00
|
|
|
|
message.success('删除成功')
|
2017-08-09 13:48:06 +08:00
|
|
|
|
await self.props.fetchGroupList()
|
|
|
|
|
const currGroup = self.props.groupList[0] || { group_name: '', group_desc: '' };
|
|
|
|
|
self.setState({groupList: self.props.groupList});
|
|
|
|
|
self.props.setCurrGroup(currGroup)
|
|
|
|
|
}
|
2017-07-19 15:32:51 +08:00
|
|
|
|
}
|
|
|
|
|
|
2017-07-19 17:17:07 +08:00
|
|
|
|
@autobind
|
|
|
|
|
searchGroup(e, value) {
|
|
|
|
|
const v = value || e.target.value;
|
|
|
|
|
const { groupList } = this.props;
|
|
|
|
|
if (v === '') {
|
|
|
|
|
this.setState({groupList})
|
|
|
|
|
} else {
|
|
|
|
|
this.setState({groupList: groupList.filter(group => new RegExp(v, 'i').test(group.group_name))})
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-07-12 11:43:10 +08:00
|
|
|
|
render () {
|
2017-07-19 17:17:07 +08:00
|
|
|
|
const { currGroup } = this.props;
|
2017-08-01 15:03:34 +08:00
|
|
|
|
const delmark = <Icon className="edit-group" type="edit" title="编辑分组" onClick={() => this.showModal(TYPE_EDIT)}/>
|
2017-08-16 17:13:14 +08:00
|
|
|
|
const editmark = <Icon className="delete-group" onClick={()=> {this.showConfirm()}} type="delete" title="删除分组"/>
|
|
|
|
|
|
2017-07-12 11:43:10 +08:00
|
|
|
|
|
2017-08-07 19:34:34 +08:00
|
|
|
|
|
2017-07-12 11:43:10 +08:00
|
|
|
|
return (
|
2017-07-28 12:04:29 +08:00
|
|
|
|
<div className="m-group">
|
2017-07-18 17:32:32 +08:00
|
|
|
|
<div className="group-bar">
|
|
|
|
|
<div className="curr-group">
|
2017-07-19 14:53:51 +08:00
|
|
|
|
<div className="curr-group-name">
|
2017-07-26 10:26:15 +08:00
|
|
|
|
<div className="text" title={currGroup.group_name}>{currGroup.group_name}</div>
|
2017-08-01 15:03:34 +08:00
|
|
|
|
{
|
|
|
|
|
this.props.curUserRole === "admin"?(editmark):''
|
|
|
|
|
}
|
|
|
|
|
{
|
|
|
|
|
this.props.curUserRole === "admin"?(delmark):''
|
|
|
|
|
}
|
2017-08-07 19:34:34 +08:00
|
|
|
|
|
2017-07-19 14:53:51 +08:00
|
|
|
|
</div>
|
2017-07-26 10:26:15 +08:00
|
|
|
|
<div className="curr-group-desc" title={currGroup.group_desc}>简介:{currGroup.group_desc}</div>
|
2017-07-18 17:32:32 +08:00
|
|
|
|
</div>
|
|
|
|
|
<div className="group-operate">
|
2017-07-18 18:23:38 +08:00
|
|
|
|
<div className="search">
|
2017-07-19 17:17:07 +08:00
|
|
|
|
<Search onChange={this.searchGroup} onSearch={(v) => this.searchGroup(null, v)}/>
|
2017-07-18 18:23:38 +08:00
|
|
|
|
</div>
|
2017-08-01 15:03:34 +08:00
|
|
|
|
{
|
|
|
|
|
this.props.curUserRole === "admin"?(<Button type="primary" onClick={this.showModal}>添加分组</Button>):''
|
|
|
|
|
}
|
2017-08-07 19:34:34 +08:00
|
|
|
|
|
2017-07-18 17:32:32 +08:00
|
|
|
|
</div>
|
2017-07-19 10:39:59 +08:00
|
|
|
|
<Menu
|
|
|
|
|
className="group-list"
|
|
|
|
|
mode="inline"
|
|
|
|
|
onClick={this.selectGroup}
|
2017-07-19 11:09:21 +08:00
|
|
|
|
selectedKeys={[`${currGroup._id}`]}
|
2017-07-19 10:39:59 +08:00
|
|
|
|
>
|
2017-07-18 17:32:32 +08:00
|
|
|
|
{
|
2017-07-19 17:17:07 +08:00
|
|
|
|
this.state.groupList.map((group) => (
|
2017-07-19 11:09:21 +08:00
|
|
|
|
<Menu.Item key={`${group._id}`} className="group-item">
|
2017-07-18 18:23:38 +08:00
|
|
|
|
<Icon type="folder-open" />{group.group_name}
|
2017-07-18 17:32:32 +08:00
|
|
|
|
</Menu.Item>
|
|
|
|
|
))
|
|
|
|
|
}
|
|
|
|
|
</Menu>
|
|
|
|
|
</div>
|
2017-07-18 15:06:12 +08:00
|
|
|
|
<Modal
|
|
|
|
|
title="添加分组"
|
|
|
|
|
visible={this.state.addGroupModalVisible}
|
|
|
|
|
onOk={this.addGroup}
|
2017-07-19 14:53:51 +08:00
|
|
|
|
onCancel={this.hideModal}
|
2017-07-19 10:39:59 +08:00
|
|
|
|
className="add-group-modal"
|
2017-07-18 15:06:12 +08:00
|
|
|
|
>
|
2017-07-19 10:39:59 +08:00
|
|
|
|
<Row gutter={6} className="modal-input">
|
|
|
|
|
<Col span="5"><div className="label">分组名:</div></Col>
|
|
|
|
|
<Col span="15">
|
|
|
|
|
<Input placeholder="请输入分组名称" onChange={this.inputNewGroupName}></Input>
|
|
|
|
|
</Col>
|
|
|
|
|
</Row>
|
|
|
|
|
<Row gutter={6} className="modal-input">
|
|
|
|
|
<Col span="5"><div className="label">简介:</div></Col>
|
|
|
|
|
<Col span="15">
|
2017-07-25 10:31:19 +08:00
|
|
|
|
<TextArea rows = {3} placeholder="请输入分组描述" onChange={this.inputNewGroupDesc}></TextArea>
|
2017-07-19 10:39:59 +08:00
|
|
|
|
</Col>
|
2017-08-16 17:13:14 +08:00
|
|
|
|
</Row>
|
|
|
|
|
<Row gutter={6} className="modal-input">
|
|
|
|
|
<Col span="5"><div className="label">组长:</div></Col>
|
|
|
|
|
<Col span="15">
|
|
|
|
|
<UsernameAutoComplete callbackState={this.onUserSelect} />
|
|
|
|
|
</Col>
|
2017-07-19 10:39:59 +08:00
|
|
|
|
</Row>
|
2017-07-18 15:06:12 +08:00
|
|
|
|
</Modal>
|
2017-07-19 14:53:51 +08:00
|
|
|
|
<Modal
|
|
|
|
|
title="编辑分组"
|
|
|
|
|
visible={this.state.editGroupModalVisible}
|
|
|
|
|
onOk={this.editGroup}
|
|
|
|
|
onCancel={() => this.hideModal(TYPE_EDIT)}
|
|
|
|
|
className="add-group-modal"
|
|
|
|
|
>
|
|
|
|
|
<Row gutter={6} className="modal-input">
|
|
|
|
|
<Col span="5"><div className="label">分组名:</div></Col>
|
|
|
|
|
<Col span="15">
|
|
|
|
|
<Input placeholder="请输入分组名称" value={this.state.currGroupName} onChange={(e) => this.inputNewGroupName(e, TYPE_EDIT)}></Input>
|
|
|
|
|
</Col>
|
|
|
|
|
</Row>
|
|
|
|
|
<Row gutter={6} className="modal-input">
|
|
|
|
|
<Col span="5"><div className="label">简介:</div></Col>
|
|
|
|
|
<Col span="15">
|
2017-07-25 21:12:30 +08:00
|
|
|
|
<TextArea rows={3} placeholder="请输入分组描述" value={this.state.currGroupDesc} onChange={(e) => this.inputNewGroupDesc(e, TYPE_EDIT)}></TextArea>
|
2017-07-19 14:53:51 +08:00
|
|
|
|
</Col>
|
|
|
|
|
</Row>
|
|
|
|
|
</Modal>
|
2017-07-18 17:32:32 +08:00
|
|
|
|
</div>
|
2017-07-12 11:43:10 +08:00
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
}
|