import React, { Component } from 'react'
|
import PropTypes from 'prop-types'
|
import { fromJS } from 'immutable'
|
import { Table, Input, InputNumber, Popconfirm, Form, Icon, notification, Select } from 'antd'
|
|
import ColorSketch from '@/mob/colorsketch'
|
import Utils from '@/utils/utils.js'
|
import './index.scss'
|
|
const EditableContext = React.createContext()
|
|
class EditableCell extends Component {
|
getInput = (form) => {
|
const { inputType } = this.props
|
if (inputType === 'number') {
|
return <InputNumber min={12} max={50} precision={0} onPressEnter={() => this.getValue(form)} />
|
} else if (inputType === 'color') {
|
return <ColorSketch />
|
} else if (inputType === 'select') {
|
return <Select>
|
<Select.Option key="left" value="left"> left </Select.Option>
|
<Select.Option key="center" value="center"> center </Select.Option>
|
<Select.Option key="right" value="right"> right </Select.Option>
|
<Select.Option key="justify" value="justify"> justify </Select.Option>
|
</Select>
|
} else {
|
return <Input onPressEnter={() => this.getValue(form)} />
|
}
|
}
|
|
getValue = (form) => {
|
const { record } = this.props
|
form.validateFields((error, row) => {
|
if (error) {
|
return
|
}
|
this.props.onSave({...record, ...row})
|
})
|
}
|
|
renderCell = (form) => {
|
const { getFieldDecorator } = form
|
const {
|
editing,
|
dataIndex,
|
title,
|
inputType,
|
record,
|
index,
|
children,
|
onSave,
|
...restProps
|
} = this.props;
|
return (
|
<td {...restProps}>
|
{editing ? (
|
<Form.Item style={{ margin: 0 }}>
|
{getFieldDecorator(dataIndex, {
|
rules: [
|
{
|
required: true,
|
message: `Please Input ${title}!`,
|
},
|
],
|
initialValue: record[dataIndex],
|
})(this.getInput(form))}
|
</Form.Item>
|
) : (
|
children
|
)}
|
</td>
|
)
|
}
|
|
render() {
|
return <EditableContext.Consumer>{this.renderCell}</EditableContext.Consumer>
|
}
|
}
|
|
class EdiFieldsTable extends Component {
|
static propTpyes = {
|
dict: PropTypes.object, // 字典项
|
onChange: PropTypes.func // 数据变化
|
}
|
|
UNSAFE_componentWillMount () {
|
let data = this.props['data-__meta'].initialValue
|
|
this.setState({
|
data: data
|
})
|
}
|
|
state = {
|
data: [],
|
editingKey: '',
|
columns: [
|
{
|
title: '字段名',
|
dataIndex: 'field',
|
inputType: 'input',
|
editable: true,
|
},
|
{
|
title: '字体颜色',
|
dataIndex: 'color',
|
inputType: 'color',
|
editable: true,
|
render: (text, record) => {
|
return <span style={{color: text}}>示例</span>
|
}
|
},
|
{
|
title: '字体大小',
|
dataIndex: 'fontSize',
|
inputType: 'number',
|
editable: true,
|
},
|
{
|
title: '对齐方式',
|
dataIndex: 'align',
|
inputType: 'select',
|
editable: true,
|
},
|
{
|
title: 'operation',
|
dataIndex: 'operation',
|
width: '18%',
|
render: (text, record) => {
|
const { editingKey } = this.state
|
const editable = this.isEditing(record)
|
return editable ? (
|
<span>
|
<EditableContext.Consumer>
|
{form => (
|
<span onClick={() => this.save(form, record.key)} style={{ marginRight: 8 , color: '#1890ff', cursor: 'pointer'}}>
|
保存
|
</span>
|
)}
|
</EditableContext.Consumer>
|
<span style={{ color: '#1890ff', cursor: 'pointer'}} onClick={() => this.cancel(record.key)}>取消</span>
|
</span>
|
) : (
|
<div className={'operation-btn' + (editingKey !== '' ? ' disabled' : '')}>
|
<span className="primary" onClick={() => {editingKey === '' && this.edit(record.key)}}><Icon type="edit" /></span>
|
<span className="primary" onClick={() => {editingKey === '' && this.handleUpDown(record.key, 'up')}}><Icon type="arrow-up" /></span>
|
<span className="danger" onClick={() => {editingKey === '' && this.handleUpDown(record.key, 'down')}}><Icon type="arrow-down" /></span>
|
{editingKey === '' ? <Popconfirm
|
overlayClassName="popover-confirm"
|
title={this.props.dict['model.query.delete']}
|
onConfirm={() => this.handleDelete(record.key)
|
}>
|
<span className="danger"><Icon type="delete" /></span>
|
</Popconfirm> : null}
|
{editingKey !== '' ? <span className="danger"><Icon type="delete" /></span> : null}
|
</div>
|
)
|
},
|
},
|
]
|
}
|
|
isEditing = record => record.key === this.state.editingKey
|
|
cancel = () => {
|
this.setState({ editingKey: '' })
|
}
|
|
onSave = (record) => {
|
const newData = [...this.state.data]
|
const index = newData.findIndex(item => record.key === item.key)
|
if (index > -1) {
|
newData.splice(index, 1, record)
|
this.setState({ data: newData, editingKey: '' }, () => {
|
this.props.onChange(newData)
|
})
|
}
|
}
|
|
handleDelete = (key) => {
|
const { data } = this.state
|
let _data = data.filter(item => key !== item.key)
|
|
this.setState({
|
data: _data
|
}, () => {
|
this.props.onChange(_data)
|
})
|
}
|
|
handleUpDown = (key, direction) => {
|
let _data = fromJS(this.state.data).toJS()
|
const index = _data.findIndex(item => key === item.key)
|
|
if ((index === 0 && direction === 'up') || (index === _data.length - 1 && direction === 'down')) {
|
return
|
}
|
|
if (direction === 'up') {
|
_data.splice(index - 1, 0, ..._data.splice(index, 1))
|
} else {
|
_data.splice(index + 1, 0, ..._data.splice(index, 1))
|
}
|
|
this.setState({
|
data: _data
|
}, () => {
|
this.props.onChange(_data)
|
})
|
}
|
|
save(form, key) {
|
form.validateFields((error, row) => {
|
if (error) {
|
return;
|
}
|
const newData = [...this.state.data]
|
const index = newData.findIndex(item => key === item.key)
|
if (index > -1) {
|
const item = newData[index]
|
newData.splice(index, 1, {
|
...item,
|
...row,
|
})
|
this.setState({ data: newData, editingKey: '' }, () => {
|
this.props.onChange(newData)
|
})
|
} else {
|
newData.push(row);
|
this.setState({ data: newData, editingKey: '' }, () => {
|
this.props.onChange(newData)
|
})
|
}
|
})
|
}
|
|
handleAdd = () => {
|
if (this.state.editingKey) {
|
notification.warning({
|
top: 92,
|
message: '请保存编辑中的元素!',
|
duration: 5
|
})
|
return
|
}
|
|
let item = {
|
key: Utils.getuuid(),
|
field: `field${this.state.data.length + 1}`,
|
color: 'rgba(0, 0, 0, 0.85)',
|
align: 'left',
|
fontSize: 14,
|
}
|
|
let data = [...this.state.data, item]
|
|
this.setState({ data }, () => {
|
this.props.onChange(data)
|
})
|
}
|
|
edit(key) {
|
this.setState({ editingKey: key })
|
}
|
|
render() {
|
const components = {
|
body: {
|
cell: EditableCell,
|
},
|
}
|
|
const columns = this.state.columns.map(col => {
|
if (!col.editable) {
|
return col
|
}
|
return {
|
...col,
|
onCell: record => ({
|
record,
|
inputType: col.inputType,
|
dataIndex: col.dataIndex,
|
title: col.title,
|
editing: this.isEditing(record),
|
onSave: this.onSave,
|
}),
|
}
|
})
|
|
return (
|
<EditableContext.Provider value={this.props.form}>
|
<div className="modal-card-field-table">
|
{this.state.data.length < 3 ? <Icon className="add-row" type="plus" onClick={this.handleAdd} /> : null}
|
<Table
|
components={components}
|
bordered
|
dataSource={this.state.data}
|
columns={columns}
|
rowClassName="editable-row"
|
pagination={false}
|
/>
|
</div>
|
</EditableContext.Provider>
|
)
|
}
|
}
|
|
export default Form.create()(EdiFieldsTable)
|