UNPKG

thin-component

Version:
329 lines (306 loc) 9.18 kB
/* eslint-disable react/no-unused-prop-types */ /* eslint-disable react/forbid-prop-types */ import React from 'react'; import PropTypes from 'prop-types'; import { Checkbox } from 'antd'; import { Resizable } from 'react-resizable'; import Sorter from './sorter'; class Columns extends React.Component { constructor() { super(); this.state = { sorterActiveField: '', sorterDirection: 'default', }; } handleCheckboxChange = e => { const { rowSelection, dataSource, rowKey } = this.props; const { checked } = e.target; const { onChange = () => {}, onSelectAll = () => {}, selectedRowKeys = [], getCheckboxProps = this.defaultCheckboxProps, } = rowSelection || {}; const dataSourceCopy = dataSource.filter(item => { if (selectedRowKeys.indexOf(item[rowKey]) !== -1) { return checked; } const { disabled } = getCheckboxProps(item); return !disabled; }); let selectedRowKeysCopy = []; let selectedRows = []; if (checked) { selectedRowKeysCopy = dataSourceCopy.map(item => { return item[rowKey]; }); selectedRows = [...dataSourceCopy]; onChange(selectedRowKeysCopy, selectedRows); const changeRows = this.getChangeRows(dataSourceCopy, checked, selectedRowKeys); onSelectAll(checked, selectedRows, changeRows); } else { selectedRowKeysCopy = []; selectedRows = dataSource.filter(item => { const { disabled } = getCheckboxProps(item); if (selectedRowKeys.indexOf(item[rowKey]) !== -1 && disabled) { selectedRowKeysCopy.push(item[rowKey]); return true; } return false; }); const changeRows = dataSource.filter(item => { const { disabled } = getCheckboxProps(item); if (!disabled) { return true; } return false; }); onChange(selectedRowKeysCopy, selectedRows); onSelectAll(checked, selectedRows, changeRows); } }; getChangeRows = (dataSource, checked, selectedRowKeys) => { const { rowKey } = this.props; const allKeys = dataSource.map(item => { return item[rowKey]; }); const changeRows = []; const len = allKeys.length; if (checked) { for (let i = 0; i < len; i += 1) { const key = allKeys[i]; if (selectedRowKeys.indexOf(key) === -1) { changeRows.push(key); } } return dataSource.filter(item => { return changeRows.indexOf(item[rowKey]) > -1; }); } return [...dataSource]; }; getIndeterminate = checked => { // const { rowSelection } = this.props; // const { selectedRowKeys = [] } = rowSelection || {}; const len = this.getNotDisabledKeyLength(); if (!checked && len > 0) { return true; } return false; }; defaultCheckboxProps = () => { return { disabled: false, }; }; getCheckboxValue = () => { const { rowSelection, dataSource, rowKey } = this.props; const { selectedRowKeys = [], getCheckboxProps = this.defaultCheckboxProps } = rowSelection || {}; const len2 = dataSource.length; if (len2 === 0) { return false; } let flag = true; for (let i = 0; i < len2; i += 1) { const checkboxProps = getCheckboxProps(dataSource[i]); if (!checkboxProps.disabled) { const key = dataSource[i][rowKey]; if (selectedRowKeys.indexOf(key) === -1) { flag = false; break; } } } return flag; }; handleSort = (sorter, field, item) => { const { sorterDirection: sorterDirection0 } = this.state; let sorterDirection; const val = this.getSortValue(item); if (val) { sorterDirection = val; } else { sorterDirection = sorterDirection0; } const { onSort } = this.props; let direction = 'default'; if (sorterDirection === 'up') { direction = 'down'; } else if (sorterDirection === 'down') { direction = 'default'; } else { direction = 'up'; } if (sorter) { this.setState({ sorterActiveField: field, sorterDirection: direction, }); onSort(sorter, direction, item); } }; renderHandleHtml = () => { const { isResizeColumn } = this.props; if (!isResizeColumn) { return null; } return ( <div className="drag-item"> <div /> </div> ); }; getSortValue = item => { const value = null; if (typeof item.sortOrder === 'boolean' && item.sortOrder === false) { return 'default'; } if (typeof item.sortOrder === 'string') { if (item.sortOrder === 'ascend') { return 'up'; } return 'down'; } return value; }; getNotDisabledKeyLength = () => { const { dataSource, rowKey, rowSelection } = this.props; const { selectedRowKeys = [], getCheckboxProps = this.defaultCheckboxProps } = rowSelection || {}; let len = selectedRowKeys.length; for (let i = 0; i < dataSource.length; i += 1) { const item = getCheckboxProps(dataSource[i]); if (item.disabled && selectedRowKeys.indexOf(dataSource[i][rowKey]) > -1) { len -= 1; } } return len; }; isDisableAll = (rowSelection, dataSource) => { if (dataSource.length === 0) { return true; } if (rowSelection && rowSelection.getCheckboxProps) { let flag = true; const fn = rowSelection.getCheckboxProps; for (let i = 0; i < dataSource.length; i += 1) { const item = fn(dataSource[i]); if (!item.disabled) { flag = false; break; } } return flag; } return false; }; render() { const { columns, rowSelection, dataSource, checkboxWidth, headerCellClassName, onResize, } = this.props; const { sorterActiveField, sorterDirection } = this.state; const arr = []; const checked = this.getCheckboxValue(); if (rowSelection) { arr.push( <span key="lazy-table-columns-key-span" className="checkbox" style={{ width: checkboxWidth, }} > <Checkbox onChange={this.handleCheckboxChange} indeterminate={this.getIndeterminate(checked)} checked={checked} disabled={this.isDisableAll(rowSelection, dataSource)} /> </span> ); } const len = columns.length; return arr.concat( columns.map((item, index) => { const spanStyle = { width: item.width, }; if (index + 1 === len) { spanStyle.borderRight = 0; } const { sorter } = item; let spanWidth = item.width - 8; if (sorter) { spanWidth = item.width - 8 - 2 - 12; } let value; const val = this.getSortValue(item); if (val) { value = val; } else { value = sorterActiveField === item.dataIndex ? sorterDirection : 'default'; } const title = item.renderTitle ? item.renderTitle(item.title, item) : item.title; return ( <Resizable key={item.key} width={item.width} height={0} onResize={(e, resizeData) => { onResize(e, index, resizeData); }} axis="both" handle={this.renderHandleHtml()} > <span style={spanStyle}> <div onClick={this.handleSort.bind(this, sorter, item.dataIndex, item)} className={ sorter ? `column-item column-has-sorter ${headerCellClassName}` : `column-item ${headerCellClassName}` } > <span style={{ maxWidth: spanWidth - 2, display: 'inline-block' }} className="column-item-text" > {title} </span> {sorter ? <Sorter value={value} /> : null} </div> </span> </Resizable> ); }), <span style={{ width: 50 }} key="item.key.Columns.lazy" /> ); } } Columns.defaultProps = { columns: [], rowSelection: null, onSort: () => {}, headerCellClassName: '', onResize: () => {}, isResizeColumn: true, }; Columns.propTypes = { columns: PropTypes.array, rowSelection: PropTypes.object, dataSource: PropTypes.array.isRequired, checkboxWidth: PropTypes.number.isRequired, onSort: PropTypes.func, headerCellClassName: PropTypes.string, onResize: PropTypes.func, isResizeColumn: PropTypes.bool, rowKey: PropTypes.string.isRequired, }; export default Columns;