ffr-components
Version:
Fiori styled UI components
619 lines (499 loc) • 19.3 kB
JavaScript
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;
};
};