From 68809608a055191af04a5b61271e18c740c11368 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E5=B8=85?= Date: Wed, 17 Apr 2019 23:39:58 +0800 Subject: [PATCH] Tablist finish --- TableList/src/{_mock.js => _mock.ts} | 40 ++- TableList/src/components/CreateForm.tsx | 42 +++ .../StandardTable/{index.js => index.tsx} | 62 +++- TableList/src/components/UpdateForm.tsx | 236 ++++++++++++ TableList/src/data.d.ts | 34 ++ TableList/src/{index.js => index.tsx} | 340 ++++-------------- TableList/src/locales/en-US.js | 1 - TableList/src/locales/pt-BR.js | 1 - TableList/src/locales/zh-CN.js | 1 - TableList/src/locales/zh-TW.js | 1 - TableList/src/{model.js => model.ts} | 31 +- TableList/src/{service.js => service.ts} | 9 +- package.json | 2 +- 13 files changed, 497 insertions(+), 303 deletions(-) rename TableList/src/{_mock.js => _mock.ts} (79%) create mode 100644 TableList/src/components/CreateForm.tsx rename TableList/src/components/StandardTable/{index.js => index.tsx} (57%) create mode 100644 TableList/src/components/UpdateForm.tsx create mode 100644 TableList/src/data.d.ts rename TableList/src/{index.js => index.tsx} (57%) delete mode 100644 TableList/src/locales/en-US.js delete mode 100644 TableList/src/locales/pt-BR.js delete mode 100644 TableList/src/locales/zh-CN.js delete mode 100644 TableList/src/locales/zh-TW.js rename TableList/src/{model.js => model.ts} (65%) rename TableList/src/{service.js => service.ts} (62%) diff --git a/TableList/src/_mock.js b/TableList/src/_mock.ts similarity index 79% rename from TableList/src/_mock.js rename to TableList/src/_mock.ts index 96ebed0b..46d8a02b 100644 --- a/TableList/src/_mock.js +++ b/TableList/src/_mock.ts @@ -1,8 +1,9 @@ import { parse } from 'url'; - +import { TableListItem, TableListParams } from './data'; // mock tableListDataSource -let tableListDataSource = []; -for (let i = 0; i < 46; i += 1) { +let tableListDataSource: TableListItem[] = []; + +for (let i = 0; i < 8; i += 1) { tableListDataSource.push({ key: i, disabled: i % 6 === 0, @@ -23,13 +24,24 @@ for (let i = 0; i < 46; i += 1) { }); } -function getRule(req, res, u) { +function getRule( + req: { url: any }, + res: { + json: ( + arg0: { + list: TableListItem[]; + pagination: { total: number; pageSize: number; current: number }; + } + ) => void; + }, + u: any +) { let url = u; if (!url || Object.prototype.toString.call(url) !== '[object String]') { url = req.url; // eslint-disable-line } - const params = parse(url, true).query; + const params = (parse(url, true).query as unknown) as TableListParams; let dataSource = tableListDataSource; @@ -45,10 +57,15 @@ function getRule(req, res, u) { if (params.status) { const status = params.status.split(','); - let filterDataSource = []; + let filterDataSource: TableListItem[] = []; status.forEach(s => { filterDataSource = filterDataSource.concat( - dataSource.filter(data => parseInt(data.status, 10) === parseInt(s[0], 10)) + dataSource.filter(item => { + if (parseInt(item.status + '', 10) === parseInt(s.split('')[0], 10)) { + return true; + } + return false; + }) ); }); dataSource = filterDataSource; @@ -60,7 +77,7 @@ function getRule(req, res, u) { let pageSize = 10; if (params.pageSize) { - pageSize = params.pageSize * 1; + pageSize = parseInt(params.pageSize) * 1; } const result = { @@ -75,7 +92,12 @@ function getRule(req, res, u) { return res.json(result); } -function postRule(req, res, u, b) { +function postRule( + req: { url: any; body: any }, + res: { json: (arg0: { list: TableListItem[]; pagination: { total: number } }) => void }, + u: any, + b: { body: any } +) { let url = u; if (!url || Object.prototype.toString.call(url) !== '[object String]') { url = req.url; // eslint-disable-line diff --git a/TableList/src/components/CreateForm.tsx b/TableList/src/components/CreateForm.tsx new file mode 100644 index 00000000..5195e820 --- /dev/null +++ b/TableList/src/components/CreateForm.tsx @@ -0,0 +1,42 @@ +import React from 'react'; +import { Input, Modal, Form } from 'antd'; +import { FormComponentProps } from 'antd/lib/form'; + +const FormItem = Form.Item; + +interface CreateFormProps extends FormComponentProps { + modalVisible: boolean; + handleAdd: ( + fieldsValue: { + desc: string; + } + ) => void; + handleModalVisible: () => void; +} +const CreateForm: React.SFC = props => { + const { modalVisible, form, handleAdd, handleModalVisible } = props; + const okHandle = () => { + form.validateFields((err, fieldsValue) => { + if (err) return; + form.resetFields(); + handleAdd(fieldsValue); + }); + }; + return ( + handleModalVisible()} + > + + {form.getFieldDecorator('desc', { + rules: [{ required: true, message: '请输入至少五个字符的规则描述!', min: 5 }], + })()} + + + ); +}; + +export default CreateForm; diff --git a/TableList/src/components/StandardTable/index.js b/TableList/src/components/StandardTable/index.tsx similarity index 57% rename from TableList/src/components/StandardTable/index.js rename to TableList/src/components/StandardTable/index.tsx index c0c17251..ab7d0710 100644 --- a/TableList/src/components/StandardTable/index.js +++ b/TableList/src/components/StandardTable/index.tsx @@ -1,9 +1,31 @@ -import React, { PureComponent, Fragment } from 'react'; +import React, { Component, Fragment } from 'react'; import { Table, Alert } from 'antd'; +import { TableProps, ColumnProps, SorterResult } from 'antd/lib/table'; import styles from './index.less'; +import { TableListItem } from '../../data'; -function initTotalList(columns) { - const totalList = []; +type Omit = Pick>; + +export interface StandardTableProps extends Omit, 'columns'> { + columns: StandardTableColumnProps[]; + data: { + list: Array; + pagination: StandardTableProps['pagination']; + }; + selectedRows: TableListItem[]; + onSelectRow: (rows: any) => void; +} + +export type StandardTableColumnProps = ColumnProps & { + needTotal?: boolean; + total?: number; +}; + +function initTotalList(columns: StandardTableColumnProps[]) { + if (!columns) { + return []; + } + const totalList: StandardTableColumnProps[] = []; columns.forEach(column => { if (column.needTotal) { totalList.push({ ...column, total: 0 }); @@ -12,8 +34,13 @@ function initTotalList(columns) { return totalList; } -class StandardTable extends PureComponent { - constructor(props) { +interface StandardTableState { + selectedRowKeys: string[]; + needTotalList: StandardTableColumnProps[]; +} + +class StandardTable extends Component, StandardTableState> { + constructor(props: StandardTableProps) { super(props); const { columns } = props; const needTotalList = initTotalList(columns); @@ -24,7 +51,7 @@ class StandardTable extends PureComponent { }; } - static getDerivedStateFromProps(nextProps) { + static getDerivedStateFromProps(nextProps: StandardTableProps) { // clean state if (nextProps.selectedRows.length === 0) { const needTotalList = initTotalList(nextProps.columns); @@ -36,7 +63,7 @@ class StandardTable extends PureComponent { return null; } - handleRowSelectChange = (selectedRowKeys, selectedRows) => { + handleRowSelectChange = (selectedRowKeys: string[], selectedRows: TableListItem[]) => { let { needTotalList } = this.state; needTotalList = needTotalList.map(item => ({ ...item, @@ -50,10 +77,15 @@ class StandardTable extends PureComponent { this.setState({ selectedRowKeys, needTotalList }); }; - handleTableChange = (pagination, filters, sorter) => { + handleTableChange = ( + pagination: StandardTableProps['pagination'], + filters: Record, + sorter: SorterResult, + ...rest + ) => { const { onChange } = this.props; if (onChange) { - onChange(pagination, filters, sorter); + onChange(pagination, filters, sorter, ...rest); } }; @@ -63,8 +95,8 @@ class StandardTable extends PureComponent { render() { const { selectedRowKeys, needTotalList } = this.state; - const { data = {}, rowKey, ...rest } = this.props; - const { list = [], pagination } = data; + const { data, rowKey, ...rest } = this.props; + const { list = [], pagination = false } = data || {}; const paginationProps = { showSizeChanger: true, @@ -75,7 +107,7 @@ class StandardTable extends PureComponent { const rowSelection = { selectedRowKeys, onChange: this.handleRowSelectChange, - getCheckboxProps: record => ({ + getCheckboxProps: (record: TableListItem) => ({ disabled: record.disabled, }), }; @@ -87,12 +119,14 @@ class StandardTable extends PureComponent { message={ 已选择 {selectedRowKeys.length} 项   - {needTotalList.map(item => ( + {needTotalList.map((item, index) => ( {item.title} 总计  - {item.render ? item.render(item.total) : item.total} + {item.render + ? item.render(item.total, item as TableListItem, index) + : item.total} ))} diff --git a/TableList/src/components/UpdateForm.tsx b/TableList/src/components/UpdateForm.tsx new file mode 100644 index 00000000..40b9a058 --- /dev/null +++ b/TableList/src/components/UpdateForm.tsx @@ -0,0 +1,236 @@ +import React, { Component } from 'react'; +import { Input, Select, Button, DatePicker, Form, Modal, Steps, Radio } from 'antd'; +import { TableListItem } from '../data'; +import { FormComponentProps } from 'antd/lib/form'; + +export type IFormValsType = { + target?: string; + template?: string; + type?: string; + time?: string; + frequency?: string; +} & Partial; + +export interface UpdateFormProps extends FormComponentProps { + handleUpdateModalVisible: (flag?: boolean, formVals?: IFormValsType) => void; + handleUpdate: (values: IFormValsType) => void; + updateModalVisible: boolean; + values: Partial; +} +const FormItem = Form.Item; +const { Step } = Steps; +const { TextArea } = Input; +const { Option } = Select; +const RadioGroup = Radio.Group; + +export interface UpdateFormState { + formVals: IFormValsType; + currentStep: number; +} + +class UpdateForm extends Component { + static defaultProps = { + handleUpdate: () => {}, + handleUpdateModalVisible: () => {}, + values: {}, + }; + formLayout = { + labelCol: { span: 7 }, + wrapperCol: { span: 13 }, + }; + constructor(props: UpdateFormProps) { + super(props); + + this.state = { + formVals: { + name: props.values.name, + desc: props.values.desc, + key: props.values.key, + target: '0', + template: '0', + type: '1', + time: '', + frequency: 'month', + }, + currentStep: 0, + }; + } + + handleNext = (currentStep: number) => { + const { form, handleUpdate } = this.props; + const { formVals: oldValue } = this.state; + form.validateFields((err, fieldsValue) => { + if (err) return; + const formVals = { ...oldValue, ...fieldsValue }; + this.setState( + { + formVals, + }, + () => { + if (currentStep < 2) { + this.forward(); + } else { + handleUpdate(formVals); + } + } + ); + }); + }; + + backward = () => { + const { currentStep } = this.state; + this.setState({ + currentStep: currentStep - 1, + }); + }; + + forward = () => { + const { currentStep } = this.state; + this.setState({ + currentStep: currentStep + 1, + }); + }; + + renderContent = (currentStep: number, formVals: IFormValsType) => { + const { form } = this.props; + if (currentStep === 1) { + return [ + + {form.getFieldDecorator('target', { + initialValue: formVals.target, + })( + + )} + , + + {form.getFieldDecorator('template', { + initialValue: formVals.template, + })( + + )} + , + + {form.getFieldDecorator('type', { + initialValue: formVals.type, + })( + + + + + )} + , + ]; + } + if (currentStep === 2) { + return [ + + {form.getFieldDecorator('time', { + rules: [{ required: true, message: '请选择开始时间!' }], + })( + + )} + , + + {form.getFieldDecorator('frequency', { + initialValue: formVals.frequency, + })( + + )} + , + ]; + } + return [ + + {form.getFieldDecorator('name', { + rules: [{ required: true, message: '请输入规则名称!' }], + initialValue: formVals.name, + })()} + , + + {form.getFieldDecorator('desc', { + rules: [{ required: true, message: '请输入至少五个字符的规则描述!', min: 5 }], + initialValue: formVals.desc, + })(