feat: 修改项目功能

This commit is contained in:
wenbo.dong 2017-07-19 20:59:59 +08:00
parent c5da772403
commit 0fdb804f1d
7 changed files with 484 additions and 20 deletions

View File

@ -1,7 +1,9 @@
import {
FETCH_PROJECT_LIST,
PROJECT_ADD,
PROJECT_DEL
PROJECT_DEL,
OPRATE_UPDATE_MODAL,
PROJECT_UPDATE
} from '../constants/action-types.js';
import axios from 'axios';
@ -12,6 +14,13 @@ const fetchProjectList = (id) => {
};
};
const changeUpdateModal = (data, index) => {
return {
type: OPRATE_UPDATE_MODAL,
payload: { data, index }
};
};
const addProject = (data) => {
const { name, prd_host, basepath, desc, group_id } = data;
const param = {
@ -28,6 +37,22 @@ const addProject = (data) => {
};
};
const updateProject = (data) => {
const { name, prd_host, basepath, desc, group_id } = data;
const param = {
name,
prd_host,
basepath,
desc,
group_id
};
return {
type: PROJECT_UPDATE,
// payload 可以返回 Promise异步请求使用 axios 即可
payload: axios.post('/project/up', param)
};
};
const delProject = (id) => {
const param = { id };
return {
@ -40,5 +65,7 @@ const delProject = (id) => {
export default {
fetchProjectList,
addProject,
delProject
delProject,
changeUpdateModal,
updateProject
};

View File

@ -8,14 +8,17 @@ export const FETCH_GROUP_LIST = 'FETCH_GROUP_LIST'
export const SET_CURR_GROUP = 'SET_CURR_GROUP'
// project
export const FETCH_PROJECT_LIST = 'FETCH_PROJECT_LIST'
export const PROJECT_ADD = 'PROJECT_ADD'
export const PROJECT_DEL = 'PROJECT_DEL'
export const OPRATE_UPDATE_MODAL = 'OPRATE_UPDATE_MODAL' // 控制模态框 - 修改项目
export const OPRATE_ADD_MODAL = 'OPRATE_ADD_MODAL' // 控制模态框 - 创建项目
export const FETCH_PROJECT_LIST = 'FETCH_PROJECT_LIST' // 获取项目列表
export const PROJECT_ADD = 'PROJECT_ADD' // 添加项目
export const PROJECT_UPDATE = 'PROJECT_UPDATE' // 修改项目
export const PROJECT_DEL = 'PROJECT_DEL' // 删除项目
// login
export const LOGIN = 'LOGIN';
export const GET_LOGIN_STATE = 'GET_LOGIN_STATE';
export const REGISTER = 'REGISTER';
export const LOGIN = 'LOGIN'; // 登录
export const GET_LOGIN_STATE = 'GET_LOGIN_STATE'; // 获取登录信息
export const REGISTER = 'REGISTER'; // 注册
//header
export const LOGIN_TYPE = 'LOGIN_TYPE';

View File

@ -1,6 +1,6 @@
import React, { Component } from 'react';
import GroupList from './GroupList/GroupList.js';
import ProjectList from './ProjectList';
import ProjectList from './ProjectList/ProjectList.js';
import { Row, Col } from 'antd';
import './ProjectGroups.scss'

View File

@ -2,14 +2,15 @@ import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { Table, Button, Modal, Form, Input, Icon, Tooltip, Select, Popconfirm, message } from 'antd';
import { addProject, fetchProjectList, delProject } from '../../../actions/project';
import { addProject, fetchProjectList, delProject, changeUpdateModal } from '../../../actions/project';
import UpDateModal from './UpDateModal';
const { TextArea } = Input;
const FormItem = Form.Item;
const Option = Select.Option;
import './ProjectList.scss'
const confirm = (id, handleDelete, currGroupId, handleFetchList) => {
const deleteConfirm = (id, handleDelete, currGroupId, handleFetchList) => {
const test = () => {
handleDelete(id).then((res) => {
console.log(res);
@ -22,7 +23,7 @@ const confirm = (id, handleDelete, currGroupId, handleFetchList) => {
return test;
};
const getColumns = (data, handleDelete, currGroupId, handleFetchList) => {
const getColumns = (data, handleDelete, currGroupId, handleFetchList, handleUpdateModal) => {
return [{
title: '项目名称',
dataIndex: 'name',
@ -39,13 +40,13 @@ const getColumns = (data, handleDelete, currGroupId, handleFetchList) => {
}, {
title: '操作',
key: 'action',
render: (text, record) => {
render: (text, record, index) => {
const id = record._id;
return (
<span>
<a href="#">修改</a>
<a onClick={() => handleUpdateModal(true, index)}>修改</a>
<span className="ant-divider" />
<Popconfirm title="你确定要删除项目吗?" onConfirm={confirm(id, handleDelete, currGroupId, handleFetchList)} okText="删除" cancelText="取消">
<Popconfirm title="你确定要删除项目吗?" onConfirm={deleteConfirm(id, handleDelete, currGroupId, handleFetchList)} okText="删除" cancelText="取消">
<a href="#">删除</a>
</Popconfirm>
</span>
@ -74,7 +75,8 @@ const formItemLayout = {
{
fetchProjectList,
addProject,
delProject
delProject,
changeUpdateModal
}
)
class ProjectList extends Component {
@ -92,6 +94,7 @@ class ProjectList extends Component {
fetchProjectList: PropTypes.func,
addProject: PropTypes.func,
delProject: PropTypes.func,
changeUpdateModal: PropTypes.func,
projectList: PropTypes.array,
currGroup: PropTypes.object
}
@ -227,7 +230,7 @@ class ProjectList extends Component {
<FormItem
{...formItemLayout}
label="URL"
label="基本路径"
>
{getFieldDecorator('basepath', {
rules: [{
@ -252,10 +255,10 @@ class ProjectList extends Component {
</FormItem>
</Form>
</Modal>
<UpDateModal/>
<Table
loading={this.state.tabelLoading}
columns={getColumns(this.state.projectData, this.props.delProject, this.props.currGroup._id, this.props.fetchProjectList)}
columns={getColumns(this.state.projectData, this.props.delProject, this.props.currGroup._id, this.props.fetchProjectList, this.props.changeUpdateModal)}
dataSource={this.state.projectData}
title={() => <Button type="primary" onClick={this.showAddProjectModal}>创建项目</Button>}
/>

View File

@ -0,0 +1,201 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { Modal, Form, Input, Icon, Tooltip, Select, message } from 'antd';
import { updateProject, fetchProjectList, delProject, changeUpdateModal } from '../../../actions/project';
const { TextArea } = Input;
const FormItem = Form.Item;
const Option = Select.Option;
import './ProjectList.scss'
const formItemLayout = {
labelCol: {
xs: { span: 24 },
sm: { span: 6 }
},
wrapperCol: {
xs: { span: 24 },
sm: { span: 14 }
}
};
@connect(
state => {
return {
projectList: state.project.projectList,
isUpdateModalShow: state.project.isUpdateModalShow,
handleUpdateIndex: state.project.handleUpdateIndex,
currGroup: state.group.currGroup
}
},
{
fetchProjectList,
updateProject,
delProject,
changeUpdateModal
}
)
class UpDateModal extends Component {
constructor(props) {
super(props);
this.state = {
visible: false,
tabelLoading: true,
protocol: 'http:\/\/'
}
}
static propTypes = {
form: PropTypes.object,
fetchProjectList: PropTypes.func,
updateProject: PropTypes.func,
delProject: PropTypes.func,
changeUpdateModal: PropTypes.func,
projectList: PropTypes.array,
currGroup: PropTypes.object,
isUpdateModalShow: PropTypes.bool,
handleUpdateIndex: PropTypes.number
}
// 修改线上域名的协议类型 (http/https)
protocolChange = (value) => {
this.setState({
protocol: value
})
}
handleCancel = () => {
this.props.form.resetFields();
this.props.changeUpdateModal(false, -1);
}
handleOk = (e) => {
e.preventDefault();
const { form, updateProject, changeUpdateModal, currGroup, projectList, handleUpdateIndex, fetchProjectList } = this.props;
form.validateFields((err, values) => {
if (!err) {
let assignValue = Object.assign(projectList[handleUpdateIndex], values);
assignValue.prd_host = this.state.protocol + assignValue.prd_host;
this.setState({
tabelLoading: true
});
updateProject(assignValue).then((res) => {
if (res.payload.data.errcode == 0) {
changeUpdateModal(false, -1);
message.success('修改成功! ');
fetchProjectList(currGroup._id).then((res) => {
this.setState({
tabelLoading: false
});
console.log(res);
});
} else {
message.error(res.payload.data.errmsg);
}
}).catch((err) => {
console.log(err);
this.setState({
tabelLoading: false
});
});
form.resetFields();
}
});
}
render() {
const { getFieldDecorator } = this.props.form;
// const that = this;
const { isUpdateModalShow, projectList, handleUpdateIndex } = this.props;
let initFormValues = {};
// 如果列表存在且用户点击修改按钮时,设置表单默认值
if (projectList.length !== 0 && handleUpdateIndex !== -1 ) {
console.log(projectList[handleUpdateIndex]);
const { name, basepath, desc } = projectList[handleUpdateIndex];
initFormValues = { name, basepath, desc };
initFormValues.prd_host = projectList[handleUpdateIndex].prd_host.split('\/\/')[1];
initFormValues.prd_protocol = projectList[handleUpdateIndex].prd_host.split('\/\/')[0] + '\/\/';
}
return (
<Modal
title="修改项目"
visible={isUpdateModalShow}
onOk={this.handleOk}
onCancel={this.handleCancel}
>
<Form>
<FormItem
{...formItemLayout}
label="项目名称"
>
{getFieldDecorator('name', {
initialValue: initFormValues.name,
rules: [{
required: true, message: '请输入项目名称!'
}]
})(
<Input />
)}
</FormItem>
<FormItem
{...formItemLayout}
label={(
<span>
线上域名&nbsp;
<Tooltip title="将根据配置的线上域名访问mock数据">
<Icon type="question-circle-o" />
</Tooltip>
</span>
)}
>
{getFieldDecorator('prd_host', {
initialValue: initFormValues.prd_host,
rules: [{
required: true, message: '请输入项目线上域名!'
}]
})(
<Input addonBefore={(
<Select defaultValue={initFormValues.prd_protocol} onChange={this.protocolChange}>
<Option value="http://">{'http:\/\/'}</Option>
<Option value="https://">{'https:\/\/'}</Option>
</Select>)} />
)}
</FormItem>
<FormItem
{...formItemLayout}
label="基本路径"
>
{getFieldDecorator('basepath', {
initialValue: initFormValues.basepath,
rules: [{
required: true, message: '请输入项目基本路径!'
}]
})(
<Input />
)}
</FormItem>
<FormItem
{...formItemLayout}
label="描述"
>
{getFieldDecorator('desc', {
initialValue: initFormValues.desc,
rules: [{
required: true, message: '请输入描述!'
}]
})(
<TextArea rows={4} />
)}
</FormItem>
</Form>
</Modal>
);
}
}
export default Form.create()(UpDateModal);

View File

@ -0,0 +1,220 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { Modal, Form, Input, Icon, Tooltip, Select, message } from 'antd';
import { addProject, fetchProjectList, delProject } from '../../../actions/project';
const { TextArea } = Input;
const FormItem = Form.Item;
const Option = Select.Option;
import './ProjectList.scss'
const formItemLayout = {
labelCol: {
xs: { span: 24 },
sm: { span: 6 }
},
wrapperCol: {
xs: { span: 24 },
sm: { span: 14 }
}
};
@connect(
state => {
return {
projectList: state.project.projectList,
isAddModalShow: state.project.isAddModalShow,
currGroup: state.group.currGroup
}
},
{
fetchProjectList,
addProject,
delProject
}
)
class addProjectModal extends Component {
constructor(props) {
super(props);
this.state = {
visible: false,
tabelLoading: true,
protocol: 'http:\/\/',
projectData: []
}
}
static propTypes = {
form: PropTypes.object,
fetchProjectList: PropTypes.func,
addProject: PropTypes.func,
delProject: PropTypes.func,
projectList: PropTypes.array,
currGroup: PropTypes.object,
isAddModalShow: PropTypes.bool
}
showAddProjectModal = () => {
this.setState({
visible: true
});
}
handleOk = (e) => {
e.preventDefault();
this.props.form.validateFields((err, values) => {
if (!err) {
values.prd_host = this.state.protocol + values.prd_host;
// 获取当前分组id传入values
values.group_id = this.props.currGroup._id;
console.log('Received values of form: ', values);
this.setState({
visible: false,
tabelLoading: true
});
this.props.addProject(values).then((res) => {
console.log(res);
// 添加项目成功后再次请求列表
this.props.fetchProjectList(this.props.currGroup._id).then((res) => {
this.setState({
tabelLoading: false
});
console.log(117,res);
});
}).catch((err) => {
console.log(err);
this.setState({
tabelLoading: false
});
});
this.props.form.resetFields();
}
});
}
// 取消修改
handleCancel = () => {
this.props.form.resetFields();
this.setState({
visible: false
});
}
// 修改线上域名的协议类型 (http/https)
protocolChange = (value) => {
this.setState({
protocol: value
})
}
componentWillReceiveProps(nextProps){
// 切换分组
if (this.props.currGroup !== nextProps.currGroup) {
this.props.fetchProjectList(nextProps.currGroup._id).then((res) => {
if (res.payload.data.errcode) {
message.error(res.payload.data.errmsg);
} else {
this.setState({
tabelLoading: false
});
}
});
}
// 切换项目列表
if (this.props.projectList !== nextProps.projectList) {
// console.log(nextProps.projectList);
const data = nextProps.projectList.map((item, index) => {
item.key = index;
return item;
});
this.setState({
projectData: data
});
}
}
componentWillMount() {
console.log(this.props);
}
render() {
console.log(12);
const { getFieldDecorator } = this.props.form;
console.log(this.props);
return (
<Modal
title="创建项目"
visible={true}
onOk={this.handleOk}
onCancel={this.handleCancel}
>
<Form>
<FormItem
{...formItemLayout}
label="项目名称"
>
{getFieldDecorator('name', {
rules: [{
required: true, message: '请输入项目名称!'
}]
})(
<Input />
)}
</FormItem>
<FormItem
{...formItemLayout}
label={(
<span>
线上域名&nbsp;
<Tooltip title="将根据配置的线上域名访问mock数据">
<Icon type="question-circle-o" />
</Tooltip>
</span>
)}
>
{getFieldDecorator('prd_host', {
rules: [{
required: true, message: '请输入项目线上域名!'
}]
})(
<Input addonBefore={(
<Select defaultValue="http://" onChange={this.protocolChange}>
<Option value="http://">{'http:\/\/'}</Option>
<Option value="https://">{'https:\/\/'}</Option>
</Select>)} />
)}
</FormItem>
<FormItem
{...formItemLayout}
label="基本路径"
>
{getFieldDecorator('basepath', {
rules: [{
required: true, message: '请输入项目基本路径!'
}]
})(
<Input />
)}
</FormItem>
<FormItem
{...formItemLayout}
label="描述"
>
{getFieldDecorator('desc', {
rules: [{
required: true, message: '请输入描述!'
}]
})(
<TextArea rows={4} />
)}
</FormItem>
</Form>
</Modal>
);
}
}
export default Form.create()(addProjectModal);

View File

@ -1,16 +1,26 @@
import {
FETCH_PROJECT_LIST,
PROJECT_ADD,
PROJECT_DEL
PROJECT_DEL,
OPRATE_UPDATE_MODAL
} from '../../constants/action-types';
const initialState = {
isUpdateModalShow: false,
handleUpdateIndex: -1,
projectList: [],
total: null
};
export default (state = initialState, action) => {
switch (action.type) {
case OPRATE_UPDATE_MODAL: {
return {
...state,
isUpdateModalShow: action.payload.data,
handleUpdateIndex: action.payload.index
};
}
case FETCH_PROJECT_LIST: {
return {
...state,