UNPKG

devextreme

Version:

HTML5 JavaScript Component Suite for Responsive Web Development

247 lines (245 loc) • 11.3 kB
/** * DevExtreme (esm/ui/data_grid/ui.data_grid.grouping.core.js) * Version: 21.1.4 * Build date: Mon Jun 21 2021 * * Copyright (c) 2012 - 2021 Developer Express Inc. ALL RIGHTS RESERVED * Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/ */ import $ from "../../core/renderer"; import Class from "../../core/class"; import gridCore from "./ui.data_grid.core"; import dataUtils from "../../data/utils"; import { when } from "../../core/utils/deferred"; export function createOffsetFilter(path, storeLoadOptions, lastLevelOnly) { var groups = dataUtils.normalizeSortingInfo(storeLoadOptions.group); var filter = []; for (var i = lastLevelOnly ? path.length - 1 : 0; i < path.length; i++) { var filterElement = []; for (var j = 0; j <= i; j++) { var selector = groups[j].selector; if (i === j && (null === path[j] || false === path[j] || true === path[j])) { if (false === path[j]) { filterElement.push([selector, "=", groups[j].desc ? true : null]) } else if (path[j] ? !groups[j].desc : groups[j].desc) { filterElement.push([selector, "<>", path[j]]) } else { filterElement.push([selector, "<>", null]); filterElement.push([selector, "=", null]) } } else { var currentFilter = [selector, i === j ? groups[j].desc ? ">" : "<" : "=", path[j]]; if ("<" === currentFilter[1]) { filterElement.push([currentFilter, "or", [selector, "=", null]]) } else { filterElement.push(currentFilter) } } } filter.push(gridCore.combineFilters(filterElement)) } filter = gridCore.combineFilters(filter, "or"); return gridCore.combineFilters([filter, storeLoadOptions.filter]) } export var GroupingHelper = Class.inherit(function() { var findGroupInfoByKey = function(groupsInfo, key) { var hash = groupsInfo.hash; return hash && hash[JSON.stringify(key)] }; var getGroupInfoIndexByOffset = function(groupsInfo, offset) { var leftIndex = 0; var rightIndex = groupsInfo.length - 1; if (!groupsInfo.length) { return 0 } do { var middleIndex = rightIndex + leftIndex >> 1; if (groupsInfo[middleIndex].offset > offset) { rightIndex = middleIndex } else { leftIndex = middleIndex } } while (rightIndex - leftIndex > 1); var index; for (index = leftIndex; index <= rightIndex; index++) { if (groupsInfo[index].offset > offset) { break } } return index }; return { ctor: function(dataSourceAdapter) { this._dataSource = dataSourceAdapter; this.reset() }, reset: function() { this._groupsInfo = []; this._totalCountCorrection = 0 }, totalCountCorrection: function() { return this._totalCountCorrection }, updateTotalItemsCount: function(totalCountCorrection) { this._totalCountCorrection = totalCountCorrection || 0 }, isGroupItemCountable: function(item) { return !this._isVirtualPaging() || !item.isContinuation }, _isVirtualPaging: function() { var scrollingMode = this._dataSource.option("scrolling.mode"); return "virtual" === scrollingMode || "infinite" === scrollingMode }, itemsCount: function() { var dataSourceAdapter = this._dataSource; var dataSource = dataSourceAdapter._dataSource; var groupCount = gridCore.normalizeSortingInfo(dataSource.group() || []).length; var itemsCount = function calculateItemsCount(that, items, groupsCount) { var result = 0; if (items) { if (!groupsCount) { result = items.length } else { for (var i = 0; i < items.length; i++) { if (that.isGroupItemCountable(items[i])) { result++ } result += calculateItemsCount(that, items[i].items, groupsCount - 1) } } } return result }(this, dataSource.items(), groupCount); return itemsCount }, foreachGroups: function(callback, childrenAtFirst, foreachCollapsedGroups, updateOffsets, updateParentOffsets) { var that = this; return function foreachGroupsCore(groupsInfo, callback, childrenAtFirst, parents) { var callbackResults = []; function executeCallback(callback, data, parents, callbackResults) { var callbackResult = data && callback(data, parents); callbackResult && callbackResults.push(callbackResult); return callbackResult } for (var i = 0; i < groupsInfo.length; i++) { parents.push(groupsInfo[i].data); if (!childrenAtFirst && false === executeCallback(callback, groupsInfo[i].data, parents, callbackResults)) { return false } if (!groupsInfo[i].data || groupsInfo[i].data.isExpanded || foreachCollapsedGroups) { var children = groupsInfo[i].children; var callbackResult = children.length && foreachGroupsCore(children, callback, childrenAtFirst, parents); callbackResult && callbackResults.push(callbackResult); if (false === callbackResult) { return false } } if (childrenAtFirst && false === executeCallback(callback, groupsInfo[i].data, parents, callbackResults)) { return false } if (!groupsInfo[i].data || groupsInfo[i].data.offset !== groupsInfo[i].offset) { updateOffsets = true } parents.pop() } var currentParents = updateParentOffsets && parents.slice(0); return updateOffsets && when.apply($, callbackResults).always((function() { that._updateGroupInfoOffsets(groupsInfo, currentParents) })) }(that._groupsInfo, callback, childrenAtFirst, []) }, _updateGroupInfoOffsets: function(groupsInfo, parents) { parents = parents || []; for (var index = 0; index < groupsInfo.length; index++) { var groupInfo = groupsInfo[index]; if (groupInfo.data && groupInfo.data.offset !== groupInfo.offset) { groupInfo.offset = groupInfo.data.offset; for (var parentIndex = 0; parentIndex < parents.length; parentIndex++) { parents[parentIndex].offset = groupInfo.offset } } } groupsInfo.sort((function(a, b) { return a.offset - b.offset })) }, findGroupInfo: function(path) { var groupInfo; var groupsInfo = this._groupsInfo; for (var pathIndex = 0; groupsInfo && pathIndex < path.length; pathIndex++) { groupInfo = findGroupInfoByKey(groupsInfo, path[pathIndex]); groupsInfo = groupInfo && groupInfo.children } return groupInfo && groupInfo.data }, addGroupInfo: function(groupInfoData) { var groupInfo; var path = groupInfoData.path; var groupsInfo = this._groupsInfo; for (var pathIndex = 0; pathIndex < path.length; pathIndex++) { groupInfo = findGroupInfoByKey(groupsInfo, path[pathIndex]); if (!groupInfo) { groupInfo = { key: path[pathIndex], offset: groupInfoData.offset, data: { offset: groupInfoData.offset, isExpanded: true, path: path.slice(0, pathIndex + 1) }, children: [] }; var index = getGroupInfoIndexByOffset(groupsInfo, groupInfoData.offset); groupsInfo.splice(index, 0, groupInfo); groupsInfo.hash = groupsInfo.hash || {}; groupsInfo.hash[JSON.stringify(groupInfo.key)] = groupInfo } if (pathIndex === path.length - 1) { groupInfo.data = groupInfoData; if (groupInfo.offset !== groupInfoData.offset) { this._updateGroupInfoOffsets(groupsInfo) } } groupsInfo = groupInfo.children } }, allowCollapseAll: function() { return true }, refresh: function(options) { var storeLoadOptions = options.storeLoadOptions; var groups = dataUtils.normalizeSortingInfo(storeLoadOptions.group || []); var oldGroups = "_group" in this ? dataUtils.normalizeSortingInfo(this._group || []) : groups; var groupsCount = Math.min(oldGroups.length, groups.length); this._group = storeLoadOptions.group; for (var groupIndex = 0; groupIndex < groupsCount; groupIndex++) { if (oldGroups[groupIndex].selector !== groups[groupIndex].selector) { groupsCount = groupIndex; break } } if (!groupsCount) { this.reset() } else { ! function cleanGroupsInfo(groupsInfo, groupIndex, groupsCount) { for (var i = 0; i < groupsInfo.length; i++) { if (groupIndex + 1 >= groupsCount) { groupsInfo[i].children = [] } else { cleanGroupsInfo(groupsInfo[i].children, groupIndex + 1, groupsCount) } } }(this._groupsInfo, 0, groupsCount) } }, handleDataLoading: function() {}, handleDataLoaded: function(options, callBase) { callBase(options) }, handleDataLoadedCore: function(options, callBase) { callBase(options) } } }());