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
JavaScript
/**
* 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);
}
}