@visactor/vtable
Version:
canvas table width high performance
775 lines (762 loc) • 55.8 kB
JavaScript
import * as sort from "../tools/sort";
import { AggregationType, HierarchyState } from "../ts-types";
import { applyChainSafe, getOrApply, obj, isPromise, emptyFn } from "../tools/helper";
import { EventTarget } from "../event/EventTarget";
import { computeChildrenNodeLength, getValueByPath, isAllDigits } from "../tools/util";
import { arrayEqual, cloneDeep, isNumber, isObject, isValid } from "@visactor/vutils";
import { RecordAggregator, SumAggregator, CountAggregator, MaxAggregator, MinAggregator, AvgAggregator, NoneAggregator, CustomAggregator } from "../ts-types/dataset/aggregation";
function isFieldAssessor(field) {
if (obj.isObject(field)) {
const a = field;
if (isValid(a.get) && isValid(a.set)) return !0;
}
return !1;
}
const EVENT_TYPE = {
SOURCE_LENGTH_UPDATE: "source_length_update",
CHANGE_ORDER: "change_order"
};
export function getValue(value, promiseCallBack) {
const maybePromiseOrValue = getOrApply(value);
if (isPromise(maybePromiseOrValue)) {
const promiseValue = maybePromiseOrValue.then((r => (promiseCallBack(r), r)));
return promiseCallBack(promiseValue), promiseValue;
}
return maybePromiseOrValue;
}
export function getField(record, field, col, row, table, promiseCallBack) {
if (null == record) return;
if (isPromise(record)) return record.then((r => getField(r, field, col, row, table, promiseCallBack)));
const fieldGet = isFieldAssessor(field) ? field.get : field;
if ((void 0 === fieldGet || "" === fieldGet) && Array.isArray(record)) {
return record[col - table.leftRowSeriesNumberCount];
}
if (isObject(record) && fieldGet in record) {
return getValue(record[fieldGet], promiseCallBack);
}
if ("function" == typeof fieldGet) {
return getValue(fieldGet(record, col, row, table), promiseCallBack);
}
if (Array.isArray(fieldGet)) {
return getValue(getValueByPath(record, [ ...fieldGet ]), promiseCallBack);
}
const fieldArray = `${fieldGet}`.split(".");
if (fieldArray.length <= 1) {
return getValue(record[fieldGet], promiseCallBack);
}
return getValue(applyChainSafe(record, ((val, name) => getField(val, name, col, row, table, emptyFn)), ...fieldArray), promiseCallBack);
}
function _getIndex(sortedIndexMap, index) {
if (!sortedIndexMap) return index;
const mapIndex = sortedIndexMap[index];
return isValid(mapIndex) ? mapIndex : index;
}
export class DataSource extends EventTarget {
static get EVENT_TYPE() {
return EVENT_TYPE;
}
constructor(dataSourceObj, dataConfig, pagination, columns, rowHierarchyType, hierarchyExpandLevel) {
var _a;
super(), this.addRecordRule = "Object", this.currentIndexedData = [], this.hierarchyExpandLevel = 0,
this.hasHierarchyStateExpand = !1, this.beforeChangedRecordsMap = new Map, this.registedAggregators = {},
this.rowHierarchyType = "grid", this.fieldAggregators = [], this.addRecordRule = (null == dataConfig ? void 0 : dataConfig.addRecordRule) || "Object",
this.registerAggregators(), this.dataSourceObj = dataSourceObj, this.dataConfig = dataConfig,
this._get = null == dataSourceObj ? void 0 : dataSourceObj.get, this.columns = columns,
this._source = (null == dataSourceObj ? void 0 : dataSourceObj.records) ? this.processRecords(null == dataSourceObj ? void 0 : dataSourceObj.records) : dataSourceObj,
this._sourceLength = (null === (_a = this._source) || void 0 === _a ? void 0 : _a.length) || 0,
this.sortedIndexMap = new Map, this._currentPagerIndexedData = [], this.userPagination = pagination,
this.pagination = pagination || {
totalCount: this._sourceLength,
perPageCount: this._sourceLength,
currentPage: 0
}, hierarchyExpandLevel >= 1 && (this.hierarchyExpandLevel = hierarchyExpandLevel),
this.currentIndexedData = Array.from({
length: this._sourceLength
}, ((_, i) => i)), "tree" === rowHierarchyType && this.initTreeHierarchyState(),
this.rowHierarchyType = rowHierarchyType, this.updatePagerData();
}
initTreeHierarchyState() {
var _a, _b;
this._sourceLength = (null === (_a = this._source) || void 0 === _a ? void 0 : _a.length) || 0,
this.currentIndexedData = Array.from({
length: this._sourceLength
}, ((_, i) => i));
let nodeLength = this._sourceLength;
for (let i = 0; i < nodeLength; i++) {
const indexKey = this.currentIndexedData[i], nodeData = this.getOriginalRecord(indexKey);
if (!nodeData) continue;
const children = null !== (_b = nodeData.filteredChildren) && void 0 !== _b ? _b : nodeData.children;
if ((null == children ? void 0 : children.length) > 0) {
if (this.hierarchyExpandLevel > 1 ? !nodeData.hierarchyState && (nodeData.hierarchyState = HierarchyState.expand) : !nodeData.hierarchyState && (nodeData.hierarchyState = HierarchyState.collapse),
this.hasHierarchyStateExpand = !0, nodeData.hierarchyState === HierarchyState.collapse) continue;
const childrenLength = this.initChildrenNodeHierarchy(indexKey, this.hierarchyExpandLevel, 2, nodeData);
i += childrenLength, nodeLength += childrenLength;
} else !0 === nodeData.children && !nodeData.hierarchyState && (nodeData.hierarchyState = HierarchyState.collapse);
}
}
supplementConfig(pagination, columns, rowHierarchyType, hierarchyExpandLevel) {
var _a;
this.columns = columns, this._sourceLength = (null === (_a = this._source) || void 0 === _a ? void 0 : _a.length) || 0,
this.sortedIndexMap = new Map, this._currentPagerIndexedData = [], this.userPagination = pagination,
this.pagination = pagination || {
totalCount: this._sourceLength,
perPageCount: this._sourceLength,
currentPage: 0
}, hierarchyExpandLevel >= 1 && (this.hierarchyExpandLevel = hierarchyExpandLevel),
this.currentIndexedData = Array.from({
length: this._sourceLength
}, ((_, i) => i)), "tree" === rowHierarchyType && this.initTreeHierarchyState(),
this.rowHierarchyType = rowHierarchyType, this.updatePagerData();
}
registerAggregator(type, aggregator) {
this.registedAggregators[type] = aggregator;
}
registerAggregators() {
this.registerAggregator(AggregationType.RECORD, RecordAggregator), this.registerAggregator(AggregationType.SUM, SumAggregator),
this.registerAggregator(AggregationType.COUNT, CountAggregator), this.registerAggregator(AggregationType.MAX, MaxAggregator),
this.registerAggregator(AggregationType.MIN, MinAggregator), this.registerAggregator(AggregationType.AVG, AvgAggregator),
this.registerAggregator(AggregationType.NONE, NoneAggregator), this.registerAggregator(AggregationType.CUSTOM, CustomAggregator);
}
updateColumns(columns) {
this.columns = columns;
}
_generateFieldAggragations() {
const columnObjs = this.columns;
this.fieldAggregators = [];
const processColumn = column => {
delete column.vtable_aggregator;
const field = column.field, aggregation = column.aggregation;
if (aggregation) if (Array.isArray(aggregation)) for (const item of aggregation) {
const aggregator = new this.registedAggregators[item.aggregationType]({
field: field,
formatFun: item.formatFun,
isRecord: !0,
aggregationFun: item.aggregationFun
});
this.fieldAggregators.push(aggregator), column.vtable_aggregator || (column.vtable_aggregator = []),
column.vtable_aggregator.push(aggregator);
} else {
const aggregator = new this.registedAggregators[aggregation.aggregationType]({
field: field,
formatFun: aggregation.formatFun,
isRecord: !0,
aggregationFun: aggregation.aggregationFun
});
this.fieldAggregators.push(aggregator), column.vtable_aggregator = aggregator;
}
}, traverseColumns = columns => {
if (columns && 0 !== columns.length) for (const column of columns) processColumn(column),
column.columns && traverseColumns(column.columns);
};
traverseColumns(columnObjs);
}
processRecords(records) {
var _a, _b, _c, _d, _e, _f, _g, _h;
this._generateFieldAggragations();
const filteredRecords = [], isHasAggregation = this.fieldAggregators.length >= 1;
if ((null === (_b = null === (_a = this.dataConfig) || void 0 === _a ? void 0 : _a.filterRules) || void 0 === _b ? void 0 : _b.length) >= 1 || (null === (_c = this.lastFilterRules) || void 0 === _c ? void 0 : _c.length) >= 1 || isHasAggregation) {
for (let i = 0, len = records.length; i < len; i++) {
const record = records[i];
null != record && ((null === (_e = null === (_d = this.dataConfig) || void 0 === _d ? void 0 : _d.filterRules) || void 0 === _e ? void 0 : _e.length) >= 1 ? this.filterRecord(record) && (filteredRecords.push(record),
"tree" === this.rowHierarchyType && record.children && (record.filteredChildren = this.filteredChildren(record.children)),
isHasAggregation && this.processRecord(record)) : (null === (_f = this.lastFilterRules) || void 0 === _f ? void 0 : _f.length) >= 1 ? (this.clearFilteredChildren(record),
isHasAggregation && this.processRecord(record)) : isHasAggregation && this.processRecord(record));
}
if ((null === (_h = null === (_g = this.dataConfig) || void 0 === _g ? void 0 : _g.filterRules) || void 0 === _h ? void 0 : _h.length) >= 1) return filteredRecords;
}
return records;
}
filteredChildren(records) {
const filteredRecords = [];
for (let i = 0, len = records.length; i < len; i++) {
const record = records[i];
this.filterRecord(record) && (filteredRecords.push(record), record.children && (record.filteredChildren = this.filteredChildren(record.children)));
}
return filteredRecords;
}
processRecord(record) {
for (let i = 0; i < this.fieldAggregators.length; i++) {
this.fieldAggregators[i].push(record);
}
}
initChildrenNodeHierarchy(indexKey, hierarchyExpandLevel, currentLevel, nodeData) {
var _a, _b, _c;
let childTotalLength = 0;
const nodeLength = nodeData.filteredChildren ? nodeData.filteredChildren.length : null !== (_b = null === (_a = nodeData.children) || void 0 === _a ? void 0 : _a.length) && void 0 !== _b ? _b : 0;
for (let j = 0; j < nodeLength; j++) {
(currentLevel <= hierarchyExpandLevel || nodeData.hierarchyState === HierarchyState.expand) && (childTotalLength += 1);
const childNodeData = nodeData.filteredChildren ? nodeData.filteredChildren[j] : nodeData.children[j], childIndexKey = Array.isArray(indexKey) ? indexKey.concat(j) : [ indexKey, j ];
(currentLevel <= hierarchyExpandLevel || nodeData.hierarchyState === HierarchyState.expand) && this.currentIndexedData.splice(this.currentIndexedData.indexOf(indexKey) + childTotalLength, 0, childIndexKey),
(childNodeData.filteredChildren ? childNodeData.filteredChildren.length > 0 : (null === (_c = childNodeData.children) || void 0 === _c ? void 0 : _c.length) > 0) && (currentLevel < hierarchyExpandLevel || childNodeData.hierarchyState === HierarchyState.expand ? (!childNodeData.hierarchyState && (childNodeData.hierarchyState = HierarchyState.expand),
this.hasHierarchyStateExpand = !0) : !childNodeData.hierarchyState && (childNodeData.hierarchyState = HierarchyState.collapse)),
childNodeData.hierarchyState === HierarchyState.expand && (childTotalLength += this.initChildrenNodeHierarchy(childIndexKey, hierarchyExpandLevel, currentLevel + 1, childNodeData)),
!0 === childNodeData.children && !childNodeData.hierarchyState && (childNodeData.hierarchyState = HierarchyState.collapse);
}
return childTotalLength;
}
updatePagination(pagination) {
this.pagination = pagination || {
totalCount: this._sourceLength,
perPageCount: this._sourceLength,
currentPage: 0
}, this.updatePagerData();
}
updatePagerData() {
const {currentIndexedData: currentIndexedData} = this, {perPageCount: perPageCount, currentPage: currentPage} = this.pagination, startIndex = perPageCount * (currentPage || 0), endIndex = startIndex + perPageCount;
if (this._currentPagerIndexedData.length = 0, currentIndexedData && currentIndexedData.length > 0) {
let firstLevelIndex = -1;
for (let i = 0; i < currentIndexedData.length; i++) if ((Array.isArray(currentIndexedData[i]) && 1 === currentIndexedData[i].length || !Array.isArray(currentIndexedData[i])) && firstLevelIndex++,
firstLevelIndex >= startIndex && firstLevelIndex < endIndex) this._currentPagerIndexedData.push(currentIndexedData[i]); else if (firstLevelIndex >= endIndex) break;
} else if (this._sourceLength > 0) throw new Error("currentIndexedData should has values!");
}
getRecordIndexPaths(bodyShowIndex) {
return this._currentPagerIndexedData[bodyShowIndex];
}
get records() {
return Array.isArray(this._source) ? this._source : [];
}
get source() {
return this._source;
}
get(index) {
return this.getOriginalRecord(_getIndex(this.currentPagerIndexedData, index));
}
getRaw(index) {
return this.getRawRecord(_getIndex(this.currentPagerIndexedData, index));
}
getIndexKey(index) {
return _getIndex(this.currentPagerIndexedData, index);
}
getTableIndex(colOrRow) {
return Array.isArray(colOrRow) ? "tree" === this.rowHierarchyType ? this.currentPagerIndexedData.findIndex((value => arrayEqual(value, colOrRow))) : this.currentPagerIndexedData.findIndex((value => value === colOrRow[0])) : this.currentPagerIndexedData.findIndex((value => value === colOrRow));
}
getField(index, field, col, row, table) {
return this.getOriginalField(_getIndex(this.currentPagerIndexedData, index), field, col, row, table);
}
getRawField(index, field, col, row, table) {
return this.getRawFieldData(_getIndex(this.currentPagerIndexedData, index), field, col, row, table);
}
hasField(index, field) {
return this.hasOriginalField(_getIndex(this.currentPagerIndexedData, index), field);
}
getHierarchyState(index) {
var _a;
const record = this.getOriginalRecord(this.currentPagerIndexedData[index]);
if (null == record ? void 0 : record.hierarchyState) {
const hierarchyState = record.hierarchyState;
if ((null === (_a = record.children) || void 0 === _a ? void 0 : _a.length) > 0 || !0 === record.children) return hierarchyState;
}
return null;
}
toggleHierarchyState(index, bodyStartIndex, bodyEndIndex) {
const oldIndexedData = this.currentIndexedData.slice(0), indexed = this.getIndexKey(index), state = this.getHierarchyState(index), data = this.getOriginalRecord(indexed);
if (this.clearSortedIndexMap(), state === HierarchyState.collapse) data.hierarchyState = HierarchyState.expand,
this.pushChildrenNode(indexed, HierarchyState.expand, data), this.hasHierarchyStateExpand = !0; else if (state === HierarchyState.expand) {
const childrenLength = computeChildrenNodeLength(indexed, state, data);
this.currentIndexedData.splice(this.currentIndexedData.indexOf(indexed) + 1, childrenLength),
data.hierarchyState = HierarchyState.collapse;
}
this.updatePagerData();
const add = [], remove = [];
if (state === HierarchyState.collapse) {
const addLength = this.currentIndexedData.length - oldIndexedData.length;
for (let i = 0; i < addLength; i++) add.push(index + i + 1);
} else if (state === HierarchyState.expand) {
const removeLength = oldIndexedData.length - this.currentIndexedData.length;
for (let i = 0; i < removeLength; i++) remove.push(index + i + 1);
}
return {
add: add,
remove: remove
};
}
pushChildrenNode(indexKey, hierarchyState, nodeData) {
var _a, _b;
if (!hierarchyState || hierarchyState === HierarchyState.collapse || hierarchyState === HierarchyState.none) return 0;
let childrenLength = 0;
const children = nodeData.filteredChildren ? nodeData.filteredChildren : nodeData.children;
if (children) {
const subNodeSortedIndexArray = Array.from({
length: children.length
}, ((_, i) => i));
null === (_a = this.lastSortStates) || void 0 === _a || _a.forEach((state => {
"normal" !== state.order && sort.sort((index => isValid(subNodeSortedIndexArray[index]) ? subNodeSortedIndexArray[index] : subNodeSortedIndexArray[index] = index), ((index, rel) => {
subNodeSortedIndexArray[index] = rel;
}), children.length, state.orderFn, state.order, (index => this.getOriginalField(Array.isArray(indexKey) ? indexKey.concat([ index ]) : [ indexKey, index ], state.field)));
}));
for (let i = 0; i < subNodeSortedIndexArray.length; i++) {
childrenLength += 1;
const childIndex = Array.isArray(indexKey) ? indexKey.concat([ subNodeSortedIndexArray[i] ]) : [ indexKey, subNodeSortedIndexArray[i] ];
this.currentIndexedData.splice(this.currentIndexedData.indexOf(indexKey) + childrenLength, 0, childIndex);
const childData = this.getOriginalRecord(childIndex);
!childData.hierarchyState && (null !== (_b = childData.filteredChildren) && void 0 !== _b ? _b : childData.children) && (childData.hierarchyState = HierarchyState.collapse),
childrenLength += this.pushChildrenNode(childIndex, childData.hierarchyState, children[subNodeSortedIndexArray[i]]);
}
}
return childrenLength;
}
changeFieldValue(value, index, field, col, row, table) {
var _a;
if (null !== field && index >= 0) {
const dataIndex = this.getIndexKey(index);
if (this.cacheBeforeChangedRecord(dataIndex, table), void 0 !== field && "" !== field || (field = col - table.leftRowSeriesNumberCount),
"string" == typeof field || "number" == typeof field) {
const beforeChangedValue = null === (_a = this.beforeChangedRecordsMap.get(dataIndex.toString())) || void 0 === _a ? void 0 : _a[field], record = this.getOriginalRecord(dataIndex);
let formatValue = value;
"number" == typeof beforeChangedValue && isAllDigits(value) && (formatValue = parseFloat(value)),
isPromise(record) ? record.then((record => {
record[field] = formatValue;
})).catch((err => {})) : record ? record[field] = formatValue : (this.records[dataIndex] = "Array" === this.addRecordRule ? [] : {},
this.records[dataIndex][field] = formatValue);
}
}
}
changeFieldValueByRecordIndex(value, recordIndex, field, table) {
var _a, _b, _c, _d;
if (null === field) return;
if (null == recordIndex) return;
const rawKey = recordIndex.toString();
if (!this.beforeChangedRecordsMap.has(rawKey)) {
const rawRecords = Array.isArray(null === (_a = this.dataSourceObj) || void 0 === _a ? void 0 : _a.records) ? this.dataSourceObj.records : null, originRecord = rawRecords ? Array.isArray(recordIndex) ? getValueFromDeepArray(rawRecords, recordIndex) : rawRecords[recordIndex] : void 0;
this.beforeChangedRecordsMap.set(rawKey, null !== (_b = cloneDeep(originRecord, void 0, [ "vtable_gantt_linkedFrom", "vtable_gantt_linkedTo" ])) && void 0 !== _b ? _b : {});
}
if ("string" == typeof field || "number" == typeof field) {
const beforeChangedValue = null === (_c = this.beforeChangedRecordsMap.get(rawKey)) || void 0 === _c ? void 0 : _c[field], rawRecords = Array.isArray(null === (_d = this.dataSourceObj) || void 0 === _d ? void 0 : _d.records) ? this.dataSourceObj.records : null, record = rawRecords ? Array.isArray(recordIndex) ? getValueFromDeepArray(rawRecords, recordIndex) : rawRecords[recordIndex] : void 0;
let formatValue = value;
"number" == typeof beforeChangedValue && isAllDigits(value) && (formatValue = parseFloat(value)),
record ? record[field] = formatValue : rawRecords && "number" == typeof recordIndex && (rawRecords[recordIndex] = "Array" === this.addRecordRule ? [] : {},
rawRecords[recordIndex][field] = formatValue);
}
}
cacheBeforeChangedRecord(dataIndex, table) {
var _a;
if (!this.beforeChangedRecordsMap.has(dataIndex.toString())) {
const originRecord = this.getOriginalRecord(dataIndex);
this.beforeChangedRecordsMap.set(dataIndex.toString(), null !== (_a = cloneDeep(originRecord, void 0, [ "vtable_gantt_linkedFrom", "vtable_gantt_linkedTo" ])) && void 0 !== _a ? _a : {});
}
}
setRecord(record, index) {
var _a, _b;
let isAdd = !0;
if ((null === (_b = null === (_a = this.dataConfig) || void 0 === _a ? void 0 : _a.filterRules) || void 0 === _b ? void 0 : _b.length) >= 1 && (this.filterRecord(record) ? "tree" === this.rowHierarchyType && record.children && (record.filteredChildren = this.filteredChildren(record.children)) : isAdd = !1),
isAdd && Array.isArray(this.records)) {
const indexed = this.getIndexKey(index);
Array.isArray(indexed) || this.records.splice(indexed, 1, record);
}
}
_getRawRecordsArray() {
var _a;
const rawRecords = null === (_a = this.dataSourceObj) || void 0 === _a ? void 0 : _a.records;
return Array.isArray(rawRecords) ? rawRecords : null;
}
_hasFilterInEffect() {
var _a, _b, _c, _d, _e;
return (null !== (_c = null === (_b = null === (_a = this.dataConfig) || void 0 === _a ? void 0 : _a.filterRules) || void 0 === _b ? void 0 : _b.length) && void 0 !== _c ? _c : 0) >= 1 || (null !== (_e = null === (_d = this.lastFilterRules) || void 0 === _d ? void 0 : _d.length) && void 0 !== _e ? _e : 0) >= 1;
}
_normalizeInsertIndex(index, length) {
return null == index || index > length ? length : index < 0 ? 0 : index;
}
_mapViewInsertIndexToRawInsertIndex(rawRecords, viewIndex) {
if (0 === this.records.length) return rawRecords.length;
if (viewIndex <= 0) {
const firstVisibleRecord = this.records[0], rawIndex = rawRecords.indexOf(firstVisibleRecord);
return rawIndex >= 0 ? rawIndex : 0;
}
if (viewIndex >= this.records.length) {
const lastVisibleRecord = this.records[this.records.length - 1], rawIndex = rawRecords.indexOf(lastVisibleRecord);
return rawIndex >= 0 ? rawIndex + 1 : rawRecords.length;
}
const prevRecord = this.records[viewIndex - 1], rawIndex = rawRecords.indexOf(prevRecord);
return rawIndex >= 0 ? rawIndex + 1 : rawRecords.length;
}
_resetIndexingFromViewRecords() {
if (this._sourceLength = this.records.length, this.currentIndexedData = Array.from({
length: this._sourceLength
}, ((_, i) => i)), "tree" === this.rowHierarchyType && this.initTreeHierarchyState(),
this.userPagination) return this.pagination.totalCount = this._sourceLength, void this.updatePagerData();
this.pagination.perPageCount = this._sourceLength, this.pagination.totalCount = this._sourceLength,
this.updatePagerData();
}
addRecord(record, index, syncToOriginalRecords = !1) {
var _a, _b, _c;
if (!syncToOriginalRecords) {
if (Array.isArray(this.records)) {
this.records.splice(index, 0, record), this.adjustBeforeChangedRecordsMap(index, 1),
this.currentIndexedData.push(this.currentIndexedData.length), this._sourceLength += 1;
for (let i = 0; i < this.fieldAggregators.length; i++) this.fieldAggregators[i].push(record);
if ("tree" === this.rowHierarchyType && this.initTreeHierarchyState(), this.userPagination) {
this.pagination.totalCount = this._sourceLength;
const {perPageCount: perPageCount, currentPage: currentPage} = this.pagination;
index < perPageCount * (currentPage || 0) + perPageCount && this.updatePagerData();
} else this.pagination.perPageCount = this._sourceLength, this.pagination.totalCount = this._sourceLength,
this.updatePagerData();
(null === (_a = this.dataSourceObj) || void 0 === _a ? void 0 : _a.added) && this.dataSourceObj.added(index, 1);
}
return;
}
const rawRecords = this._getRawRecordsArray();
if (!rawRecords) return;
const viewInsertIndex = this._normalizeInsertIndex(index, this.records.length), rawInsertIndex = this._hasFilterInEffect() ? this._mapViewInsertIndexToRawInsertIndex(rawRecords, viewInsertIndex) : this._normalizeInsertIndex(viewInsertIndex, rawRecords.length);
rawRecords.splice(rawInsertIndex, 0, record), syncToOriginalRecords && this._hasFilterInEffect() && this.markForceVisibleRecord(record),
this.beforeChangedRecordsMap.clear(), this.sortedIndexMap.clear(), this.updateFilterRules(null === (_b = this.dataConfig) || void 0 === _b ? void 0 : _b.filterRules),
(null === (_c = this.dataSourceObj) || void 0 === _c ? void 0 : _c.added) && this.dataSourceObj.added(rawInsertIndex, 1);
}
addRecords(recordArr, index, syncToOriginalRecords = !1) {
var _a, _b, _c;
if (!syncToOriginalRecords) {
if (Array.isArray(this.records)) {
if (Array.isArray(recordArr)) {
this.records.splice(index, 0, ...recordArr), this.adjustBeforeChangedRecordsMap(index, recordArr.length);
for (let i = 0; i < recordArr.length; i++) this.currentIndexedData.push(this.currentIndexedData.length);
this._sourceLength += recordArr.length;
for (let i = 0; i < this.fieldAggregators.length; i++) for (let j = 0; j < recordArr.length; j++) this.fieldAggregators[i].push(recordArr[j]);
}
if (this.userPagination) {
this.pagination.totalCount = this._sourceLength;
const {perPageCount: perPageCount, currentPage: currentPage} = this.pagination;
index < perPageCount * (currentPage || 0) + perPageCount && this.updatePagerData();
} else this.pagination.perPageCount = this._sourceLength, this.pagination.totalCount = this._sourceLength,
this.updatePagerData();
(null === (_a = this.dataSourceObj) || void 0 === _a ? void 0 : _a.added) && this.dataSourceObj.added(index, recordArr.length);
}
return;
}
const rawRecords = this._getRawRecordsArray();
if (!rawRecords || !Array.isArray(recordArr) || 0 === recordArr.length) return;
const viewInsertIndex = this._normalizeInsertIndex(index, this.records.length), rawInsertIndex = this._hasFilterInEffect() ? this._mapViewInsertIndexToRawInsertIndex(rawRecords, viewInsertIndex) : this._normalizeInsertIndex(viewInsertIndex, rawRecords.length);
if (rawRecords.splice(rawInsertIndex, 0, ...recordArr), syncToOriginalRecords && this._hasFilterInEffect()) for (let i = 0; i < recordArr.length; i++) this.markForceVisibleRecord(recordArr[i]);
this.beforeChangedRecordsMap.clear(), this.sortedIndexMap.clear(), this.updateFilterRules(null === (_b = this.dataConfig) || void 0 === _b ? void 0 : _b.filterRules),
(null === (_c = this.dataSourceObj) || void 0 === _c ? void 0 : _c.added) && this.dataSourceObj.added(rawInsertIndex, recordArr.length);
}
addRecordForSorted(record) {
Array.isArray(this.records) && (this.beforeChangedRecordsMap.clear(), this.records.push(record),
this.currentIndexedData.push(this.currentIndexedData.length), this._sourceLength += 1,
this.sortedIndexMap.clear(), this.userPagination || (this.pagination.perPageCount = this._sourceLength,
this.pagination.totalCount = this._sourceLength));
}
addRecordsForSorted(recordArr) {
if (Array.isArray(this.records)) {
if (this.beforeChangedRecordsMap.clear(), Array.isArray(recordArr)) {
this.records.push(...recordArr);
for (let i = 0; i < recordArr.length; i++) this.currentIndexedData.push(this.currentIndexedData.length);
this._sourceLength += recordArr.length, this.sortedIndexMap.clear();
}
this.userPagination || (this.pagination.perPageCount = this._sourceLength, this.pagination.totalCount = this._sourceLength);
}
}
adjustBeforeChangedRecordsMap(insertIndex, insertCount, type = "add") {
const delta = "add" === type ? insertCount : -insertCount, numericKeys = [];
this.beforeChangedRecordsMap.forEach(((_, key) => {
const numKey = Number(key);
Number.isInteger(numKey) && numKey.toString() === key && numKey >= insertIndex && numericKeys.push(numKey);
})), numericKeys.sort(((a, b) => "add" === type ? b - a : a - b));
for (let i = 0; i < numericKeys.length; i++) {
const key = numericKeys[i], record = this.beforeChangedRecordsMap.get(key.toString());
this.beforeChangedRecordsMap.delete(key.toString()), this.beforeChangedRecordsMap.set((key + delta).toString(), record);
}
}
deleteRecords(recordIndexs, syncToOriginalRecords = !1) {
var _a, _b, _c;
if (!syncToOriginalRecords) {
if (Array.isArray(this.records)) {
const realDeletedRecordIndexs = [], recordIndexsMaxToMin = recordIndexs.sort(((a, b) => b - a));
for (let index = 0; index < recordIndexsMaxToMin.length; index++) {
const recordIndex = recordIndexsMaxToMin[index];
if (recordIndex >= this._sourceLength || recordIndex < 0) continue;
this.adjustBeforeChangedRecordsMap(recordIndex, 1, "delete"), realDeletedRecordIndexs.push(recordIndex);
const deletedRecord = this.records[recordIndex];
for (let i = 0; i < this.fieldAggregators.length; i++) this.fieldAggregators[i].deleteRecord(deletedRecord);
this.records.splice(recordIndex, 1), this.currentIndexedData.pop(), this._sourceLength -= 1;
}
return this.userPagination || (this.pagination.perPageCount = this._sourceLength,
this.pagination.totalCount = this._sourceLength), this.updatePagerData(), (null === (_a = this.dataSourceObj) || void 0 === _a ? void 0 : _a.deleted) && this.dataSourceObj.deleted(realDeletedRecordIndexs),
realDeletedRecordIndexs;
}
return [];
}
const rawRecords = this._getRawRecordsArray();
if (!rawRecords || !Array.isArray(this.records)) return [];
const realDeletedRecordIndexs = [], recordIndexsMaxToMin = recordIndexs.slice().sort(((a, b) => b - a)), rawDeletedIndexs = [];
for (let index = 0; index < recordIndexsMaxToMin.length; index++) {
const viewIndex = recordIndexsMaxToMin[index];
if (viewIndex >= this.records.length || viewIndex < 0) continue;
const deletedRecord = this.records[viewIndex], rawIndex = rawRecords.indexOf(deletedRecord);
rawIndex >= 0 && (rawRecords.splice(rawIndex, 1), rawDeletedIndexs.push(rawIndex)),
realDeletedRecordIndexs.push(viewIndex);
}
return this.beforeChangedRecordsMap.clear(), this.sortedIndexMap.clear(), this.updateFilterRules(null === (_b = this.dataConfig) || void 0 === _b ? void 0 : _b.filterRules),
(null === (_c = this.dataSourceObj) || void 0 === _c ? void 0 : _c.deleted) && this.dataSourceObj.deleted(rawDeletedIndexs),
realDeletedRecordIndexs;
}
deleteRecordsForSorted(recordIndexs) {
if (Array.isArray(this.records)) {
const recordIndexsMaxToMin = recordIndexs.sort(((a, b) => b - a));
for (let index = 0; index < recordIndexsMaxToMin.length; index++) {
const recordIndex = recordIndexsMaxToMin[index];
if (recordIndex >= this._sourceLength || recordIndex < 0) continue;
const rawIndex = this.currentIndexedData[recordIndex];
this.records.splice(rawIndex, 1), this._sourceLength -= 1;
}
this.sortedIndexMap.clear(), this.userPagination || (this.pagination.perPageCount = this._sourceLength,
this.pagination.totalCount = this._sourceLength), this.beforeChangedRecordsMap.clear();
}
}
updateRecords(records, recordIndexs, syncToOriginalRecords = !1) {
var _a;
if (!syncToOriginalRecords) {
const realDeletedRecordIndexs = [];
for (let index = 0; index < recordIndexs.length; index++) {
const recordIndex = recordIndexs[index];
if (Array.isArray(recordIndex)) this.beforeChangedRecordsMap.delete(recordIndex.toString()),
realDeletedRecordIndexs.push(recordIndex), recordIndex.slice(0, -1).reduce(((acc, key) => (void 0 === acc[key] && (acc[key] = {}),
acc[key].children)), this.records)[recordIndex[recordIndex.length - 1]] = records[index]; else {
if (recordIndex >= this._sourceLength || recordIndex < 0) continue;
this.beforeChangedRecordsMap.delete(recordIndex.toString()), realDeletedRecordIndexs.push(recordIndex);
for (let i = 0; i < this.fieldAggregators.length; i++) this.fieldAggregators[i].updateRecord(this.records[recordIndex], records[index]);
this.records[recordIndex] = records[index];
}
}
return this.userPagination && this.updatePagerData(), realDeletedRecordIndexs;
}
const rawRecords = this._getRawRecordsArray();
if (!rawRecords || !Array.isArray(this.records)) return [];
const realUpdatedIndexs = [];
for (let index = 0; index < recordIndexs.length; index++) {
const recordIndex = recordIndexs[index];
if (Array.isArray(recordIndex)) this.beforeChangedRecordsMap.delete(recordIndex.toString()),
realUpdatedIndexs.push(recordIndex), recordIndex.slice(0, -1).reduce(((acc, key) => (void 0 === acc[key] && (acc[key] = {}),
acc[key].children)), rawRecords)[recordIndex[recordIndex.length - 1]] = records[index]; else {
if (recordIndex >= this.records.length || recordIndex < 0) continue;
const oldRecord = this.records[recordIndex], rawIndex = rawRecords.indexOf(oldRecord);
rawIndex >= 0 && (rawRecords[rawIndex] = records[index]), realUpdatedIndexs.push(recordIndex);
}
}
return this.beforeChangedRecordsMap.clear(), this.sortedIndexMap.clear(), this.updateFilterRules(null === (_a = this.dataConfig) || void 0 === _a ? void 0 : _a.filterRules),
realUpdatedIndexs;
}
updateRecordsForSorted(records, recordIndexs) {
const realDeletedRecordIndexs = [];
for (let index = 0; index < recordIndexs.length; index++) {
const recordIndex = recordIndexs[index];
if (recordIndex >= this._sourceLength || recordIndex < 0) continue;
const rawIndex = this.currentIndexedData[recordIndex];
if ("number" != typeof rawIndex) return;
this.beforeChangedRecordsMap.delete(rawIndex.toString()), realDeletedRecordIndexs.push(recordIndex),
this.records[rawIndex] = records[index];
}
this.sortedIndexMap.clear();
}
sort(states) {
states = (Array.isArray(states) ? states : [ states ]).filter((state => {
const column = this.columns.find((obj => obj.field === state.field));
return !1 !== (null == column ? void 0 : column.sort) && "normal" !== state.order;
})), this.lastSortStates = states;
let filedMapArray = states.map((state => this.sortedIndexMap.get(null == state ? void 0 : state.field) || {
asc: [],
desc: [],
normal: []
})), orderedData = null;
if (filedMapArray.length > 0 && (orderedData = states.reduce(((data, state, index) => {
var _a;
const currentData = null === (_a = filedMapArray[index]) || void 0 === _a ? void 0 : _a[state.order];
return currentData && currentData.length > 0 ? currentData : data;
}), null), orderedData && orderedData.length > 0)) return this.currentIndexedData = orderedData,
this.updatePagerData(), void this.fireListeners(EVENT_TYPE.CHANGE_ORDER, null);
const sortedIndexArray = Array.from({
length: this._sourceLength
}, ((_, i) => i));
if (sortedIndexArray.sort(((indexA, indexB) => {
const recordA = this.getOriginalRecord(indexA), recordB = this.getOriginalRecord(indexB), isEmptyA = null == recordA || "object" == typeof recordA && 0 === Object.keys(recordA).length, isEmptyB = null == recordB || "object" == typeof recordB && 0 === Object.keys(recordB).length;
return states.reduce(((result, state) => {
if (0 !== result) return result;
if ("asc" === state.order || "desc" === state.order) {
if (isEmptyA && !isEmptyB) return 1;
if (!isEmptyA && isEmptyB) return -1;
if (isEmptyA && isEmptyB) return indexA - indexB;
} else if (isEmptyA || isEmptyB) return indexA - indexB;
return (state.orderFn || ("desc" !== state.order ? (v1, v2) => v1 === v2 ? 0 : v1 > v2 ? 1 : -1 : (v1, v2) => v1 === v2 ? 0 : v1 < v2 ? 1 : -1))(this.getOriginalField(indexA, state.field), this.getOriginalField(indexB, state.field), state.order);
}), 0);
})), this.currentIndexedData = sortedIndexArray, this.hierarchyExpandLevel && "tree" === this.rowHierarchyType) {
let nodeLength = sortedIndexArray.length;
for (let i = 0; i < nodeLength; i++) {
const record = this.getOriginalRecord(sortedIndexArray[i]), subNodeLength = this.pushChildrenNode(sortedIndexArray[i], record.hierarchyState, this.getOriginalRecord(sortedIndexArray[i]));
nodeLength += subNodeLength, i += subNodeLength;
}
}
if (!filedMapArray.length) {
filedMapArray = states.map((() => ({
asc: [],
desc: [],
normal: []
})));
for (let index = 0; index < states.length; index++) this.sortedIndexMap.set(states[index].field, filedMapArray[index]);
}
states.forEach(((state, index) => {
filedMapArray[index][state.order] = sortedIndexArray.slice();
})), this.updatePagerData(), this.fireListeners(EVENT_TYPE.CHANGE_ORDER, null);
}
setSortedIndexMap(field, filedMap) {
this.sortedIndexMap.set(field, filedMap);
}
markForceVisibleRecord(record) {
!record || "object" != typeof record && "function" != typeof record || (this._forceVisibleRecords || (this._forceVisibleRecords = new WeakSet),
this._forceVisibleRecords.add(record));
}
clearForceVisibleRecords() {
this._forceVisibleRecords = void 0;
}
clearFilteredChildren(record) {
var _a, _b;
record.filteredChildren = void 0, delete record.filteredChildren;
for (let i = 0; i < (null !== (_b = null === (_a = record.children) || void 0 === _a ? void 0 : _a.length) && void 0 !== _b ? _b : 0); i++) this.clearFilteredChildren(record.children[i]);
}
filterRecord(record) {
var _a, _b, _c, _d;
if (null === (_a = this._forceVisibleRecords) || void 0 === _a ? void 0 : _a.has(record)) return !0;
let isReserved = !0;
for (let i = 0; i < (null === (_b = this.dataConfig.filterRules) || void 0 === _b ? void 0 : _b.length); i++) {
const filterRule = null === (_c = this.dataConfig) || void 0 === _c ? void 0 : _c.filterRules[i];
if (filterRule.filterKey) {
const filterValue = record[filterRule.filterKey];
if (-1 === filterRule.filteredValues.indexOf(filterValue)) {
isReserved = !1;
break;
}
} else if (!(null === (_d = filterRule.filterFunc) || void 0 === _d ? void 0 : _d.call(filterRule, record))) {
isReserved = !1;
break;
}
}
return isReserved;
}
updateFilterRulesForSorted(filterRules) {
var _a, _b, _c;
this.lastFilterRules = this.dataConfig.filterRules, this.dataConfig.filterRules = filterRules,
this._source = this.processRecords(null !== (_b = null === (_a = this.dataSourceObj) || void 0 === _a ? void 0 : _a.records) && void 0 !== _b ? _b : this.dataSourceObj),
this._sourceLength = (null === (_c = this._source) || void 0 === _c ? void 0 : _c.length) || 0,
this.sortedIndexMap.clear(), this.currentIndexedData = Array.from({
length: this._sourceLength
}, ((_, i) => i)), "tree" === this.rowHierarchyType && this.initTreeHierarchyState(),
this.userPagination || (this.pagination.perPageCount = this._sourceLength, this.pagination.totalCount = this._sourceLength);
}
updateFilterRules(filterRules, onFilterRecordsEnd) {
var _a, _b, _c;
this.lastFilterRules = this.dataConfig.filterRules, this.dataConfig.filterRules = filterRules,
this._source = this.processRecords(null !== (_b = null === (_a = this.dataSourceObj) || void 0 === _a ? void 0 : _a.records) && void 0 !== _b ? _b : this.dataSourceObj),
onFilterRecordsEnd && onFilterRecordsEnd(this._source), this._sourceLength = (null === (_c = this._source) || void 0 === _c ? void 0 : _c.length) || 0,
this.currentIndexedData = Array.from({
length: this._sourceLength
}, ((_, i) => i)), this.userPagination || (this.pagination.perPageCount = this._sourceLength,
this.pagination.totalCount = this._sourceLength, "tree" === this.rowHierarchyType && this.initTreeHierarchyState()),
this.updatePagerData();
}
clearSortedIndexMap() {
this.lastSortStates && this.lastSortStates.length > 0 && this.sortedIndexMap.forEach(((sortMap, key) => {
this.lastSortStates.some((state => state.field === key)) ? this.lastSortStates.forEach((state => {
"asc" === state.order ? (sortMap.desc = [], sortMap.normal = []) : "desc" === state.order ? (sortMap.asc = [],
sortMap.normal = []) : (sortMap.asc = [], sortMap.desc = []);
})) : this.sortedIndexMap.delete(key);
}));
}
get sourceLength() {
return this._sourceLength;
}
set sourceLength(sourceLen) {
this._sourceLength !== sourceLen && (this._sourceLength = sourceLen, this.fireListeners(EVENT_TYPE.SOURCE_LENGTH_UPDATE, this._sourceLength));
}
get length() {
return this.currentPagerIndexedData.length;
}
get dataSource() {
return this;
}
get currentPagerIndexedData() {
return this._currentPagerIndexedData.length > 0 ? this._currentPagerIndexedData : [];
}
release() {
var _a;
null === (_a = super.release) || void 0 === _a || _a.call(this), this.lastFilterRules = null,
this.clearSortedMap(), this.clearCurrentIndexedData(), this.currentPagerIndexedData.length = 0;
}
clearSortedMap() {
this.currentIndexedData && (this.currentIndexedData.length = 0), this.currentIndexedData = null,
this.sortedIndexMap.forEach((item => {
item.asc && (item.asc.length = 0), item.desc && (item.desc.length = 0);
})), this.sortedIndexMap.clear();
}
clearCurrentIndexedData() {
this.currentIndexedData = null, this.currentPagerIndexedData.length = 0;
}
getOriginalRecord(dataIndex) {
let data;
return data = this.dataSourceObj.records ? Array.isArray(dataIndex) ? getValueFromDeepArray(this.records, dataIndex) : this.records[dataIndex] : this._get(dataIndex),
getValue(data, (val => {
this.recordPromiseCallBack(dataIndex, val);
}));
}
getRawRecord(dataIndex) {
var _a, _b;
if (null === (_a = this.beforeChangedRecordsMap) || void 0 === _a ? void 0 : _a.has(dataIndex.toString())) return null === (_b = this.beforeChangedRecordsMap) || void 0 === _b ? void 0 : _b.get(dataIndex.toString());
let data;
return data = this.dataSourceObj.records ? Array.isArray(dataIndex) ? getValueFromDeepArray(this.records, dataIndex) : this.records[dataIndex] : this._get(dataIndex),
getValue(data, (val => {
this.recordPromiseCallBack(dataIndex, val);
}));
}
getOriginalField(index, field, col, row, table) {
if (null === field) return;
return getField(this.getOriginalRecord(index), field, col, row, table, (val => {
this.fieldPromiseCallBack(index, field, val);
}));
}
getRawFieldData(index, field, col, row, table) {
if (null === field) return;
return getField(this.getRawRecord(index), field, col, row, table, (val => {
this.fieldPromiseCallBack(index, field, val);
}));
}
hasOriginalField(index, field) {
if (null === field) return !1;
if ("function" == typeof field) return !0;
const record = this.getOriginalRecord(index);
return Boolean(record && field in record);
}
fieldPromiseCallBack(_index, _field, _value) {}
recordPromiseCallBack(_index, _record) {}
canChangeOrder(sourceIndex, targetIndex) {
var _a, _b;
if (null === (_a = this.dataSourceObj) || void 0 === _a ? void 0 : _a.canChangeOrder) return this.dataSourceObj.canChangeOrder(sourceIndex, targetIndex);
if (null === (_b = this.lastSortStates) || void 0 === _b ? void 0 : _b.some((state => "asc" === state.order || "desc" === state.order))) return !1;
if (this.hasHierarchyStateExpand) {
let sourceIndexs = this.currentPagerIndexedData[sourceIndex], targetIndexs = this.currentPagerIndexedData[targetIndex];
if (sourceIndexs = Array.isArray(sourceIndexs) ? [ ...sourceIndexs ] : [ sourceIndexs ],
targetIndexs = Array.isArray(targetIndexs) ? [ ...targetIndexs ] : [ targetIndexs ],
targetIndex > sourceIndex && targetIndexs.length > sourceIndexs.length) {
let targetNextIndexs = this.currentPagerIndexedData[targetIndex + 1];
targetNextIndexs = Array.isArray(targetNextIndexs) ? [ ...targetNextIndexs ] : [ targetNextIndexs ],
targetNextIndexs.length < targetIndexs.length && targetIndexs.splice(targetIndexs.length - 1, 1);
}
if (sourceIndexs.length === targetIndexs.length) {
for (let i = 0; i <= sourceIndexs.length - 2; i++) if (sourceIndexs[i] !== targetIndexs[i]) return !1;
return !0;
}
return !1;
}
return !0;
}
changeOrder(sourceIndex, targetIndex) {
var _a, _b, _c;
if (null === (_a = this.dataSourceObj) || void 0 === _a ? void 0 : _a.changeOrder) this.dataSourceObj.changeOrder(sourceIndex, targetIndex); else if (!(null === (_b = this.lastSortStates) || void 0 === _b ? void 0 : _b.some((state => "asc" === state.order || "desc" === state.order))) && this.canChangeOrder(sourceIndex, targetIndex)) if (this.hasHierarchyStateExpand) {
let sourceI, targetI, sourceIndexs = this.currentPagerIndexedData[sourceIndex], targetIndexs = this.currentPagerIndexedData[targetIndex];
if (sourceIndexs = Array.isArray(sourceIndexs) ? [ ...sourceIndexs ] : [ sourceIndexs ],
targetIndexs = Array.isArray(targetIndexs) ? [ ...targetIndexs ] : [ targetIndexs ],
sourceIndexs.length > 1 || targetIndexs.length > 1) {
if (targetIndex > sourceIndex && targetIndexs.length > sourceIndexs.length) {
let targetNextIndexs = this.currentPagerIndexedData[targetIndex + 1];
targetNextIndexs = Array.isArray(targetNextIndexs) ? [ ...targetNextIndexs ] : [ targetNextIndexs ],
targetNextIndexs.length < targetIndexs.length && targetIndexs.splice(targetIndexs.length - 1, 1);
}
if (sourceI = sourceIndexs.splice(sourceIndexs.length - 1, 1)[0], targetI = targetIndexs.splice(targetIndexs.length - 1, 1)[0],
sourceIndexs.length >= 1) {
const parent = this.getOriginalRecord(sourceIndexs);
if (parent) {