UNPKG

devexpress-reporting

Version:

DevExpress Reporting provides the capability to develop a reporting application to create and customize reports.

120 lines (119 loc) 5.29 kB
/** * DevExpress HTML/JS Reporting (designer\bands\xrGroupBand.js) * Version: 25.1.3 * Build date: Jun 26, 2025 * Copyright (c) 2012 - 2025 Developer Express Inc. ALL RIGHTS RESERVED * License: https://www.devexpress.com/Support/EULAs/universal.xml */ import { deserializeArray } from '@devexpress/analytics-core/analytics-utils'; import { GroupFieldModel } from './groupfield'; import { BandViewModel } from './xrBand'; import { coerceNewLevelValueOnReordering, coerceNewLevelValueOnInserting, getExistedSameLevelBand, getFirstEmptyLevel, getMaxLevel, levelSetup, changeLevels, NEW_GROUPBAND_DEFAULT_LEVEL } from './_bandUtils'; import * as ko from 'knockout'; export class GroupBandViewModel extends BandViewModel { constructor(band, parent, serializer) { super(band, parent, serializer); this._disposables.push(this.maxLevel = ko.pureComputed(() => getMaxLevel(this.parentModel().bands().filter(b => b instanceof GroupBandViewModel)))); this._disposables.push(this.level = ko.pureComputed({ read: () => this._level(), write: (newValue) => levelSetup(this, newValue) })); levelSetup(this, this.level()); } coerceDefaultLevelValue(newValue) { return newValue === NEW_GROUPBAND_DEFAULT_LEVEL ? 0 : newValue; } _updateLevelsOnInsertWithDefaultLevel() { const parentBands = this.parentModel().bands; const minPossibleLevel = this.findMinPossibleLevel(parentBands); this._level(minPossibleLevel); } _updateLevelsOnInsert(newLevelValue, maxLevel) { const parentBands = this.parentModel().bands; if (!parentBands) return null; const parentGroupBands = this.getSortedGroupBands(parentBands()); const existedSameLevelBand = getExistedSameLevelBand(parentGroupBands, newLevelValue); if (!existedSameLevelBand) { newLevelValue = coerceNewLevelValueOnInserting(newLevelValue, 0, maxLevel); this._level(newLevelValue); return; } const startIndex = parentGroupBands.indexOf(existedSameLevelBand); const endIndex = this._calculateEndIndex(parentGroupBands, startIndex); changeLevels(parentGroupBands, startIndex, endIndex); this._level(newLevelValue); } updateLevelsOnInsert(maxLevel, newValue) { if (newValue === NEW_GROUPBAND_DEFAULT_LEVEL) this._updateLevelsOnInsertWithDefaultLevel(); else this._updateLevelsOnInsert(newValue, maxLevel + 1); } _calculateEndIndex(bands, startIndex) { const thisIndex = bands.indexOf(this); const endIndex = thisIndex === -1 ? bands.length : thisIndex; const direction = startIndex < endIndex ? 1 : -1; let currentIndex = startIndex; while (currentIndex != endIndex) { const level = bands[currentIndex].level(); const nextLevelBand = bands.find(b => b.level() === (level + direction)); currentIndex += direction; if (!nextLevelBand) break; } return currentIndex; } _reorderLevelsCore(newLevelValue) { const parentBands = this.parentModel().bands; const parentGroupBands = this.getSortedGroupBands(parentBands()); const existedSameLevelBand = getExistedSameLevelBand(parentGroupBands, newLevelValue); if (!existedSameLevelBand) { this._level(newLevelValue); return; } const startIndex = parentGroupBands.indexOf(existedSameLevelBand); const endIndex = this._calculateEndIndex(parentGroupBands, startIndex); changeLevels(parentGroupBands, startIndex, endIndex); this._level(newLevelValue); } reorderLevels(maxLevel, newValue) { newValue = coerceNewLevelValueOnReordering(newValue, 0, maxLevel); this._reorderLevelsCore(newValue); } getSortedGroupBands(parentBands) { return null; } findMinPossibleLevel(parentBands) { return !parentBands ? NEW_GROUPBAND_DEFAULT_LEVEL : getFirstEmptyLevel(this.getSortedGroupBands(parentBands())); } getFilteredParentBands() { return this.parentModel().bands().filter(b => b instanceof GroupBandViewModel); } } export class GroupHeaderBand extends GroupBandViewModel { constructor(band, parent, serializer) { super(band, parent, serializer); this.groupFields = deserializeArray(band.GroupFields, (field) => { return new GroupFieldModel(field, serializer); }); this.sortingSummary.getPath = (propertyName) => { if (propertyName === 'fieldName') return this.getPath('groupFields'); }; } getSortedGroupBands(parentBands) { return parentBands?.filter(band => band.controlType === this.controlType).reverse(); } dispose() { super.dispose(); this.disposeObservableArray(this.groupFields); this.resetObservableArray(this.groupFields); } } export class GroupFooterBand extends GroupBandViewModel { constructor(band, parent, serializer) { super(band, parent, serializer); } getSortedGroupBands(parentBands) { return parentBands.filter(band => band.controlType === this.controlType); } }