UNPKG

@integec/grid-tools

Version:
1,092 lines (935 loc) 47.7 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _range = require('ramda/src/range'); var _range2 = _interopRequireDefault(_range); var _drop = require('ramda/src/drop'); var _drop2 = _interopRequireDefault(_drop); var _take = require('ramda/src/take'); var _take2 = _interopRequireDefault(_take); var _compose = require('ramda/src/compose'); var _compose2 = _interopRequireDefault(_compose); var _sort = require('ramda/src/sort'); var _sort2 = _interopRequireDefault(_sort); var _isEmpty = require('ramda/src/isEmpty'); var _isEmpty2 = _interopRequireDefault(_isEmpty); var _any = require('ramda/src/any'); var _any2 = _interopRequireDefault(_any); var _filter = require('ramda/src/filter'); var _filter2 = _interopRequireDefault(_filter); var _find = require('ramda/src/find'); var _find2 = _interopRequireDefault(_find); var _isNil = require('ramda/src/isNil'); var _isNil2 = _interopRequireDefault(_isNil); 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 _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; var _react = require('react'); var _react2 = _interopRequireDefault(_react); var _utils = require('./utils'); var _clipboardUtils = require('./clipboard-utils'); var _data = require('data.maybe'); var _propTypes = require('prop-types'); var _propTypes2 = _interopRequireDefault(_propTypes); var _ScrollSyncHelper = require('./ScrollSyncHelper'); var _ScrollSyncHelper2 = _interopRequireDefault(_ScrollSyncHelper); var _ScrollPane = require('./ScrollPane'); var _ScrollPane2 = _interopRequireDefault(_ScrollPane); var _moment = require('moment'); var _moment2 = _interopRequireDefault(_moment); var _RowEditor = require('./RowEditor'); var _RowEditor2 = _interopRequireDefault(_RowEditor); var _editEngine = require('./editEngine'); var _selectionUtil = require('./selection-util'); var _constants = require('./constants.js'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return 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; } function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } var noopEditRowProcess = function noopEditRowProcess(_ref) { var editedRow = _ref.editedRow; return editedRow; }; var rowHeightOf = function rowHeightOf(index, rowHeight) { return typeof rowHeight === 'function' ? rowHeight(index) : rowHeight; }; var toggleSortOrder = function toggleSortOrder(order) { return order === 'asc' ? 'desc' : order === 'desc' ? undefined : 'asc'; }; var normalizeValue = function normalizeValue(val, type) { return type === 'num' && typeof val === 'string' ? parseFloat(val) : type === 'date' && (_moment2.default.isDate(val) || _moment2.default.isMoment(val)) ? val.valueOf() : type === 'date' && typeof val === 'string' ? (0, _moment2.default)(val).valueOf() : val; }; var compare = function compare(_ref2) { var aVal = _ref2.aVal, bVal = _ref2.bVal, sortOrder = _ref2.sortOrder; var greaterThanResult = sortOrder === 'asc' ? 1 : -1; var lessThanResult = sortOrder === 'asc' ? -1 : 1; if (!(0, _isNil2.default)(aVal) || !(0, _isNil2.default)(bVal)) { if ((0, _isNil2.default)(aVal)) return greaterThanResult; if ((0, _isNil2.default)(bVal)) return lessThanResult; if (typeof aVal === 'string' && typeof bVal === 'string' && aVal.toLowerCase().localeCompare(bVal.toLowerCase()) === 1) return greaterThanResult; if (typeof aVal === 'string' && typeof bVal === 'string' && bVal.toLowerCase().localeCompare(aVal.toLowerCase()) === 1) return lessThanResult; if (typeof aVal === 'number' && typeof bVal === 'number' && aVal > bVal) return greaterThanResult; if (typeof aVal === 'number' && typeof bVal === 'number' && bVal > aVal) return lessThanResult; } return 0; }; var defaultDataComparator = function defaultDataComparator(_ref3) { var sortOptions = _ref3.sortOptions, headers = _ref3.headers; return function (a, b) { var _loop = function _loop(i) { var _sortOptions$i = sortOptions[i], ident = _sortOptions$i.ident, display = _sortOptions$i.display, sortOrder = _sortOptions$i.sortOrder; var header = headers.find(function (a) { return a.ident === ident && (!display || display === a.display); }); var type = header.type, sortIndexGetter = header.sortIndexGetter; // TODO may need to look into getting custom data for example date var aVal = normalizeValue(sortIndexGetter ? sortIndexGetter({ rowData: a, header: header }) : (0, _utils.extractData)({ rowData: a, header: header }), type); var bVal = normalizeValue(sortIndexGetter ? sortIndexGetter({ rowData: b, header: header }) : (0, _utils.extractData)({ rowData: b, header: header }), type); var res = compare({ aVal: aVal, bVal: bVal, sortOrder: sortOrder }); if (res !== 0) return { v: res }; }; // const headerMap = R.compose(R.fromPairs, R.map(header => [header.ident, header]))(headers) // console.log('**$$**$$sorting**$$**$$') for (var i = 0; i < sortOptions.length; i++) { var _ret = _loop(i); if ((typeof _ret === 'undefined' ? 'undefined' : _typeof(_ret)) === "object") return _ret.v; } return 0; }; }; var computeSortOptions = function computeSortOptions(sortOptions, _ref4) { var ident = _ref4.ident, display = _ref4.display; if ((0, _find2.default)(function (opt) { return opt.ident === ident; }, sortOptions) !== undefined) { return sortOptions.map(function (opt) { return opt.ident === ident && (opt.display == null || opt.display === display) ? { ident: ident, sortOrder: toggleSortOrder(opt.sortOrder) } : opt; }).filter(function (opt) { return opt.sortOrder !== undefined; }); } else { return [].concat(_toConsumableArray(sortOptions), [{ ident: ident, display: display, sortOrder: 'asc' }]); } }; var matchData = function matchData(rowData, fuzzyFilter) { return function (header) { return (0, _data.fromNullable)((0, _utils.extractAndFormatData)({ rowData: rowData, header: header })).map(function (txt) { return txt.toLowerCase().includes(fuzzyFilter.toLowerCase()); }).getOrElse(false); }; }; var filterData = function filterData(data, headers, fuzzyFilter) { var filteredHeaders = (0, _filter2.default)(function (_ref5) { var isKey = _ref5.isKey, isFiltered = _ref5.isFiltered; return isKey || isFiltered; }, headers); return (0, _filter2.default)(function (rowData) { return (0, _any2.default)(matchData(rowData, fuzzyFilter), filteredHeaders); }, data); }; var computeView = function computeView(_ref6) { var _ref6$data = _ref6.data, data = _ref6$data === undefined ? [] : _ref6$data, sortOptions = _ref6.sortOptions, _ref6$comparator = _ref6.comparator, comparator = _ref6$comparator === undefined ? defaultDataComparator : _ref6$comparator, fuzzyFilter = _ref6.fuzzyFilter, headers = _ref6.headers, rowsPerPage = _ref6.rowsPerPage, currentPage = _ref6.currentPage, editInfo = _ref6.editInfo, altBy = _ref6.altBy; // TODO have to add edited value // var editedData = (0, _editEngine.applyEdits)({ data: data, editInfo: editInfo }); console.log('*****calling compute view******'); var filteredData = !(0, _isNil2.default)(fuzzyFilter) && !(0, _isEmpty2.default)(fuzzyFilter) ? filterData(editedData, headers, fuzzyFilter) : editedData; var sortredData = (0, _isNil2.default)(sortOptions) || (0, _isEmpty2.default)(sortOptions) ? filteredData : (0, _sort2.default)(comparator({ sortOptions: sortOptions, headers: headers }), filteredData); var normalizedCurrentPage = Math.min(filteredData.length, currentPage); var pagedData = (0, _isNil2.default)(rowsPerPage) ? sortredData : (0, _compose2.default)((0, _take2.default)(rowsPerPage), (0, _drop2.default)((normalizedCurrentPage - 1) * rowsPerPage))(sortredData); return { view: pagedData, filteredDataLength: filteredData.length, currentPage: normalizedCurrentPage, altIndexes: (0, _utils.computeAltIndexes)({ data: pagedData, altBy: altBy }) }; }; var sortOrderOf = function sortOrderOf(header) { return function (options) { if ((0, _isNil2.default)(options)) return undefined; return (0, _compose2.default)(function (opt) { return opt ? opt.sortOrder : undefined; }, (0, _find2.default)(function (opt) { return opt.ident === header.ident && (opt.display == null || opt.display === header.display); }))(options); }; }; var Grid = function (_React$PureComponent) { _inherits(Grid, _React$PureComponent); function Grid() { var _ref7; var _temp, _this, _ret2; _classCallCheck(this, Grid); for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } return _ret2 = (_temp = (_this = _possibleConstructorReturn(this, (_ref7 = Grid.__proto__ || Object.getPrototypeOf(Grid)).call.apply(_ref7, [this].concat(args))), _this), _this.scrollSync = new _ScrollSyncHelper2.default(), _this.localEditInfo = (0, _editEngine.generateInitialEditInfo)(), _this.isEditInfoControlled = function () { return !(0, _isNil2.default)(_this.props.editInfo) && !(0, _isNil2.default)(_this.props.onEditInfoChange); }, _this.editInfo = function () { return _this.isEditInfoControlled() ? _this.props.editInfo : _this.localEditInfo; }, _this.setEditInfo = function (editInfo) { if (_this.isEditInfoControlled()) { _this.props.onEditInfoChange(editInfo); return false; } _this.localEditInfo = editInfo; return true; }, _this.state = _extends({ hoveredRow: undefined, hoveredColumn: undefined, x1: undefined, x2: undefined, y1: undefined, y2: undefined }, computeView({ data: _this.props.data, sortOptions: _this.props.initialSortOptions || _this.props.sortOptions, fuzzyFilter: _this.props.fuzzyFilter, headers: _this.props.headers, rowsPerPage: _this.props.rowsPerPage, currentPage: _this.props.currentPage || 1, editInfo: _this.editInfo(), altBy: _this.props.altBy }), { sortOptions: _this.props.initialSortOptions, currentPage: _this.props.currentPage || 1, editingRow: undefined, editingColumn: undefined }), _this.bodyMouseRelease = function (e) { /* * this will only work with one grid on screen * may need to figureout another solution * isPositionValid only cares if data-row-index data-column-index is there * */ if (_this.selecting && !(0, _utils.isPositionValid)((0, _utils.extractPosition)(e))) { _this.selecting = false; } }, _this.hasPaging = function () { var _ref8 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, _ref8$data = _ref8.data, data = _ref8$data === undefined ? _this.props.data : _ref8$data; return _this.props.rowsPerPage !== undefined && data.length > _this.props.rowsPerPage; }, _this.isPagingControlled = function () { return _this.props.totalPages !== undefined && _this.props.currentPage !== undefined && _this.props.onPageChange !== undefined; }, _this.currentPage = function () { return _this.hasPaging() ? _this.props.currentPage || _this.state.currentPage : undefined; }, _this.totalPages = function () { return !_this.hasPaging() ? undefined : (0, _isNil2.default)(_this.props.totalPages) ? Math.ceil(_this.state.filteredDataLength / _this.props.rowsPerPage) : _this.props.totalPages; }, _this.setCurrentPage = function (page) { if (isNaN(parseInt(page))) return; if (_this.hasPaging()) { var guardedPage = Math.max(Math.min(_this.totalPages(), parseInt(page)), 1); if (guardedPage !== _this.currentPage()) { if (_this.isPagingControlled()) { _this.props.onPageChange(guardedPage); } else { _this.setState(function (_) { return _extends({ currentPage: guardedPage }, _this.generateViewProps({ currentPage: guardedPage })); }); } } } }, _this.incrementPage = function () { if (_this.hasPaging()) { if (_this.isPagingControlled()) { _this.props.onPageChange(Math.max(Math.min(_this.totalPages(), _this.currentPage() + 1), 1)); } else { _this.setState(function (_ref9) { var currentPage = _ref9.currentPage, view = _ref9.view; var totalPages = Math.ceil(_this.props.data.length / _this.props.rowsPerPage); var newPage = Math.max(Math.min(totalPages, currentPage + 1), 1); if (newPage !== currentPage) { return _extends({ currentPage: newPage }, _this.generateViewProps({ currentPage: newPage })); } else { return null; } }); } } }, _this.decrementPage = function () { if (_this.hasPaging()) { if (_this.isPagingControlled()) { _this.props.onPageChange(Math.max(Math.min(_this.totalPages(), _this.currentPage() - 1), 1)); } else { _this.setState(function (_ref10) { var currentPage = _ref10.currentPage, view = _ref10.view; var totalPages = Math.ceil(_this.props.data.length / _this.props.rowsPerPage); var newPage = Math.max(Math.min(totalPages, currentPage - 1), 1); if (newPage !== currentPage) { return _extends({ currentPage: newPage }, _this.generateViewProps({ currentPage: newPage })); } else { return null; } }); } } }, _this.isSortControlled = function () { return _this.props.sortOptions !== undefined && _this.props.onSortOptionsChange !== undefined; }, _this.toggleSort = function (header) { if (_this.isSortControlled()) { _this.props.onSortOptionsChange(computeSortOptions(_this.sortOptions(), header)); } else { _this.setState(function (_ref11) { var _ref11$sortOptions = _ref11.sortOptions, sortOptions = _ref11$sortOptions === undefined ? [] : _ref11$sortOptions; var newOptions = computeSortOptions(sortOptions, header); return _extends({ sortOptions: newOptions }, _this.generateViewProps({ sortOptions: newOptions })); }); } }, _this.generateViewProps = function () { var _ref12 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, _ref12$data = _ref12.data, data = _ref12$data === undefined ? _this.props.data : _ref12$data, _ref12$sortOptions = _ref12.sortOptions, sortOptions = _ref12$sortOptions === undefined ? _this.sortOptions() : _ref12$sortOptions, _ref12$fuzzyFilter = _ref12.fuzzyFilter, fuzzyFilter = _ref12$fuzzyFilter === undefined ? _this.props.fuzzyFilter : _ref12$fuzzyFilter, _ref12$currentPage = _ref12.currentPage, currentPage = _ref12$currentPage === undefined ? _this.currentPage() : _ref12$currentPage, _ref12$editInfo = _ref12.editInfo, editInfo = _ref12$editInfo === undefined ? _this.editInfo() : _ref12$editInfo, _ref12$altBy = _ref12.altBy, altBy = _ref12$altBy === undefined ? _this.props.altBy : _ref12$altBy; return computeView({ data: data, sortOptions: sortOptions, fuzzyFilter: fuzzyFilter, headers: _this.props.headers, rowsPerPage: _this.props.rowsPerPage, currentPage: currentPage, editInfo: editInfo, altBy: _this.props.altBy }); }, _this.selectRight = function (expand) { _this.setState(_selectionUtil.selector.right(_this.state, expand, _this.props.headers.length), _this.selectionChanged); }, _this.selectLeft = function (expand) { _this.setState(_selectionUtil.selector.left(_this.state, expand), _this.selectionChanged); }, _this.selectTop = function (expand) { _this.setState(_selectionUtil.selector.up(_this.state, expand), _this.selectionChanged); }, _this.selectBottom = function (expand) { _this.setState(_selectionUtil.selector.down(_this.state, expand, _this.state.view.length), _this.selectionChanged); }, _this.selectionChanged = function (_) { var _this$props = _this.props, headers = _this$props.headers, onSelectionChange = _this$props.onSelectionChange; // console.log(this.state.x1, this.state.y1, this.state.x2, this.state.y2) if (onSelectionChange) { var _normalizeSelection = (0, _selectionUtil.normalizeSelection)(_this.state), x1 = _normalizeSelection.x1, x2 = _normalizeSelection.x2, y1 = _normalizeSelection.y1, y2 = _normalizeSelection.y2; var selectedRows = []; var selectedHeaders = []; var view = _this.state.view; for (var r = y1; r <= y2; r++) { selectedRows.push(view[r]); } for (var c = x1; c <= x2; c++) { selectedHeaders.push(headers[c]); } onSelectionChange({ selectedRows: selectedRows, selectedHeaders: selectedHeaders }); } }, _this.getSelectionInfo = function (_) { return _extends({}, (0, _selectionUtil.normalizeSelection)(_this.state), { rawPositions: { x1: _this.state.x1, x2: _this.state.x2, y1: _this.state.y1, y2: _this.state.y2 } }); }, _this.isEditable = function (props) { var isEditable = _this.props.isEditable; return typeof isEditable === 'function' ? isEditable(props) : isEditable; }, _this.processUpdate = function (_ref13) { var currentRow = _ref13.currentRow, row = _ref13.editedRow; var _this$props2 = _this.props, mapEditRow = _this$props2.mapEditRow, processEditedRow = _this$props2.processEditedRow; // console.log('procssing edited frow with', mapEditRow,processEditedRow) var editedRow = mapEditRow ? mapEditRow(row) : processEditedRow({ currentRow: currentRow, editedRow: row }); // console.log('result is ',editedRow) return { originalRow: currentRow, currentRow: currentRow, editedRow: editedRow }; }, _this.commitRowEdit = function (editProps) { var currentRow = editProps.currentRow, row = editProps.editedRow; var dataDidUpdate = _this.props.dataDidUpdate; if (currentRow !== row) { var _this$processUpdate = _this.processUpdate({ currentRow: currentRow, editedRow: row }), editedRow = _this$processUpdate.editedRow; if (_this.props.onEdit) { // expect new data to be passed down via props _this.props.onEdit(_extends({}, editProps, { currentRow: currentRow, originalRow: currentRow, editedRow: editedRow }), _this.focusGrid); if (dataDidUpdate) { dataDidUpdate(_extends({}, editProps, { currentRow: currentRow, originalRow: currentRow, editedRow: editedRow })); } } else { // console.log('***********adding stuff', currentRow, editedRow,'') // if edit info is controlled then there should not be state updates var updateState = _this.setEditInfo((0, _editEngine.updateRow)({ editInfo: _this.editInfo(), currentRow: currentRow, editedRow: editedRow })); _this.setState(function (_) { return updateState ? _extends({}, _this.generateViewProps(), { editingRow: undefined, editingColumn: undefined }) : { editingRow: undefined, editingColumn: undefined }; }, function () { _this.focusGrid && _this.focusGrid(); dataDidUpdate && updateState && dataDidUpdate(_extends({}, editProps, { originalRow: currentRow, currentRow: currentRow, editedRow: editedRow })); }); } } }, _this.cancelEdit = function () { return _this.setState(function (_) { return { editingRow: undefined, editingColumn: undefined }; }, function () { try { if (_this.props.onEditCancel != null) _this.props.onEditCancel(); } finally { _this.focusGrid(); } }); }, _this.cellDoubleClick = function (e) { var pos = (0, _utils.extractPosition)(e); var rowIndex = pos.rowIndex, columnIndex = pos.columnIndex; _this.edit(rowIndex, columnIndex); }, _this.gridKeyDown = function (e) { var _normalizeSelection2 = (0, _selectionUtil.normalizeSelection)(_this.state), columnIndex = _normalizeSelection2.x2, rowIndex = _normalizeSelection2.y2; var selectionValid = !(0, _isNil2.default)(columnIndex) && !(0, _isNil2.default)(rowIndex); if (selectionValid) { var isEditAttempt = !_this.isGridEditing() && !e.metaKey && !e.ctrlKey && (e.keyCode >= 32 && e.keyCode <= 126 || e.keyCode === 187 || e.keyCode === 189) && e.key.length === 1; if (isEditAttempt) { console.log('attempting edit', { editingColumn: columnIndex, editingRow: rowIndex, initialEditChar: String.fromCharCode(e.keyCode) }); _this.edit(rowIndex, columnIndex); } } if (!_this.isGridEditing()) { if (e.keyCode === 37) _this.selectLeft(e.shiftKey); if (e.keyCode === 39) _this.selectRight(e.shiftKey); if (e.keyCode === 38) _this.selectTop(e.shiftKey); if (e.keyCode === 40) _this.selectBottom(e.shiftKey); if (e.keyCode === 9) { e.preventDefault(); _this.selectRight(); } if (e.keyCode === 46) { e.preventDefault(); _this.deleteSelection(); } } }, _this.focusGrid = function () { if (_this.clipboardHelper && _this.clipboardHelper.focus) { // console.log('clipboard focus available focusting') _this.clipboardHelper.focus(); } else if (_this.gridContainer && _this.gridContainer.focus) { // console.log('grid focus available focusting') _this.gridContainer.focus(); } }, _this.cancelCellEdit = function () { _this.setState({ editingColumn: undefined, editingRow: undefined }, _this.focusGrid); }, _this.cellMouseDown = function (e) { var pos = (0, _utils.extractPosition)(e); var rowIndex = pos.rowIndex, columnIndex = pos.columnIndex; if (e.button === 2 && (0, _selectionUtil.isCellSelected)(rowIndex, columnIndex, _this.state)) return; _this.setState(function (_) { return _this.startSelectionState(rowIndex, columnIndex); }, _this.selectionChanged); }, _this.cellMouseUp = function (e) { var pos = (0, _utils.extractPosition)(e); var rowIndex = pos.rowIndex, columnIndex = pos.columnIndex; var isSelecting = _this.selecting; _this.setState(function (_) { return _this.expandSelectionState(rowIndex, columnIndex, true); }, function () { _this.focusGrid(); isSelecting && _this.selectionChanged(); }); }, _this.cellMouseEnter = function (e) { var pos = (0, _utils.extractPosition)(e); var rowIndex = pos.rowIndex, columnIndex = pos.columnIndex; var isSelecting = _this.selecting; _this.setState(function (_) { return _extends({}, _this.hoverState(rowIndex, columnIndex), _this.expandSelectionState(rowIndex, columnIndex)); }, isSelecting ? _this.selectionChanged : undefined); }, _this.cellMouseLeave = function (e) { _this.setState(function (_) { return _extends({}, _this.hoverState()); }); }, _this.columnHeaderClick = function (e) { var ident = (0, _utils.extractColIdent)(e); var header = _this.props.headers.filter(function (h) { return h.ident === ident; })[0]; if (!(0, _isNil2.default)(header)) { _this.toggleSort(header); } }, _this.getRowProps = function (_ref14) { var key = _ref14.key, index = _ref14.index, _ref14$isHeader = _ref14.isHeader, isHeader = _ref14$isHeader === undefined ? false : _ref14$isHeader, headers = _ref14.headers, width = _ref14.width, rowHeight = _ref14.rowHeight, headerRowHeight = _ref14.headerRowHeight, yOffSet = _ref14.yOffSet, xOffSet = _ref14.xOffSet, scroll = _ref14.scroll, scrollY = _ref14.scrollY; return { key: key || index, width: width === undefined || width === null ? (0, _utils.sumWidth)(headers) : width, height: isHeader ? headerRowHeight : rowHeightOf(index, rowHeight), colCount: headers.length, isHeader: isHeader, yOffSet: yOffSet, xOffSet: xOffSet, scroll: scroll, scrollY: scrollY }; }, _this.getCellProps = function (_ref15) { var _extends2; var key = _ref15.key, rowIndex = _ref15.rowIndex, columnIndex = _ref15.columnIndex, header = _ref15.header, data = _ref15.data, rowData = _ref15.rowData, rowHeight = _ref15.rowHeight, rest = _objectWithoutProperties(_ref15, ['key', 'rowIndex', 'columnIndex', 'header', 'data', 'rowData', 'rowHeight']); var _this$props3 = _this.props, selectionType = _this$props3.selectionType, hoverType = _this$props3.hoverType; return _extends((_extends2 = {}, _defineProperty(_extends2, _constants.ROW_INDEX_ATTRIBUTE, rowIndex), _defineProperty(_extends2, 'key', key || rowIndex + '-x-' + columnIndex + '-' + header.ident), _defineProperty(_extends2, _constants.COLUMN_INDEX_ATTRIBUTE, columnIndex), _defineProperty(_extends2, 'header', header), _defineProperty(_extends2, 'onMouseDown', _this.cellMouseDown), _defineProperty(_extends2, 'onMouseEnter', _this.cellMouseEnter), _defineProperty(_extends2, 'onMouseUp', _this.cellMouseUp), _defineProperty(_extends2, 'onMouseLeave', _this.cellMouseLeave), _defineProperty(_extends2, 'onDoubleClick', _this.cellDoubleClick), _defineProperty(_extends2, 'isSelected', selectionType === 'cell' ? (0, _selectionUtil.isCellSelected)(rowIndex, columnIndex, _this.state) : (0, _selectionUtil.isRowSelected)(rowIndex, _this.state)), _defineProperty(_extends2, 'isHovered', hoverType === 'cell' ? _this.state.hoveredRow === rowIndex && _this.state.hoveredColumn === columnIndex : _this.state.hoveredRow === rowIndex), _defineProperty(_extends2, 'data', data), _defineProperty(_extends2, 'rowIndex', rowIndex), _defineProperty(_extends2, 'columnIndex', columnIndex), _defineProperty(_extends2, 'height', rowHeightOf(rowIndex, rowHeight)), _defineProperty(_extends2, 'width', header.width), _defineProperty(_extends2, 'alignment', header.alignment), _defineProperty(_extends2, 'isEditing', _this.isCellEditing(rowIndex, columnIndex)), _defineProperty(_extends2, 'commitRowEdit', _this.commitRowEdit), _defineProperty(_extends2, 'cancelEdit', _this.cancelCellEdit), _defineProperty(_extends2, 'selectRight', _this.selectRight), _defineProperty(_extends2, 'selectLeft', _this.selectLeft), _defineProperty(_extends2, 'selectTop', _this.selectTop), _defineProperty(_extends2, 'selectBottom', _this.selectBottom), _defineProperty(_extends2, 'altIndexes', _this.state.altIndexes), _defineProperty(_extends2, 'altBgColor', _this.props.altBgColor), _defineProperty(_extends2, 'fontSize', header.fontSize), _defineProperty(_extends2, 'fontWeight', header.fontWeight), _defineProperty(_extends2, 'backgroundColor', header.backgroundColor || _this.state.altIndexes && _this.state.altIndexes[rowIndex] && _this.props.altBgColor), _defineProperty(_extends2, 'hoverSelectionBackgroundColor', header.hoverSelectionBackgroundColor), _defineProperty(_extends2, 'hoverBackgroundColor', header.hoverBackgroundColor), _defineProperty(_extends2, 'selectionBackgroundColor', header.selectionBackgroundColor), _defineProperty(_extends2, 'hoverSelectionColor', header.hoverSelectionColor), _defineProperty(_extends2, 'hoverColor', header.hoverColor), _defineProperty(_extends2, 'selectionColor', header.selectionColor), _defineProperty(_extends2, 'color', header.color), _extends2), rest); }, _this.getGridContainerProps = function () { var _ref16 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, width = _ref16.width, height = _ref16.height, _ref16$refKey = _ref16.refKey, refKey = _ref16$refKey === undefined ? 'ref' : _ref16$refKey; return _defineProperty({ width: width, height: height, onKeyDown: _this.gridKeyDown }, refKey, _this.gridContainerRefHandler); }, _this.getColumnHeaderProps = function (_ref18) { var _extends3; var key = _ref18.key, index = _ref18.index, header = _ref18.header, rest = _objectWithoutProperties(_ref18, ['key', 'index', 'header']); return _extends((_extends3 = { key: key || index + '-x-' + header.ident, header: header, width: header.width }, _defineProperty(_extends3, _constants.COL_IDENT_ATTRIBUTE, header.ident), _defineProperty(_extends3, 'onClick', _this.props.sortEnabled ? _this.columnHeaderClick : undefined), _defineProperty(_extends3, 'sortOrder', _this.props.sortEnabled ? sortOrderOf(header)(_this.state.sortOptions) : undefined), _defineProperty(_extends3, 'data-column-index', index), _extends3), rest); }, _this.getPagerProps = function (props) { return _extends({}, props, { totalPages: _this.totalPages(), currentPage: _this.currentPage(), setCurrentPage: _this.setCurrentPage, incrementPage: _this.incrementPage, decrementPage: _this.decrementPage }); }, _this.getRowEditorProps = function (_) { var _normalizeSelection3 = (0, _selectionUtil.normalizeSelection)(_this.state), y1 = _normalizeSelection3.y1; var addWithSelected = _this.props.addWithSelected; return { onClose: _this.cancelEdit, commitEdit: _this.commitRowEdit, // TODO: add feature to pop up editor based on some row for add featrues showAdd: _this.props.showAdd, rowData: _this.props.showAdd ? addWithSelected ? _this.state.view[y1] : {} : _this.state.view[_this.state.editingRow], headers: _this.props.headers, isEditing: _this.isRowEditing() }; }, _this.getClipboardHelperProps = function () { var _ref20; var _ref19 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, _ref19$refKey = _ref19.refKey, refKey = _ref19$refKey === undefined ? 'ref' : _ref19$refKey; return _ref20 = {}, _defineProperty(_ref20, refKey, _this.clipboardHelperRefHandler), _defineProperty(_ref20, 'style', { position: 'fixed', bottom: 0, right: 0, width: '100vw', height: '0px', border: 'none', outline: 'none' }), _defineProperty(_ref20, 'onFocus', function onFocus() { return console.log('focused gained'); }), _defineProperty(_ref20, 'onBlur', function onBlur() { return console.log('focused lost'); }), _defineProperty(_ref20, 'onCopy', _this.onCopy), _defineProperty(_ref20, 'onPaste', _this.onPaste), _ref20; }, _this.gridContainerRefHandler = function (node) { return _this.gridContainer = node; }, _this.clipboardHelperRefHandler = function (node) { return _this.clipboardHelper = node; }, _this.onCopy = function (e) { var selection = (0, _selectionUtil.normalizeSelection)(_this.state); console.log('copied selectio', selection); var data = _this.state.view; var headers = _this.props.headers; var selectedData = (0, _selectionUtil.getSelectedData)({ headers: headers, data: data }, selection); console.log('copied data', selectedData); var rawClipboardData = (0, _clipboardUtils.toClipboardData)(selectedData); console.log('copied clip board data', rawClipboardData); var clipboardInfo = (0, _data.fromNullable)(e.clipboardData).map(function (clipboard) { return { evt: e, clipboard: clipboard }; }); (0, _data.fromNullable)(_clipboardUtils.copyToClipboard).ap(clipboardInfo).ap((0, _data.Just)(rawClipboardData)); }, _this.pastedToBatchUpdate = function (_ref21) { var columnIndex = _ref21.columnIndex, rowIndex = _ref21.rowIndex, dataSet = _ref21.dataSet; console.log('pasting to ', 'row[' + rowIndex + ']:col[' + columnIndex + ']', dataSet); var updatedData = []; var view = _this.state.view; var headers = _this.props.headers; for (var y = rowIndex, dy = 0; y < view.length && dy < dataSet.length; y++, dy++) { console.log('pasting rowIndex from ', dy, ' to ', y); var dataSetRow = dataSet[dy]; var currentRow = view[y]; var editedRow = _extends({}, currentRow); for (var x = columnIndex, dx = 0; x < headers.length && dx < dataSetRow.length; x++, dx++) { var header = headers[x]; var _ident = header.ident; if (_this.isEditable({ header: header, rowData: currentRow })) { // TODO: hadle special cases for selection types as well as numbers // look to row editro editedRow[_ident] = dataSetRow[dx]; } } updatedData.push({ currentRow: currentRow, editedRow: editedRow }); } // console.log('final edit ops', updatedData) return updatedData; }, _this.deleteSelection = function () { var selection = (0, _selectionUtil.normalizeSelection)(_this.state); var _this$state = _this.state, x1 = _this$state.x1, x2 = _this$state.x2, y1 = _this$state.y1, y2 = _this$state.y2; var headers = _this.props.headers; var view = _this.state.view; console.log('deleting selection', selection); console.log('view is', view, 'heder is', headers); var updates = (0, _range2.default)(y1, y2 + 1).map(function (row) { return view[row]; }).map(function (currentRow) { return { currentRow: currentRow, editedRow: _extends({}, currentRow, (0, _range2.default)(x1, x2 + 1).filter(function (col) { return _this.isEditable({ header: headers[col], rowData: currentRow }); }).map(function (col) { return _defineProperty({}, headers[col].ident, null); }).reduce(function (a, b) { return _extends({}, a, b); }, {})) }; }); // console.log('updates are ', updates) _this.batchUpdate(updates); }, _this.batchUpdate = function (updates) { console.log('batch updates are', updates); if (_this.props.onBatchUpdate) { console.log('batch update'); // expect new data to be passed down via props _this.props.onBatchUpdate(updates.map(_this.processUpdate), _this.focusGrid); } else if (_this.props.onEdit) { console.log('on Edit'); for (var i = 0; i < updates.length; i++) { _this.props.onEdit(_this.processUpdate(updates[i]), _this.focusGrid); } } else { console.log('self-controlled'); var updateState = _this.setEditInfo((0, _editEngine.batchUpdateRow)({ editInfo: _this.editInfo(), updates: updates.map(_this.processUpdate) })); _this.setState(function (_) { return updateState ? _extends({}, _this.generateViewProps(), { editingRow: undefined, editingColumn: undefined }) : { editingRow: undefined, editingColumn: undefined }; }, _this.focusGrid); } if (_this.props.dataDidUpdate) { _this.props.dataDidUpdate({ mode: 'batched', editRecords: updates.map(_this.processUpdate) }); } }, _this.onPaste = function (e) { e.preventDefault(); var selection = (0, _utils.fromEmpty)((0, _selectionUtil.normalizeSelection)(_this.state)); var clipboardData = (0, _clipboardUtils.fromPasteEvent)(e); (0, _data.Just)(_clipboardUtils.normalizePasteInfo).ap(selection).ap(clipboardData).map(_this.pastedToBatchUpdate).map(_this.batchUpdate).getOrElse(''); }, _temp), _possibleConstructorReturn(_this, _ret2); } /* compond components */ _createClass(Grid, [{ key: 'getChildContext', value: function getChildContext() { return _defineProperty({}, _constants.SCROLL_SYNC_CONTEXT, this.scrollSync); } }, { key: 'componentDidMount', value: function componentDidMount() { window.document.body.addEventListener('mouseup', this.bodyMouseRelease); window.document.body.addEventListener('mouseleave', this.bodyMouseRelease); if (this.clipboardHelper && this.clipboardHelper.focus) { console.log('found clipboard helper', this.clipboardHelper); this.clipboardHelper.focus(); if (this.clipboardHelper.nodeName !== 'INPUT') { console.log('clipboardHelper is not input. please render input with getClipboardHelperProps'); } } else { console.log('Please render an INPUT element with getClipboardHelperProps to support copy&paste.'); } } }, { key: 'componentWillUnmount', value: function componentWillUnmount() { window.document.body.removeEventListener('mouseleave', this.bodyMouseRelease); window.document.body.removeEventListener('mouseup', this.bodyMouseRelease); } }, { key: 'componentWillReceiveProps', value: function componentWillReceiveProps(nextProps) { var _this2 = this; var _props = this.props, data = _props.data, sortOptions = _props.sortOptions, fuzzyFilter = _props.fuzzyFilter, currentPage = _props.currentPage, editInfo = _props.editInfo; if (data !== nextProps.data || sortOptions !== nextProps.sortOptions || fuzzyFilter !== nextProps.fuzzyFilter || currentPage !== nextProps.currentPage || editInfo !== nextProps.editInfo) { this.setState(function (_ref24) { var editingRow = _ref24.editingRow, editingColumn = _ref24.editingColumn, x1 = _ref24.x1, x2 = _ref24.x2, y1 = _ref24.y1, y2 = _ref24.y2, currentPage = _ref24.currentPage; return _extends({}, _this2.generateViewProps({ data: data !== nextProps.data ? nextProps.data : data, sortOptions: sortOptions !== nextProps.sortOptions ? nextProps.sortOptions : undefined, fuzzyFilter: fuzzyFilter !== nextProps.fuzzyFilter ? nextProps.fuzzyFilter : fuzzyFilter, currentPage: _this2.isPagingControlled() && _this2.props.currentPage !== nextProps.currentPage ? nextProps.currentPage : currentPage, editInfo: editInfo !== nextProps.editInfo ? nextProps.editInfo : _this2.editInfo() }), { editingRow: data !== nextProps.data ? undefined : editingRow, editingColumn: data !== nextProps.data ? undefined : editingColumn }); }, this.selectionChanged); } } /* paging starts */ /* paging ends */ /* sorting starts */ }, { key: 'sortOptions', value: function sortOptions() { return this.isSortControlled() ? this.props.sortOptions : this.state.sortOptions; } /* sorting ends */ /* selection starts */ }, { key: 'startSelectionState', value: function startSelectionState(rowIndex, columnIndex) { this.selecting = this.props.selectionMode === 'multi' && true; return { x1: columnIndex, y1: rowIndex, x2: columnIndex, y2: rowIndex }; } }, { key: 'expandSelectionState', value: function expandSelectionState(rowIndex, columnIndex, ended) { if (this.selecting && this.props.selectionMode === 'multi') { this.selecting = ended ? false : this.selecting; return { y2: rowIndex, x2: columnIndex }; } } /** this is for external listeners only */ }, { key: 'hoverState', /* selection ends */ /* hover starts */ value: function hoverState(rowIndex, columnIndex) { var hoverType = this.props.hoverType; return hoverType === 'cell' ? { hoveredRow: rowIndex, hoveredColumn: columnIndex } : { hoveredRow: rowIndex }; } /* hover ends */ /* editing starts */ }, { key: 'edit', value: function edit(rowIndex, columnIndex) { var header = this.props.headers[columnIndex]; var rowData = this.state.view[rowIndex]; if (this.isEditable({ header: header, rowData: rowData })) { this.setState({ editingRow: rowIndex, editingColumn: columnIndex }); } } }, { key: 'isGridEditing', value: function isGridEditing() { var editingRow = this.state.editingRow; var showAdd = this.props.showAdd; return showAdd || !(0, _isNil2.default)(editingRow); } }, { key: 'isRowEditing', value: function isRowEditing() { var editingRow = this.state.editingRow; var _props2 = this.props, showAdd = _props2.showAdd, editMode = _props2.editMode; return showAdd || editMode === 'row' && !(0, _isNil2.default)(editingRow); } }, { key: 'isCellEditing', value: function isCellEditing(rowIndex, columnIndex) { var editMode = this.props.editMode; var _state = this.state, editingRow = _state.editingRow, editingColumn = _state.editingColumn; return editMode === 'cell' && rowIndex === editingRow && columnIndex === editingColumn; } }, { key: 'undoEdit', value: function undoEdit() {} /* todo implemented via short-cut key */ /* editing ends */ /** prop getters */ }, { key: 'render', value: function render() { console.log('grid renderer.... '); var view = this.state.view; return this.props.render({ getColumnHeaderProps: this.getColumnHeaderProps, getRowProps: this.getRowProps, getCellProps: this.getCellProps, getContainerProps: this.getGridContainerProps, getPagerProps: this.getPagerProps, getRowEditorProps: this.getRowEditorProps, getClipboardHelperProps: this.getClipboardHelperProps, headers: this.props.headers, data: view, hasPaging: this.hasPaging(), renderRowEditor: this.props.renderRowEditor, getSelectionInfo: this.getSelectionInfo }); } }]); return Grid; }(_react2.default.PureComponent); Grid.SyncedScrollPane = _ScrollPane2.default; Grid.propTypes = { render: _propTypes2.default.func.isRequired, data: _propTypes2.default.array.isRequired, headers: _propTypes2.default.array.isRequired, selectionMode: _propTypes2.default.oneOf(['single', 'multi']).isRequired, selectionType: _propTypes2.default.oneOf(['row', 'cell']).isRequired, hoverType: _propTypes2.default.oneOf(['row', 'cell']).isRequired, sortEnabled: _propTypes2.default.bool.isRequired, isEditable: _propTypes2.default.oneOfType([_propTypes2.default.bool, _propTypes2.default.func]).isRequired, editMode: _propTypes2.default.oneOf(['row', 'cell']).isRequired, /* optional stuff */ sortOptions: _propTypes2.default.array, onSortOptionsChange: _propTypes2.default.func, fuzzyFilter: _propTypes2.default.string, totalPages: _propTypes2.default.number, currentPage: _propTypes2.default.number, onPageChange: _propTypes2.default.number, rowsPerPage: _propTypes2.default.number, // this handles row edits onEdit: _propTypes2.default.func, showAdd: _propTypes2.default.bool, addWithSelected: _propTypes2.default.bool, onSelectionChange: _propTypes2.default.func, renderRowEditor: _propTypes2.default.func, // this handles cell edits onEditInfoChange: _propTypes2.default.func, // define shpae of editInfo editInfo: _propTypes2.default.object, mapEditRow: _propTypes2.default.func, processEditedRow: _propTypes2.default.func }; Grid.defaultProps = { selectionType: 'cell', selectionMode: 'multi', hoverType: 'row', editMode: 'row', sortEnabled: true, isEditable: false, showAdd: false, addWithSelected: false, renderRowEditor: function renderRowEditor(props) { return _react2.default.createElement(_RowEditor2.default, props); }, processEditedRow: noopEditRowProcess }; Grid.childContextTypes = _defineProperty({}, _constants.SCROLL_SYNC_CONTEXT, _propTypes2.default.object.isRequired); Grid.ROW_INDEX_ATTRIBUTE = _constants.ROW_INDEX_ATTRIBUTE; Grid.COLUMN_INDEX_ATTRIBUTE = _constants.COLUMN_INDEX_ATTRIBUTE; exports.default = Grid; //# sourceMappingURL=Grid.js.map