import React, { Component } from 'react'
|
import PropTypes from 'prop-types'
|
import { is, fromJS } from 'immutable'
|
import { DndProvider, DragSource, DropTarget } from 'react-dnd'
|
import { Table, Form, Popover, Icon, Modal } from 'antd'
|
|
import asyncComponent from '@/utils/asyncComponent'
|
import asyncIconComponent from '@/utils/asyncIconComponent'
|
import Utils from '@/utils/utils.js'
|
import zhCN from '@/locales/zh-CN/model.js'
|
import enUS from '@/locales/en-US/model.js'
|
import MKEmitter from '@/utils/events.js'
|
import './index.scss'
|
|
const { confirm } = Modal
|
const coldict = localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS
|
const EditColumn = asyncIconComponent(() => import('./editColumn'))
|
const CardCellComponent = asyncComponent(() => import('@/menu/components/card/cardcellcomponent'))
|
|
class HeaderCol extends Component {
|
deleteCol = () => {
|
const _this = this
|
|
confirm({
|
content: '确定删除显示列吗?',
|
onOk() {
|
_this.props.deleteCol(_this.props.column)
|
},
|
onCancel() {}
|
})
|
}
|
|
shouldComponentUpdate (nextProps, nextState) {
|
|
if (!nextProps.column) return false
|
|
return !is(fromJS(this.props.column), fromJS(nextProps.column)) ||
|
!is(fromJS(this.props.fields), fromJS(nextProps.fields)) ||
|
this.props.index !== nextProps.index
|
}
|
|
render() {
|
const { connectDragSource, connectDropTarget, moveCol, addElement, editColumn, deleteCol, index, column, align, fields, children, ...restProps } = this.props
|
|
if (index !== undefined) {
|
return connectDragSource(
|
connectDropTarget(<th {...restProps} index={index} style={{ cursor: 'move', textAlign: align }}>
|
<Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
|
<div className="mk-popover-control">
|
{column && (column.type === 'custom' || column.type === 'colspan' || column.type === 'action') ?
|
<Icon className="plus" title="添加" type="plus" onClick={() => this.props.addElement(column)} /> : null
|
}
|
<Icon className="edit" title="编辑" type="edit" onClick={() => this.props.editColumn(column)} />
|
<Icon className="close" title="删除" type="delete" onClick={this.deleteCol} />
|
</div>
|
} trigger="hover">
|
{children}
|
</Popover>
|
</th>),
|
)
|
} else if (column) {
|
return (
|
<th {...restProps}>
|
<Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
|
<div className="mk-popover-control">
|
{column && column.type === 'custom' ?
|
<Icon className="plus" title="添加" type="plus" onClick={() => this.props.addElement(column)} /> : null
|
}
|
<Icon className="edit" title="编辑" type="edit" onClick={() => this.props.editColumn(column)} />
|
<Icon className="close" title="删除" type="delete" onClick={this.deleteCol} />
|
</div>
|
} trigger="hover">
|
{children}
|
</Popover>
|
</th>
|
)
|
} else {
|
return (<th {...restProps}>{children}</th>)
|
}
|
}
|
}
|
|
const rowSource = {
|
beginDrag(props) {
|
return {
|
index: props.index,
|
}
|
}
|
}
|
|
const ColTarget = {
|
drop(props, monitor) {
|
const dragIndex = monitor.getItem().index
|
const hoverIndex = props.index
|
|
if (dragIndex === undefined || hoverIndex === undefined || dragIndex === hoverIndex) {
|
return
|
}
|
|
props.moveCol(dragIndex, hoverIndex)
|
monitor.getItem().index = hoverIndex
|
},
|
}
|
|
const DragableHeaderCol = DropTarget('col', ColTarget, connect => ({
|
connectDropTarget: connect.dropTarget()
|
}))(
|
DragSource('col', rowSource, connect => ({
|
connectDragSource: connect.dragSource(),
|
}))(HeaderCol),
|
)
|
|
class EditableCell extends Component {
|
updateCard = (vals) => {
|
const { column } = this.props
|
this.props.upComponent({...column, elements: vals})
|
}
|
|
shouldComponentUpdate (nextProps, nextState) {
|
const { config, column } = this.props
|
|
if (!nextProps.column) return true
|
|
return !is(fromJS(column), fromJS(nextProps.column)) ||
|
!is(fromJS(config.columns), fromJS(nextProps.config.columns)) ||
|
!is(fromJS(config.search), fromJS(nextProps.config.search))
|
}
|
|
render() {
|
const { column, config, children, className, style } = this.props
|
|
if (column && column.type === 'custom') {
|
return (
|
<td style={{padding: 0, verticalAlign: 'top', minWidth: column.Width || 100}} className={className}>
|
<CardCellComponent cards={config} cardCell={column} elements={column.elements} updateElement={this.updateCard}/>
|
</td>
|
)
|
} else if (column && column.type === 'action') {
|
return (
|
<td style={{padding: '0 5px', textAlign: column.Align, minWidth: column.Width || 100}} className={className}>
|
<CardCellComponent cards={config} cardCell={column} elements={column.elements} updateElement={this.updateCard}/>
|
</td>
|
)
|
} else if (column) {
|
return (
|
<td style={{...style, minWidth: column.Width || 100}} className={className}>
|
{column.field}
|
</td>
|
)
|
} else {
|
return (
|
<td style={style} className={className}>
|
{children}
|
</td>
|
)
|
}
|
}
|
}
|
|
class EditTable extends Component {
|
static propTpyes = {
|
config: PropTypes.object, // 配置信息
|
updatecolumn: PropTypes.func // 数据变化
|
}
|
|
state = {
|
data: [{uuid: Utils.getuuid()}],
|
columns: [],
|
fields: []
|
}
|
|
UNSAFE_componentWillMount () {
|
const { config } = this.props
|
|
this.setState({
|
columns: fromJS(config.cols).toJS(),
|
fields: fromJS(config.columns).toJS()
|
})
|
}
|
|
UNSAFE_componentWillReceiveProps (nextProps) {
|
if (!is(fromJS(this.state.columns), fromJS(nextProps.config.cols))) {
|
let _columns = fromJS(nextProps.config.cols).toJS()
|
this.setState({columns: _columns})
|
if (_columns[_columns.length - 1] && _columns[_columns.length - 1].focus) {
|
this.editColumn(_columns[_columns.length - 1])
|
}
|
} else if (!is(fromJS(this.state.fields), fromJS(nextProps.config.columns))) {
|
this.setState({fields: fromJS(nextProps.config.columns).toJS()})
|
}
|
}
|
shouldComponentUpdate (nextProps, nextState) {
|
const { config } = this.props
|
|
return !is(fromJS(this.state), fromJS(nextState)) ||
|
!is(fromJS(config.wrap), fromJS(nextProps.config.wrap)) ||
|
!is(fromJS(config.search), fromJS(nextProps.config.search)) ||
|
config.setting.laypage !== nextProps.config.setting.laypage
|
}
|
|
moveCol = (dragIndex, hoverIndex) => {
|
let _columns = fromJS(this.state.columns).toJS()
|
|
_columns.splice(hoverIndex, 0, ..._columns.splice(dragIndex, 1))
|
|
this.setState({
|
columns: _columns
|
}, () => {
|
this.props.updatecolumn({...this.props.config, cols: _columns})
|
})
|
}
|
|
updateCol = (col) => {
|
let _columns = fromJS(this.state.columns).toJS()
|
|
if (col.isSub) {
|
_columns = _columns.map(column => {
|
if (column.type === 'colspan') {
|
column.subcols = column.subcols.map(item => {
|
if (item.uuid === col.uuid) {
|
return col
|
}
|
return item
|
})
|
}
|
return column
|
})
|
} else {
|
_columns = _columns.map(column => {
|
if (column.uuid === col.uuid) {
|
return col
|
}
|
return column
|
})
|
}
|
|
this.setState({
|
columns: _columns,
|
}, () => {
|
this.props.updatecolumn({...this.props.config, cols: _columns})
|
})
|
}
|
|
editColumn = (col) => {
|
this.setState({
|
card: fromJS(col).toJS()
|
})
|
}
|
|
addElement = (col) => {
|
const { config } = this.props
|
let column = fromJS(col).toJS()
|
|
if (column.type === 'colspan') {
|
column.subcols = column.subcols || []
|
let subcol = { isSub: true, focus: true, uuid: Utils.getuuid(), label: 'label', field: '', type: 'text' }
|
column.subcols.push(subcol)
|
|
this.setState({
|
card: subcol
|
})
|
this.updateCol(column)
|
} else if (column.type === 'custom') {
|
let newcard = {uuid: Utils.getuuid(), focus: true, eleType: 'text', datatype: 'dynamic'}
|
|
// 注册事件-添加元素
|
MKEmitter.emit('cardAddElement', [config.uuid, column.uuid], newcard)
|
} else if (column.type === 'action') {
|
let newcard = {
|
uuid: Utils.getuuid(),
|
focus: true,
|
eleType: 'button',
|
label: 'button',
|
OpenType: 'prompt',
|
class: 'primary',
|
intertype: 'system',
|
execSuccess: 'grid',
|
execError: 'never',
|
show: 'link',
|
$type: 'tableButton'
|
}
|
|
// 注册事件-添加元素
|
MKEmitter.emit('cardAddElement', [config.uuid, column.uuid], newcard)
|
}
|
}
|
|
submitCol = (col) => {
|
const { card } = this.state
|
|
col.uuid = card.uuid
|
col.isSub = card.isSub === true
|
col.marks = card.marks || []
|
|
if (col.type === 'colspan') {
|
col.subcols = card.subcols || []
|
} else if (col.type === 'custom') {
|
col.elements = card.type === 'custom' ? (card.elements || []) : []
|
} else if (col.type === 'action') {
|
col.elements = card.type === 'action' ? (card.elements || []) : []
|
}
|
|
this.setState({card: null})
|
this.updateCol(col)
|
}
|
|
cancelCol = () => {
|
const { card } = this.state
|
|
if (card.focus) {
|
this.deleteCol(card)
|
}
|
|
this.setState({card: null})
|
}
|
|
deleteCol = (col) => {
|
let _columns = fromJS(this.state.columns).toJS()
|
|
if (col.isSub) {
|
_columns = _columns.map(column => {
|
if (column.type !== 'colspan') return column
|
if (column.subcols && column.subcols.length > 0) {
|
column.subcols = column.subcols.filter(item => item.uuid !== col.uuid)
|
}
|
return column
|
})
|
} else {
|
_columns = _columns.filter(column => column.uuid !== col.uuid)
|
}
|
|
this.setState({
|
columns: _columns
|
}, () => {
|
this.props.updatecolumn({...this.props.config, cols: _columns})
|
})
|
}
|
|
render() {
|
const { config } = this.props
|
const { fields, card } = this.state
|
const components = {
|
header: {
|
cell: DragableHeaderCol
|
},
|
body: {
|
cell: EditableCell
|
}
|
}
|
|
const columns = this.state.columns.map((col, index) => {
|
return {
|
title: col.label,
|
dataIndex: col.field,
|
align: col.Align,
|
sorter: col.IsSort === 'true',
|
onCell: () => ({
|
column: col,
|
width: col.Width,
|
config: config,
|
upComponent: this.updateCol
|
}),
|
children: col.subcols && col.subcols.length > 0 ? col.subcols.map(cell => ({
|
align: col.Align,
|
title: cell.label,
|
key: cell.uuid,
|
onCell: () => ({
|
column: cell,
|
width: cell.Width,
|
config: config,
|
upComponent: this.updateCol
|
}),
|
onHeaderCell: () => ({
|
column: cell,
|
align: cell.Align,
|
addElement: this.addElement,
|
editColumn: this.editColumn,
|
deleteCol: this.deleteCol,
|
})
|
})) : null,
|
onHeaderCell: () => ({
|
index,
|
column: col,
|
align: col.Align,
|
moveCol: this.moveCol,
|
addElement: this.addElement,
|
editColumn: this.editColumn,
|
deleteCol: this.deleteCol,
|
})
|
}
|
})
|
|
return (
|
<div className={`normal-table-columns ${config.setting.laypage} ${config.wrap.tableType}`}>
|
<DndProvider>
|
<Table
|
rowKey="uuid"
|
bordered={config.wrap.border !== 'false'}
|
components={components}
|
dataSource={this.state.data}
|
rowSelection={config.wrap.tableType ? { type: 'radio' } : null}
|
columns={columns}
|
rowClassName="editable-row"
|
pagination={{
|
current: 1,
|
pageSize: 10,
|
pageSizeOptions: ['10', '25', '50', '100', '500', '1000'],
|
showSizeChanger: true,
|
total: 58,
|
showTotal: (total, range) => `${range[0]}-${range[1]} 共 ${total} 条`
|
}}
|
/>
|
</DndProvider>
|
<EditColumn column={card} dict={coldict} fields={fields} submitCol={this.submitCol} cancelCol={this.cancelCol}/>
|
</div>
|
)
|
}
|
}
|
|
export default Form.create()(EditTable)
|