UNPKG

ffr-components

Version:

Fiori styled UI components

449 lines (388 loc) 15.2 kB
import _extends from "@babel/runtime/helpers/esm/extends"; import _defineProperty from "@babel/runtime/helpers/esm/defineProperty"; import _classCallCheck from "@babel/runtime/helpers/esm/classCallCheck"; import _createClass from "@babel/runtime/helpers/esm/createClass"; import _possibleConstructorReturn from "@babel/runtime/helpers/esm/possibleConstructorReturn"; import _getPrototypeOf from "@babel/runtime/helpers/esm/getPrototypeOf"; import _inherits from "@babel/runtime/helpers/esm/inherits"; import classnames from 'classnames'; import React from 'react'; import Icon from '../icon'; import { FormInput } from '../dynamic-form'; import ListGroup, { ListItem } from '../list-group'; import ColGroup from './ColGroup'; import { isLeadingCheckbox, CheckboxHeader } from './LeadingCheckboxRenderer'; import { connect } from './TableContext'; import Popover from '../popover'; import { isDefaultFocusAble, generateTableIndex } from './tableUtil'; import oType, { KeyCode } from '../utils'; import { REF_TYPE } from './constant'; var defaultSortDirectionKey = [{ key: 'ascend', text: 'Ascending', sapIcon: 'sort-ascending' }, { key: 'descend', text: 'Descending', sapIcon: 'sort-descending' }]; export var TableHeader = /*#__PURE__*/ function (_React$Component) { _inherits(TableHeader, _React$Component); function TableHeader(props) { var _this; _classCallCheck(this, TableHeader); _this = _possibleConstructorReturn(this, _getPrototypeOf(TableHeader).call(this, props)); _this.renderFilerItem = function (col, key, onFilter) { var _this$props = _this.props, filterLabel = _this$props.filterLabel, tableContext = _this$props.tableContext; var classes = classnames('ffr-table-menu-item', { 'ffr-table-menu-item-compact': tableContext.isCompact() }); return col.filterable && React.createElement(ListItem, { className: classes }, React.createElement(Icon, { glyph: "filter" }), React.createElement("span", null, filterLabel), React.createElement(FormInput, { className: "fd-input", onKeyDown: onFilter, value: _this.state[key] || '', onChange: function onChange(e) { return _this.onFilterChange(e, key); } })); }; _this.sortTable = function (sortKey, data, comparedCol) { var tableContext = _this.props.tableContext; var currentSorter = tableContext.getCurrentSorter(); if (!currentSorter && !comparedCol) { return; } /* when sorted by one column, then remove filter from another column, that filtered column is not the sorted column, even not in same table */ var sorter = comparedCol ? comparedCol.sorter : currentSorter.sorter; var dataKey = comparedCol ? _this.getDataKey(comparedCol) : currentSorter.dataKey; if (oType.isFunction(sorter.sortFunction)) { data.sort(function () { var _sorter$sortFunction; for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } return (_sorter$sortFunction = sorter.sortFunction).call.apply(_sorter$sortFunction, [sorter].concat(args, [sortKey])); }); } else { var _ascendSortFunction = function _ascendSortFunction(a, b) { var firstAsString = String(a[dataKey]); var secondAsString = String(b[dataKey]); if (firstAsString < secondAsString) { return -1; } else if (firstAsString > secondAsString) { return 1; } else { return 0; } }; if (sortKey === 'ascend') { data.sort(_ascendSortFunction); } else { data.sort(_ascendSortFunction).reverse(); } } }; _this.renderSortItem = function (col, popRef) { var sorter = col.sorter; var tableContext = _this.props.tableContext; if (!sorter) { return null; } var onSortTable = function onSortTable(e, key) { var tableContext = _this.props.tableContext; var data = tableContext.getData() || []; var dataKey = _this.getDataKey(col); var currentSorter = tableContext.getCurrentSorter(); popRef.current.triggerBody(); if (!currentSorter || currentSorter.dataKey !== dataKey || currentSorter.value !== key) { _this.sortTable(key, data, col); tableContext.updateData(data); tableContext.updateCurrentSorter({ dataKey: dataKey, value: key, sorter: sorter }); } }; var sorterList = sorter.sortDirections || defaultSortDirectionKey; var classes = classnames('ffr-table-menu-item', { 'ffr-table-menu-item-compact': tableContext.isCompact() }); return sorterList.map(function (sorter, inx) { return React.createElement(ListItem, { key: sorter.key, className: classes, onClick: function onClick(e) { return onSortTable(e, sorter.key); } }, sorter.sapIcon && React.createElement(Icon, { glyph: sorter.sapIcon }), React.createElement("span", null, sorter.text)); }); }; _this.wrapWithMenu = function (control, col, isLast) { var _this$props2 = _this.props, tableContext = _this$props2.tableContext, filterCondition = _this$props2.filterCondition; var key = col.attribute || col.key; var popRef = React.createRef(); var onFilter = function onFilter(e) { var keyCode = e.keyCode; if (keyCode !== KeyCode.ENTER) return; var data = tableContext.getData(); var value = _this.state[key]; var filterSingleCondition = function filterSingleCondition(val, _data, _col) { if (_col.onFilter) { return _col.onFilter(val, _data); } else { return _data.filter(function (__data) { return String(__data[_col.attribute]).indexOf(val) >= 0; }); } }; var changeMode = function changeMode() { if (!filterCondition[key] && value) { return 'A'; } if (value === filterCondition[key]) return 'N'; if (!value) return 'D'; return 'C'; }; var mode = changeMode(); if (mode === 'N') { return; } filterCondition[key] = value; var results = []; if (mode === 'C' || mode === 'D') { var currentSorter = tableContext.getCurrentSorter(); var fullData = tableContext.getOriginData(); var cols = tableContext.getCurrentFilteredColumn(); results = Object.keys(filterCondition).reduce(function (_data, k) { if ((col.attribute === k || col.key === k) && mode === 'D') return _data; var targetCol = cols.find(function (clm) { return clm.attribute === k || clm.key === k; }); var val = filterCondition[k]; return filterSingleCondition(val, _data, targetCol); }, fullData); if (currentSorter) { _this.sortTable(currentSorter.value, results); } } else { results = filterSingleCondition(value, data, col); } popRef.current.triggerBody(); tableContext.updateData(results); if (tableContext.getSelectionColumn()) { tableContext.updateSelectAll(false); } }; var menu = React.createElement(ListGroup, { className: "ffr-table-menu" }, _this.renderSortItem(col, popRef), _this.renderFilerItem(col, key, onFilter)); return React.createElement(React.Fragment, null, React.createElement(Popover, { ref: popRef, body: menu, control: control, placement: isLast && _this.isLastTableHeader ? Popover.POPPER_PLACEMENTS.bottomEnd : Popover.POPPER_PLACEMENTS.bottomStart, toggleMenu: function toggleMenu(flag) { if (flag && col.filterable) { _this.setState(_defineProperty({}, key, filterCondition[key])); } }, referenceProps: { style: { height: '100%' } }, noArrow: true, popperModifiers: { preventOverflow: { enabled: true, escapeWithReference: true, boundariesElement: 'scrollParent' } } }), React.createElement("span", { className: "ffr-shadow-header" }, col.title)); }; _this.onFilterChange = function (e, key) { var value = e.target.value; _this.setState(_defineProperty({}, key, value)); }; _this.renderSorter = function (col) { var sorter = col.sorter; var tableContext = _this.props.tableContext; var currentSorter = tableContext.getCurrentSorter(); var dKey = _this.getDataKey(col); if (!sorter || !currentSorter) { return null; } var dataKey = currentSorter.dataKey, sorterKey = currentSorter.value; if (dKey !== dataKey) { return null; } var target = (sorter === true || !sorter.sortDirections ? defaultSortDirectionKey : sorter.sortDirections).find(function (ds) { return ds.key === sorterKey; }); var iconStr = target && target.sapIcon; return iconStr ? React.createElement(Icon, { glyph: iconStr, className: "ffr-table-action-id" }) : null; }; _this.renderFilterFlag = function (col) { var filterCondition = _this.props.filterCondition; return filterCondition[col.attribute || col.key] ? React.createElement(Icon, { glyph: "filter", className: "ffr-table-action-id" }) : null; }; _this.getDataKey = function (col) { return col.attribute || col.key; }; _this.assignHeaderRef = function (ref) { var innerHeaderRef = _this.props.innerHeaderRef; _this.headerRef.current = ref; if (typeof innerHeaderRef === 'function') { innerHeaderRef(ref); } else if (innerHeaderRef) { innerHeaderRef.current = ref; } }; var columns = props.columns, fixed = props.fixed, _tableContext = props.tableContext; _this.headerRef = React.createRef(); _this.state = {}; _this.isLastTableHeader = false; var withMenuHeader = false; columns.forEach(function (row) { row.forEach(function (col) { var sorter = col.sorter, filterable = col.filterable; withMenuHeader = withMenuHeader || !!sorter || !!filterable; if (oType.isObject(sorter) && !oType.isFunction(sorter.sortFunction)) { if (Object.keys(sorter).some(function (k) { return defaultSortDirectionKey.every(function (def) { return def.key !== k; }); })) { throw new Error('sortFunction must be supplied if sort key is other than ascend or descend'); } } }); }); if (withMenuHeader) { _this.isLastTableHeader = fixed === 'right' || fixed === undefined && !_tableContext.hasRightFixedTable(); } return _this; } _createClass(TableHeader, [{ key: "componentDidMount", value: function componentDidMount() { var _this$props3 = this.props, tableContext = _this$props3.tableContext, fixed = _this$props3.fixed; var clientHeight = this.headerRef.current.clientHeight; if (!fixed) { tableContext.updateHeaderHeight(clientHeight); } } }, { key: "render", value: function render() { var _this2 = this; var _this$props4 = this.props, columns = _this$props4.columns, lastLine = _this$props4.lastLine, headerAlignment = _this$props4.headerAlignment, tableID = _this$props4.tableID, tableContext = _this$props4.tableContext, fixed = _this$props4.fixed, handleMoveFocus = _this$props4.handleMoveFocus; var className = classnames('fd-table__header', "ffr-align-".concat(headerAlignment), { 'ffr-multiple-header': columns.length > 1 }); return React.createElement(React.Fragment, null, React.createElement(ColGroup, { lastColumns: lastLine }), React.createElement("thead", { ref: this.assignHeaderRef, className: className }, columns.map(function (row, rowInx) { return React.createElement("tr", { key: rowInx, role: "row", className: "fd-table__row" }, row.map(function (col, inx) { var thProps = {}; var isLast = inx === row.length - 1; if (col.colSpan) { thProps.colSpan = col.colSpan; } if (col.rowSpan) { thProps.rowSpan = col.rowSpan; } var classes = classnames('fd-table__cell', { 'ffr-clickable-column': col.filterable || col.sorter }); var contentClass = classnames({ 'ffr-clickable-content': col.filterable || col.sorter }); if (isLeadingCheckbox(col)) { return React.createElement(CheckboxHeader, { col: col, className: classes, spanProps: thProps, key: inx, fixed: fixed, handleMoveFocus: handleMoveFocus }); } var thComponent = React.createElement("div", { className: "".concat(contentClass, " ffr-clickable-content-").concat(headerAlignment) }, React.createElement("span", { className: "ffr-column-title", id: "".concat(tableID, "-l").concat(rowInx, "-h").concat(inx) }, col.title), col.sorter ? _this2.renderSorter(col) : null, col.filterable ? _this2.renderFilterFlag(col) : null); var tabIndex = rowInx === columns.length - 1 && isDefaultFocusAble(tableContext, fixed, inx) ? 0 : -1; var dataIndex = generateTableIndex(REF_TYPE.header, fixed, rowInx, inx); if (tabIndex === 0) { tableContext.updateHeaderFocusIndex(dataIndex); } return React.createElement("th", _extends({ key: col.key || col.attribute }, thProps, { className: classes, role: "columnheader", "aria-labelledby": "".concat(tableID, "-l").concat(rowInx, "-h").concat(inx), tabIndex: tabIndex, "data-index": dataIndex, onKeyDown: handleMoveFocus }), col.filterable || col.sorter ? _this2.wrapWithMenu(thComponent, col, isLast) : thComponent); })); }))); } }]); return TableHeader; }(React.Component); TableHeader.defaultProps = { columns: [], handleMoveFocus: function handleMoveFocus() {} }; TableHeader.displayName = 'TableHeader'; export default connect('headerAlignment', 'filterLabel', 'filterCondition', 'tableID', 'currentSorter')(TableHeader);