yapi/client/containers/Project/Interface/InterfaceCol/InterfaceColMenu.js

273 lines
8.3 KiB
JavaScript
Raw Normal View History

2017-08-11 21:10:54 +08:00
import React, { Component } from 'react'
2017-08-14 17:32:17 +08:00
import { connect } from 'react-redux';
import { withRouter } from 'react-router'
import PropTypes from 'prop-types'
2017-08-17 20:24:07 +08:00
import { fetchInterfaceColList, fetchInterfaceCaseList, setColData } from '../../../../reducer/modules/interfaceCol'
2017-08-14 17:32:17 +08:00
import { autobind } from 'core-decorators';
import axios from 'axios';
2017-08-22 16:50:15 +08:00
import { Input, Icon, Tag, Modal, message, Tooltip, Tree, Dropdown, Menu, Form } from 'antd';
2017-08-14 17:32:17 +08:00
2017-08-17 12:19:16 +08:00
const TreeNode = Tree.TreeNode;
2017-08-22 16:50:15 +08:00
const FormItem = Form.Item;
2017-08-22 18:05:20 +08:00
const confirm = Modal.confirm;
2017-08-14 17:32:17 +08:00
2017-08-17 16:10:34 +08:00
import './InterfaceColMenu.scss'
2017-08-22 16:50:15 +08:00
const ColModalForm = Form.create()((props) => {
const { visible, onCancel, onCreate, form, title } = props;
const { getFieldDecorator } = form;
return (
<Modal
visible={visible}
title={title}
onCancel={onCancel}
onOk={onCreate}
>
<Form layout="vertical">
<FormItem label="集合名">
{getFieldDecorator('colName', {
rules: [{ required: true, message: '请输入集合命名!' }]
})(
<Input />
)}
</FormItem>
<FormItem label="简介">
{getFieldDecorator('colDesc')(<Input type="textarea" />)}
</FormItem>
</Form>
</Modal>
)
});
2017-08-14 17:32:17 +08:00
@connect(
state => {
return {
2017-08-17 20:24:07 +08:00
interfaceColList: state.interfaceCol.interfaceColList,
currColId: state.interfaceCol.currColId,
currCaseId: state.interfaceCol.currCaseId,
isShowCol: state.interfaceCol.isShowCol
2017-08-14 17:32:17 +08:00
}
},
{
fetchInterfaceColList,
2017-08-17 20:24:07 +08:00
fetchInterfaceCaseList,
setColData
2017-08-14 17:32:17 +08:00
}
)
@withRouter
2017-08-11 21:10:54 +08:00
export default class InterfaceColMenu extends Component {
2017-08-14 17:32:17 +08:00
static propTypes = {
match: PropTypes.object,
interfaceColList: PropTypes.array,
fetchInterfaceColList: PropTypes.func,
2017-08-17 16:10:34 +08:00
fetchInterfaceCaseList: PropTypes.func,
2017-08-17 20:24:07 +08:00
setColData: PropTypes.func,
history: PropTypes.object,
currColId: PropTypes.number,
currCaseId: PropTypes.number,
isShowCol: PropTypes.bool
2017-08-14 17:32:17 +08:00
}
state = {
2017-08-22 16:50:15 +08:00
expandedKeys: [],
colModalType: '',
colModalVisible: false,
2017-09-04 11:52:49 +08:00
editColId: 0,
filterValue: ''
2017-08-14 17:32:17 +08:00
}
2017-08-11 21:10:54 +08:00
constructor(props) {
super(props)
}
2017-08-18 17:31:48 +08:00
async componentWillMount() {
const { isShowCol, currColId, currCaseId } = this.props;
const action = isShowCol ? 'col' : 'case';
const actionId = isShowCol ? currColId : currCaseId;
this.setState({expandedKeys: [action+'_'+actionId]})
}
2017-08-14 17:32:17 +08:00
2017-08-18 17:31:48 +08:00
async componentWillReceiveProps(nextProps) {
2017-08-18 21:11:09 +08:00
const { currColId } = nextProps;
2017-08-18 17:56:26 +08:00
let expandedKeys = this.state.expandedKeys;
2017-08-18 21:11:09 +08:00
if (expandedKeys.indexOf('col_'+currColId) === -1) {
expandedKeys = expandedKeys.concat(['col_'+currColId])
2017-08-18 17:56:26 +08:00
}
this.setState({expandedKeys})
2017-08-18 17:31:48 +08:00
}
2017-08-17 16:10:34 +08:00
2017-08-14 17:32:17 +08:00
@autobind
2017-08-22 16:50:15 +08:00
async addorEditCol() {
const { colName: name, colDesc: desc } = this.form.getFieldsValue();
const { colModalType, editColId: col_id } = this.state;
const project_id = this.props.match.params.id;
let res = {};
if (colModalType === 'add') {
res = await axios.post('/api/col/add_col', { name, desc, project_id })
} else if (colModalType === 'edit') {
res = await axios.post('/api/col/up_col', { name, desc, col_id })
}
2017-08-14 17:32:17 +08:00
if (!res.data.errcode) {
this.setState({
2017-08-22 16:50:15 +08:00
colModalVisible: false
2017-08-14 17:32:17 +08:00
});
2017-08-22 16:50:15 +08:00
message.success(colModalType === 'edit' ? '修改集合成功' : '添加集合成功');
2017-08-14 17:32:17 +08:00
await this.props.fetchInterfaceColList(project_id);
2017-08-17 10:17:33 +08:00
} else {
message.error(res.data.errmsg);
2017-08-14 17:32:17 +08:00
}
}
2017-08-18 21:11:09 +08:00
onExpand = (keys) => {
this.setState({expandedKeys: keys})
}
2017-08-18 11:33:37 +08:00
onSelect = (keys) => {
2017-08-18 17:31:48 +08:00
if (keys.length) {
const type = keys[0].split('_')[0];
const id = keys[0].split('_')[1];
const project_id = this.props.match.params.id
if (type === 'col') {
this.props.setColData({
isShowCol: true,
currColId: +id
})
this.props.history.push('/project/' + project_id + '/interface/col/' + id)
} else {
this.props.setColData({
isShowCol: false,
currCaseId: +id
})
this.props.history.push('/project/' + project_id + '/interface/case/' + id)
}
2017-08-14 17:32:17 +08:00
}
}
2017-08-22 18:05:20 +08:00
showDelColConfirm = (colId) => {
let that = this;
confirm({
title: '您确认删除此测试集合',
content: '温馨提示:该操作会删除该集合下所有测试用例,用例删除后无法恢复',
async onOk() {
const res = await axios.get('/api/col/del_col?col_id=' + colId)
if (!res.data.errcode) {
message.success('删除集合成功');
await that.props.fetchInterfaceColList(that.props.match.params.id);
} else {
message.error(res.data.errmsg);
}
2017-08-22 19:57:39 +08:00
}
});
}
showDelCaseConfirm = (caseId) => {
let that = this;
confirm({
title: '您确认删除此测试用例',
content: '温馨提示:用例删除后无法恢复',
async onOk() {
const res = await axios.get('/api/col/del_case?caseid=' + caseId)
if (!res.data.errcode) {
message.success('删除用例成功');
await that.props.fetchInterfaceColList(that.props.match.params.id);
} else {
message.error(res.data.errmsg);
}
}
2017-08-22 18:05:20 +08:00
});
}
2017-08-22 16:50:15 +08:00
showColModal = (type, col) => {
const editCol = type === 'edit' ? {colName: col.name, colDesc: col.desc} : {colName: '', colDesc: ''};
this.setState({
colModalVisible: true,
colModalType: type || 'add',
2017-08-22 18:05:20 +08:00
editColId: col && col._id
2017-08-22 16:50:15 +08:00
})
this.form.setFieldsValue(editCol)
}
saveFormRef = (form) => {
this.form = form;
}
2017-08-14 17:32:17 +08:00
2017-09-04 11:52:49 +08:00
filterCol = (e) => {
const value = e.target.value;
this.setState({filterValue: value})
}
2017-08-11 21:10:54 +08:00
render() {
2017-08-17 20:24:07 +08:00
const { currColId, currCaseId, isShowCol } = this.props;
2017-09-04 11:52:49 +08:00
const { colModalType, colModalVisible, filterValue } = this.state;
2017-08-22 16:50:15 +08:00
const menu = (col) => {
return (
<Menu>
<Menu.Item>
<span onClick={() => this.showColModal('edit', col)}>修改集合</span>
</Menu.Item>
<Menu.Item>
<span onClick={() => {
this.showDelColConfirm(col._id)
}}>删除集合</span>
</Menu.Item>
</Menu>
)
};
2017-08-18 11:33:37 +08:00
2017-08-14 17:32:17 +08:00
return (
<div>
<div className="interface-filter">
2017-09-04 11:52:49 +08:00
<Input placeholder="Filter by name" style={{ width: "70%" }} onChange={this.filterCol} />
2017-08-14 17:32:17 +08:00
<Tooltip placement="bottom" title="添加集合">
<Tag color="#108ee9" style={{ marginLeft: "16px" }} onClick={() => this.showColModal('add')} ><Icon type="plus" /></Tag>
2017-08-14 17:32:17 +08:00
</Tooltip>
</div>
2017-08-17 12:19:16 +08:00
<Tree
2017-08-17 16:10:34 +08:00
className="col-list-tree"
2017-08-18 11:33:37 +08:00
expandedKeys={this.state.expandedKeys}
selectedKeys={[isShowCol ? 'col_'+currColId : 'case_'+currCaseId]}
2017-08-17 12:19:16 +08:00
onSelect={this.onSelect}
2017-08-18 11:33:37 +08:00
autoExpandParent
2017-08-18 21:11:09 +08:00
onExpand={this.onExpand}
2017-08-14 17:32:17 +08:00
>
{
2017-09-04 11:52:49 +08:00
this.props.interfaceColList.filter(col => col.name.indexOf(filterValue) !== -1).map((col) => (
2017-08-17 12:19:16 +08:00
<TreeNode
2017-08-17 20:24:07 +08:00
key={'col_' + col._id}
2017-08-22 16:50:15 +08:00
title={
<div className="menu-title">
<span><Icon type="folder-open" style={{marginRight: 5}} /><span>{col.name}</span></span>
<Dropdown overlay={menu(col)}>
<Icon type='bars'/>
</Dropdown>
</div>
}
2017-08-14 17:32:17 +08:00
>
{
2017-08-17 12:19:16 +08:00
col.caseList && col.caseList.map((interfaceCase) => (
<TreeNode
2017-08-17 16:10:34 +08:00
style={{width: '100%'}}
2017-08-17 20:24:07 +08:00
key={'case_' + interfaceCase._id}
2017-08-22 16:50:15 +08:00
title={
<div className="menu-title" title={interfaceCase.casename}>
<span className="casename">{interfaceCase.casename}</span>
2017-08-22 19:57:39 +08:00
<Icon type='delete' className="case-delete-icon" onClick={() => { this.showDelCaseConfirm(interfaceCase._id) }} />
2017-08-22 16:50:15 +08:00
</div>
}
2017-08-17 12:19:16 +08:00
></TreeNode>
2017-08-14 17:32:17 +08:00
))
}
2017-08-17 12:19:16 +08:00
</TreeNode>
2017-08-14 17:32:17 +08:00
))
}
2017-08-17 12:19:16 +08:00
</Tree>
2017-08-22 16:50:15 +08:00
<ColModalForm
ref={this.saveFormRef}
type={colModalType}
visible={colModalVisible}
onCancel={() => { this.setState({ colModalVisible: false }) }}
onCreate={this.addorEditCol}
></ColModalForm>
2017-08-14 17:32:17 +08:00
</div>
)
2017-08-11 21:10:54 +08:00
}
}