UNPKG

qm-ui

Version:

千米公有云管理端UI基础组件库

227 lines (210 loc) 5.42 kB
/** * @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 @DragDropContext(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 }, } @DropTarget('table_manager', colTarget, connect => ({ connectDropTarget: connect.dropTarget(), })) @DragSource('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> ) ) } }