Commit 28d3327d authored by valleykid's avatar valleykid Committed by ddcat1115

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
parent 34f49bfd
import mockjs from 'mockjs'; import mockjs from 'mockjs';
import { getRule, postRule } from './mock/rule'; 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 { getFakeChartData } from './mock/chart';
import { imgMap } from './mock/utils'; import { imgMap } from './mock/utils';
import { getProfileBasicData } from './mock/profile'; import { getProfileBasicData } from './mock/profile';
...@@ -65,6 +65,7 @@ const proxy = { ...@@ -65,6 +65,7 @@ const proxy = {
'list|100': [{ name: '@city', 'value|1-100': 150, 'type|0-2': 1 }] 'list|100': [{ name: '@city', 'value|1-100': 150, 'type|0-2': 1 }]
}), }),
'GET /api/fake_list': getFakeList, 'GET /api/fake_list': getFakeList,
'POST /api/fake_list': postFakeList,
'GET /api/fake_chart_data': getFakeChartData, 'GET /api/fake_chart_data': getFakeChartData,
'GET /api/profile/basic': getProfileBasicData, 'GET /api/profile/basic': getProfileBasicData,
'GET /api/profile/advanced': getProfileAdvancedData, 'GET /api/profile/advanced': getProfileAdvancedData,
......
...@@ -104,6 +104,8 @@ export function fakeList(count) { ...@@ -104,6 +104,8 @@ export function fakeList(count) {
return list; return list;
} }
let sourceData;
export function getFakeList(req, res, u) { export function getFakeList(req, res, u) {
let url = u; let url = u;
if (!url || Object.prototype.toString.call(url) !== '[object String]') { if (!url || Object.prototype.toString.call(url) !== '[object String]') {
...@@ -115,6 +117,44 @@ export function getFakeList(req, res, u) { ...@@ -115,6 +117,44 @@ export function getFakeList(req, res, u) {
const count = (params.count * 1) || 20; const count = (params.count * 1) || 20;
const result = fakeList(count); 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) { if (res && res.json) {
res.json(result); res.json(result);
...@@ -292,4 +332,5 @@ export default { ...@@ -292,4 +332,5 @@ export default {
getNotice, getNotice,
getActivities, getActivities,
getFakeList, getFakeList,
postFakeList,
}; };
import { queryFakeList } from '../services/api'; import { queryFakeList, removeFakeList, addFakeList, updateFakeList } from '../services/api';
export default { export default {
namespace: 'list', namespace: 'list',
...@@ -15,11 +15,17 @@ export default { ...@@ -15,11 +15,17 @@ export default {
payload: Array.isArray(response) ? response : [], payload: Array.isArray(response) ? response : [],
}); });
}, },
*appendFetch({ payload }, { call, put }) { *submit({ payload }, { call, put }) {
const response = yield call(queryFakeList, payload); 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({ yield put({
type: 'appendList', type: 'queryList',
payload: Array.isArray(response) ? response : [], payload: response,
}); });
}, },
}, },
...@@ -31,11 +37,5 @@ export default { ...@@ -31,11 +37,5 @@ export default {
list: action.payload, list: action.payload,
}; };
}, },
appendList(state, action) {
return {
...state,
list: state.list.concat(action.payload),
};
},
}, },
}; };
import React, { PureComponent } from 'react'; import React, { PureComponent } from 'react';
import moment from 'moment'; import moment from 'moment';
import { connect } from 'dva'; 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 PageHeaderLayout from '../../layouts/PageHeaderLayout';
import Result from '../../components/Result';
import styles from './BasicList.less'; import styles from './BasicList.less';
const FormItem = Form.Item;
const RadioButton = Radio.Button; const RadioButton = Radio.Button;
const RadioGroup = Radio.Group; const RadioGroup = Radio.Group;
const { Search } = Input; const SelectOption = Select.Option;
const { Search, TextArea } = Input;
@connect(({ list, loading }) => ({ @connect(({ list, loading }) => ({
list, list,
loading: loading.models.list, loading: loading.models.list,
})) }))
@Form.create()
export default class BasicList extends PureComponent { export default class BasicList extends PureComponent {
state = { visible: false, done: false };
componentDidMount() { componentDidMount() {
this.props.dispatch({ this.props.dispatch({
type: 'list/fetch', type: 'list/fetch',
...@@ -24,9 +31,78 @@ export default class BasicList extends PureComponent { ...@@ -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() { render() {
const { list: { list }, loading } = this.props; 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 }) => ( const Info = ({ title, value, bordered }) => (
<div className={styles.headerInfo}> <div className={styles.headerInfo}>
...@@ -74,25 +150,77 @@ export default class BasicList extends PureComponent { ...@@ -74,25 +150,77 @@ export default class BasicList extends PureComponent {
</div> </div>
); );
const menu = ( const MoreBtn = props => (
<Menu> <Dropdown overlay={
<Menu.Item> <Menu onClick={({ key }) => editAndDelete(key, props.current)}>
<a>编辑</a> <Menu.Item key="edit">编辑</Menu.Item>
</Menu.Item> <Menu.Item key="delete">删除</Menu.Item>
<Menu.Item> </Menu>}
<a>删除</a> >
</Menu.Item>
</Menu>
);
const MoreBtn = () => (
<Dropdown overlay={menu}>
<a> <a>
更多 <Icon type="down" /> 更多 <Icon type="down" />
</a> </a>
</Dropdown> </Dropdown>
); );
const getModalContent = () => {
if (done) {
return (
<Result
type="success"
title="操作成功"
description="一系列的信息描述,很短同样也可以带标点。"
actions={<Button type="primary" onClick={this.handleDone}>知道了</Button>}
style={{ width: '100%', marginBottom: '24px' }}
/>
);
}
return (
<Form onSubmit={this.handleSubmit}>
<FormItem label="任务名称" {...this.formLayout}>
{getFieldDecorator('title', {
rules: [{ required: true, message: '请输入任务名称' }],
initialValue: current.title,
})(
<Input placeholder="请输入" />
)}
</FormItem>
<FormItem label="开始时间" {...this.formLayout}>
{getFieldDecorator('createdAt', {
rules: [{ required: true, message: '请选择开始时间' }],
initialValue: current.createdAt ? moment(current.createdAt) : null,
})(
<DatePicker
showTime
placeholder="请选择"
format="YYYY-MM-DD HH:mm:ss"
style={{ width: '100%' }}
/>
)}
</FormItem>
<FormItem label="任务负责人" {...this.formLayout}>
{getFieldDecorator('owner', {
rules: [{ required: true, message: '请选择任务负责人' }],
initialValue: current.owner,
})(
<Select placeholder="请选择">
<SelectOption value="付晓晓">付晓晓</SelectOption>
<SelectOption value="周毛毛">周毛毛</SelectOption>
</Select>
)}
</FormItem>
<FormItem {...this.formLayout} label="产品描述">
{getFieldDecorator('subDescription', {
rules: [{ message: '请输入至少五个字符的产品描述!', min: 5 }],
initialValue: current.subDescription,
})(
<TextArea rows={4} placeholder="请输入至少五个字符" />
)}
</FormItem>
</Form>
);
};
return ( return (
<PageHeaderLayout> <PageHeaderLayout>
<div className={styles.standardList}> <div className={styles.standardList}>
...@@ -118,7 +246,7 @@ export default class BasicList extends PureComponent { ...@@ -118,7 +246,7 @@ export default class BasicList extends PureComponent {
bodyStyle={{ padding: '0 32px 40px 32px' }} bodyStyle={{ padding: '0 32px 40px 32px' }}
extra={extraContent} extra={extraContent}
> >
<Button type="dashed" style={{ width: '100%', marginBottom: 8 }} icon="plus"> <Button type="dashed" style={{ width: '100%', marginBottom: 8 }} icon="plus" onClick={this.showModal}>
添加 添加
</Button> </Button>
<List <List
...@@ -129,7 +257,10 @@ export default class BasicList extends PureComponent { ...@@ -129,7 +257,10 @@ export default class BasicList extends PureComponent {
dataSource={list} dataSource={list}
renderItem={item => ( renderItem={item => (
<List.Item <List.Item
actions={[<a>编辑</a>, <MoreBtn />]} actions={[
<a onClick={(e) => { e.preventDefault(); this.showEditModal(item); }}>编辑</a>,
<MoreBtn current={item} />,
]}
> >
<List.Item.Meta <List.Item.Meta
avatar={<Avatar src={item.logo} shape="square" size="large" />} avatar={<Avatar src={item.logo} shape="square" size="large" />}
...@@ -142,6 +273,16 @@ export default class BasicList extends PureComponent { ...@@ -142,6 +273,16 @@ export default class BasicList extends PureComponent {
/> />
</Card> </Card>
</div> </div>
<Modal
title={`任务${this.state.current ? '编辑' : '添加'}`}
width={640}
bodyStyle={{ padding: '32px 0 8px' }}
destroyOnClose
visible={visible}
{...modalFooter}
>
{getModalContent()}
</Modal>
</PageHeaderLayout> </PageHeaderLayout>
); );
} }
......
...@@ -70,6 +70,39 @@ export async function queryFakeList(params) { ...@@ -70,6 +70,39 @@ export async function queryFakeList(params) {
return request(`/api/fake_list?${stringify(params)}`); return request(`/api/fake_list?${stringify(params)}`);
} }
export async function removeFakeList(params) {
const { count = 5, ...restParams } = params;
return request(`/api/fake_list?count=${count}`, {
method: 'POST',
body: {
...restParams,
method: 'delete',
},
});
}
export async function addFakeList(params) {
const { count = 5, ...restParams } = params;
return request(`/api/fake_list?count=${count}`, {
method: 'POST',
body: {
...restParams,
method: 'post',
},
});
}
export async function updateFakeList(params) {
const { count = 5, ...restParams } = params;
return request(`/api/fake_list?count=${count}`, {
method: 'POST',
body: {
...restParams,
method: 'update',
},
});
}
export async function fakeAccountLogin(params) { export async function fakeAccountLogin(params) {
return request('/api/login/account', { return request('/api/login/account', {
method: 'POST', method: 'POST',
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment