UNPKG

@krowdy-ui/views

Version:

React components that implement Google's Material Design.

441 lines (416 loc) 13.4 kB
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose"; import _extends from "@babel/runtime/helpers/esm/extends"; import React, { useState, useEffect, useRef } from 'react'; import PropTypes from 'prop-types'; import { withStyles } from '@krowdy-ui/styles'; import { Paper, TextField, InputAdornment, TablePagination } from '@krowdy-ui/core'; import SearchIcon from '@material-ui/icons/Search'; import StarIcon from '@material-ui/icons/Star'; import StarBorderIcon from '@material-ui/icons/StarBorder'; import { GroupingState, SortingState, IntegratedSorting, CustomGrouping } from '@devexpress/dx-react-grid'; import { Grid as GridTable, Table // VirtualTable, , TableHeaderRow, TableGroupRow, GroupingPanel, DragDropProvider, Toolbar } from '@devexpress/dx-react-grid-material-ui'; import Autocomplete from '@material-ui/lab/Autocomplete'; export const styles = theme => ({ containerFullwidth: { height: '100%' }, containerHeaderTable: { padding: theme.spacing(2) }, containerSearch: { display: 'flex', justifyContent: 'space-between' }, contetPagination: { display: 'flex', justifyContent: 'flex-end', padding: 20 }, gridTableChip: { '&:focus': { '& > div': { '&:focus': { background: '#F3FBFF' } } }, '&:hover': { background: '#F3FBFF' }, background: '#F3FBFF', border: '1px solid #80DBFF' }, gridTableGroupingEmpty: { '& > div': { background: 'transparent', border: `solid 1px ${theme.palette.primary.main}`, color: '#595959' }, alignItems: 'center', display: 'flex', height: '32px', marginTop: theme.spacing(1) }, gridTableHeader: { '& svg': { color: `${theme.palette.primary.main} !important` }, '& th': {}, fontSize: '0.875rem', fontWeight: 'bold', padding: theme.spacing(1, 2) }, gridTableHeaderGroup: { '& > td': { background: '#E6E9F0' }, '& > td > div': { background: '#E6E9F0', color: '#262626', fontWeight: 'bold' }, background: '#E6E9F0' }, gridTableHeaderRoot: { background: '#F2F4F7' }, gridTableSearch: { background: '#fff', padding: theme.spacing(2), paddingBottom: 0 }, gridTableToolbar: { display: 'flex', flexDirection: 'column', padding: theme.spacing(2) }, inputSearch: { '& * input': { fontSize: 14, padding: '12px 10px !important' }, '& > div': { padding: '0 14px 0 0 !important' }, margin: '2px 0' }, paperRoot: { '& > div:first-child': { height: '100%' }, '& > div:first-child > div:nth-child(2)': { flex: 1, overflow: 'auto' }, height: '100%' }, searchIcon: { cursor: 'pointer' }, tableContainer: { display: 'flex', flexDirection: 'column', height: '100%' } }); const formatColumnsExtension = columns => columns.map(column => { if (column.type) if (column.type === 'star') column.width = 160; return _extends({}, column, { columnName: column.key, title: column.label }); }); const formatColumns = columns => columns.map(column => _extends({}, column, { name: column.key, title: column.label })); const columnsDraggableDisable = columns => columns.map(column => ({ columnName: column.key, groupingEnabled: column.draggable })); const sortingFormat = sortings => sortings.map(sorting => ({ columnName: sorting.orderBy, direction: sorting.sort })); const sortingFormatReverse = sortings => sortings.map(sorting => ({ orderBy: sorting.columnName, sort: sorting.direction })); const getRowId = row => row._id; const TableRow = (_ref, callback) => { let { row } = _ref, restProps = _objectWithoutPropertiesLoose(_ref, ["row"]); return /*#__PURE__*/React.createElement(Table.Row, _extends({}, restProps, { onClick: () => callback(row._id), style: { cursor: 'pointer' } })); }; const StartCell = _ref2 => { let { value } = _ref2, restProps = _objectWithoutPropertiesLoose(_ref2, ["value"]); const { column } = restProps; return /*#__PURE__*/React.createElement(Table.Cell, restProps, /*#__PURE__*/React.createElement("span", null, value ? [1, 2, 3, 4, 5].map(currentValue => currentValue <= value ? /*#__PURE__*/React.createElement(StarIcon, { color: "primary", key: `star-${column._id}-${currentValue}` }) : /*#__PURE__*/React.createElement(StarBorderIcon, { color: "primary", key: `star-${column._id}-${currentValue}` })) : '')); }; const TableCell = props => { const { column } = props; if (column.type === 'star') return /*#__PURE__*/React.createElement(StartCell, props); return /*#__PURE__*/React.createElement(Table.Cell, props); }; var _ref3 = /*#__PURE__*/React.createElement(SearchIcon, null); var _ref4 = /*#__PURE__*/React.createElement(DragDropProvider, null); var _ref5 = /*#__PURE__*/React.createElement(IntegratedSorting, null); var _ref6 = /*#__PURE__*/React.createElement(Toolbar, null); const TableGroup = props => { const { classes, rows = [], columns = [], groupingData = [], changeGrouping = () => {}, sorting = false, grouping = false, sortingData = [], changeSorting = () => {}, withPagination = false, withHeader = false, withSearch = false, onChangePerPage = () => {}, withAutocomplete = false, searchSuggestions = [], onHandleSearch = () => {}, groupingDataTemp = null, pagination = {}, limitDragable = 1, onChangePage = () => {}, onClickRow = () => {}, // multiSorting = false, onHandleSelectAutocomplete = () => {} } = props; const [columnsData, setColumnData] = useState(formatColumns(columns)); const [columnsDataExtension, setColumnsDataExtension] = useState(formatColumnsExtension(columns)); const [sortingDataFormat, setSortingFormat] = useState(sortingFormat(sortingData)); const [groupingStateColumnExtensions, setGroupingStateColumnExtensions] = useState(columnsDraggableDisable(columns)); const [expandData, setExpandData] = useState([]); const inputSearch = useRef(null); // effects useEffect(() => { if (columns.length) { setColumnData(formatColumns(columns)); setGroupingStateColumnExtensions(columnsDraggableDisable(columns)); setColumnsDataExtension(formatColumnsExtension(columns)); } }, [columns]); useEffect(() => { if (sortingData.length) setSortingFormat(sortingFormat(sortingData)); }, [sortingData]); // actions const getChildGroups = groups => groups.map(group => ({ childRows: group.items, key: group.key })); const setExpandedGroups = value => { // recibe un array de string ["Confirmed", "Completed"] setExpandData(value); }; const _handleSearchValidate = e => { const { value } = e.target; if (e.keyCode === 13) onHandleSearch(value); }; const onChangeSorting = value => { // if(multiSorting) // if(sortingData.length) { // const data = [ // ...sortingDataFormat.map(item => item.columnName === value[0].columnName ? value[0] : item), // ...value // ] // changeSorting(sortingFormatReverse(data)) // } else { // } changeSorting(sortingFormatReverse(value)); }; const onChangeGrouping = value => { if (rows.length) if (value.length <= limitDragable) changeGrouping(value); }; return /*#__PURE__*/React.createElement(Paper, { classes: { root: classes.paperRoot }, style: { position: 'relative' }, variant: "outlined" }, /*#__PURE__*/React.createElement("div", { className: classes.tableContainer }, withHeader ? /*#__PURE__*/React.createElement("div", { className: classes.containerHeaderTable }, /*#__PURE__*/React.createElement("div", { className: classes.containerSearch }, withSearch ? withAutocomplete ? /*#__PURE__*/React.createElement(Autocomplete, { freeSolo: true, noOptionsText: "No hay coincidencias", onChange: onHandleSelectAutocomplete, options: searchSuggestions.map(option => option.title), popupIcon: _ref3, renderInput: params => /*#__PURE__*/React.createElement(TextField, _extends({}, params, { className: classes.inputSearch, fullWidth: true, InputLabelProps: { shrink: false }, InputProps: _extends({}, params.InputProps, { endAdornment: /*#__PURE__*/React.createElement(InputAdornment, { position: "end" }, /*#__PURE__*/React.createElement(SearchIcon, { className: classes.searchIcon, onClick: () => onHandleSearch(inputSearch.current.value) })) }), inputRef: inputSearch, onKeyUp: _handleSearchValidate, placeholder: "Buscar", variant: "outlined" })), style: { width: 400 } }) : /*#__PURE__*/React.createElement(TextField, { className: classes.inputSearch, InputLabelProps: { shrink: false }, InputProps: { endAdornment: /*#__PURE__*/React.createElement(InputAdornment, { position: "end" }, /*#__PURE__*/React.createElement(SearchIcon, { className: classes.searchIcon, onClick: () => onHandleSearch(inputSearch.current.value) })) }, inputRef: inputSearch, onKeyUp: _handleSearchValidate, placeholder: "Buscar", style: { width: 400 }, variant: "outlined" }) : null)) : null, /*#__PURE__*/React.createElement(GridTable, { columns: columnsData, getRowId: getRowId, rows: rows }, /*#__PURE__*/React.createElement(SortingState, { onSortingChange: onChangeSorting, sorting: sortingDataFormat }), grouping && _ref4, /*#__PURE__*/React.createElement(GroupingState // expandedGroups={[ 'Confirmed' ]} , { columnExtensions: groupingStateColumnExtensions, grouping: groupingData, onExpandedGroupsChange: setExpandedGroups, onGroupingChange: onChangeGrouping }), /*#__PURE__*/React.createElement(CustomGrouping, { expandedGroups: expandData, getChildGroups: getChildGroups, grouping: groupingDataTemp }), _ref5, /*#__PURE__*/React.createElement(Table, { cellComponent: TableCell, columnExtensions: columnsDataExtension, rowComponent: row => TableRow(row, onClickRow) }), /*#__PURE__*/React.createElement(TableHeaderRow, { messages: { sortingHint: 'Ordenar' }, showSortingControls: /* groupingData.length ? false : */ sorting }), /*#__PURE__*/React.createElement(TableGroupRow, { rowComponent: ({ children }) => /*#__PURE__*/React.createElement(TableHeaderRow.Row, { className: classes.gridTableHeaderGroup }, children) }), _ref6, /*#__PURE__*/React.createElement(GroupingPanel, { emptyMessageComponent: () => /*#__PURE__*/React.createElement("div", { className: classes.gridTableGroupingEmpty }, "Arrastra aqu\xED una columna para agrupar tus registros."), itemComponent: ev => { const customSorting = true; // const customSorting = (ev.item && ev.item.column && groupingData.length) ? // Boolean(ev.item.column.name === groupingData[0].columnName) : true return /*#__PURE__*/React.createElement(GroupingPanel.Item, _extends({}, ev, { className: classes.gridTableChip, sortingEnabled: customSorting })); }, showGroupingControls: true, showSortingControls: true })), withPagination ? /*#__PURE__*/React.createElement("div", { className: classes.contetPagination }, /*#__PURE__*/React.createElement(TablePagination, { backIconButtonText: "P\xE1gina anterior", component: "div", labelRowsPerPage: "Mostrar", nextIconButtonText: "P\xE1gina siguiente", onChangePage: onChangePage, onChangeRowsPerPage: onChangePerPage, page: pagination.page, rowsPerPage: pagination.perPage, rowsPerPageOptions: [10, 25, 100], totalItems: pagination.totalItems, totalPages: pagination.totalPages })) : null)); }; process.env.NODE_ENV !== "production" ? TableGroup.propTypes = { changeGrouping: PropTypes.func, changeSorting: PropTypes.func, columns: PropTypes.arrayOf(PropTypes.shape({ align: PropTypes.string, currency: PropTypes.bool, key: PropTypes.string.isRequired, label: PropTypes.string.isRequired, minWidth: PropTypes.number, ordering: PropTypes.bool })).isRequired, grouping: PropTypes.bool, groupingData: PropTypes.arrayOf(PropTypes.shape({ name: PropTypes.string })), limitDragable: PropTypes.number, onChangePage: PropTypes.func, onChangePerPage: PropTypes.func, onClickRow: PropTypes.func, onHandleSearch: PropTypes.func, onHandleSelectAutocomplete: PropTypes.func, pagination: PropTypes.object, rows: PropTypes.arrayOf(PropTypes.shape({ _id: PropTypes.string.isRequired })).isRequired, searchSuggestions: PropTypes.array, sorting: PropTypes.bool, sortingData: PropTypes.arrayOf(PropTypes.shape({ orderBy: PropTypes.string, sort: PropTypes.string })), withAutocomplete: PropTypes.bool, withHeader: PropTypes.bool, withPagination: PropTypes.bool, withSearch: PropTypes.bool } : void 0; TableGroup.muiName = 'TableGroup'; export default withStyles(styles, { name: 'KrowdyTableGroup' })(TableGroup);