From ab262bbe2c64ba086a14f181e5a27eba4b46b555 Mon Sep 17 00:00:00 2001 From: king <18310653075@163.com> Date: 星期五, 13 十月 2023 17:59:53 +0800 Subject: [PATCH] 2023-10-13 --- src/templates/zshare/modalform/modaleditable/index.jsx | 519 ++++++++++++++++++++++++++++++--------------------------- 1 files changed, 276 insertions(+), 243 deletions(-) diff --git a/src/templates/zshare/modalform/modaleditable/index.jsx b/src/templates/zshare/modalform/modaleditable/index.jsx index b8ca161..0427a95 100644 --- a/src/templates/zshare/modalform/modaleditable/index.jsx +++ b/src/templates/zshare/modalform/modaleditable/index.jsx @@ -1,106 +1,138 @@ import React, {Component} from 'react' import PropTypes from 'prop-types' import { is, fromJS } from 'immutable' -import { Table, Input, Popconfirm, Form, message } from 'antd' -import { ArrowUpOutlined, ArrowDownOutlined, DeleteOutlined, PlusOutlined, SwapOutlined } from '@ant-design/icons' +import { DndProvider, DragSource, DropTarget } from 'react-dnd' +import { Table, Input, Popconfirm, message } from 'antd' +import { DeleteOutlined, PlusOutlined, SwapOutlined, DragOutlined } from '@ant-design/icons' import Utils from '@/utils/utils.js' +import asyncComponent from '@/utils/asyncComponent' import './index.scss' -const EditableContext = React.createContext() +const SourceComponent = asyncComponent(() => import('@/menu/components/share/sourcecomponent')) -const EditableRow = ({ form, index, ...props }) => ( - <EditableContext.Provider value={form}> - <tr {...props} /> - </EditableContext.Provider> +class MoveTd extends React.Component { + render() { + const { connectDragSource, connectDropTarget } = this.props + + return connectDragSource( + connectDropTarget(<td className="mk-move-col"><DragOutlined /></td>), + ) + } +} + +const rowSource = { + beginDrag(props) { + return { + index: props.index, + } + } +} + +const rowTarget = { + drop(props, monitor) { + const dragIndex = monitor.getItem().index + const hoverIndex = props.index + + if (dragIndex === hoverIndex) { + return + } + + props.moveRow(dragIndex, hoverIndex) + + monitor.getItem().index = hoverIndex + }, +} + +const DragableTd = DropTarget('td', rowTarget, connect => ({ + connectDropTarget: connect.dropTarget(), +}))( + DragSource('td', rowSource, (connect, monitor) => ({ + connectDragSource: connect.dragSource(), + // isDragging: monitor.isDragging() + }))(MoveTd), ) - -const EditableFormRow = Form.create()(EditableRow) class EditableCell extends Component { state = { - editing: false + editing: false, + value: '' } - toggleEdit = () => { - const editing = !this.state.editing - this.setState({ editing }, () => { - if (editing && this.input && this.input.select) { + trigger = () => { + const { dataIndex, record } = this.props + + this.setState({ editing: true, value: record[dataIndex] }, () => { + if (this.input && this.input.select) { this.input.select() - } else if (editing && this.input && this.input.focus) { + } else if (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() - }) + save = () => { + const { record, handleSave, dataIndex } = this.props + const { value } = this.state + + handleSave({ ...record, [dataIndex]: value }) + + this.setState({ editing: false, value: '' }) } - renderCell = form => { - this.form = form - const { children, dataIndex, record } = this.props + changeUrl = (val) => { + const { record, handleSave, dataIndex } = this.props + + handleSave({ ...record, [dataIndex]: val }) + } + + renderCell = () => { + const { dataIndex, inputType, record } = this.props const { editing } = this.state - return editing ? ( - <Form.Item style={{ margin: '0 -5px 0 -5px' }}> - {form.getFieldDecorator(dataIndex, { - rules: [ - { - required: dataIndex === 'Text', - message: '涓嶅彲涓虹┖.', - } - ], - 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> - ) + if (inputType === 'file') { + return <SourceComponent initialValue={record[dataIndex]} type="" onChange={this.changeUrl} placement="right"/> + } + + if (!editing) { + return ( + <div + className="editable-cell-value-wrap" + onClick={this.trigger} + > + {record[dataIndex]} + </div> + ) + } else { + return <Input ref={node => (this.input = node)} defaultValue={record[dataIndex]} autoComplete="off" onChange={(e) => this.setState({value: e.target.value})} onPressEnter={this.save} onBlur={this.save} /> + } } render() { - const { - editable, - dataIndex, - title, - record, - index, - handleSave, - children, - ...restProps - } = this.props + const { editable, dataIndex, index } = this.props + + if (dataIndex === '$move') { + return (<DragableTd key={index} {...this.props} />) + } + + if (editable) { + return ( + <td>{this.renderCell()}</td> + ) + } + return ( - <td {...restProps}> - {editable ? ( - <EditableContext.Consumer style={{padding: 0}}>{this.renderCell}</EditableContext.Consumer> - ) : ( - children - )} - </td> + <td {...this.props}/> ) } } class EditTable extends Component { static propTpyes = { - type: PropTypes.string, // 琛ㄥ崟绫诲瀷 - module: PropTypes.string, // 鍏冪礌绫诲瀷 - linkSubFields: PropTypes.array, // 鍏宠仈瀛楁 - transfield: PropTypes.object, // 琛ㄥ崟瀛楁鍚嶇О - onChange: PropTypes.func // 鏁版嵁鍙樺寲 + type: PropTypes.any, + module: PropTypes.string, + columns: PropTypes.array, + onChange: PropTypes.func } state = { @@ -110,38 +142,40 @@ } UNSAFE_componentWillMount () { - const { linkSubFields, type } = this.props - let data = this.props['data-__meta'].initialValue || [] - - const { columns } = this.getColumns(type, linkSubFields, data) + const { columns, value } = this.props + let data = value || [] this.setState({ - columns: columns, - dataSource: data, + columns: this.getColumns(), + dataSource: data.map(item => { + columns.forEach(n => { + if (item[n.key] !== undefined) return + item[n.key] = ['ParentID', '$url', '$color', '$value'].includes(n.key) ? '' : item.Text || '' + }) + return item + }), count: data.length }) } - handleUpDown = (record, direction) => { + moveRow = (dragId, hoverId) => { const { dataSource } = this.state - let index = 0 - - let _data = dataSource.filter((item, i) => { - if (item.key === record.key) { - index = i + let dragIndex = -1 + let hoverIndex = -1 + + dataSource.forEach((item, i) => { + if (item.key === dragId) { + dragIndex = i + } else if (item.key === hoverId) { + hoverIndex = i } - - return item.key !== record.key }) - if ((index === 0 && direction === 'up') || (index === dataSource.length - 1 && direction === 'down')) { - return - } + + if (dragIndex === -1 || hoverIndex === -1) return - if (direction === 'up') { - _data.splice(index - 1, 0, record) - } else { - _data.splice(index + 1, 0, record) - } + let _data = fromJS(dataSource).toJS() + + _data.splice(hoverIndex, 0, ..._data.splice(dragIndex, 1)) this.setState({ dataSource: _data @@ -150,13 +184,14 @@ }) } - handleHide = (record) => { + handleHide = (key) => { let _data = this.state.dataSource.map(item => { - if (item.key === record.key) { + if (item.key === key) { item.Hide = !item.Hide } return item }) + this.setState({ dataSource: _data }, () => { @@ -164,7 +199,7 @@ }) } - handleDelete = key => { + handleDelete = (key) => { const { dataSource } = this.state let _data = dataSource.filter(item => item.key !== key) @@ -173,22 +208,26 @@ }) } - handleAdd = (e) => { - e.stopPropagation() - const { linkSubFields } = this.props + handleAdd = () => { + const { columns } = this.props const { count, dataSource } = this.state - const newData = { - key: Utils.getuuid(), - Value: `${count}`, - Text: `${count}`, - ParentID: '' - } - linkSubFields.forEach(m => { - newData[m] = newData[m] || '' + let item = { key: Utils.getuuid() } + + columns.forEach(m => { + item[m.key] = '' }) - let _data = [...dataSource, newData] + if (item.Value === '') { + item.Value = `${count + 1}` + } + if (item.$value === '') { + item.$value = `${count + 1}` + } + + item.Text = `${count + 1}` + + let _data = [...dataSource, item] this.setState({ dataSource: _data, @@ -199,18 +238,49 @@ } handleSave = row => { - const { type } = this.props + const { columns, type } = this.props const newData = [...this.state.dataSource] const index = newData.findIndex(item => row.key === item.key) const item = newData[index] - if (type === 'link') { - if (newData.filter(m => row.key !== m.key && row.Value === m.Value && row.ParentID === m.ParentID).length > 0) { - message.warning('鐩稿悓ParentID涓嬶紝姝alue鍊煎凡瀛樺湪锛�') - } + if (type === 'proc') { + // if (!row.origin || /^\s+$/.test(row.origin)) { + // message.warning(columns[0].title + '涓虹┖鏃舵棤鏁堬紒') + // } } else { - if (newData.filter(m => row.key !== m.key && row.Value === m.Value).length > 0) { - message.warning('姝alue鍊煎凡瀛樺湪锛�') + let val = '' + let repeat = false + let _type = '' + columns.forEach(col => { + if (!col.strict) return + + if (col.key === 'ParentID') { + _type = 'mutil' + } + + val += row[col.key] + }) + + newData.forEach(item => { + if (row.key === item.key) return + + let _val = '' + columns.forEach(col => { + if (!col.strict) return + + _val += item[col.key] + }) + + if (val === _val) { + repeat = true + } + }) + if (repeat) { + if (_type === 'mutil') { + message.warning('鐩稿悓ParentID涓嬶紝姝alue鍊煎凡瀛樺湪锛�') + } else { + message.warning('姝alue鍊煎凡瀛樺湪锛�') + } } } @@ -223,112 +293,83 @@ }) } - getColumns = (type, linkSubFields, dataSource) => { - const { transfield } = this.props + getColumns = () => { + const { columns } = this.props - let _dataSource = fromJS(dataSource).toJS() - let fields = [] - let subFields = linkSubFields.filter(m => m !== 'Value' && m !== 'Text') - - if (subFields.length > 0) { - _dataSource = _dataSource.map(data => { - subFields.forEach(n => { - if (data[n] !== undefined) return - data[n] = data.Text || '' - }) - return data + let fields = [{ + title: ' ', + width: '60px', + dataIndex: '$move', + onCell: (record) => ({ + index: record.key, + dataIndex: '$move', + moveRow: this.moveRow }) - - fields = subFields.map(field => { - return { - title: transfield[field] || field, - $title: transfield[field] || field, - dataIndex: field, + }] + columns.forEach(n => { + let col = { + title: n.title, + dataIndex: n.key, + onCell: record => ({ + record, editable: true, - } - }) - } - - let columns = [ - { - title: 'Value', - $title: 'Value', - dataIndex: 'Value', - editable: true - }, - { - title: 'Text', - $title: 'Text', - dataIndex: 'Text', - editable: true - }, - ...fields, - { - title: '鎿嶄綔', - align: 'center', - width: '20%', - dataIndex: 'operation', - render: (text, record) => - this.state.dataSource.length >= 1 ? ( - <div style={{fontSize: '15px'}}> - <span className="operation-btn" onClick={() => this.handleUpDown(record, 'up')} style={{color: '#1890ff'}}><ArrowUpOutlined /></span> - <span className="operation-btn" onClick={() => this.handleUpDown(record, 'down')} style={{color: '#ff4d4f'}}><ArrowDownOutlined /></span> - <span className="operation-btn" title="鏄剧ず/闅愯棌" onClick={() => this.handleHide(record)} style={{color: 'rgb(142, 68, 173)'}}><SwapOutlined /></span> - <Popconfirm - title="纭畾鍒犻櫎鍚楋紵" - overlayClassName="popover-confirm" - onConfirm={() => this.handleDelete(record.key) - }> - <span style={{color: '#ff4d4f', cursor: 'pointer'}}><DeleteOutlined /></span> - </Popconfirm> - </div> - ) : null, + inputType: n.type || 'text', + dataIndex: n.key, + handleSave: this.handleSave + }) } - ] - if (type === 'link') { - columns.unshift({ - title: 'ParentID', - $title: 'ParentID', - dataIndex: 'ParentID', - editable: true - }) - } + if (n.width) { + col.width = n.width + } + if (n.fixed) { + delete col.onCell + } - return { - columns: columns.map(col => { - if (col.dataIndex !== 'operation') { - col.title = <div> - {col.$title} + fields.push(col) + }) + + fields.push({ + title: '鎿嶄綔', + align: 'center', + width: '110px', + dataIndex: 'operation', + render: (text, record) => + ( + <div style={{fontSize: '15px'}}> + <span className="operation-btn" title="鏄剧ず/闅愯棌" onClick={() => this.handleHide(record.key)} style={{color: 'rgb(142, 68, 173)'}}><SwapOutlined /></span> + <Popconfirm + title="纭畾鍒犻櫎鍚楋紵" + overlayClassName="popover-confirm" + onConfirm={() => this.handleDelete(record.key) + }> + <span style={{color: '#ff4d4f', cursor: 'pointer'}}><DeleteOutlined /></span> + </Popconfirm> </div> - } - return col - }), - dataSource: _dataSource - } + ) + }) + + return fields } - handleEmpty = (e) => { - e.stopPropagation() - const { linkSubFields, module } = this.props + handleEmpty = () => { + const { columns, module } = this.props const { dataSource } = this.state if (dataSource.filter(item => item.Value === '').length > 0) { message.warning('Value涓虹┖宸插瓨鍦紒') return } - const newData = { - key: Utils.getuuid(), - Value: '', - Text: module === 'form' ? '绌�' : '鍏ㄩ儴', - ParentID: '' - } - linkSubFields.forEach(m => { - newData[m] = newData[m] || '' + let item = { key: Utils.getuuid() } + + columns.forEach(m => { + item[m.key] = '' }) - let _data = [newData, ...dataSource] + item.Text = module === 'form' ? '绌�' : '鍏ㄩ儴' + + let _data = [item, ...dataSource] this.setState({ dataSource: _data, @@ -337,65 +378,57 @@ }) } - resetColumn = (type, linkSubFields) => { - const { columns, dataSource } = this.getColumns(type, linkSubFields, this.state.dataSource) + resetColumn = () => { + const { columns, value } = this.props + + let data = fromJS(value).toJS().map(item => { + columns.forEach(n => { + if (item[n.key] !== undefined) return + item[n.key] = ['ParentID', '$url', '$color', '$value'].includes(n.key) ? '' : item.Text || '' + }) + return item + }) - if (!is(fromJS(dataSource), fromJS(this.state.dataSource))) { - this.setState({ - columns, - dataSource - }, () => { - this.props.onChange(dataSource) - }) - } else { - this.setState({ - columns - }) - } + this.setState({ + columns: this.getColumns(), + dataSource: data, + count: data.length + }, () => { + this.props.onChange(data) + }) } UNSAFE_componentWillReceiveProps (nextProps) { - if (!is(fromJS(this.props.linkSubFields), fromJS(nextProps.linkSubFields)) || this.props.type !== nextProps.type) { - this.resetColumn(nextProps.type, nextProps.linkSubFields) + if (!is(fromJS(this.props.columns), fromJS(nextProps.columns))) { + this.setState({}, () => { + this.resetColumn() + }) } } render() { const { module } = this.props - const { dataSource } = this.state + const { dataSource, columns } = this.state const components = { body: { - row: EditableFormRow, cell: EditableCell } } - const columns = this.state.columns.map(col => { - if (!col.editable) { - return col - } - return { - ...col, - onCell: record => ({ - record, - editable: col.editable, - dataIndex: col.dataIndex, - title: col.title, - handleSave: this.handleSave - }) - } - }) + return ( <div className="common-modal-edit-table"> - <span className="add-row add-row-empty" onClick={this.handleEmpty}>{module === 'form' ? '绌�' : '鍏ㄩ儴'}</span> + {module ? <span className="add-row add-row-empty" onClick={this.handleEmpty}>{module === 'form' ? '绌�' : '鍏ㄩ儴'}</span> : null} <PlusOutlined className="add-row" onClick={this.handleAdd} /> - <Table - components={components} - rowClassName={(record) => record.Hide ? 'editable-row hide' : 'editable-row'} - bordered - dataSource={dataSource} - columns={columns} - pagination={false} - /> + <DndProvider> + <Table + components={components} + rowClassName={(record) => record.Hide ? 'editable-row hide' : 'editable-row'} + bordered + dataSource={dataSource} + columns={columns} + pagination={false} + /> + </DndProvider> </div> ) } -- Gitblit v1.8.0