qm-ui
Version:
千米公有云管理端UI基础组件库
227 lines (210 loc) • 5.42 kB
JavaScript
/**
* @author gcy[of1518]
* @date 16/10/11
*
* @description ColumnManage基于AntDesign的实现
*
*
* columns:props
* type: true || false || undefined || disabled
*
*/
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import { findDOMNode } from 'react-dom'
import update from 'react/lib/update'
import { DragDropContext, DragSource, DropTarget } from 'react-dnd'
import HTML5Backend from 'react-dnd-html5-backend'
import { Menu, Dropdown, Button, Checkbox, Icon, message } from 'antd'
const noop = () => undefined
(HTML5Backend)
export default class ColumnsManagerUI extends Component {
static defaultProps = {
//proteced
__hash: '',
columns: [], //列对象集合
onChange: noop,
//private
storageKey: '', //持久化key
storageType: '', //持久化方式 localStorage || sessionStorage || cookie
sortable: true, //是否支持排序
closeLimit: 1, //关闭列限制 number | boolean
}
constructor(props) {
super(props)
let { columns } = props || {}
columns = columns.map((v, k) => {
v.id = k
return v
})
this.state = {
columns,
visible: false,
}
}
componentWillReceiveProps(nextProps) {
let { columns } = nextProps || {}
columns = columns.map((v, k) => {
v.id = k
return v
})
this.setState({
columns,
})
}
render() {
let self = this
let { columns, visible } = this.state
const columnNode = (
<Menu className="colunms-dropdown">
{columns.map((column, i) => (
<ColumnItem
key={column.id}
index={i}
id={column.id}
column={column}
moveColumn={self.moveColumn}
endDrag={self.endDrag}
onColumnChecked={this.onColumnChecked}
/>
))}
</Menu>
)
return (
<div id="_col_m">
<Dropdown overlay={columnNode}>
<Button type="ghost" className="ant-dropdown-link">
更改列展示
<Icon type="down" />
</Button>
</Dropdown>
</div>
)
}
/**
* end drag
*/
endDrag = () => {
let { onChange } = this.props
let { columns } = this.state
columns = columns.map(v => {
delete v.id
return v
})
onChange(columns)
}
/**
* darging
*/
moveColumn = (dragIndex, hoverIndex) => {
const { columns } = this.state
const dragCol = columns[dragIndex]
this.setState(
update(this.state, {
columns: {
$splice: [
[dragIndex, 1],
[hoverIndex, 0, dragCol],
],
},
})
)
}
/**
* 列显示操作
*/
onColumnChecked = (index, checked) => {
let { onChange, closeLimit } = this.props
let { columns } = this.state
let i = closeLimit
columns.forEach(v => {
if (v && v.show == false) {
i++
}
})
if (!checked && i >= columns.length) {
message.warn(`顽皮!当前表格至少展示${closeLimit}列哦!`)
} else {
columns[index].show = checked ? undefined : false
onChange(columns)
}
}
}
const style = {
borderBottom: '1px dashed #f5f5f5',
padding: '8px 10px',
cursor: 'move',
}
const colSource = {
beginDrag(props) {
return {
id: props.id,
index: props.index,
}
},
endDrag(props, monitor) {
props.endDrag()
},
}
const colTarget = {
hover(props, monitor, component) {
const dragIndex = monitor.getItem().index
const hoverIndex = props.index
if (dragIndex === hoverIndex) {
return
}
const hoverBoundingRect = findDOMNode(component).getBoundingClientRect()
const hoverMiddleY = (hoverBoundingRect.bottom - hoverBoundingRect.top) / 2
const clientOffset = monitor.getClientOffset()
const hoverClientY = clientOffset.y - hoverBoundingRect.top
if (dragIndex < hoverIndex && hoverClientY < hoverMiddleY) {
return
}
if (dragIndex > hoverIndex && hoverClientY > hoverMiddleY) {
return
}
props.moveColumn(dragIndex, hoverIndex)
monitor.getItem().index = hoverIndex
},
}
('table_manager', colTarget, connect => ({
connectDropTarget: connect.dropTarget(),
}))
('table_manager', colSource, (connect, monitor) => ({
connectDragSource: connect.dragSource(),
isDragging: monitor.isDragging(),
}))
class ColumnItem extends Component {
static propTypes = {
connectDragSource: PropTypes.func.isRequired,
connectDropTarget: PropTypes.func.isRequired,
index: PropTypes.number.isRequired,
isDragging: PropTypes.bool.isRequired,
id: PropTypes.any.isRequired,
column: PropTypes.object.isRequired,
moveColumn: PropTypes.func.isRequired,
onColumnChecked: PropTypes.func.isRequired,
}
render() {
const {
index,
column,
isDragging,
connectDragSource,
connectDropTarget,
onColumnChecked,
} = this.props
const opacity = isDragging ? 0 : 1
return connectDragSource(
connectDropTarget(
<div style={{ ...style, opacity }}>
<Checkbox
checked={column.show == true || column.show == undefined ? true : false}
onChange={e => onColumnChecked(index, e.target.checked)}>
{column.title || '-'}
</Checkbox>
</div>
)
)
}
}