UNPKG

@o2xp/react-datatable

Version:

@o2xp/react-datatable is a modulable component to render data in a table with some nice features !

257 lines (241 loc) 6.65 kB
import React, { Component } from "react"; import { sortableElement } from "react-sortable-hoc"; import { Tooltip, Zoom, Grid } from "@material-ui/core"; import { ArrowUpward as ArrowIcon } from "@material-ui/icons"; import { connect } from "react-redux"; import { NumberWrapper, TextWrapper, BooleanWrapper, DateWrapper, TimeWrapper, DateTimeWrapper } from "../CellTypes"; import { columnPropType, widthPropType, indexPropType, orderByColumnsPropType, orderByPropType, canOrderColumnsPropType, textPropType, stylePropType, isLastLockedPropType, isScrollingPropType, areFilterFieldsDisplayedPropType } from "../../../proptypes"; import { orderByColumns as orderByColumnsAction } from "../../../redux/actions/datatableActions"; import HeaderColumnsFilterBar from "./HeaderColumnsFilterBar"; export class HeaderCell extends Component { constructor(props) { super(props); this.state = { childButtonHovered: false }; } setHover = bool => { this.setState({ childButtonHovered: bool }); }; buildButton = (column, width) => { const { orderByColumns, orderBy, orderByText } = this.props; const index = orderBy.findIndex(el => el.id === column.id); let orderElement; if (index !== -1) { orderElement = orderBy[index]; } return ( <Tooltip arrow TransitionComponent={Zoom} title={orderByText}> <Grid className="cell-header" container style={{ width }} justifyContent="center" alignItems="center" > <Grid item xs={orderElement ? 8 : 12}> <button type="button" className="button-header" onMouseOver={() => this.setHover(true)} onMouseLeave={() => this.setHover(false)} onFocus={() => null} onClick={e => { e.stopPropagation(); orderByColumns(column.id); }} > {column.label} </button> </Grid> {orderElement && ( <Grid container item xs={4} justifyContent="center" alignItems="center" > <Grid item xs={6}> <ArrowIcon className={ orderElement.value === "asc" ? "ascIcon" : "descIcon" } /> </Grid> <Grid item xs={6}> {index + 1} </Grid> </Grid> )} </Grid> </Tooltip> ); }; buildHeaderCell = () => { const { width, column, canOrderColumns, areFilterFieldsDisplayed } = this.props; const content = canOrderColumns ? this.buildButton(column, width) : column.label; let wrapperType; switch (column.dataType) { case "number": wrapperType = ( <NumberWrapper style={{ width }}>{content}</NumberWrapper> ); break; case "text": wrapperType = <TextWrapper style={{ width }}>{content}</TextWrapper>; break; case "boolean": wrapperType = ( <BooleanWrapper style={{ width }}>{content}</BooleanWrapper> ); break; case "date": wrapperType = <DateWrapper style={{ width }}>{content}</DateWrapper>; break; case "time": wrapperType = <TimeWrapper style={{ width }}>{content}</TimeWrapper>; break; case "dateTime": wrapperType = ( <DateTimeWrapper style={{ width }}>{content}</DateTimeWrapper> ); break; default: wrapperType = <TextWrapper style={{ width }}>{content}</TextWrapper>; break; } // TODO: déplacer les searchbars ici return ( <> {wrapperType} {areFilterFieldsDisplayed ? ( <HeaderColumnsFilterBar column={column} /> ) : null} </> ); }; render() { const { index, dragText, style, locked, isLastLocked, isScrolling } = this.props; const { childButtonHovered } = this.state; let className = ""; switch (true) { case isLastLocked && isScrolling: className = `scrolling-shadow`; break; case isLastLocked && !isScrolling: className = ` no-scrolling-shadow`; break; default: className = ``; break; } return ( <> {locked ? ( <div style={style} className={ childButtonHovered ? `Table-Header-Cell-Child-Hovered ${className}` : `Table-Header-Cell ${className}` } > {this.buildHeaderCell()} </div> ) : ( <SortableItem dragText={dragText} index={index} value={this.buildHeaderCell()} childButtonHovered={childButtonHovered} /> )} </> ); } } const SortableItem = sortableElement( ({ value, childButtonHovered, dragText, style }) => ( <Tooltip arrow TransitionComponent={Zoom} title={childButtonHovered ? "" : dragText} > <div className={ childButtonHovered ? "Table-Header-Cell-Child-Hovered" : "Table-Header-Cell" } style={style} > {value} </div> </Tooltip> ) ); HeaderCell.propTypes = { column: columnPropType.isRequired, width: widthPropType.isRequired, index: indexPropType.isRequired, orderBy: orderByPropType.isRequired, canOrderColumns: canOrderColumnsPropType.isRequired, style: stylePropType, isScrolling: isScrollingPropType.isRequired, isLastLocked: isLastLockedPropType, locked: isLastLockedPropType, orderByColumns: orderByColumnsPropType, orderByText: textPropType, dragText: textPropType, areFilterFieldsDisplayed: areFilterFieldsDisplayedPropType }; const mapDispatchToProps = dispatch => { return { orderByColumns: col => dispatch(orderByColumnsAction(col)) }; }; const mapStateToProps = state => { return { canOrderColumns: state.datatableReducer.features.canOrderColumns, areFilterFieldsDisplayed: state.datatableReducer.areFilterFieldsDisplayed, orderBy: state.datatableReducer.orderBy, orderByText: state.textReducer.orderBy, dragText: state.textReducer.drag, isScrolling: state.datatableReducer.dimensions.isScrolling }; }; export default connect(mapStateToProps, mapDispatchToProps)(HeaderCell);