import React, {Component} from 'react'
|
import PropTypes from 'prop-types'
|
import { Table, Input, Form } from 'antd'
|
import { CloseOutlined } from '@ant-design/icons'
|
import Utils from '@/utils/utils.js'
|
import './index.scss'
|
|
const EditableContext = React.createContext()
|
|
const EditableRow = ({ form, index, ...props }) => (
|
<EditableContext.Provider value={form}>
|
<tr {...props} />
|
</EditableContext.Provider>
|
)
|
|
const EditableFormRow = Form.create()(EditableRow)
|
|
class EditableCell extends Component {
|
state = {
|
editing: false
|
}
|
|
toggleEdit = () => {
|
const { dataIndex } = this.props
|
|
if (!dataIndex) return
|
|
const editing = !this.state.editing
|
this.setState({ editing }, () => {
|
if (editing && this.input && this.input.select) {
|
this.input.select()
|
} else if (editing && this.input && this.input.focus) {
|
this.input.focus()
|
}
|
})
|
}
|
|
save = e => {
|
const { record, handleSave } = this.props
|
this.form.validateFields((error, values) => {
|
handleSave({ ...record, ...values })
|
if (error && error[e.currentTarget.id]) {
|
return
|
}
|
this.toggleEdit()
|
})
|
}
|
|
renderCell = form => {
|
this.form = form
|
const { children, dataIndex, record } = this.props
|
const { editing } = this.state
|
|
return editing ? (
|
<Form.Item style={{ margin: 0 }}>
|
{form.getFieldDecorator(dataIndex, {
|
initialValue: record[dataIndex]
|
})(<Input ref={node => (this.input = node)} autoComplete="off" onPressEnter={this.save} onBlur={this.save} />)}
|
</Form.Item>
|
) : (
|
<div
|
className="editable-cell-value-wrap"
|
onClick={this.toggleEdit}
|
>
|
{children}
|
</div>
|
)
|
}
|
|
render() {
|
const { dataIndex, title, record, index, handleSave, children, ...restProps } = this.props
|
return (
|
<td {...restProps}>
|
<EditableContext.Consumer style={{padding: 0}}>{this.renderCell}</EditableContext.Consumer>
|
</td>
|
)
|
}
|
}
|
|
class EditTable extends Component {
|
static propTpyes = {
|
data: PropTypes.array,
|
onChange: PropTypes.func
|
}
|
|
state = {
|
dataSource: [],
|
selectedRowKeys: [],
|
count: 0,
|
columns: [{
|
dataIndex: 'key',
|
title: 'KEY',
|
width: '33%'
|
}, {
|
dataIndex: 'value',
|
title: 'VALUE',
|
width: '33%'
|
}, {
|
dataIndex: 'description',
|
title: 'DESCRIPTION',
|
className: 'no-border',
|
width: '33%'
|
}, {
|
dataIndex: '',
|
title: '',
|
width: '20px',
|
render: (text, record) => {
|
return (<CloseOutlined onClick={() => this.delete(record)}/>)
|
}
|
}]
|
}
|
|
UNSAFE_componentWillMount () {
|
const { data } = this.props
|
|
let _data = data || []
|
let selectedRowKeys = []
|
if (_data && _data.length > 0) {
|
_data.forEach(item => {
|
if (item.selected) {
|
selectedRowKeys.push(item.uuid)
|
}
|
})
|
} else {
|
_data = [{
|
uuid: Utils.getuuid(),
|
key: '',
|
value: '',
|
description: '',
|
selected: true
|
}]
|
selectedRowKeys.push(_data[0].uuid)
|
this.props.onChange(_data)
|
}
|
|
this.setState({
|
dataSource: _data,
|
selectedRowKeys
|
})
|
}
|
|
handleDelete = key => {
|
const { dataSource } = this.state
|
let _data = dataSource.filter(item => item.key !== key)
|
|
this.setState({ dataSource: _data }, () => {
|
this.props.onChange(_data)
|
})
|
}
|
|
delete = (item) => {
|
const { dataSource, selectedRowKeys } = this.state
|
|
let _data = dataSource.filter(cell => cell.uuid !== item.uuid)
|
let _keys = selectedRowKeys.filter(key => key !== item.uuid)
|
|
if (_data.length === 0) {
|
_data = [{
|
uuid: Utils.getuuid(),
|
key: '',
|
value: '',
|
description: '',
|
selected: true
|
}]
|
_keys = [_data[0].uuid]
|
this.props.onChange(_data)
|
}
|
|
this.setState({
|
dataSource: _data,
|
selectedRowKeys: _keys
|
}, () => {
|
this.props.onChange(_data)
|
})
|
}
|
|
handleSave = row => {
|
let newData = this.state.dataSource.map(item => {
|
if (row.uuid === item.uuid) return row
|
return item
|
})
|
|
let selectedRowKeys = this.state.selectedRowKeys
|
|
let last = newData[newData.length - 1]
|
if (last.key || last.value || last.description) {
|
const item = {
|
uuid: Utils.getuuid(),
|
key: '',
|
value: '',
|
description: '',
|
selected: true
|
}
|
|
newData = [...newData, item]
|
selectedRowKeys = [...selectedRowKeys, item.uuid]
|
}
|
|
this.setState({ dataSource: newData, selectedRowKeys }, () => {
|
this.props.onChange(newData)
|
})
|
}
|
|
onChange = selectedRowKeys => {
|
const newData = this.state.dataSource.map(item => {
|
item.selected = selectedRowKeys.includes(item.uuid)
|
return item
|
})
|
|
this.setState({ dataSource: newData, selectedRowKeys }, () => {
|
this.props.onChange(newData)
|
})
|
}
|
|
render() {
|
const { dataSource, selectedRowKeys } = this.state
|
const components = {
|
body: {
|
row: EditableFormRow,
|
cell: EditableCell
|
}
|
}
|
const columns = this.state.columns.map(col => {
|
return {
|
...col,
|
onCell: record => ({
|
record,
|
dataIndex: col.dataIndex,
|
title: col.title,
|
handleSave: this.handleSave,
|
})
|
}
|
})
|
return (
|
<div className="params-edit-table">
|
<Table
|
rowKey="uuid"
|
components={components}
|
bordered
|
dataSource={dataSource}
|
columns={columns}
|
rowSelection={{ type: 'checkbox', selectedRowKeys, onChange: this.onChange }}
|
pagination={false}
|
/>
|
</div>
|
)
|
}
|
}
|
|
export default EditTable
|