| | |
| | | import PropTypes from 'prop-types' |
| | | import { is, fromJS } from 'immutable' |
| | | import { DndProvider, DragSource, DropTarget } from 'react-dnd' |
| | | import { Table, Input, InputNumber, Popconfirm, Form, Icon, Select, Radio, Cascader, notification } from 'antd' |
| | | import { Table, Input, InputNumber, Popconfirm, Form, Icon, Select, Radio, Cascader, notification, message, Modal, Typography } from 'antd' |
| | | |
| | | import Utils from '@/utils/utils.js' |
| | | import ColorSketch from '@/mob/colorsketch' |
| | | import PasteForm from '@/templates/zshare/pasteform' |
| | | import CusSwitch from './cusSwitch' |
| | | import zhCN from '@/locales/zh-CN/model.js' |
| | | import enUS from '@/locales/en-US/model.js' |
| | | import './index.scss' |
| | | |
| | | let eTDict = localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS |
| | | let eTDict = sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS |
| | | const EditableContext = React.createContext() |
| | | const { confirm } = Modal |
| | | let dragingIndex = -1 |
| | | const { Paragraph } = Typography |
| | | |
| | | class BodyRow extends React.Component { |
| | | render() { |
| | |
| | | state = { |
| | | data: [], |
| | | editingKey: '', |
| | | visible: false, |
| | | columns: [] |
| | | } |
| | | |
| | | UNSAFE_componentWillMount () { |
| | | const { data, actions } = this.props |
| | | let columns = fromJS(this.props.columns).toJS() |
| | | let operation = null |
| | | |
| | | if (!actions || actions.length > 0) { |
| | | columns.push({ |
| | | title: eTDict['model.operation'], |
| | | if (actions && (actions.includes('edit') || actions.includes('copy') || actions.includes('del'))) { |
| | | let _operation = null |
| | | columns = columns.filter(item => { |
| | | if (item.dataIndex === 'operation') { |
| | | _operation = item |
| | | } |
| | | return item.dataIndex !== 'operation' |
| | | }) |
| | | |
| | | operation = { |
| | | title: (<div> |
| | | {eTDict['model.operation']} |
| | | <span className="copy-control"> |
| | | {actions.includes('copy') ? <Icon type="copy" title="复制" onClick={() => this.copy()} /> : null} |
| | | {actions.includes('copy') ? <Icon type="snippets" title="粘贴" onClick={this.paste} /> : null} |
| | | {actions.includes('clear') ? <Icon type="delete" title="清空" onClick={this.clear} /> : null} |
| | | </span> |
| | | </div>), |
| | | dataIndex: 'operation', |
| | | width: '140px', |
| | | render: (text, record) => { |
| | |
| | | </div> |
| | | ) : ( |
| | | <div className={'edit-operation-btn' + (editingKey !== '' ? ' disabled' : '')} style={{minWidth: '110px'}}> |
| | | {!actions || actions.includes('edit') ? <span className="primary" onClick={() => {editingKey === '' && this.edit(record.uuid)}}><Icon type="edit" /></span> : null} |
| | | {(!actions || actions.includes('del')) && editingKey === '' ? <Popconfirm |
| | | {actions.includes('edit') ? <span className="primary" onClick={() => {editingKey === '' && this.edit(record.uuid)}}><Icon type="edit" /></span> : null} |
| | | {actions.includes('copy') ? <span className="copy" onClick={() => {editingKey === '' && this.copy(record)}}><Icon type="copy" /></span> : null} |
| | | {actions.includes('del') && editingKey === '' ? <Popconfirm |
| | | overlayClassName="popover-confirm" |
| | | title={eTDict['model.query.delete']} |
| | | onConfirm={() => this.handleDelete(record.uuid) |
| | | }> |
| | | <span className="danger"><Icon type="delete" /></span> |
| | | </Popconfirm> : null} |
| | | {(!actions || actions.includes('del')) && editingKey !== '' ? <span className="danger"><Icon type="delete" /></span> : null} |
| | | {actions.includes('del') && editingKey !== '' ? <span className="danger"><Icon type="delete" /></span> : null} |
| | | </div> |
| | | ) |
| | | } |
| | | }) |
| | | } |
| | | |
| | | if (_operation) { |
| | | operation.render = _operation.render |
| | | operation.width = _operation.width |
| | | } |
| | | columns.push(operation) |
| | | } |
| | | |
| | | this.setState({ |
| | | data: data || [], |
| | | oricolumns: fromJS(this.props.columns).toJS(), |
| | | operation, |
| | | columns |
| | | }) |
| | | } |
| | |
| | | UNSAFE_componentWillReceiveProps (nextProps) { |
| | | if (!is(fromJS(this.state.data), fromJS(nextProps.data))) { |
| | | this.setState({data: nextProps.data, editingKey: ''}) |
| | | } else if (!is(fromJS(this.state.oricolumns), fromJS(nextProps.columns))) { |
| | | let cols = {} |
| | | nextProps.columns.forEach(col => {cols[col.dataIndex] = col}) |
| | | |
| | | this.setState({ |
| | | oricolumns: fromJS(nextProps.columns).toJS(), |
| | | columns: this.state.columns.map(col => { |
| | | if (cols[col.dataIndex]) { |
| | | return cols[col.dataIndex] |
| | | } |
| | | return col |
| | | } else if (!is(fromJS(this.props.columns), fromJS(nextProps.columns))) { |
| | | if (nextProps.columns.length === this.props.columns.length) { |
| | | let cols = {} |
| | | nextProps.columns.forEach(col => {cols[col.dataIndex] = col}) |
| | | |
| | | this.setState({ |
| | | columns: this.state.columns.map(col => { |
| | | if (cols[col.dataIndex]) { |
| | | return cols[col.dataIndex] |
| | | } |
| | | return col |
| | | }) |
| | | }) |
| | | }) |
| | | } else { |
| | | let columns = fromJS(nextProps.columns).toJS() |
| | | if (this.state.operation) { |
| | | columns.push(this.state.operation) |
| | | } |
| | | this.setState({columns}) |
| | | } |
| | | } |
| | | } |
| | | |
| | |
| | | |
| | | cancel = () => { |
| | | this.setState({ editingKey: '' }) |
| | | } |
| | | |
| | | clear = () => { |
| | | const _this = this |
| | | |
| | | confirm({ |
| | | title: '确定清空列表吗?', |
| | | content: '', |
| | | onOk() { |
| | | _this.setState({ data: [], editingKey: '' }, () => { |
| | | _this.props.onChange([]) |
| | | }) |
| | | }, |
| | | onCancel() {} |
| | | }) |
| | | } |
| | | |
| | | copy = (item) => { |
| | | const { type } = this.props |
| | | const { data } = this.state |
| | | |
| | | if (!data || data.length === 0) { |
| | | message.warning('未获取到配置信息') |
| | | return |
| | | } |
| | | |
| | | let msg = { key: type } |
| | | |
| | | if (item) { |
| | | msg.type = 'line' |
| | | msg.data = item |
| | | } else { |
| | | msg.type = 'array' |
| | | msg.data = data |
| | | } |
| | | |
| | | try { |
| | | msg = window.btoa(window.encodeURIComponent(JSON.stringify(msg))) |
| | | } catch (e) { |
| | | console.warn('Stringify Failure') |
| | | msg = '' |
| | | } |
| | | |
| | | if (msg) { |
| | | let oInput = document.createElement('input') |
| | | oInput.value = msg |
| | | document.body.appendChild(oInput) |
| | | oInput.select() |
| | | document.execCommand('Copy') |
| | | document.body.removeChild(oInput) |
| | | message.success('复制成功。') |
| | | } |
| | | } |
| | | |
| | | paste = () => { |
| | | this.setState({visible: true}) |
| | | } |
| | | |
| | | pasteSubmit = () => { |
| | | const { type } = this.props |
| | | const { columns } = this.state |
| | | let data = fromJS(this.state.data).toJS() |
| | | |
| | | this.pasteFormRef.handleConfirm().then(res => { |
| | | if (res.key !== type) { |
| | | message.warning('配置信息格式错误!') |
| | | return |
| | | } |
| | | |
| | | if (res.type === 'line') { |
| | | let unique = true |
| | | res.data.uuid = Utils.getuuid() |
| | | columns.forEach(col => { |
| | | if (col.unique !== true || !unique) return |
| | | |
| | | let _index = data.findIndex(item => res.data[col.dataIndex] === item[col.dataIndex]) |
| | | |
| | | if (_index > -1) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: col.title + '不可重复!', |
| | | duration: 5 |
| | | }) |
| | | unique = false |
| | | } |
| | | }) |
| | | |
| | | if (!unique) return |
| | | |
| | | data.unshift(res.data) |
| | | this.setState({ data, editingKey: '', visible: false }, () => { |
| | | this.props.onChange(data) |
| | | }) |
| | | } else if (res.type === 'array') { |
| | | res.data.forEach(cell => { |
| | | let unique = true |
| | | cell.uuid = Utils.getuuid() |
| | | columns.forEach(col => { |
| | | if (col.unique !== true || !unique) return |
| | | let _index = data.findIndex(item => cell[col.dataIndex] === item[col.dataIndex]) |
| | | |
| | | if (_index > -1) { |
| | | unique = false |
| | | } |
| | | }) |
| | | |
| | | if (!unique) return |
| | | |
| | | data.push(cell) |
| | | }) |
| | | |
| | | this.setState({ data, editingKey: '', visible: false }, () => { |
| | | this.props.onChange(data) |
| | | }) |
| | | } |
| | | message.success('粘贴成功。') |
| | | }) |
| | | } |
| | | |
| | | onSave = (record) => { |
| | |
| | | cell: EditableCell |
| | | } |
| | | } |
| | | if (!actions || actions.length === 0 || actions.includes('down') || actions.includes('up')) { |
| | | |
| | | let moveprops = {} |
| | | if (actions.includes('move')) { |
| | | components.body.row = DragableBodyRow |
| | | moveprops.moveAble = !this.state.editingKey |
| | | moveprops.moveRow = this.moveRow |
| | | } |
| | | |
| | | const columns = this.state.columns.map(col => { |
| | | let columns = this.state.columns.map(col => { |
| | | if (col.copy) { |
| | | col.render = (text) => (<Paragraph copyable>{text}</Paragraph>) |
| | | } |
| | | if (!col.editable) return col |
| | | return { |
| | | ...col, |
| | |
| | | } |
| | | }) |
| | | |
| | | columns.unshift({ |
| | | title: '序号', |
| | | dataIndex: '$index', |
| | | className: 'mk-index', |
| | | width: '60px', |
| | | }) |
| | | |
| | | const data = this.state.data.map((item, index) => { |
| | | item.$index = index + 1 |
| | | |
| | | return item |
| | | }) |
| | | |
| | | return ( |
| | | <EditableContext.Provider value={this.props.form}> |
| | | <div className="modal-edit-table"> |
| | |
| | | bordered |
| | | rowKey="uuid" |
| | | components={components} |
| | | dataSource={this.state.data} |
| | | dataSource={data} |
| | | columns={columns} |
| | | rowClassName="editable-row" |
| | | pagination={false} |
| | | onRow={(record, index) => ({ |
| | | index, |
| | | moveAble: !this.state.editingKey, |
| | | moveRow: this.moveRow, |
| | | ...moveprops |
| | | })} |
| | | /> |
| | | </DndProvider> |
| | | {/* 信息粘贴 */} |
| | | <Modal |
| | | title={eTDict['header.form.paste']} |
| | | visible={this.state.visible} |
| | | width={600} |
| | | maskClosable={false} |
| | | onOk={this.pasteSubmit} |
| | | onCancel={() => {this.setState({visible: false})}} |
| | | destroyOnClose |
| | | > |
| | | <PasteForm dict={eTDict} wrappedComponentRef={(inst) => this.pasteFormRef = inst}/> |
| | | </Modal> |
| | | </div> |
| | | </EditableContext.Provider> |
| | | ) |