import React, { memo } from 'react'; import { calcOffsets, mapFixedClass, getPageInfo } from '../helpers'; import { HeaderRow, SortIcon, TD, Dropdown, InlineFlex } from '../style'; import Checkbox from '../../checkbox'; import { IColumn, ITable } from '../types'; type IProps = { tableProps: ITable; columns: IColumn[]; state: any; dispatch: any; rowData: any[]; }; const getFilterState = (state: any, changedKey: string, changedValue: any) => { const filters: object[] = [{ key: changedKey, value: changedValue }]; Object.entries(state).forEach(([stateKey, value]) => { const colKey = stateKey.replace('Filter', ''); if (stateKey.endsWith('Filter') && value && colKey !== changedKey) { filters.push({ key: colKey, value }); } }); return filters; }; const renderTitle = (col: IColumn, state: any, dispatch: any, onChange: any) => { if (col.filter) { if (col.sorter) { throw new Error('过滤和排序只能定义其一'); } const key = col.key + 'Filter'; return ( { dispatch({ [key]: value }); const filter = getFilterState(state, key.replace('Filter', ''), value); if (!filter.length) { var changed = null; } else if (filter.length === 1) { changed = filter[0]; } else { changed = filter; } onChange && onChange({ filter: changed }); }} toggle={true} value={state[key]} indicator={true} multiple={col.filterMultiple} trigger="click" options={col.filter} content={col.title} /> ); } if (col.sorter) { return ( { let sortOrder; if (state.sortOrder === 'ascend') { sortOrder = 'descend'; } else if (state.sortOrder === 'descend') { sortOrder = undefined; } else { sortOrder = 'ascend'; } const payload = { sortKey: col.key, sortOrder }; dispatch(payload); onChange && onChange({ sorter: sortOrder && payload }); }} > {col.title} ); } if (typeof col.title === 'function') { return col.title(); } return col.title; }; const Header = function({ tableProps, columns, state, dispatch, rowData }: IProps) { const { showChecker, fixRow, rowId, onChange, pagination = {}, dataSource = [], maxChecked = 100 } = tableProps; const [leftOffset, rightOffset, leftFixedIndex, rightFixedIndex] = calcOffsets(columns, !!showChecker); const checkFixed = columns[0] && columns[0].fixed === 'left' ? 'fix-left-cell' : ''; const { page } = getPageInfo(state, pagination); const currentPage = state.rowChecked[page - 1] || []; const flat = state.rowChecked.reduce((acc: any, val: any) => acc.concat(val), []); const totalChecked = flat.filter(Boolean).length; const disableCheckAll = totalChecked >= maxChecked; return ( {[ !!showChecker && ( { const rowChecked = [...state.rowChecked]; if (checkAll) { if (totalChecked + rowData.length <= maxChecked) { rowChecked[page - 1] = rowData.map(() => true); } else { var count = maxChecked - totalChecked; if (count > 0) { rowChecked[page - 1] = rowData.map((checked, idx) => { if (rowChecked[page - 1][idx]) { return true; } else if (count > 0) { count -= 1; return true; } return false; }); } else if (!count) { rowChecked[page - 1] = rowData.map(() => false); } } const flat = rowChecked.reduce((acc, val) => acc.concat(val), []); dispatch({ rowChecked }); onChange && onChange({ checked: dataSource.filter((row, index) => flat[index]).map(r => r[rowId]), }); } else { rowChecked[page - 1] = rowData.map(() => false); dispatch({ rowChecked }); onChange && onChange({ checked: [] }); } }} /> ), ].concat( columns.map((col: IColumn, index) => { return ( index ? leftOffset[index] : rightOffset[index]} > {renderTitle(col, state, dispatch, onChange)} ); }) )} ); }; export default memo(Header);