UNPKG

sematable

Version:

Client side sorting, pagination, and text filter for redux/react based apps

370 lines (318 loc) 15.3 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); var _propTypes = require('prop-types'); var _propTypes2 = _interopRequireDefault(_propTypes); var _react = require('react'); var _react2 = _interopRequireDefault(_react); var _reactRedux = require('react-redux'); var _lodash = require('lodash'); var _lodash2 = _interopRequireDefault(_lodash); var _Filter = require('./Filter.js'); var _Filter2 = _interopRequireDefault(_Filter); var _Pagination = require('./Pagination.js'); var _Pagination2 = _interopRequireDefault(_Pagination); var _PageSize = require('./PageSize.js'); var _PageSize2 = _interopRequireDefault(_PageSize); var _selectors = require('./selectors.js'); var _selectors2 = _interopRequireDefault(_selectors); var _actions = require('./actions.js'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } var propTypes = { data: _propTypes2.default.array, isInitialized: _propTypes2.default.bool.isRequired, visibleRows: _propTypes2.default.array, filter: _propTypes2.default.array, filterText: _propTypes2.default.string, sortInfo: _propTypes2.default.object, pageInfo: _propTypes2.default.object, selectAll: _propTypes2.default.bool, selectedRows: _propTypes2.default.array, primaryKey: _propTypes2.default.string, filterOptions: _propTypes2.default.array, filterValue: _propTypes2.default.array, onPageChange: _propTypes2.default.func.isRequired, onPageSizeChange: _propTypes2.default.func.isRequired, onFilterChange: _propTypes2.default.func.isRequired, onFilterTextChange: _propTypes2.default.func.isRequired, onHeaderClick: _propTypes2.default.func.isRequired, onInitialize: _propTypes2.default.func.isRequired, onNewData: _propTypes2.default.func.isRequired, onNewFilterValue: _propTypes2.default.func.isRequired, onRowCheckedChange: _propTypes2.default.func.isRequired, onSelectAllChange: _propTypes2.default.func.isRequired, onEditingChange: _propTypes2.default.func.isRequired }; /** * Wrapper for adding filter, sort and pagination for tabular data. * * See AppsTable.js and AppsPage.js on how to use the wrapper. * * When wrapping a table component, you need to provide the component itself, * and column definitions. Column definitions should look like this: * * { * id: { header: 'ID', searchable: true }, * name: { header: 'Name', searchable: true }, * }; * */ var sematable = function sematable(tableName, TableComponent, columns) { var configs = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {}; var selectors = (0, _selectors2.default)(tableName); var mapStateToProps = function mapStateToProps(state, props) { var isInitialized = selectors.getIsInitialized(state); if (!isInitialized) { return { isInitialized: isInitialized }; } return { isInitialized: isInitialized, visibleRows: selectors.getVisible(state, props), filter: selectors.getFilter(state, props), filterText: selectors.getFilterText(state), sortInfo: selectors.getSortInfo(state, props), pageInfo: selectors.getPageInfo(state, props), selectAll: selectors.getSelectAll(state, props), selectedRows: selectors.getSelectedRows(state, props), primaryKey: selectors.getPrimaryKey(state, props), filterOptions: selectors.getFilterOptions(state, props) }; }; var mapDispatchToProps = function mapDispatchToProps(dispatch, ownProps) { return { onPageChange: function onPageChange(page) { return dispatch((0, _actions.tablePageChanged)(tableName, page)); }, onPageSizeChange: function onPageSizeChange(pageSize) { return dispatch((0, _actions.tablePageSizeChanged)(tableName, pageSize)); }, onFilterChange: function onFilterChange(filter, action) { return dispatch((0, _actions.tableFilterChanged)(tableName, filter, action)); }, onFilterTextChange: function onFilterTextChange(filterText) { return dispatch((0, _actions.tableFilterTextChanged)(tableName, filterText)); }, onHeaderClick: function onHeaderClick(sortKey) { return dispatch((0, _actions.tableSortChanged)(tableName, sortKey)); }, onNewData: function onNewData(data) { return dispatch((0, _actions.tableNewData)(tableName, data)); }, onNewFilterValue: function onNewFilterValue(data) { return dispatch((0, _actions.tableSetFilter)(tableName, data)); }, onSelectAllChange: function onSelectAllChange() { return dispatch((0, _actions.tableSelectAllChanged)(tableName)); }, onRowCheckedChange: function onRowCheckedChange(row) { return dispatch((0, _actions.tableRowCheckedChanged)(tableName, row)); }, onEditingChange: function onEditingChange(editing) { return dispatch((0, _actions.editingChange)(tableName, editing)); }, onInitialize: function onInitialize(data, filterValue) { return dispatch((0, _actions.tableInitialize)(tableName, data, columns, configs, filterValue, ownProps)); } }; }; var DataTable = function (_Component) { _inherits(DataTable, _Component); function DataTable() { _classCallCheck(this, DataTable); return _possibleConstructorReturn(this, (DataTable.__proto__ || Object.getPrototypeOf(DataTable)).apply(this, arguments)); } _createClass(DataTable, [{ key: 'componentWillMount', value: function componentWillMount() { var _props = this.props, data = _props.data, filterValue = _props.filterValue, onInitialize = _props.onInitialize; onInitialize(data, filterValue); } }, { key: 'componentWillReceiveProps', value: function componentWillReceiveProps(nextProps) { var _props2 = this.props, data = _props2.data, filterValue = _props2.filterValue, onNewData = _props2.onNewData, onNewFilterValue = _props2.onNewFilterValue; if (data !== nextProps.data) { onNewData(nextProps.data); } if (filterValue !== nextProps.filterValue) { onNewFilterValue(nextProps.filterValue); } } }, { key: 'componentWillUnmount', value: function componentWillUnmount() { var onEditingChange = this.props.onEditingChange; onEditingChange(false); } }, { key: 'render', value: function render() { var _props3 = this.props, isInitialized = _props3.isInitialized, visibleRows = _props3.visibleRows, filter = _props3.filter, filterText = _props3.filterText, sortInfo = _props3.sortInfo, pageInfo = _props3.pageInfo, selectAll = _props3.selectAll, selectedRows = _props3.selectedRows, primaryKey = _props3.primaryKey, filterOptions = _props3.filterOptions, data = _props3.data, _onPageChange = _props3.onPageChange, onPageSizeChange = _props3.onPageSizeChange, onFilterChange = _props3.onFilterChange, onFilterTextChange = _props3.onFilterTextChange, onHeaderClick = _props3.onHeaderClick, onRowCheckedChange = _props3.onRowCheckedChange, onSelectAllChange = _props3.onSelectAllChange, otherProps = _objectWithoutProperties(_props3, ['isInitialized', 'visibleRows', 'filter', 'filterText', 'sortInfo', 'pageInfo', 'selectAll', 'selectedRows', 'primaryKey', 'filterOptions', 'data', 'onPageChange', 'onPageSizeChange', 'onFilterChange', 'onFilterTextChange', 'onHeaderClick', 'onRowCheckedChange', 'onSelectAllChange']); var _configs$showPageSize = configs.showPageSize, showPageSize = _configs$showPageSize === undefined ? true : _configs$showPageSize, _configs$showFilter = configs.showFilter, showFilter = _configs$showFilter === undefined ? true : _configs$showFilter, _configs$showPaginati = configs.showPagination, showPagination = _configs$showPaginati === undefined ? true : _configs$showPaginati, _configs$autoHidePagi = configs.autoHidePagination, autoHidePagination = _configs$autoHidePagi === undefined ? true : _configs$autoHidePagi, _configs$pageSizeCont = configs.pageSizeContainerClassName, pageSizeContainerClassName = _configs$pageSizeCont === undefined ? 'col-md-6' : _configs$pageSizeCont, _configs$filterContai = configs.filterContainerClassName, filterContainerClassName = _configs$filterContai === undefined ? 'col-md-6' : _configs$filterContai, pageSizeClassName = configs.pageSizeClassName, filterClassName = configs.filterClassName, _configs$filterClassN = configs.filterClassNamePrefix, filterClassNamePrefix = _configs$filterClassN === undefined ? 'Select' : _configs$filterClassN, filterPlaceholder = configs.filterPlaceholder; if (!isInitialized) { return _react2.default.createElement('div', null); } var isSelected = function isSelected(row) { return _lodash2.default.includes(selectedRows, row); }; var select = { onRowCheckedChange: onRowCheckedChange, onSelectAllChange: onSelectAllChange, selectAll: selectAll, isSelected: isSelected, selectedRows: selectedRows }; var columnMap = _lodash2.default.keyBy(columns, 'key'); var hasFilterable = _lodash2.default.some(columns, 'filterable'); var columnHeaders = _lodash2.default.mapValues(columnMap, function (value, key) { return { sorted: key === sortInfo.sortKey ? sortInfo.direction : null, sortKey: key, primaryKey: value.primaryKey, name: value.header, sortable: value.sortable, title: value.title, handleClick: function handleClick(k) { return onHeaderClick(k); } }; }); var headers = _extends({}, columnHeaders, { select: select }); if (configs.plain) { return _react2.default.createElement(TableComponent, _extends({}, otherProps, { data: visibleRows, headers: headers, primaryKey: primaryKey, columns: columns, filter: filter, tableName: tableName }, configs)); } return _react2.default.createElement( 'div', { className: 'row' }, _react2.default.createElement( 'div', { className: pageSizeContainerClassName }, showPageSize && _react2.default.createElement(_PageSize2.default, { className: pageSizeClassName, pageSize: pageInfo.pageSize, pageSizes: pageInfo.pageSizes, totalSize: data.length, onChange: function onChange(f) { return onPageSizeChange(f); }, style: { margin: '1rem 0 1rem 0' }, selectStyle: { display: 'inline-block', width: '80px', margin: '0 0 0 5px' } }) ), _react2.default.createElement( 'div', { className: filterContainerClassName }, showFilter && _react2.default.createElement(_Filter2.default, { className: filterClassName, classNamePrefix: filterClassNamePrefix, value: filter, filterText: filterText, options: filterOptions, onChange: function onChange(f, a) { return onFilterChange(f, a); }, onTextChange: function onTextChange(f) { return onFilterTextChange(f); }, hasFilterable: hasFilterable, placeholder: filterPlaceholder, style: { margin: '1rem 0 1rem 0' } }) ), _react2.default.createElement( 'div', { className: 'col-md-12' }, _react2.default.createElement(TableComponent, _extends({}, otherProps, { data: visibleRows, headers: headers, primaryKey: primaryKey, columns: columns, filter: filter, tableName: tableName }, configs)) ), showPagination && _react2.default.createElement( 'div', { className: 'col-md-12' }, _react2.default.createElement(_Pagination2.default, _extends({}, pageInfo, { autoHidePagination: autoHidePagination, onPageChange: function onPageChange(p) { return _onPageChange(p); } })) ) ); } }]); return DataTable; }(_react.Component); DataTable.propTypes = propTypes; return (0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps)(DataTable); }; exports.default = sematable;