UNPKG

@aappddeevv/dynamics-client-ui

Version:

## What is it? A library to help you create great dynamics applications.

485 lines (401 loc) 18 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.wrapTH = exports.wrapTD = exports.HorizontalScrollBar = exports.colLenses = exports.addTitleTransformer = exports.CrmTable = undefined; var _extends2 = require('babel-runtime/helpers/extends'); var _extends3 = _interopRequireDefault(_extends2); var _objectWithoutProperties2 = require('babel-runtime/helpers/objectWithoutProperties'); var _objectWithoutProperties3 = _interopRequireDefault(_objectWithoutProperties2); var _getPrototypeOf = require('babel-runtime/core-js/object/get-prototype-of'); var _getPrototypeOf2 = _interopRequireDefault(_getPrototypeOf); var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck'); var _classCallCheck3 = _interopRequireDefault(_classCallCheck2); var _createClass2 = require('babel-runtime/helpers/createClass'); var _createClass3 = _interopRequireDefault(_createClass2); var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn'); var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2); var _inherits2 = require('babel-runtime/helpers/inherits'); var _inherits3 = _interopRequireDefault(_inherits2); exports.controlOverflow = controlOverflow; var _react = require('react'); var React = _interopRequireWildcard(_react); var _reactabularTable = require('reactabular-table'); var Table = _interopRequireWildcard(_reactabularTable); var _reactabularSticky = require('reactabular-sticky'); var Sticky = _interopRequireWildcard(_reactabularSticky); var _sortabular = require('sortabular'); var sort = _interopRequireWildcard(_sortabular); var _orderBy = require('lodash/orderBy'); var _orderBy2 = _interopRequireDefault(_orderBy); var _selectabular = require('selectabular'); var select = _interopRequireWildcard(_selectabular); var _Ellipsis = require('./Ellipsis'); var _Ellipsis2 = _interopRequireDefault(_Ellipsis); var _BuildSettings = require('BuildSettings'); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var R = require("ramda"); // Similar searches augments var styles = require("./CrmTable.css"); var fstyles = require("../Dynamics/flexutilities.css"); var cx = require("classnames"); /** * Simple CRM styled table. Component can managed data state * or you can pass in data through props "data". The table can perform * local sorting so index based tracking of selection does not make * alot of sense. * * @param data Data for grid if dataSource is null. * @param columns Ready to go column array. * @param sortingColumns Sorting state per the manual. * @param dataSource Create a Promise that returns an array of data. Overrides `data`. Component * will ignore data coming through props if dataSource is defined. * @param columnGenerator Function to generate columns. Called with sortable. * @param onSelectIndex Callback. Provides selected index. (only single selection?) * @param onSelectId Callback. Provides selected id, if defined. * @param selectedId Selected entity id or null. * @param {string} idAttr Attribute of an entities' identity i.e. "id" attribute. Defaults to "id". */ var CrmTable = exports.CrmTable = function (_React$Component) { (0, _inherits3.default)(CrmTable, _React$Component); function CrmTable(props) { (0, _classCallCheck3.default)(this, CrmTable); var _this = (0, _possibleConstructorReturn3.default)(this, (CrmTable.__proto__ || (0, _getPrototypeOf2.default)(CrmTable)).call(this, props)); _this.doScroll = function (e) { _this.tableHeader.scrollLeft = e.target.scrollLeft; _this.tableBody.scrollLeft = e.target.scrollLeft; }; _this.onSelectRowByIndex = function (byIndex, byId, rows) { return function (idx) { return _this.reportBack(byIndex, byId, null, rows, idx); }; }; _this.onRow = function (byIndex, byId, selectedRowIndex) { return function (row, _ref) { var rowIndex = _ref.rowIndex; //console.log("onRow",selectedRowIndex, rowIndex) return { className: cx(rowIndex % 2 ? "oddRow" : "evenRow", (row.selected || selectedRowIndex === rowIndex) && styles.selected), onClick: function onClick() { return _this.reportBack(byIndex, byId, row[_this.state.idAttr], null, rowIndex); } }; }; }; _this.reportBack = function (byIndex, byId, id, rows, idx) { if (byIndex && idx !== null) byIndex(idx); // should reverse engineer index if rows, id are defined if (byId && !R.isNil(id)) byId(id);else if (!R.isNil(idx) && rows && byId) { var idAttr = _this.state.idAttr; var _id = rows[idx][idAttr]; if (!R.isNil(_id)) byId(_id); } }; var getSortingColumns = function getSortingColumns() { return _this.state.sortingColumns || []; }; _this.state = { data: null, dataInternallyManaged: false, // whether data is internally managed columns: props.columns || [], dataSource: props.dataSource, sortingColumns: props.sortingColumns || {}, originalSortingColumns: props.sortingColumns || {}, columnGenerator: props.columnGenerator, strategy: props.strategy || sort.strategies.byProperty, getSortingColumns: props.getSortingColumns || getSortingColumns, sortable: props.sortable || null, resetable: props.resetable || null, idAttr: props.idAttr || "id" }; _this.tableHeader = null; _this.tableBody = null; if (!_this.state.sortable) { _this.state.sortable = sort.sort({ getSortingColumns: _this.state.getSortingColumns, strategy: _this.state.strategy, onSort: function onSort(selectedColumn) { _this.setState({ sortingColumns: sort.byColumn({ sortingColumns: _this.state.sortingColumns, selectedColumn: selectedColumn }) }); } }); } if (!_this.state.resetable) { _this.state.resetable = sort.reset({ event: 'onDoubleClick', getSortingColumns: _this.state.getSortingColumns, onReset: function onReset(_ref2) { var sortingColumns = _ref2.sortingColumns; return _this.setState({ sortingColumns: sortingColumns }); }, strategy: _this.state.strategy }); } _this.refreshData = _this.refreshData.bind(_this); return _this; } /** Call from external scrollbar. */ (0, _createClass3.default)(CrmTable, [{ key: 'componentWillMount', value: function componentWillMount() { var gen = this.state.columnGenerator; if (gen) { //console.log("CrmTable: Generating columns"); this.setState({ columns: gen({ getSortingColumns: this.state.getSortingColumns, strategy: this.state.strategy, sortable: this.state.sortable, resetable: this.state.resetable }) }); } } }, { key: 'componentDidMount', value: function componentDidMount() { this.forceUpdate(); this.refreshData(); } }, { key: 'refreshData', value: function refreshData() { var _this2 = this; if (this.state.dataSource) { this.state.dataSource(this.state).then(function (data) { _this2.setState({ data: data, dataInternallyManaged: true }); }).catch(function (e) { // not sure the issue console.log("CrmTable: error obtaining data", e); _this2.setState({ dataInternallyManaged: true }); }); } } }, { key: 'render', value: function render() { var _this3 = this; var _state = this.state, data = _state.data, columns = _state.columns, sortingColumns = _state.sortingColumns, dataInternallyManaged = _state.dataInternallyManaged; if (!dataInternallyManaged) { data = this.props.data || data; } var _props = this.props, onSelectIndex = _props.onSelectIndex, onSelectId = _props.onSelectId, selectedId = _props.selectedId, className = _props.className; // add some non-invasive properties to all columns if they render it columns = columns.map(function (c) { var current = R.view(colLenses.transforms, c) || []; return R.set(colLenses.transforms, current.concat([addTitleTransformer]), c); }); // Pre-sort if sorting criteria is set. var sortedData = sort.sorter({ columns: columns, sortingColumns: sortingColumns, strategy: this.state.strategy, sort: _orderBy2.default })(data); // Identify selected rows. Selected rows will be modified // with a property added "selected: boolean" which means they will be re-rendered and // onRow called again on those rows only. var _ref3 = this.state.idAttr && selectedId ? R.pipe(select.none, // set selected = false select.rows(function (row) { return row[_this3.state.idAttr] === selectedId; }))(sortedData) : { rows: sortedData, selectedRows: [] // After sorting and selection, find selectedRowIndex }, rows = _ref3.rows, selectedRows = _ref3.selectedRows; var selectedRowIndex = this.state.idAttr && selectedId ? R.findIndex(R.propEq(this.state.idAttr, selectedId))(rows) : -1; // add some space for a scrollbar if one is needed ever var totalColumnsWidth = columns.reduce(function (sum, c) { return sum += c.props.style.minWidth; }, 0) + 17; if (_BuildSettings.DEBUG) console.log("totalColumnsWidth", totalColumnsWidth); var tableWidth = totalColumnsWidth; //const tableHeight= this.props.tableHeight || 250 var tableStyle = { width: tableWidth, clear: "none" }; var tableHeaderStyle = { maxWidth: tableWidth, overflow: "hidden" }; var tableBodyStyle = { maxWidth: tableWidth, //maxHeight: tableHeight, overflow: "auto" //console.log("CrmTable.props", {selectedId, data}, selectedRowIndex) // select.byArrowKeys introduces a in-the-wild div. };return React.createElement( 'div', { className: cx(fstyles.flexVertical, styles.wrapper, className), 'data-ctag': 'CrmTable' }, select.byArrowKeys({ rows: sortedData, selectedRowIndex: selectedRowIndex, onSelectRow: this.onSelectRowByIndex(onSelectIndex, onSelectId, rows) })(React.createElement( Table.Provider, { className: styles.crmTable, columns: columns, style: tableStyle, components: { header: { cell: wrapTH }, body: { cell: wrapTD } } }, React.createElement(Sticky.Header, { ref: function ref(h) { _this3.tableHeader = h && h.getRef(); }, tableBody: this.tableBody, style: tableHeaderStyle, onScroll: this.doScroll }), React.createElement(Sticky.Body, { className: styles.crmBody, onRow: this.onRow(onSelectIndex, onSelectId, selectedRowIndex), rows: rows, rowKey: this.props.rowKey, ref: function ref(b) { _this3.tableBody = b && b.getRef(); }, tableHeader: this.tableHeader, onScroll: this.doScroll, style: tableBodyStyle }) )), React.createElement(HorizontalScrollBar, { className: fstyles.flexNone, width: tableWidth, scrollWidth: totalColumnsWidth, left: 0, top: 0, onScroll: this.doScroll }) ); } }]); return CrmTable; }(React.Component); CrmTable.defaultProps = { rowKey: "id", idAttr: "id" }; exports.default = CrmTable; /** Take the property value for a cell and add a title property. */ var addTitleTransformer = exports.addTitleTransformer = function addTitleTransformer(value, ctx) { return { title: value }; }; /** Column lenses. */ var colLenses = exports.colLenses = { transforms: R.lensPath(["cell", "transforms"]), formatters: R.lensPath(["cell", "formatters"]) /** * See: https://reactabular.js.org/#/examples/header-body-aligned */ }; var HorizontalScrollBar = exports.HorizontalScrollBar = function (_React$PureComponent) { (0, _inherits3.default)(HorizontalScrollBar, _React$PureComponent); function HorizontalScrollBar() { (0, _classCallCheck3.default)(this, HorizontalScrollBar); return (0, _possibleConstructorReturn3.default)(this, (HorizontalScrollBar.__proto__ || (0, _getPrototypeOf2.default)(HorizontalScrollBar)).apply(this, arguments)); } (0, _createClass3.default)(HorizontalScrollBar, [{ key: 'render', value: function render() { var _props2 = (0, _extends3.default)({}, this.props), width = _props2.width, scrollWidth = _props2.scrollWidth, left = _props2.left, top = _props2.top, props = (0, _objectWithoutProperties3.default)(_props2, ['width', 'scrollWidth', 'left', 'top']); left = left || 0; top = top || 0; var scrollbarOuterStyle = { display: 'inline-block', overflow: 'auto', backgroundColor: 'transparent', position: 'relative', width: width, height: 16, left: { left: left }, top: { top: top } }; var scrollbarInnerStyle = { display: 'inline-block', width: scrollWidth, height: '100%' }; return React.createElement( 'div', (0, _extends3.default)({ style: scrollbarOuterStyle }, props), React.createElement('span', { style: scrollbarInnerStyle }) ); } }]); return HorizontalScrollBar; }(React.PureComponent); function controlOverflow(content, title, _ref4) { var className = _ref4.className; var cls = cx(styles.textOverflowContainer, className); return React.createElement( 'span', { className: cls }, React.createElement( 'span', { className: styles.textOverflowEllipsis, title: title }, content ) ); } var wrapTD = function wrapTD(_ref5) { var children = _ref5.children, className = _ref5.className, title = _ref5.title, rest = (0, _objectWithoutProperties3.default)(_ref5, ['children', 'className', 'title']); //title = typeof title === "string" ? title || null var cls = cx(className); return React.createElement( 'td', (0, _extends3.default)({}, rest, { className: cls, title: title }), React.createElement( _Ellipsis2.default, null, children ) ); }; exports.wrapTD = wrapTD; var wrapTH = function wrapTH(_ref6) { var children = _ref6.children, className = _ref6.className, title = _ref6.title, rest = (0, _objectWithoutProperties3.default)(_ref6, ['children', 'className', 'title']); //title = (typeof title === "string") ? title || null var cls = cx(className); return React.createElement( 'th', (0, _extends3.default)({}, rest, { className: cls }), React.createElement( _Ellipsis2.default, null, children ) ); }; exports.wrapTH = wrapTH; //# sourceMappingURL=CrmTable.js.map