From 28d3327d6056ee53c52eaa554fe79bb64d8c02c9 Mon Sep 17 00:00:00 2001 From: valleykid Date: Wed, 7 Feb 2018 23:31:49 +0800 Subject: [PATCH] New page info modal (#876) * New page - info modal * Replace `Array.some` to `for` * Fix py-lint * Keep original DatePicker * Remove modal's vertical style * Remove fake_dataBase --- .roadhogrc.mock.js | 3 +- mock/api.js | 41 ++++++++ src/models/list.js | 22 ++--- src/routes/List/BasicList.js | 175 +++++++++++++++++++++++++++++++---- src/services/api.js | 33 +++++++ 5 files changed, 245 insertions(+), 29 deletions(-) diff --git a/.roadhogrc.mock.js b/.roadhogrc.mock.js index 076ee0c6..1f9bb763 100644 --- a/.roadhogrc.mock.js +++ b/.roadhogrc.mock.js @@ -1,6 +1,6 @@ import mockjs from 'mockjs'; import { getRule, postRule } from './mock/rule'; -import { getActivities, getNotice, getFakeList } from './mock/api'; +import { getActivities, getNotice, getFakeList, postFakeList } from './mock/api'; import { getFakeChartData } from './mock/chart'; import { imgMap } from './mock/utils'; import { getProfileBasicData } from './mock/profile'; @@ -65,6 +65,7 @@ const proxy = { 'list|100': [{ name: '@city', 'value|1-100': 150, 'type|0-2': 1 }] }), 'GET /api/fake_list': getFakeList, + 'POST /api/fake_list': postFakeList, 'GET /api/fake_chart_data': getFakeChartData, 'GET /api/profile/basic': getProfileBasicData, 'GET /api/profile/advanced': getProfileAdvancedData, diff --git a/mock/api.js b/mock/api.js index 35b64946..e596c755 100644 --- a/mock/api.js +++ b/mock/api.js @@ -104,6 +104,8 @@ export function fakeList(count) { return list; } +let sourceData; + export function getFakeList(req, res, u) { let url = u; if (!url || Object.prototype.toString.call(url) !== '[object String]') { @@ -115,6 +117,44 @@ export function getFakeList(req, res, u) { const count = (params.count * 1) || 20; const result = fakeList(count); + sourceData = result; + + if (res && res.json) { + res.json(result); + } else { + return result; + } +} + +export function postFakeList(req, res) { + const { /* url = '', */ body } = req; + // const params = getUrlParams(url); + const { method, id, ...restParams } = body; + + // const count = (params.count * 1) || 20; + let result = sourceData; + + switch (method) { + case 'delete': + result = result.filter(item => item.id !== id); + break; + case 'update': + result.forEach((item, i) => { + if (item.id === id) { + result[i] = Object.assign(item, restParams); + } + }); + break; + case 'post': + result.unshift({ + ...restParams, + id: `fake-list-${result.length}`, + createdAt: new Date().getTime(), + }); + break; + default: + break; + } if (res && res.json) { res.json(result); @@ -292,4 +332,5 @@ export default { getNotice, getActivities, getFakeList, + postFakeList, }; diff --git a/src/models/list.js b/src/models/list.js index 147eeca6..8acf49f3 100644 --- a/src/models/list.js +++ b/src/models/list.js @@ -1,4 +1,4 @@ -import { queryFakeList } from '../services/api'; +import { queryFakeList, removeFakeList, addFakeList, updateFakeList } from '../services/api'; export default { namespace: 'list', @@ -15,11 +15,17 @@ export default { payload: Array.isArray(response) ? response : [], }); }, - *appendFetch({ payload }, { call, put }) { - const response = yield call(queryFakeList, payload); + *submit({ payload }, { call, put }) { + let callback; + if (payload.id) { + callback = Object.keys(payload).length === 1 ? removeFakeList : updateFakeList; + } else { + callback = addFakeList; + } + const response = yield call(callback, payload); // post yield put({ - type: 'appendList', - payload: Array.isArray(response) ? response : [], + type: 'queryList', + payload: response, }); }, }, @@ -31,11 +37,5 @@ export default { list: action.payload, }; }, - appendList(state, action) { - return { - ...state, - list: state.list.concat(action.payload), - }; - }, }, }; diff --git a/src/routes/List/BasicList.js b/src/routes/List/BasicList.js index 0478cdfb..15cfb967 100644 --- a/src/routes/List/BasicList.js +++ b/src/routes/List/BasicList.js @@ -1,21 +1,28 @@ import React, { PureComponent } from 'react'; import moment from 'moment'; import { connect } from 'dva'; -import { List, Card, Row, Col, Radio, Input, Progress, Button, Icon, Dropdown, Menu, Avatar } from 'antd'; +import { List, Card, Row, Col, Radio, Input, Progress, Button, Icon, Dropdown, Menu, Avatar, + Modal, Form, DatePicker, Select } from 'antd'; import PageHeaderLayout from '../../layouts/PageHeaderLayout'; +import Result from '../../components/Result'; import styles from './BasicList.less'; +const FormItem = Form.Item; const RadioButton = Radio.Button; const RadioGroup = Radio.Group; -const { Search } = Input; +const SelectOption = Select.Option; +const { Search, TextArea } = Input; @connect(({ list, loading }) => ({ list, loading: loading.models.list, })) +@Form.create() export default class BasicList extends PureComponent { + state = { visible: false, done: false }; + componentDidMount() { this.props.dispatch({ type: 'list/fetch', @@ -24,9 +31,78 @@ export default class BasicList extends PureComponent { }, }); } + formLayout = { + labelCol: { span: 7 }, + wrapperCol: { span: 13 }, + }; + showModal = () => { + this.setState({ + visible: true, + current: undefined, + }); + } + showEditModal = (item) => { + this.setState({ + visible: true, + current: item, + }); + } + handleDone = () => { + this.setState({ + done: false, + visible: false, + }); + } + handleCancel = () => { + this.setState({ + visible: false, + }); + } + handleSubmit = (e) => { + e.preventDefault(); + const { dispatch, form } = this.props; + const id = this.state.current ? this.state.current.id : ''; + + form.validateFields((err, fieldsValue) => { + if (err) return; + this.setState({ + done: true, + }); + dispatch({ + type: 'list/submit', + payload: { id, ...fieldsValue }, + }); + }); + } + deleteItem = (id) => { + this.props.dispatch({ + type: 'list/submit', + payload: { id }, + }); + } render() { const { list: { list }, loading } = this.props; + const { getFieldDecorator } = this.props.form; + const { visible, done, current = {} } = this.state; + + const editAndDelete = (key, currentItem) => { + if (key === 'edit') this.showEditModal(currentItem); + else if (key === 'delete') { + Modal.confirm({ + title: '删除任务', + content: '确定删除该任务吗?', + okText: '确认', + cancelText: '取消', + onOk: () => this.deleteItem(currentItem.id), + }); + } + }; + + const modalFooter = done ? + { footer: null, onCancel: this.handleDone } + : + { okText: '保存', onOk: this.handleSubmit, onCancel: this.handleCancel }; const Info = ({ title, value, bordered }) => (
@@ -74,25 +150,77 @@ export default class BasicList extends PureComponent {
); - const menu = ( - - - 编辑 - - - 删除 - - - ); - - const MoreBtn = () => ( - + const MoreBtn = props => ( + editAndDelete(key, props.current)}> + 编辑 + 删除 + } + > 更多 ); + const getModalContent = () => { + if (done) { + return ( + 知道了} + style={{ width: '100%', marginBottom: '24px' }} + /> + ); + } + return ( +
+ + {getFieldDecorator('title', { + rules: [{ required: true, message: '请输入任务名称' }], + initialValue: current.title, + })( + + )} + + + {getFieldDecorator('createdAt', { + rules: [{ required: true, message: '请选择开始时间' }], + initialValue: current.createdAt ? moment(current.createdAt) : null, + })( + + )} + + + {getFieldDecorator('owner', { + rules: [{ required: true, message: '请选择任务负责人' }], + initialValue: current.owner, + })( + + )} + + + {getFieldDecorator('subDescription', { + rules: [{ message: '请输入至少五个字符的产品描述!', min: 5 }], + initialValue: current.subDescription, + })( +