@progress/kendo-angular-grid
Version:
Kendo UI Grid for Angular - high performance data grid with paging, filtering, virtualization, CRUD, and more.
137 lines (136 loc) • 6.64 kB
JavaScript
/**-----------------------------------------------------------------------------------------
* Copyright © 2025 Progress Software Corporation. All rights reserved.
* Licensed under commercial license. See LICENSE.md in the project root for more information
*-------------------------------------------------------------------------------------------*/
import { Injectable } from '@angular/core';
import { RowspanService } from '../rendering/rowspan.service';
import { GroupsService } from '../grouping/groups.service';
import { DetailsService } from '../rendering/details/details.service';
import { ContextService } from '../common/provider.service';
import { isPresent } from '@progress/kendo-angular-common';
import * as i0 from "@angular/core";
import * as i1 from "../rendering/rowspan.service";
import * as i2 from "../grouping/groups.service";
import * as i3 from "../rendering/details/details.service";
import * as i4 from "../common/provider.service";
/**
* @hidden
*/
export class DataMappingService {
rowspanService;
groupsService;
detailsService;
ctx;
recalculateRowspan = true;
dataArray = null;
constructor(rowspanService, groupsService, detailsService, ctx) {
this.rowspanService = rowspanService;
this.groupsService = groupsService;
this.detailsService = detailsService;
this.ctx = ctx;
}
isGroup(item) {
return item.type === 'group';
}
/**
* Maps the data to the Grid row items, applying rowspan and detail row logic.
*/
dataMapper(data, nonLockedColumnsToRender, lockedLeafColumns, detailTemplate, showFooter) {
const result = [];
if (!data || !nonLockedColumnsToRender && !lockedLeafColumns) {
return [];
}
let dataIndex = 0;
for (const item of data) {
if (this.shouldRenderItem(item, detailTemplate, showFooter)) {
if (item.type === 'data') {
item.cells = [];
for (let i = 0; i < (lockedLeafColumns.length + nonLockedColumnsToRender.length); i++) {
const column = i < lockedLeafColumns.length ? lockedLeafColumns.get(i) : nonLockedColumnsToRender.get(i - lockedLeafColumns.length);
const cell = {};
if (column.cellRowspan && this.shouldSkipCell(dataIndex, i)) {
cell.skip = true;
}
else {
cell.rowspan = column.cellRowspan ? this.getRowspan({
index: dataIndex,
dataItem: item
}, column, i, data) : 1;
}
if (isPresent(this.ctx.highlightDirective)) {
cell.isHighlighted = this.ctx.highlightDirective.isCellHighlighted(item, column, i);
}
item.cells.push(cell);
}
if (isPresent(this.ctx.highlightDirective)) {
item.isHighlighted = this.ctx.highlightDirective.isRowHighlighted(item);
}
}
result.push(item);
}
dataIndex++;
}
this.recalculateRowspan = true;
this.rowspanService.reset();
return result;
}
isDataItem(item) {
return !this.isGroup(item) && !this.isFooter(item);
}
isFooter(item) {
return item.type === 'footer';
}
isFooterItemInExpandedGroup(item) {
const footerItem = { data: item.data, index: item.groupIndex, parentGroup: item.group.parentGroup };
return this.isInExpandedGroup(footerItem);
}
isDataItemInExpandedGroup(item) {
const dataItem = { data: item.group.data, index: item.groupIndex, parentGroup: item.group.parentGroup };
return this.isInExpandedGroup(dataItem);
}
isInExpandedGroup(item) {
return this.groupsService.isInExpandedGroup(item);
}
isParentGroupExpanded(item) {
return this.groupsService.isInExpandedGroup(item.parentGroup);
}
isExpanded(viewItem) {
return this.detailsService.isExpanded(viewItem.index, viewItem.data);
}
shouldRenderItem(item, detailTemplate, showFooter) {
const renderGroupHeader = this.isGroup(item) && this.isParentGroupExpanded(item);
const renderDataItem = this.isDataItem(item) && (!item.group || this.isDataItemInExpandedGroup(item));
const renderDetailTemplate = renderDataItem && detailTemplate?.templateRef && detailTemplate.showIf(item.data, item.index) && this.isExpanded(item);
const isVisibleFooter = this.isFooter(item) && item.group && (this.isFooterItemInExpandedGroup(item) || (showFooter && this.isParentGroupExpanded(item.group)));
const renderFooter = isVisibleFooter && !item.data.hideFooter;
item.showDataItem = renderDataItem;
item.showDetailRow = renderDataItem && renderDetailTemplate;
item.isExpanded = this.isExpanded(item);
return renderGroupHeader || renderDataItem || renderDetailTemplate || renderFooter;
}
shouldSkipCell(rowIndex, colIndex) {
return this.rowspanService.shouldSkip(rowIndex, colIndex);
}
cachedDataArray(data) {
if (!this.dataArray) {
this.dataArray = data.map(item => item);
}
return this.dataArray;
}
getRowspan(row, column, colIndex, data) {
if (this.recalculateRowspan) {
this.dataArray = null;
this.recalculateRowspan = false;
}
const rowspan = column.cellRowspan(row, column, this.cachedDataArray(data));
if (rowspan > 1) {
this.rowspanService.addCells(row.index, colIndex, rowspan);
}
return rowspan;
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DataMappingService, deps: [{ token: i1.RowspanService }, { token: i2.GroupsService }, { token: i3.DetailsService }, { token: i4.ContextService }], target: i0.ɵɵFactoryTarget.Injectable });
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DataMappingService });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DataMappingService, decorators: [{
type: Injectable
}], ctorParameters: function () { return [{ type: i1.RowspanService }, { type: i2.GroupsService }, { type: i3.DetailsService }, { type: i4.ContextService }]; } });