UNPKG

@revolist/revogrid

Version:

Virtual reactive data grid spreadsheet component - RevoGrid.

130 lines (129 loc) 4.78 kB
/*! * Built by Revolist OU ❤️ */ import { gatherTrimmedItems } from "../../store/index"; import { GROUP_DEPTH } from "./grouping.const"; import { isGrouping } from "./grouping.service"; export const TRIMMED_GROUPING = 'grouping'; /** * Converts a trim row index through the index maps produced while regrouping. * * Group rows are synthetic, so they may not exist in the first map. When a * second map is available, fall back to the original index so trims created * against the grouped physical source can still be remapped. If neither path * resolves to a number, the caller drops the stale trim entry. */ function convertTrimmedIndex(initialIndex, firstLevelMap, secondLevelMap) { const sourceIndex = Number.parseInt(initialIndex, 10); const firstConversionIndex = firstLevelMap[sourceIndex]; if (!secondLevelMap) { return firstConversionIndex; } const secondConversionKey = typeof firstConversionIndex === 'number' ? firstConversionIndex : sourceIndex; return secondLevelMap[secondConversionKey]; } /** * Prepare trimming updated indexes for grouping * @param initiallyTrimed * @param firstLevelMap * @param secondLevelMap */ export function processDoubleConversionTrimmed(initiallyTrimed, firstLevelMap, secondLevelMap) { const trimemedOptionsToUpgrade = {}; /** * go through all groups except grouping */ for (let type in initiallyTrimed) { if (type === TRIMMED_GROUPING) { continue; } const items = initiallyTrimed[type]; const newItems = {}; for (let initialIndex in items) { if (!items[initialIndex]) { continue; } /** * if item exists we find it in collection * we support 2 level of conversions */ const newConversionIndex = convertTrimmedIndex(initialIndex, firstLevelMap, secondLevelMap); // Group rows do not exist in the ungrouped index map and must not leak into new trims. if (typeof newConversionIndex !== 'number') { continue; } /** * if item was trimmed previously * trimming makes sense to apply */ newItems[newConversionIndex] = true; } trimemedOptionsToUpgrade[type] = newItems; } return trimemedOptionsToUpgrade; } function hasVisibleGroupItems(source, trimmed, groupIndex) { var _a; const depth = (_a = source[groupIndex]) === null || _a === void 0 ? void 0 : _a[GROUP_DEPTH]; if (depth == null) { return false; } // A group is visible when at least one descendant data row survives filtering. for (let i = groupIndex + 1; i < source.length; i++) { const model = source[i]; if (isGrouping(model)) { if (model[GROUP_DEPTH] <= depth) { break; } continue; } if (!trimmed[i]) { return true; } } return false; } /** * Preserves data-row filter results and recalculates group-row visibility * from the filtered state of each group's descendant data rows. * * @param source - Grouped row source that contains group rows and data rows. * @param filterTrimmed - Current filter trim map keyed by physical row index. * @returns Filter trim map with empty group rows hidden and matching group rows visible. */ export function filterOutEmptyGroupRows(source, filterTrimmed) { const trimmed = Object.assign({}, filterTrimmed); // Recalculate only group rows; data-row filter results are preserved as-is. source.forEach((model, index) => { if (!isGrouping(model)) { return; } if (hasVisibleGroupItems(source, trimmed, index)) { delete trimmed[index]; } else { trimmed[index] = true; } }); return trimmed; } /** * Builds grouping trims from an explicit group-to-children map by hiding * groups whose children are all hidden by any active trim type. * * @param allTrimmedGroups - Active trim maps keyed by trim type. * @param childrenByGroup - Child row indexes keyed by group row index. * @returns Grouping trim map that hides groups without visible children. */ export function filterOutEmptyGroups(allTrimmedGroups, childrenByGroup = {}) { const trimmedGroup = {}; const allTrimmed = gatherTrimmedItems(allTrimmedGroups); // find is groups are filled for (let groupIndex in childrenByGroup) { const hasChidlren = childrenByGroup[groupIndex].filter(childIndex => !allTrimmed[childIndex]).length > 0; if (!hasChidlren) { trimmedGroup[groupIndex] = true; } } return trimmedGroup; }