UNPKG

@o2xp/react-datatable

Version:

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

253 lines (234 loc) 6.15 kB
import React, { Component, Fragment } from "react"; import { connect } from "react-redux"; import { uniq } from "lodash"; import { IconButton, Tooltip, Zoom, Button, Dialog, DialogActions, DialogContent, Grid, DialogTitle } from "@material-ui/core"; import { Add as AddIcon } from "@material-ui/icons"; import { NumberType, TextType, BooleanType, DateType, TimeType, DateTimeType } from "../../DatatableCore/CellTypes"; import { addNewRow as addNewRowAction } from "../../../redux/actions/datatableActions"; import { addNewRowPropType, columnsPropType, editingPropType, textPropType } from "../../../proptypes"; export class Add extends Component { constructor(props) { super(props); const { columns } = props; const requiredVal = []; columns.forEach(col => { if (col.required) { requiredVal.push(col.id); } }); this.state = { modalOpen: false, buttonDisabled: this.getDisabledButton({}, requiredVal, []), newRow: {}, errors: [], requiredVal }; } handleClose = () => { this.setState({ modalOpen: false, newRow: {}, errors: [], buttonDisabled: true }); }; getDisabledButton = (newRow, requiredVal, newErrors) => { let newButtonDisabled = newErrors.length > 0; requiredVal.forEach(rv => { if (!newRow[rv] || newRow[rv].length === 0) { newButtonDisabled = true; } }); return newButtonDisabled; }; send = () => { const { addNewRow } = this.props; const { newRow } = this.state; addNewRow(newRow); this.handleClose(); }; test = ({ columnId, newValue, error }) => { const { newRow, errors, requiredVal } = this.state; const newErrors = error ? uniq([columnId, ...errors]) : errors.filter(err => err !== columnId); const nr = { ...newRow, [columnId]: newValue }; this.setState({ errors: newErrors, newRow: nr, buttonDisabled: this.getDisabledButton(nr, requiredVal, newErrors) }); }; buildForm = () => { const { columns } = this.props; const { newRow } = this.state; return columns .filter(column => !column.hiddenCreate) .map(column => { const { label, valueVerification, id, values = [], dateFormatIn = "", dateFormatOut = "", dataType = "", mask, required, inputType = undefined } = column; let properties = { cellVal: newRow[id] || "", editing: true, required, label, inputType, values, rowId: "", columnId: id, valueVerification, dateFormatIn, dateFormatOut, mask, setRowEdited: props => this.test(props) }; let cellContent; switch (dataType) { case "number": properties = { ...properties, cellVal: newRow[id] || undefined }; cellContent = NumberType(properties); break; case "boolean": cellContent = BooleanType(properties); break; case "date": cellContent = DateType(properties); break; case "time": cellContent = TimeType(properties); break; case "dateTime": cellContent = DateTimeType(properties); break; case "text": default: cellContent = TextType(properties); break; } return ( <Grid container item xs={4} key={column.id} className={`new-row-${id}`} > {cellContent} </Grid> ); }); }; render() { const { modalOpen, buttonDisabled } = this.state; const { editing, createText, createTitleText, createCancelText, createSubmitText } = this.props; return ( <Fragment> <Tooltip arrow TransitionComponent={Zoom} title={createText}> <span> <IconButton disabled={!editing} className={ !editing ? `disabled-icon add-row-icon` : `add-row-icon` } onClick={() => this.setState({ modalOpen: true })} > <AddIcon color="primary" /> </IconButton> </span> </Tooltip> <Dialog open={modalOpen} onClose={() => this.handleClose()}> <DialogTitle>{createTitleText}</DialogTitle> <DialogContent> <Grid container spacing={8}> {this.buildForm()} </Grid> </DialogContent> <DialogActions> <Button onClick={() => this.handleClose()} color="secondary" className="cancel" > {createCancelText} </Button> <Button className="create" disabled={buttonDisabled} onClick={() => this.send()} color="primary" autoFocus variant="contained" > {createSubmitText} </Button> </DialogActions> </Dialog> </Fragment> ); } } const mapStateToProps = state => { return { columns: state.datatableReducer.data.columns, createText: state.textReducer.create, createTitleText: state.textReducer.createTitle, createCancelText: state.textReducer.createCancel, createSubmitText: state.textReducer.createSubmit }; }; const mapDispatchToProps = dispatch => { return { addNewRow: row => dispatch(addNewRowAction(row)) }; }; Add.propTypes = { addNewRow: addNewRowPropType, columns: columnsPropType, editing: editingPropType, createText: textPropType, createTitleText: textPropType, createCancelText: textPropType, createSubmitText: textPropType }; export default connect(mapStateToProps, mapDispatchToProps)(Add);