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 96ebed0bf3ea0546f39e45334ad4025b5f02d6aa..46d8a02b3fc96d28255b95c3971d8829a4170b7a 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 0000000000000000000000000000000000000000..5195e820e85b13ccd20084cd277dfae682e8d3a8 --- /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 c0c17251edd43b2d1851cdc17fdfa6f0ac0e6f50..ab7d071035c5baf8df910ffffd6b57453279dd31 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 0000000000000000000000000000000000000000..40b9a058cfd5d244ccc1a1a121ccfceb9a69e4cc --- /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, + })(