UNPKG

ffr-components

Version:

Fiori styled UI components

619 lines (499 loc) 19.3 kB
import _extends from "@babel/runtime/helpers/esm/extends"; import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray"; import _defineProperty from "@babel/runtime/helpers/esm/defineProperty"; import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray"; import _classCallCheck from "@babel/runtime/helpers/esm/classCallCheck"; function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } import React, { useEffect, useState, useContext, useRef } from 'react'; import oType from '../utils'; import { SELECTION, DEFAULT_ROW_GROUP } from './constant'; import { calculateRowKey } from './tableUtil'; export var ComponentContext = React.createContext({}); var TableProvider = ComponentContext.Provider, TableConsumer = ComponentContext.Consumer; export { TableProvider, TableConsumer }; var contextID = 0; var TableContext = function TableContext(props) { var _this = this; _classCallCheck(this, TableContext); this.fixLastLineColumns = function (rows, targetArray) { var deep = rows.length - 1; var fixLast = function fixLast(rows, i) { rows.forEach(function (col) { if (col.rowSpan && col.rowSpan > 1) { targetArray.push(col); } else if (i === deep) { targetArray.push(col); } else if (col.children) { fixLast(col.children, i + 1); } }); }; if (deep === 0) { targetArray.push.apply(targetArray, _toConsumableArray(rows[0])); } else { fixLast(rows[0], 0); } }; this.fixColumns = function (rows) { _this.store.left = []; _this.store.right = []; _this.store.center = []; var moveChildren = function moveChildren(children, i, stack) { var targetStack = stack[i] || (stack[i] = []); children.forEach(function (chi) { var target = rows[i].find(function (c) { return c.key === chi.key; }); targetStack.push(target); if (target.children) { moveChildren(target.children, i + 1, stack); } }); }; rows[0].forEach(function (col) { var target = col.fixed === undefined ? 'center' : col.fixed.trim().toLowerCase(); var row = _this.store[target][0] || (_this.store[target][0] = []); row.push(col); if (col.children) { moveChildren(col.children, 1, _this.store[target]); } }); }; this.updateRowHeight = function (height) { if (Number(height) > Number(_this.store.contentRowHeight)) { _this.store.contentRowHeight = height; _this.notifyAll('contentRowHeight', height); } }; this.updateCurrentHoverRow = function (key) { if (key !== _this.store.currentHoverRow) { if (_this.store.currentHoverRow) { _this.rowBasedNotify('currentHoverRow', _this.store.currentHoverRow, false); } _this.store.currentHoverRow = key; _this.rowBasedNotify('currentHoverRow', key, true); } }; this.rowBasedNotify = function (attribute, rowKey, value) { if (_this.listeners[attribute]) { Object.keys(_this.listeners[attribute]).forEach(function (root) { if (_this.listeners[attribute][root][rowKey]) { _this.listeners[attribute][root][rowKey](attribute, value); } }); } }; this.updateHeaderHeight = function (height) { if (_this.store.headerHeight !== height) { _this.store.headerHeight = height; _this.notifyAll('headerHeight', height); } }; this.updateScrollbarWidth = function (width) { if (_this.store.scrollbarWidth !== width) { _this.store.scrollbarWidth = width; _this.notifyAll('scrollbarWidth', width); } }; this.updateOuterTableHeight = function (height) { if (_this.store.outerTableHeight !== height) { _this.store.outerTableHeight = height; _this.notifyAll('outerTableHeight', height); } }; this.updateCurrentSorter = function (sorter) { if (_this.store.currentSorter !== sorter) { _this.store.currentSorter = sorter; _this.notifyAll('currentSorter', sorter); } }; this.updateShouldAlignHorizentalScrollbar = function (value) { if (_this.store.shouldAlignHorizentalScrollbar !== value) { _this.store.shouldAlignHorizentalScrollbar = value; _this.notifyAll('shouldAlignHorizentalScrollbar', value); } }; this.updateShouldAlignVerticalScrollbar = function (value) { if (_this.store.shouldAlignVerticalScrollbar !== value) { _this.store.shouldAlignVerticalScrollbar = value; _this.notifyAll('shouldAlignVerticalScrollbar', value); } }; this.updateExpandedRowkeys = function (key, expand) { var index = _this.store.expandedRowkeys.indexOf(key); if (expand && index < 0) { _this.store.expandedRowkeys.push(key); } else if (!expand && index >= 0) { _this.store.expandedRowkeys.splice(index, 1); } _this.notifyAll('expandedRowkeys', _this.store.expandedRowkeys.slice()); }; this.updateData = function () { var data = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; _this.store.data = data.slice(); _this.notifyAll('data', _this.store.data.slice()); }; this.updatOriginData = function () { var data = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; _this.store.originData = data.slice(); }; this.updateSelectAll = function (isSelected) { var targetRecords = []; targetRecords = _this.store.data.filter(function (_data, index) { var rowKey = calculateRowKey(_this.store.dataKey, _data, index); if (!!_this.store.selectedRecords[rowKey] !== isSelected) { _this.updateSelectedRecords(_data, isSelected, rowKey, true); return true; } return false; }); _this.notifyAll('isSelectAll', _this.store.isSelectAll); return targetRecords; }; this.updateSelectedRecords = function (record, isSelected, rowKey, skipNotifyAll) { var selectedRecords = _this.store.selectedRecords; var prevSelectedAll = _this.isSlectedAll(); if (isSelected) { if (selectedRecords[rowKey]) { throw new Error("duplicatede key ".concat(rowKey, " for records")); } selectedRecords[rowKey] = record; } else { selectedRecords[rowKey] = undefined; } var currentSelectAll = _this.isSlectedAll(); if (prevSelectedAll !== currentSelectAll && !skipNotifyAll) { _this.notifyAll('isSelectAll', currentSelectAll); } _this.rowBasedNotify('selectedRecords', rowKey, isSelected); return selectedRecords; }; this.notifyAll = function (attribute, value) { var targets = _this.listeners[attribute] || []; targets.forEach(function (cb) { return cb(attribute, value); }); }; this.transformCheckColumn = function (selection) { var insertCheckColumn = function insertCheckColumn(tableType, column) { if (!Array.isArray(_this.store[tableType][0])) { _this.store[tableType].push([]); } _this.store[tableType][0].unshift(column); _this.store["".concat(tableType, "Last")].unshift(column); }; if (selection) { var fixed = selection.fixed; var selectionColumn = _objectSpread({}, selection, _defineProperty({}, Symbol["for"](SELECTION), true)); if (fixed && fixed !== 'left') { throw new Error('leading check box only support fixed in left side'); } if (fixed || _this.store.left.length > 0) { if (!_this.hasFixedTable()) { _this.store.center = _this.store.rows.slice(); _this.store.centerLast = _this.store.rowsLast.slice(); } insertCheckColumn('left', selectionColumn); } else { insertCheckColumn('rows', selectionColumn); } } }; this.transformColumns = function (columns, selectionColumn) { var path = []; _this.store.rows = []; var hasFixedTable = columns.some(function (col) { return col.fixed !== undefined; }); var transformRow = function transformRow(cols, i) { var row = _this.store.rows[i] || (_this.store.rows[i] = []); cols.forEach(function (col, index) { row.push(col); col.key = col.key || col.attribute; col.rowSpan = col.rowSpan || 1; col.colSpan = col.colSpan || 1; if (path.length > 0 && index !== 0) { path.forEach(function (parent) { parent.colSpan += col.colSpan; }); } if (col.children) { path.push(col); transformRow(col.children, i + 1); } if (index === cols.length - 1) { path.length && path.pop(); } }); }; var setRowSpan = function setRowSpan(rows) { rows.forEach(function (row, index) { row.forEach(function (col) { if (!col.children) { col.rowSpan = rows.length - index; } }); }); }; transformRow(columns, 0); setRowSpan(_this.store.rows); if (hasFixedTable) { _this.fixColumns(_this.store.rows); if (_this.store.left.length > 0) { _this.fixLastLineColumns(_this.store.left, _this.store.leftLast); } if (_this.store.center.length > 0) { _this.fixLastLineColumns(_this.store.center, _this.store.centerLast); } if (_this.store.right.length > 0) { _this.fixLastLineColumns(_this.store.right, _this.store.rightLast); } } else { _this.fixLastLineColumns(_this.store.rows, _this.store.rowsLast); } _this.transformCheckColumn(selectionColumn); }; this.getCurrentFilteredColumn = function () { var last = [].concat(_toConsumableArray(_this.store.leftLast), _toConsumableArray(_this.store.centerLast), _toConsumableArray(_this.store.rightLast), _toConsumableArray(_this.store.rowsLast)); return Object.keys(_this.store.filterCondition).map(function (key) { return last.find(function (col) { return col.attribute === key || col.key === key; }); }); }; this.getLeftFixedColumns = function () { return _this.store.left; }; this.getRightFixedColumns = function () { return _this.store.right; }; this.getChildName = function () { return _this.store.childName; }; this.isCompact = function () { return _this.store.compact; }; this.getCurrentSorter = function () { return _this.store.currentSorter; }; this.getHeaderFocusIndex = function () { return _this.store.headerFocusIndex; }; this.getBodyFocusIndex = function () { return _this.store.bodyFocusIndex; }; this.updateBodyFocusIndex = function (index) { return _this.store.bodyFocusIndex = index; }; this.updateHeaderFocusIndex = function (index) { return _this.store.headerFocusIndex = index; }; this.getCenterColumns = function () { return _this.hasFixedTable() ? _this.store.center : _this.store.rows; }; this.getCenterLastLine = function () { return _this.hasFixedTable() ? _this.store.centerLast : _this.store.rowsLast; }; this.getLeftLastLine = function () { return _this.store.leftLast; }; this.getRightLastLine = function () { return _this.store.rightLast; }; this.getData = function () { return _this.store.data.slice(); }; this.getOriginData = function () { return _this.store.originData.slice(); }; this.hasFixedTable = function () { return _this.store.left.length > 0 || _this.store.right.length > 0; }; this.hasLeftFixedTable = function () { return _this.store.left.length > 0; }; this.hasFixedSelection = function () { return _this.store.selectionColumn && _this.store.selectionColumn.fixed === 'left'; }; this.hasLeftFixedContentTable = function () { return !_this.hasFixedSelection() && _this.store.left.length > 0 || _this.hasFixedSelection() && _this.store.left.length > 1; }; this.hasRightFixedTable = function () { return _this.store.right.length > 0; }; this.getHeaderHeight = function () { return _this.store.headerHeight; }; this.isSlectedAll = function () { return _this.store.isSelectAll; }; this.getSelectionColumn = function () { return Object.assign({}, _this.store.selectionColumn); }; this.getSelectedRecords = function () { return Object.assign({}, _this.store.selectedRecords); }; this.subscribe = function (attribute, cb, fullKey) { if (Object.getOwnPropertyDescriptor(_this.store, attribute) !== undefined) { if (fullKey) { if (!_this.listeners[attribute]) { _this.listeners[attribute] = {}; } else if (Array.isArray(_this.listeners[attribute])) { throw new Error("attribute ".concat(attribute, " mixed subscribe and row based subscribe")); } var splitor = fullKey.search('/'); var rootKey = splitor > 0 ? fullKey.slice(0, splitor) : DEFAULT_ROW_GROUP; var key = splitor > 0 ? fullKey.slice(splitor + 1) : fullKey; if (!_this.listeners[attribute][rootKey]) { _this.listeners[attribute][rootKey] = {}; } if (!_this.listeners[attribute][rootKey][key]) { _this.listeners[attribute][rootKey][key] = cb; } } else { if (_this.listeners[attribute] && _this.listeners[attribute].indexOf(cb) >= 0) return; if (oType.isObject(_this.listeners[attribute])) { throw new Error("attribute ".concat(attribute, " mixed subscribe and row based subscribe")); } _this.listeners[attribute] = _this.listeners[attribute] ? [].concat(_toConsumableArray(_this.listeners[attribute]), [cb]) : [cb]; } } else { throw new Error("attribute ".concat(attribute, " is not in the store")); } }; this.unsubscribe = function (attribute, cb, fullKey) { if (_this.listeners[attribute]) { if (fullKey) { var splitor = fullKey.search('/'); var rootKey = splitor > 0 ? fullKey.slice(0, splitor) : DEFAULT_ROW_GROUP; var key = splitor > 0 ? fullKey.slice(splitor + 1) : fullKey; _this.listeners[attribute][rootKey][key] = undefined; } else { if (!cb) { _this.listeners[attribute] = undefined; } else { if (!Array.isArray(_this.listeners[attribute])) { throw new Error("attribute ".concat(attribute, " mixed subscribe and row based subscribe")); } _this.listeners[attribute].splice(_this.listeners[attribute].indexOf(cb), 1); } } } }; var _selectionColumn = props.selectionColumn, _props$columns = props.columns, _columns = _props$columns === void 0 ? [] : _props$columns, childName = props.childName, dataKey = props.dataKey, filterLabel = props.filterLabel, headerAlignment = props.headerAlignment, _data2 = props.data, compact = props.compact; this.store = { tableID: ++contextID, rows: [], left: [], center: [], right: [], rowsLast: [], leftLast: [], centerLast: [], rightLast: [], selectionColumn: _selectionColumn, contentRowHeight: -1, currentHoverRow: null, headerHeight: -1, outerTableHeight: -1, shouldAlignHorizentalScrollbar: false, shouldAlignVerticalScrollbar: false, scrollbarWidth: 15, expandedRowkeys: [], childName: childName, dataKey: dataKey, filterLabel: filterLabel, headerAlignment: headerAlignment, data: _data2, originData: _data2, filterCondition: {}, selectedRecords: {}, headerFocusIndex: null, bodyFocusIndex: null, currentSorter: null, // { dataKey, value: sortKey sorter} compact: compact, get isSelectAll() { var _this2 = this; var selectedArr = Object.keys(this.selectedRecords).filter(function (k) { return _this2.selectedRecords[k] !== undefined; }); return selectedArr.length === this.data.length && this.data.length > 0; } // set isSelectAll(isSelected) { // this.data.forEach((_data, index) => { // const rowKey = calculateRowKey(this.dataKey, _data, index); // this.rowBasedNotify('selectedRecords', rowKey, isSelected); // }); // } }; this.listeners = {}; this.transformColumns(_columns, _selectionColumn); [].concat(_toConsumableArray(this.store.leftLast), _toConsumableArray(this.store.centerLast), _toConsumableArray(this.store.rightLast), _toConsumableArray(this.store.rowsLast)).forEach(function (col) { if (col.filterable) { _this.store.filterCondition[col.attribute || col.key] = ''; } }); }; export { TableContext as default }; export var connect = function connect() { for (var _len = arguments.length, bindings = new Array(_len), _key = 0; _key < _len; _key++) { bindings[_key] = arguments[_key]; } return function (Component) { var WrappedComponent = React.forwardRef(function (props, ref) { var _useContext = useContext(ComponentContext), tableContext = _useContext.tableContext; var subscriber = useRef(null); var _useState = useState(function () { var notify = function notify(key, value) { setState(function (s) { return _objectSpread({}, s, _defineProperty({}, key, value)); }); }; var current = {}; var initState = (bindings || []).reduce(function (obj, k) { if (Array.isArray(tableContext.store[k])) { obj[k] = tableContext.store[k].slice(); } else { obj[k] = tableContext.store[k]; } current[k] = notify; tableContext.subscribe(k, notify); return obj; }, {}); subscriber.current = current; return initState; }), _useState2 = _slicedToArray(_useState, 2), state = _useState2[0], setState = _useState2[1]; useEffect(function () { return function () { var current = subscriber.current; Object.keys(current).forEach(function (k) { return tableContext.unsubscribe(k, current[k]); }); }; }, [tableContext]); var _props = _objectSpread({}, props, {}, state, { tableContext: tableContext }); return React.createElement(Component, _extends({}, _props, { ref: ref })); }); var comName = Component.displayName || Component.constructor.name; WrappedComponent.displayName = "Connected".concat(comName); return WrappedComponent; }; };