提交 b15834a6 作者: 郁骅焌

宏命令修改

上级 1dcd171e
# @umi-material/TestBlock # @umi-material/TestBlock
测试Block 测试
## Usage ## Usage
```sh ```sh
umi block https://github.com/umijs/umi-blocks/tree/master/TestBlock umi block https://github.com//tree/master/TestBlock
``` ```
## LICENSE ## LICENSE
......
{ {
"name": "@umi-block/TestBlock", "name": "@umi-block/TestBlock",
"version": "0.0.1", "version": "1.0.0",
"description": "测试Block", "description": "测试",
"main": "src/index.js", "main": "src/index.js",
"authors": { "authors": {
"name": "heartrainy", "name": "heartrainy",
"email": "" "email": ""
}, },
"repository": "umijs/umi-blocks/TestBlock",
"scripts": { "scripts": {
"dev": "umi dev" "dev": "umi dev"
}, },
...@@ -16,10 +15,11 @@ ...@@ -16,10 +15,11 @@
}, },
"devDependencies": { "devDependencies": {
"umi": "^2.0.0", "umi": "^2.0.0",
"umi-plugin-block-dev": "^2.0.0", "umi-plugin-block-dev": "^2.0.0",
"umi-types": "^0.2.0" "umi-types": "^0.2.0"
},
}, "blockConfig": {
"specVersion": "0.1"
},
"license": "MIT" "license": "MIT"
} }
import { parse } from 'url';
import moment from 'moment';
// mock tableListDataSource
let tableListDataSource: any[] = [];
for (let i = 0; i < 1; i += 1) {
tableListDataSource.push({
key: i,
column1: `column1_${i}`,
column2: Math.floor(Math.random() * 10) % 4,
column3: Math.floor(Math.random() * 1000),
column4: new Date(`2019-07-${Math.floor(i / 2) + 1}`).getTime(),
column5: Math.floor(Math.random() * 10) % 4,
href: 'https://ant.design',
avatar: [
'https://gw.alipayobjects.com/zos/rmsportal/eeHMaZBwmTvLdIwMfBpg.png',
'https://gw.alipayobjects.com/zos/rmsportal/udxAbMEhpwthVVcjLXik.png',
][i % 2],
name: `TradeCode ${i}`,
title: `一个任务名称 ${i}`,
owner: '曲丽丽',
desc: '这是一段描述',
callNo: Math.floor(Math.random() * 1000),
status: Math.floor(Math.random() * 10) % 4,
updatedAt: new Date(`2017-07-${Math.floor(i / 2) + 1}`),
createdAt: new Date(`2017-07-${Math.floor(i / 2) + 1}`),
progress: Math.ceil(Math.random() * 100),
});
}
function getRule(
req: { url: any },
res: {
json: (
arg0: {
list: any[];
pagination: { total: number; pageSize: number; current: number };
},
) => void;
},
u: any,
) {
let url = u;
if (!url || Object.prototype.toString.call(url) !== '[object String]') {
// eslint-disable-next-line prefer-destructuring
url = req.url;
}
const params = parse(url, true).query;
let dataSource = tableListDataSource;
if (params.sorter) {
const s = params.sorter.split('_');
dataSource = dataSource.sort((prev, next) => {
if (s[1] === 'descend') {
return next[s[0]] - prev[s[0]];
}
return prev[s[0]] - next[s[0]];
});
}
if (params.status) {
const status = params.status.split(',');
let filterDataSource: any[] = [];
status.forEach((s: string) => {
filterDataSource = filterDataSource.concat(
dataSource.filter(item => {
if (parseInt(`${item.status}`, 10) === parseInt(s.split('')[0], 10)) {
return true;
}
return false;
}),
);
});
dataSource = filterDataSource;
}
if (params.column1) {
dataSource = dataSource.filter(data => data.column1.indexOf(params.column1) > -1);
}
if (params.column2) {
dataSource = dataSource.filter(data => data.column2 == params.column2);
}
if (params.column3) {
dataSource = dataSource.filter(data => data.column3 == params.column3);
}
if (params.column4) {
dataSource = dataSource.filter(data => data.column4 <= moment(params.column4).valueOf());
}
if (params.column5) {
dataSource = dataSource.filter(data => data.column5 == params.column5);
}
let pageSize = 10;
if (params.pageSize) {
pageSize = parseInt(`${params.pageSize}`, 0);
}
const result = {
list: dataSource,
pagination: {
total: dataSource.length,
pageSize,
current: parseInt(`${params.currentPage}`, 10) || 1,
},
};
return res.json(result);
}
function postRule(
req: { url: any; body: any },
res: { json: (arg0: { list: any[]; pagination: { total: number } }) => void },
u: any,
b: { body: any },
) {
let url = u;
if (!url || Object.prototype.toString.call(url) !== '[object String]') {
// eslint-disable-next-line prefer-destructuring
url = req.url;
}
const body = (b && b.body) || req.body;
const { method, name, desc, key, column1, column2, column3, column4, column5 } = body;
switch (method) {
/* eslint no-case-declarations:0 */
case 'delete':
tableListDataSource = tableListDataSource.filter(item => key.indexOf(item.key) === -1);
break;
case 'post':
const i = Math.ceil(Math.random() * 10000);
tableListDataSource.unshift({
key: i,
column1: column1,
column2: column2,
column3: column3,
column4: column4,
column5: column5,
href: 'https://ant.design',
avatar: [
'https://gw.alipayobjects.com/zos/rmsportal/eeHMaZBwmTvLdIwMfBpg.png',
'https://gw.alipayobjects.com/zos/rmsportal/udxAbMEhpwthVVcjLXik.png',
][i % 2],
name: `TradeCode ${i}`,
title: `一个任务名称 ${i}`,
owner: '曲丽丽',
desc,
callNo: Math.floor(Math.random() * 1000),
status: Math.floor(Math.random() * 10) % 2,
updatedAt: new Date(),
createdAt: new Date(),
progress: Math.ceil(Math.random() * 100),
});
break;
case 'update':
tableListDataSource = tableListDataSource.map(item => {
if (item.key === key) {
return { ...item, column1, column2, column3, column4, column5 };
}
return item;
});
break;
default:
break;
}
const result = {
list: tableListDataSource,
pagination: {
total: tableListDataSource.length,
},
};
return res.json(result);
}
export default {
'GET /api/rule': getRule,
'POST /api/rule': postRule,
};
import { Form, Input, Modal, Select, DatePicker } from 'antd';
import { FormComponentProps } from 'antd/es/form';
import React, { Component } from 'react';
const FormItem = Form.Item;
const { Option } = Select;
interface CreateFormProps extends FormComponentProps {
modalVisible: boolean;
handleAdd: (
fieldsValue: any,
) => void;
handleModalVisible: () => void;
}
const OptionStatus: any[] = [
{ value: 1, label: '状态1' },
{ value: 2, label: '状态2' },
{ value: 3, label: '状态3' },
{ value: 4, label: '状态4' },
]
class CreateForm extends Component<CreateFormProps> {
okHandle = () => {
const { form, handleAdd } = this.props;
form.validateFields((err, fieldsValue) => {
if (err) return;
form.resetFields();
handleAdd(fieldsValue);
});
};
render() {
const { modalVisible, form, handleModalVisible } = this.props;
return (
<Modal
destroyOnClose
title="新建"
visible={modalVisible}
onOk={this.okHandle}
onCancel={() => handleModalVisible()}
>
<FormItem labelCol={{ span: 5 }} wrapperCol={{ span: 15 }} label="Column1">
{form.getFieldDecorator('column1', {
rules: [{ required: true, message: '请输入!' }],
})(<Input placeholder="请输入" />)}
</FormItem>
<FormItem labelCol={{ span: 5 }} wrapperCol={{ span: 15 }} label="Column2">
{form.getFieldDecorator('column2', {
rules: [{ required: true, message: '请输入!' }],
})(
<Select placeholder="请选择" style={{ width: '100%' }}>
{
OptionStatus.map(option => {
return <Option key={option.value} value={option.value}>{option.label}</Option>
})
}
</Select>
)}
</FormItem>
<FormItem labelCol={{ span: 5 }} wrapperCol={{ span: 15 }} label="Column3">
{form.getFieldDecorator('column3', {
rules: [{ required: true, message: '请输入!' }],
})(<Input placeholder="请输入" />)}
</FormItem>
<FormItem labelCol={{ span: 5 }} wrapperCol={{ span: 15 }} label="Column4">
{form.getFieldDecorator('column4', {
rules: [{ required: true, message: '请选择时间!' }],
})(<DatePicker style={{ width: '100%' }} />)}
</FormItem>
<FormItem labelCol={{ span: 5 }} wrapperCol={{ span: 15 }} label="Column5">
{form.getFieldDecorator('column5', {
rules: [{ required: true, message: '请输入!' }],
})(
<Select placeholder="请选择" style={{ width: '100%' }}>
{
OptionStatus.map(option => {
return <Option key={option.value} value={option.value}>{option.label}</Option>
})
}
</Select>
)}
</FormItem>
</Modal>
);
}
};
export default Form.create<CreateFormProps>()(CreateForm);
@import '~antd/es/style/themes/default.less';
.standardTable {
:global {
.ant-table-pagination {
margin-top: 24px;
}
}
.tableAlert {
margin-bottom: 16px;
}
}
import { Table } from 'antd';
import { ColumnProps, TableRowSelection, TableProps } from 'antd/es/table';
import React, { Component } from 'react';
import { TableListItem } from '../../data.d';
import styles from './index.less';
type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;
export interface StandardTableProps<T> extends Omit<TableProps<T>, 'columns'> {
columns: StandardTableColumnProps[];
data: {
list: TableListItem[];
pagination: StandardTableProps<TableListItem>['pagination'];
};
selectedRows: TableListItem[];
onSelectRow: (rows: any) => void;
}
export interface StandardTableColumnProps extends ColumnProps<TableListItem> {
}
interface StandardTableState {
selectedRowKeys: string[];
}
class StandardTable extends Component<StandardTableProps<TableListItem>, StandardTableState> {
constructor(props: StandardTableProps<TableListItem>) {
super(props);
this.state = {
selectedRowKeys: [],
};
}
handleRowSelectChange: TableRowSelection<TableListItem>['onChange'] = (
selectedRowKeys,
selectedRows: TableListItem[],
) => {
const currySelectedRowKeys = selectedRowKeys as string[];
const { onSelectRow } = this.props;
if (onSelectRow) {
onSelectRow(selectedRows);
}
this.setState({ selectedRowKeys: currySelectedRowKeys });
};
handleTableChange: TableProps<TableListItem>['onChange'] = (
pagination,
filters,
sorter,
...rest
) => {
const { onChange } = this.props;
if (onChange) {
onChange(pagination, filters, sorter, ...rest);
}
};
cleanSelectedKeys = () => {
if (this.handleRowSelectChange) {
this.handleRowSelectChange([], []);
}
};
render() {
const { selectedRowKeys } = this.state;
const { data, rowKey, ...rest } = this.props;
const { list = [], pagination = false } = data || {};
const paginationProps = {
showSizeChanger: true,
showQuickJumper: true,
...pagination,
};
const rowSelection: TableRowSelection<TableListItem> = {
selectedRowKeys,
onChange: this.handleRowSelectChange
};
return (
<div className={styles.standardTable}>
<Table
rowKey={rowKey || 'key'}
rowSelection={rowSelection}
dataSource={list}
pagination={paginationProps}
onChange={this.handleTableChange}
{...rest}
/>
</div>
);
}
}
export default StandardTable;
import { DatePicker, Form, Input, Modal, Select } from 'antd';
import React, { Component } from 'react';
import moment from 'moment';
import { FormComponentProps } from 'antd/es/form';
import { TableListItem } from '../data.d';
export interface UpdateFormProps extends FormComponentProps {
handleUpdateModalVisible: (flag?: boolean, formVals?: Partial<TableListItem>) => void;
handleUpdate: (values: Partial<TableListItem>) => void;
updateModalVisible: boolean;
values: Partial<TableListItem>;
}
const FormItem = Form.Item;
const { Option } = Select;
const OptionStatus: any[] = [
{ value: 1, label: '状态1' },
{ value: 2, label: '状态2' },
{ value: 3, label: '状态3' },
{ value: 4, label: '状态4' },
]
class UpdateForm extends Component<UpdateFormProps> {
formLayout = {
labelCol: { span: 7 },
wrapperCol: { span: 13 },
};
okHandle = () => {
const { form, handleUpdate, values } = this.props;
console.log(values)
form.validateFields((err, fieldsValue) => {
if (err) return;
form.resetFields();
const updateValue = {
...values,
...fieldsValue
}
handleUpdate(updateValue);
});
};
render() {
const { updateModalVisible, handleUpdateModalVisible, form, values } = this.props;
return (
<Modal
width={640}
bodyStyle={{ padding: '32px 40px 48px' }}
destroyOnClose
title="编辑"
visible={updateModalVisible}
onOk={this.okHandle}
onCancel={() => handleUpdateModalVisible(false, values)}
>
<FormItem key="column1" {...this.formLayout} label="Column1">
{form.getFieldDecorator('column1', {
initialValue: values.column1,
rules: [{ required: true, message: '请输入!' }],
})(<Input placeholder="请输入" />)}
</FormItem>
<FormItem key="column2" {...this.formLayout} label="Column2">
{form.getFieldDecorator('column2', {
initialValue: values.column2,
rules: [{ required: true, message: '请输入!' }],
})(
<Select placeholder="请选择" style={{ width: '100%' }}>
{
OptionStatus.map(option => {
return <Option key={option.value} value={option.value}>{option.label}</Option>
})
}
</Select>
)}
</FormItem>
<FormItem key="column3" {...this.formLayout} label="Column3">
{form.getFieldDecorator('column3', {
initialValue: values.column3,
rules: [{ required: true, message: '请输入!' }],
})(<Input placeholder="请输入" />)}
</FormItem>
<FormItem key="column4" {...this.formLayout} label="Column4">
{form.getFieldDecorator('column4', {
initialValue: moment(values.column4),
rules: [{ required: true, message: '请选择时间!' }],
})(<DatePicker style={{ width: '100%' }} />)}
</FormItem>
<FormItem key="column5" {...this.formLayout} label="Column5">
{form.getFieldDecorator('column5', {
initialValue: values.column5,
rules: [{ required: true, message: '请输入!' }],
})(
<Select placeholder="请选择" style={{ width: '100%' }}>
{
OptionStatus.map(option => {
return <Option key={option.value} value={option.value}>{option.label}</Option>
})
}
</Select>
)}
</FormItem>
</Modal>
);
}
}
export default Form.create<UpdateFormProps>()(UpdateForm);
export interface TableListItem {
key: number;
column1?: string;
column2?: number;
column3?: number;
column4?: number;
column5?: number;
disabled?: boolean;
href: string;
avatar: string;
name: string;
title: string;
owner: string;
desc: string;
callNo: number;
status: number;
updatedAt: Date;
createdAt: Date;
progress: number;
}
export interface TableListPagination {
total: number;
pageSize: number;
current: number;
}
export interface TableListDate {
list: TableListItem[];
pagination: Partial<TableListPagination>;
}
export interface TableListParams {
sorter: string;
status: string;
name: string;
pageSize: number;
currentPage: number;
}
import {
Button,
Card,
Col,
DatePicker,
Divider,
Dropdown,
Form,
Icon,
Input,
Modal,
Menu,
Row,
Select,
message,
} from 'antd';
import React, { Component, Fragment } from 'react';
import { Dispatch } from 'redux';
import { FormComponentProps } from 'antd/es/form';
import { PageHeaderWrapper } from '@ant-design/pro-layout';
import { SorterResult } from 'antd/es/table';
import { connect } from 'dva';
import moment from 'moment';
import { StateType } from './model';
import CreateForm from './components/CreateForm';
import StandardTable, { StandardTableColumnProps } from './components/StandardTable';
import UpdateForm from './components/UpdateForm';
import { TableListItem, TableListPagination, TableListParams } from './data.d';
import styles from './style.less';
const FormItem = Form.Item;
const { Option } = Select;
const getValue = (obj: { [x: string]: string[] }) =>
Object.keys(obj)
.map(key => obj[key])
.join(',');
interface TableListProps extends FormComponentProps {
dispatch: Dispatch<any>;
loading: boolean;
BLOCK_NAME_CAMEL_CASE: StateType;
}
interface TableListState {
modalVisible: boolean;
updateModalVisible: boolean;
expandForm: boolean;
selectedRows: TableListItem[];
formValues: { [key: string]: string };
updateFormValues: Partial<TableListItem>;
}
const OptionStatus: any[] = [
{ value: 1, label: '状态1' },
{ value: 2, label: '状态2' },
{ value: 3, label: '状态3' },
{ value: 4, label: '状态4' },
]
/* eslint react/no-multi-comp:0 */
@connect(
({
BLOCK_NAME_CAMEL_CASE,
loading,
}: {
BLOCK_NAME_CAMEL_CASE: StateType;
loading: {
models: {
[key: string]: boolean;
};
};
}) => ({
BLOCK_NAME_CAMEL_CASE,
loading: loading.models.BLOCK_NAME_CAMEL_CASE,
}),
)
class TableList extends Component<TableListProps, TableListState> {
state: TableListState = {
modalVisible: false,
updateModalVisible: false,
expandForm: false,
selectedRows: [],
formValues: {},
updateFormValues: {},
};
columns: StandardTableColumnProps[] = [
{
title: 'Column1',
dataIndex: 'column1',
},
{
title: 'Column2',
dataIndex: 'column2'
},
{
title: 'Column3',
dataIndex: 'column3',
sorter: true,
render: (val: number) => `${val} 万`,
},
{
title: 'Column4',
dataIndex: 'column4',
sorter: true,
render: (val: number) => <span>{moment(val).format('YYYY-MM-DD HH:mm:ss')}</span>
},
{
title: 'Column5',
dataIndex: 'column5'
},
{
title: '操作',
dataIndex: 'key',
render: (text, record) => (
<Fragment>
<a onClick={() => this.handleUpdateModalVisible(true, record)}>编辑</a>
<Divider type="vertical" />
<a onClick={() => this.handleRemoveRecord([text])}>删除</a>
</Fragment>
),
},
];
componentDidMount() {
const { dispatch } = this.props;
dispatch({
type: 'BLOCK_NAME_CAMEL_CASE/fetch',
});
}
handleStandardTableChange = (
pagination: Partial<TableListPagination>,
filtersArg: Record<keyof TableListItem, string[]>,
sorter: SorterResult<TableListItem>,
) => {
const { dispatch } = this.props;
const { formValues } = this.state;
const filters = Object.keys(filtersArg).reduce((obj, key) => {
const newObj = { ...obj };
newObj[key] = getValue(filtersArg[key]);
return newObj;
}, {});
const params: Partial<TableListParams> = {
currentPage: pagination.current,
pageSize: pagination.pageSize,
...formValues,
...filters,
};
if (sorter.field) {
params.sorter = `${sorter.field}_${sorter.order}`;
}
dispatch({
type: 'BLOCK_NAME_CAMEL_CASE/fetch',
payload: params,
});
};
handleFormReset = () => {
const { form, dispatch } = this.props;
form.resetFields();
this.setState({
formValues: {},
});
dispatch({
type: 'BLOCK_NAME_CAMEL_CASE/fetch',
payload: {},
});
};
toggleForm = () => {
const { expandForm } = this.state;
this.setState({
expandForm: !expandForm,
});
};
handleMenuClick = (e: { key: string }) => {
const { selectedRows } = this.state;
if (!selectedRows) return;
switch (e.key) {
case 'remove':
this.handleRemoveRecord(selectedRows.map(row => row.key))
break;
default:
break;
}
};
handleSelectRows = (rows: TableListItem[]) => {
this.setState({
selectedRows: rows,
});
};
handleSearch = (e: React.FormEvent) => {
e.preventDefault();
const { dispatch, form } = this.props;
form.validateFields((err, fieldsValue) => {
if (err) return;
// 格式化日期
const values = {
...fieldsValue,
'column4': fieldsValue['column4'] && fieldsValue['column4'].format('YYYY-MM-DD'),
};
this.setState({
formValues: values,
});
dispatch({
type: 'BLOCK_NAME_CAMEL_CASE/fetch',
payload: values,
});
});
};
handleModalVisible = (flag?: boolean) => {
this.setState({
modalVisible: !!flag,
});
};
handleUpdateModalVisible = (flag?: boolean, record?: Partial<TableListItem>) => {
this.setState({
updateModalVisible: !!flag,
updateFormValues: record || {},
});
};
handleAdd = (fields: any) => {
const { dispatch } = this.props;
dispatch({
type: 'BLOCK_NAME_CAMEL_CASE/add',
payload: {
...fields
},
});
message.success('添加成功');
this.handleModalVisible();
};
handleUpdate = (fields: Partial<TableListItem>) => {
const { dispatch } = this.props;
dispatch({
type: 'BLOCK_NAME_CAMEL_CASE/update',
payload: {
...fields
},
});
message.success('修改成功');
this.handleUpdateModalVisible();
};
handleRemoveRecord = (keys: number[]) => {
const _this = this;
Modal.confirm({
title: '提示',
content: keys.length == 1 ? '确定删除该条记录?' : '确定批量删除记录?',
okText: '确认',
cancelText: '取消',
onOk() {
_this.props.dispatch({
type: 'BLOCK_NAME_CAMEL_CASE/remove',
payload: {
key: keys,
},
callback: () => {
_this.setState({
selectedRows: [],
});
},
});
}
});
}
renderSimpleForm() {
const { form } = this.props;
const { getFieldDecorator } = form;
return (
<Form onSubmit={this.handleSearch} layout="inline">
<Row gutter={{ md: 8, lg: 24, xl: 48 }}>
<Col md={8} sm={24}>
<FormItem label="Column1">
{getFieldDecorator('column1')(<Input placeholder="请输入" />)}
</FormItem>
</Col>
<Col md={8} sm={24}>
<FormItem label="Column2">
{getFieldDecorator('column2')(
<Select placeholder="请选择" style={{ width: '100%' }}>
{
OptionStatus.map(option => {
return <Option key={option.value} value={option.value}>{option.label}</Option>
})
}
</Select>,
)}
</FormItem>
</Col>
<Col md={8} sm={24}>
<span className={styles.submitButtons}>
<Button type="primary" htmlType="submit">
查询
</Button>
<Button style={{ marginLeft: 8 }} onClick={this.handleFormReset}>
重置
</Button>
<a style={{ marginLeft: 8 }} onClick={this.toggleForm}>
展开 <Icon type="down" />
</a>
</span>
</Col>
</Row>
</Form>
);
}
renderAdvancedForm() {
const {
form: { getFieldDecorator },
} = this.props;
return (
<Form onSubmit={this.handleSearch} layout="inline">
<Row gutter={{ md: 8, lg: 24, xl: 48 }}>
<Col md={8} sm={24}>
<FormItem label="Column1">
{getFieldDecorator('column1')(<Input placeholder="请输入" />)}
</FormItem>
</Col>
<Col md={8} sm={24}>
<FormItem label="Column2">
{getFieldDecorator('column2')(
<Select placeholder="请选择" style={{ width: '100%' }}>
{
OptionStatus.map(option => {
return <Option key={option.value} value={option.value}>{option.label}</Option>
})
}
</Select>,
)}
</FormItem>
</Col>
<Col md={8} sm={24}>
<FormItem label="Column3">
{getFieldDecorator('column3')(<Input placeholder="请输入" />)}
</FormItem>
</Col>
</Row>
<Row gutter={{ md: 8, lg: 24, xl: 48 }}>
<Col md={8} sm={24}>
<FormItem label="Column4">
{getFieldDecorator('column4')(
<DatePicker style={{ width: '100%' }} placeholder="请输入日期" />,
)}
</FormItem>
</Col>
<Col md={8} sm={24}>
<FormItem label="Column5">
{getFieldDecorator('column5')(
<Select placeholder="请选择" style={{ width: '100%' }}>
{
OptionStatus.map(option => {
return <Option key={option.value} value={option.value}>{option.label}</Option>
})
}
</Select>,
)}
</FormItem>
</Col>
</Row>
<div style={{ overflow: 'hidden' }}>
<div style={{ float: 'right', marginBottom: 24 }}>
<Button type="primary" htmlType="submit">
查询
</Button>
<Button style={{ marginLeft: 8 }} onClick={this.handleFormReset}>
重置
</Button>
<a style={{ marginLeft: 8 }} onClick={this.toggleForm}>
收起 <Icon type="up" />
</a>
</div>
</div>
</Form>
);
}
renderForm() {
const { expandForm } = this.state;
return expandForm ? this.renderAdvancedForm() : this.renderSimpleForm();
}
render() {
const {
BLOCK_NAME_CAMEL_CASE: { data },
loading
} = this.props;
const { selectedRows, modalVisible, updateModalVisible, updateFormValues } = this.state;
const menu = (
<Menu onClick={this.handleMenuClick} selectedKeys={[]}>
<Menu.Item key="remove">删除</Menu.Item>
<Menu.Item key="approval">批量审批</Menu.Item>
</Menu>
);
const parentMethods = {
handleAdd: this.handleAdd,
handleModalVisible: this.handleModalVisible,
};
const updateMethods = {
handleUpdateModalVisible: this.handleUpdateModalVisible,
handleUpdate: this.handleUpdate,
};
return (
<PageHeaderWrapper>
<Card bordered={false}>
<div className={styles.tableList}>
<div className={styles.tableListForm}>{this.renderForm()}</div>
<div className={styles.tableListOperator}>
<Button icon="plus" type="primary" onClick={() => this.handleModalVisible(true)}>
新建
</Button>
{selectedRows.length > 0 && (
<span>
<Button>批量操作</Button>
<Dropdown overlay={menu}>
<Button>
更多操作 <Icon type="down" />
</Button>
</Dropdown>
</span>
)}
</div>
<StandardTable
selectedRows={selectedRows}
loading={loading}
data={data}
columns={this.columns}
onSelectRow={this.handleSelectRows}
onChange={this.handleStandardTableChange}
/>
</div>
</Card>
<CreateForm {...parentMethods} modalVisible={modalVisible} />
<UpdateForm
{...updateMethods}
updateModalVisible={updateModalVisible}
values={updateFormValues}
/>
{
/*
stepFormValues && Object.keys(stepFormValues).length ? (
<UpdateForm
{...updateMethods}
updateModalVisible={updateModalVisible}
values={stepFormValues}
/>
) : null
*/
}
</PageHeaderWrapper>
);
}
}
export default Form.create<TableListProps>()(TableList);
import { AnyAction, Reducer } from 'redux';
import { EffectsCommandMap } from 'dva';
import { addRule, queryRule, removeRule, updateRule } from './service';
import { TableListDate } from './data.d';
export interface StateType {
data: TableListDate;
}
export type Effect = (
action: AnyAction,
effects: EffectsCommandMap & { select: <T>(func: (state: StateType) => T) => T },
) => void;
export interface ModelType {
namespace: string;
state: StateType;
effects: {
fetch: Effect;
add: Effect;
remove: Effect;
update: Effect;
};
reducers: {
save: Reducer<StateType>;
};
}
const Model: ModelType = {
namespace: 'BLOCK_NAME_CAMEL_CASE',
state: {
data: {
list: [],
pagination: {},
},
},
effects: {
*fetch({ payload }, { call, put }) {
const response = yield call(queryRule, payload);
yield put({
type: 'save',
payload: response,
});
},
*add({ payload, callback }, { call, put }) {
const response = yield call(addRule, payload);
yield put({
type: 'save',
payload: response,
});
if (callback) callback();
},
*remove({ payload, callback }, { call, put }) {
const response = yield call(removeRule, payload);
yield put({
type: 'save',
payload: response,
});
if (callback) callback();
},
*update({ payload, callback }, { call, put }) {
const response = yield call(updateRule, payload);
yield put({
type: 'save',
payload: response,
});
if (callback) callback();
},
},
reducers: {
save(state, action) {
return {
...state,
data: action.payload,
};
},
},
};
export default Model;
import request from 'umi-request';
import { TableListParams } from './data.d';
export async function queryRule(params: TableListParams) {
return request('/api/rule', {
params,
});
}
export async function removeRule(params: TableListParams) {
return request('/api/rule', {
method: 'POST',
data: {
...params,
method: 'delete',
},
});
}
export async function addRule(params: TableListParams) {
return request('/api/rule', {
method: 'POST',
data: {
...params,
method: 'post',
},
});
}
export async function updateRule(params: TableListParams) {
return request('/api/rule', {
method: 'POST',
data: {
...params,
method: 'update',
},
});
}
@import '~antd/es/style/themes/default.less';
@import './utils/utils.less';
.tableList {
.tableListOperator {
margin-bottom: 16px;
button {
margin-right: 8px;
}
}
}
.tableListForm {
:global {
.ant-form-item {
display: flex;
margin-right: 0;
margin-bottom: 24px;
> .ant-form-item-label {
width: auto;
padding-right: 8px;
line-height: 32px;
}
.ant-form-item-control {
line-height: 32px;
}
}
.ant-form-item-control-wrapper {
flex: 1;
}
}
.submitButtons {
display: block;
margin-bottom: 24px;
white-space: nowrap;
}
}
@media screen and (max-width: @screen-lg) {
.tableListForm :global(.ant-form-item) {
margin-right: 24px;
}
}
@media screen and (max-width: @screen-md) {
.tableListForm :global(.ant-form-item) {
margin-right: 8px;
}
}
.textOverflow() {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
word-break: break-all;
}
.textOverflowMulti(@line: 3, @bg: #fff) {
position: relative;
max-height: @line * 1.5em;
margin-right: -1em;
padding-right: 1em;
overflow: hidden;
line-height: 1.5em;
text-align: justify;
&::before {
position: absolute;
right: 14px;
bottom: 0;
padding: 0 1px;
background: @bg;
content: '...';
}
&::after {
position: absolute;
right: 14px;
width: 1em;
height: 1em;
margin-top: 0.2em;
background: white;
content: '';
}
}
// mixins for clearfix
// ------------------------
.clearfix() {
zoom: 1;
&::before,
&::after {
display: table;
content: ' ';
}
&::after {
clear: both;
height: 0;
font-size: 0;
visibility: hidden;
}
}
.normal {
background: #79F2AA;
}
import React from 'react';
import styles from './index.css';
const Block: React.FC = () => {
return (
<div className={styles.normal}>
<h1>I am a umi block!</h1>
</div>
);
}
export default Block;
{ {
"private": true, "private": true,
"scripts": { "scripts": {
"dev": "cross-env PAGES_PATH='TestBlock/src' umi dev", "dev": "cross-env PAGES_PATH='MySimpleTable/src' umi dev",
"format-imports": "import-sort --write '**/*.{js,jsx,ts,tsx}'", "format-imports": "import-sort --write '**/*.{js,jsx,ts,tsx}'",
"lint": "npm run lint:js && npm run lint:style", "lint": "npm run lint:js && npm run lint:style",
"lint-staged": "lint-staged", "lint-staged": "lint-staged",
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论