From a06655e10f4242c350a3450c6c21e77f33302e2e Mon Sep 17 00:00:00 2001
From: king <18310653075@163.com>
Date: 星期五, 27 十一月 2020 22:09:04 +0800
Subject: [PATCH] 2020-11-27

---
 src/templates/zshare/editTable/index.jsx |  129 +++++++++++++++++++++++++++++++-----------
 1 files changed, 94 insertions(+), 35 deletions(-)

diff --git a/src/templates/zshare/editTable/index.jsx b/src/templates/zshare/editTable/index.jsx
index bfeffd6..24d7725 100644
--- a/src/templates/zshare/editTable/index.jsx
+++ b/src/templates/zshare/editTable/index.jsx
@@ -1,6 +1,7 @@
 import React, { Component } from 'react'
 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 ColorSketch from '@/mob/colorsketch'
@@ -11,6 +12,61 @@
 
 let eTDict = localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS
 const EditableContext = React.createContext()
+let dragingIndex = -1
+
+class BodyRow extends React.Component {
+  render() {
+    const { isOver, connectDragSource, connectDropTarget, moveRow, ...restProps } = this.props
+    const style = { ...restProps.style, cursor: 'move' }
+
+    let { className } = restProps
+    if (isOver) {
+      if (restProps.index > dragingIndex) {
+        className += ' drop-over-downward'
+      }
+      if (restProps.index < dragingIndex) {
+        className += ' drop-over-upward'
+      }
+    }
+
+    return connectDragSource(
+      connectDropTarget(<tr {...restProps} className={className} style={style} />),
+    )
+  }
+}
+
+const rowSource = {
+  beginDrag(props) {
+    dragingIndex = props.index
+    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 DragableBodyRow = DropTarget('row', rowTarget, (connect, monitor) => ({
+  connectDropTarget: connect.dropTarget(),
+  isOver: monitor.isOver(),
+}))(
+  DragSource('row', rowSource, connect => ({
+    connectDragSource: connect.dragSource(),
+  }))(BodyRow),
+)
 
 class EditableCell extends Component {
   getInput = (form) => {
@@ -130,8 +186,6 @@
         ) : (
           <div className={'edit-operation-btn' + (editingKey !== '' ? ' disabled' : '')}>
             {!actions || actions.includes('edit') ? <span className="primary" onClick={() => {editingKey === '' && this.edit(record.uuid)}}><Icon type="edit" /></span> : null}
-            {!actions || actions.includes('up') ? <span className="primary" onClick={() => {editingKey === '' && this.handleUpDown(record.uuid, 'up')}}><Icon type="arrow-up" /></span> : null}
-            {!actions || actions.includes('down') ? <span className="danger" onClick={() => {editingKey === '' && this.handleUpDown(record.uuid, 'down')}}><Icon type="arrow-down" /></span> : null}
             {(!actions || actions.includes('del')) && editingKey === '' ? <Popconfirm
               overlayClassName="popover-confirm"
               title={eTDict['model.query.delete']}
@@ -226,27 +280,6 @@
     })
   }
 
-  handleUpDown = (uuid, direction) => {
-    let _data = fromJS(this.state.data).toJS()
-    const index = _data.findIndex(item => uuid === item.uuid)
-
-    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, uuid) {
     const { columns } = this.state
     form.validateFields((error, row) => {
@@ -296,11 +329,31 @@
     this.setState({ editingKey: uuid })
   }
 
+  moveRow = (dragIndex, hoverIndex) => {
+    const { editingKey } = this.state
+    let _data = fromJS(this.state.data).toJS()
+
+    if (editingKey) return
+
+    _data.splice(hoverIndex, 0, ..._data.splice(dragIndex, 1))
+
+    this.setState({
+      data: _data
+    }, () => {
+      this.props.onChange(_data)
+    })
+  }
+
   render() {
-    const components = {
+    const { actions } = this.props
+
+    let components = {
       body: {
-        cell: EditableCell,
+        cell: EditableCell
       }
+    }
+    if (!actions || actions.includes('down') || actions.includes('up')) {
+      components.body.row = DragableBodyRow
     }
     
     const columns = this.state.columns.map(col => {
@@ -325,16 +378,22 @@
 
     return (
       <EditableContext.Provider value={this.props.form}>
-        <div className="modal-edit-table">
-          <Table
-            bordered
-            rowKey="uuid"
-            components={components}
-            dataSource={this.state.data}
-            columns={columns}
-            rowClassName="editable-row"
-            pagination={false}
-          />
+        <div className={'modal-edit-table ' + (this.state.editingKey ? 'editing' : '')}>
+          <DndProvider>
+            <Table
+              bordered
+              rowKey="uuid"
+              components={components}
+              dataSource={this.state.data}
+              columns={columns}
+              rowClassName="editable-row"
+              pagination={false}
+              onRow={(record, index) => ({
+                index,
+                moveRow: this.moveRow,
+              })}
+            />
+          </DndProvider>
         </div>
       </EditableContext.Provider>
     )

--
Gitblit v1.8.0