• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

IgniteUI / igniteui-angular / 13331632524

14 Feb 2025 02:51PM CUT coverage: 22.015% (-69.6%) from 91.622%
13331632524

Pull #15372

github

web-flow
Merge d52d57714 into bcb78ae0a
Pull Request #15372: chore(*): test ci passing

1990 of 15592 branches covered (12.76%)

431 of 964 new or added lines in 18 files covered. (44.71%)

19956 existing lines in 307 files now uncovered.

6452 of 29307 relevant lines covered (22.02%)

249.17 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

35.21
/projects/igniteui-angular/src/lib/grids/summaries/grid-summary.service.ts
1
import { Injectable } from '@angular/core';
2
import { IgxSummaryResult } from './grid-summary';
3
import { DataUtil } from '../../data-operations/data-util';
4
import { cloneArray, resolveNestedPath } from '../../core/utils';
5
import { GridType, FlatGridType, TreeGridType } from '../common/grid.interface';
6

7
/** @hidden */
8
@Injectable()
9
export class IgxGridSummaryService {
2✔
10
    public grid: GridType;
11
    public rootSummaryID = 'igxGridRootSummary';
37✔
12
    public summaryHeight = 0;
37✔
13
    public maxSummariesLength = 0;
37✔
14
    public groupingExpressions = [];
37✔
15
    public retriggerRootPipe = 0;
37✔
16
    public deleteOperation = false;
37✔
17

18
    protected summaryCacheMap: Map<string, Map<string, any[]>> = new Map<string, Map<string, IgxSummaryResult[]>>();
37✔
19

20
    public recalculateSummaries() {
21
        this.resetSummaryHeight();
×
22
        this.grid.notifyChanges(true);
×
23
    }
24

25
    public clearSummaryCache(args?) {
26
        if (!this.summaryCacheMap.size) {
120✔
27
            return;
90✔
28
        }
29
        if (!args) {
30✔
30
            this.summaryCacheMap.clear();
30✔
31
            if (this.grid && this.grid.rootSummariesEnabled) {
30✔
32
                this.retriggerRootPipe++;
30✔
33
            }
34
            return;
30✔
35
        }
UNCOV
36
        if (args.data) {
×
UNCOV
37
            const rowID = this.grid.primaryKey ? args.data[this.grid.primaryKey] : args.data;
×
UNCOV
38
            this.removeSummaries(rowID);
×
39
        }
UNCOV
40
        if (args.rowID !== undefined && args.rowID !== null) {
×
UNCOV
41
            let columnName = args.cellID ? this.grid.columns.find(col => col.index === args.cellID.columnID).field : undefined;
×
UNCOV
42
            if (columnName && this.grid.rowEditable) {
×
43
                return;
×
44
            }
45

UNCOV
46
            const isGroupedColumn = (this.grid as FlatGridType).groupingExpressions &&
×
UNCOV
47
                (this.grid as FlatGridType).groupingExpressions.map(expr => expr.fieldName).indexOf(columnName) !== -1;
×
UNCOV
48
            if (columnName && isGroupedColumn) {
×
UNCOV
49
                columnName = undefined;
×
50
            }
UNCOV
51
            this.removeSummaries(args.rowID, columnName);
×
52
        }
53
    }
54

55
    public removeSummaries(rowID, columnName?) {
UNCOV
56
        this.deleteSummaryCache(this.rootSummaryID, columnName);
×
UNCOV
57
        if (this.summaryCacheMap.size === 1 && this.summaryCacheMap.has(this.rootSummaryID)) {
×
UNCOV
58
            return;
×
59
        }
UNCOV
60
        if (this.grid.type === 'tree') {
×
UNCOV
61
            if (this.grid.transactions.enabled && this.deleteOperation) {
×
UNCOV
62
                this.deleteOperation = false;
×
63
                // TODO: this.removeChildRowSummaries(rowID, columnName);
UNCOV
64
                this.summaryCacheMap.clear();
×
UNCOV
65
                return;
×
66
            }
UNCOV
67
            this.removeAllTreeGridSummaries(rowID, columnName);
×
UNCOV
68
        } else if (this.grid.type === 'hierarchical') {
×
UNCOV
69
            if (this.grid.transactions.enabled && this.deleteOperation) {
×
70
                this.deleteOperation = false;
×
71
                this.summaryCacheMap.clear();
×
72
            }
73
        } else {
UNCOV
74
            const summaryIds = this.getSummaryID(rowID, (this.grid as FlatGridType).groupingExpressions);
×
UNCOV
75
            summaryIds.forEach(id => {
×
UNCOV
76
                this.deleteSummaryCache(id, columnName);
×
77
            });
78
        }
79
    }
80

81
    public removeSummariesCachePerColumn(columnName) {
82
        this.summaryCacheMap.forEach((cache) => {
258✔
UNCOV
83
            if (cache.get(columnName)) {
×
UNCOV
84
                cache.delete(columnName);
×
85
            }
86
        });
87
        if (this.grid.rootSummariesEnabled) {
258✔
88
            this.retriggerRootPipe++;
258✔
89
        }
90
    }
91

92
    public calcMaxSummaryHeight() {
93
        if (this.summaryHeight) {
5,670✔
94
            return this.summaryHeight;
5,487✔
95
        }
96
        if (!this.grid.data) {
183!
UNCOV
97
            return this.summaryHeight = 0;
×
98
        }
99
        let maxSummaryLength = 0;
183✔
100
        this.grid.columns.filter((col) => col.hasSummary && !col.hidden).forEach((column) => {
1,263✔
101
            const getCurrentSummary = column.summaries.operate([], [], column.field);
358✔
102
            const getCurrentSummaryColumn = column.disabledSummaries.length > 0
358!
UNCOV
103
                ? getCurrentSummary.filter(s => !column.disabledSummaries.includes(s.key)).length
×
104
                : getCurrentSummary.length;
105

106
            if (maxSummaryLength < getCurrentSummaryColumn) {
358✔
107
                maxSummaryLength = getCurrentSummaryColumn;
358✔
108
            }
109
        });
110
        this.maxSummariesLength = maxSummaryLength;
183✔
111
        this.summaryHeight = maxSummaryLength * this.grid.defaultSummaryHeight;
183✔
112
        return this.summaryHeight;
183✔
113
    }
114

115
    public calculateSummaries(rowID, data, groupRecord) {
116
        let rowSummaries = this.summaryCacheMap.get(rowID);
63✔
117
        if (!rowSummaries) {
63✔
118
            rowSummaries = new Map<string, IgxSummaryResult[]>();
63✔
119
            this.summaryCacheMap.set(rowID, rowSummaries);
63✔
120
        }
121

122
        if (!this.hasSummarizedColumns || !data) {
63!
UNCOV
123
            return rowSummaries;
×
124
        }
125

126
        this.grid.columns.filter(col => col.hasSummary).forEach((column) => {
430✔
127
            if (!rowSummaries.get(column.field)) {
122✔
128
                let summaryResult = column.summaries.operate(
122✔
129
                    data.map(r => resolveNestedPath(r, column.field)),
758✔
130
                    data,
131
                    column.field,
132
                    groupRecord,
133
                    this.grid.locale,
134
                    column.pipeArgs
135
                );
136

137
                summaryResult = column.disabledSummaries.length > 0
122!
UNCOV
138
                    ? summaryResult.filter(s => !column.disabledSummaries.includes(s.key))
×
139
                    : summaryResult;
140

141
                rowSummaries.set(column.field, summaryResult);
122✔
142
            }
143
        });
144

145
        return rowSummaries;
63✔
146
    }
147

148
    public resetSummaryHeight() {
149
        this.summaryHeight = 0;
322✔
150
        if (this.grid) {
322✔
151
            this.grid.summaryPipeTrigger++;
322✔
152
            if (this.grid.rootSummariesEnabled) {
322✔
153
                this.retriggerRootPipe++;
322✔
154
                Promise.resolve().then(() => this.grid.notifyChanges(true));
322✔
155
            }
156
        }
157
    }
158

159
    public updateSummaryCache(groupingArgs) {
UNCOV
160
        if (this.summaryCacheMap.size === 0 || !this.hasSummarizedColumns) {
×
UNCOV
161
            return;
×
162
        }
UNCOV
163
        if (this.groupingExpressions.length === 0) {
×
UNCOV
164
            this.groupingExpressions = groupingArgs.expressions.map(record => record.fieldName);
×
UNCOV
165
            return;
×
166
        }
UNCOV
167
        if (groupingArgs.length === 0) {
×
168
            this.groupingExpressions = [];
×
169
            this.clearSummaryCache();
×
170
            return;
×
171
        }
UNCOV
172
        this.compareGroupingExpressions(this.groupingExpressions, groupingArgs);
×
UNCOV
173
        this.groupingExpressions = groupingArgs.expressions.map(record => record.fieldName);
×
174
    }
175

176
    public get hasSummarizedColumns(): boolean {
177
        const summarizedColumns = this.grid.columns.filter(col => col.hasSummary && !col.hidden);
430✔
178
        return summarizedColumns.length > 0;
63✔
179
    }
180

181
    private deleteSummaryCache(id, columnName) {
UNCOV
182
        if (this.summaryCacheMap.get(id)) {
×
UNCOV
183
            const filteringApplied = columnName && this.grid.filteringExpressionsTree &&
×
UNCOV
184
                this.grid.filteringExpressionsTree.filteringOperands.map((expr) => expr.fieldName).indexOf(columnName) !== -1;
×
UNCOV
185
            if (columnName && this.summaryCacheMap.get(id).get(columnName) && !filteringApplied) {
×
UNCOV
186
                this.summaryCacheMap.get(id).delete(columnName);
×
187
            } else {
UNCOV
188
                this.summaryCacheMap.delete(id);
×
189
            }
UNCOV
190
            if (id === this.rootSummaryID && this.grid.rootSummariesEnabled) {
×
UNCOV
191
                this.retriggerRootPipe++;
×
192
            }
193
        }
194
    }
195

196
    private getSummaryID(rowID, groupingExpressions) {
UNCOV
197
        if (groupingExpressions.length === 0) {
×
UNCOV
198
            return [];
×
199
        }
UNCOV
200
        const summaryIDs = [];
×
UNCOV
201
        let data = this.grid.data;
×
UNCOV
202
        if (this.grid.transactions.enabled) {
×
UNCOV
203
            data = DataUtil.mergeTransactions(
×
204
                cloneArray(this.grid.data),
205
                this.grid.transactions.getAggregatedChanges(true),
206
                this.grid.primaryKey,
207
                this.grid.dataCloneStrategy
208
            );
209
        }
UNCOV
210
        const rowData = this.grid.primaryKey ? data.find(rec => rec[this.grid.primaryKey] === rowID) : rowID;
×
UNCOV
211
        if (!rowData) {
×
212
            return summaryIDs;
×
213
        }
UNCOV
214
        let id = '{ ';
×
UNCOV
215
        groupingExpressions.forEach(expr => {
×
UNCOV
216
            id += `'${expr.fieldName}': '${rowData[expr.fieldName]}'`;
×
UNCOV
217
            summaryIDs.push(id.concat(' }'));
×
UNCOV
218
            id += ', ';
×
219
        });
UNCOV
220
        return summaryIDs;
×
221
    }
222

223
    private removeAllTreeGridSummaries(rowID, columnName?) {
UNCOV
224
        let row = (this.grid as TreeGridType).records.get(rowID);
×
UNCOV
225
        if (!row) {
×
UNCOV
226
            return;
×
227
        }
UNCOV
228
        row = row.children ? row : row.parent;
×
UNCOV
229
        while (row) {
×
UNCOV
230
            rowID = row.key;
×
UNCOV
231
            this.deleteSummaryCache(rowID, columnName);
×
UNCOV
232
            row = row.parent;
×
233
        }
234
    }
235

236
    // TODO: remove only deleted rows
237
    // private removeChildRowSummaries(rowID, columnName?) {
238
    // }
239

240
    private compareGroupingExpressions(current, groupingArgs) {
UNCOV
241
        const newExpressions = groupingArgs.expressions.map(record => record.fieldName);
×
UNCOV
242
        const removedCols = groupingArgs.ungroupedColumns;
×
UNCOV
243
        if (current.length <= newExpressions.length) {
×
UNCOV
244
            const newExpr = newExpressions.slice(0, current.length).toString();
×
UNCOV
245
            if (current.toString() !== newExpr) {
×
UNCOV
246
                this.clearSummaryCache();
×
247
            }
248
        } else {
UNCOV
249
            const currExpr = current.slice(0, newExpressions.length).toString();
×
UNCOV
250
            if (currExpr !== newExpressions.toString()) {
×
UNCOV
251
                this.clearSummaryCache();
×
UNCOV
252
                return;
×
253
            }
UNCOV
254
            removedCols.map(col => col.field).forEach(colName => {
×
UNCOV
255
                this.summaryCacheMap.forEach((cache, id) => {
×
UNCOV
256
                    if (id.indexOf(colName) !== -1) {
×
UNCOV
257
                        this.summaryCacheMap.delete(id);
×
258
                    }
259
                });
260
            });
261
        }
262
    }
263
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc