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

IgniteUI / igniteui-angular / 20960087204

13 Jan 2026 02:19PM UTC coverage: 12.713% (-78.8%) from 91.5%
20960087204

Pull #16746

github

web-flow
Merge 9afce6e5d into a967f087e
Pull Request #16746: fix(csv): export summaries - master

1008 of 16803 branches covered (6.0%)

19 of 23 new or added lines in 2 files covered. (82.61%)

24693 existing lines in 336 files now uncovered.

3985 of 31345 relevant lines covered (12.71%)

2.49 hits per line

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

42.42
/projects/igniteui-angular/grids/core/src/headers/grid-header-group.component.ts
1
import {
2
    ChangeDetectionStrategy,
3
    ChangeDetectorRef,
4
    Component,
5
    DoCheck,
6
    ElementRef,
7
    forwardRef,
8
    HostBinding,
9
    HostListener,
10
    inject,
11
    Input,
12
    QueryList,
13
    ViewChild,
14
    ViewChildren
15
} from '@angular/core';
16
import { IgxFilteringService } from '../filtering/grid-filtering.service';
17
import { IgxColumnResizingService } from '../resizing/resizing.service';
18
import { IgxGridHeaderComponent } from './grid-header.component';
19
import { IgxGridFilteringCellComponent } from '../filtering/base/grid-filtering-cell.component';
20
import { GridType, IGX_GRID_BASE } from '../common/grid.interface';
21
import { GridSelectionMode } from '../common/enums';
22
import { IgxHeaderGroupStylePipe } from './pipes';
23
import { IgxResizeHandleDirective } from '../resizing/resize-handle.directive';
24
import { IgxColumnMovingDropDirective } from '../moving/moving.drop.directive';
25
import { IgxColumnMovingDragDirective } from '../moving/moving.drag.directive';
26
import { NgClass, NgStyle, NgTemplateOutlet } from '@angular/common';
27
import { IgxIconComponent } from 'igniteui-angular/icon';
28
import { ColumnType, PlatformUtil } from 'igniteui-angular/core';
29

30
const Z_INDEX = 9999;
3✔
31

32
/**
33
 * @hidden
34
 */
35
@Component({
36
    changeDetection: ChangeDetectionStrategy.OnPush,
37
    selector: 'igx-grid-header-group',
38
    templateUrl: './grid-header-group.component.html',
39
    imports: [NgClass, NgStyle, IgxColumnMovingDragDirective, IgxColumnMovingDropDirective, IgxIconComponent, NgTemplateOutlet, IgxGridHeaderComponent, IgxGridFilteringCellComponent, IgxResizeHandleDirective, IgxHeaderGroupStylePipe]
40
})
41
export class IgxGridHeaderGroupComponent implements DoCheck {
3✔
42

43
    private cdr = inject(ChangeDetectorRef);
3✔
44
    public grid = inject<GridType>(IGX_GRID_BASE);
3✔
45
    private ref = inject<ElementRef<HTMLElement>>(ElementRef);
3✔
46
    public colResizingService = inject(IgxColumnResizingService);
3✔
47
    public filteringService = inject(IgxFilteringService);
3✔
48
    protected platform = inject(PlatformUtil);
3✔
49

50

51
    @HostBinding('style.grid-row-end')
52
    public get rowEnd(): number {
53
        return this.column.rowEnd;
15✔
54
    }
55

56
    @HostBinding('style.grid-column-end')
57
    public get colEnd(): number {
58
        return this.column.colEnd;
15✔
59
    }
60

61
    @HostBinding('style.grid-row-start')
62
    public get rowStart(): number {
63
        return this.column.rowStart;
15✔
64
    }
65

66
    @HostBinding('style.grid-column-start')
67
    public get colStart(): number {
68
        return this.column.colStart;
15✔
69
    }
70

71
    @HostBinding('class.igx-grid-th--pinned')
72
    public get pinnedCss() {
73
        return this.column.pinned;
15✔
74
    }
75

76
    public get headerID() {
77
        return `${this.grid.id}_-1_${this.column.level}_${this.column.visibleIndex}`;
15✔
78
    }
79

80
    /**
81
     * Gets the column of the header group.
82
     *
83
     * @memberof IgxGridHeaderGroupComponent
84
     */
85
    @Input()
86
    public column: ColumnType;
87

88
    @HostBinding('class.igx-grid-th--active')
89
    public get active() {
90
        const node = this.grid.navigation.activeNode;
15✔
91
        return node && !this.column.columnGroup ?
15!
92
            node.row === -1 && node.column === this.column.visibleIndex && node.level === this.column.level : false;
15!
93
    }
94

95
    public get activeGroup() {
UNCOV
96
        const node = this.grid.navigation.activeNode;
×
UNCOV
97
        return node ? node.row === -1 && node.column === this.column.visibleIndex && node.level === this.column.level : false;
×
98
    }
99

100
    /**
101
     * @hidden
102
     */
103
    @ViewChild(IgxGridHeaderComponent)
104
    public header: IgxGridHeaderComponent;
105

106
    /**
107
     * @hidden
108
     */
109
    @ViewChild(IgxGridFilteringCellComponent)
110
    public filter: IgxGridFilteringCellComponent;
111

112
    /**
113
     * @hidden
114
     */
115
    @ViewChildren(forwardRef(() => IgxGridHeaderGroupComponent), { read: IgxGridHeaderGroupComponent })
2✔
116
    public children: QueryList<IgxGridHeaderGroupComponent>;
117

118
    /**
119
     * Gets the width of the header group.
120
     *
121
     * @memberof IgxGridHeaderGroupComponent
122
     */
123
    public get width() {
UNCOV
124
        return this.grid.getHeaderGroupWidth(this.column);
×
125
    }
126

127
    @HostBinding('class.igx-grid-thead__item')
128
    public defaultCss = true;
3✔
129

130
    @HostBinding('class.igx-grid__drag-col-header')
131
    public get headerDragCss() {
132
        return this.isHeaderDragged;
15✔
133
    }
134

135
    @HostBinding('class.igx-grid-th--filtering')
136
    public get filteringCss() {
137
        return this.isFiltered;
15✔
138
    }
139

140
    /**
141
     * @hidden
142
     */
143
    @HostBinding('style.z-index')
144
    public get zIndex() {
145
        if (!this.column.pinned) {
15✔
146
            return null;
15✔
147
        }
UNCOV
148
        return Z_INDEX - this.grid.pinnedColumns.indexOf(this.column);
×
149
    }
150

151
    /**
152
     * @hidden
153
     */
154
    public get ariaHidden(): boolean {
155
        return this.grid.hasColumnGroups && (this.column.hidden || this.grid.navigation.activeNode?.row !== -1);
15!
156
    }
157

158
    /**
159
     * Gets whether the header group belongs to a column that is filtered.
160
     *
161
     * @memberof IgxGridHeaderGroupComponent
162
     */
163
    public get isFiltered(): boolean {
164
        return this.filteringService.filteredColumn === this.column;
15✔
165
    }
166

167
    /**
168
     * Gets whether the header group is stored in the last column in the pinned area.
169
     *
170
     * @memberof IgxGridHeaderGroupComponent
171
     */
172
    public get isLastPinned(): boolean {
173
        return !this.grid.hasColumnLayouts ? this.column.isLastPinned : false;
×
174
    }
175

176
    /**
177
     * Gets whether the header group is stored in the first column of the right pinned area.
178
     */
179
    public get isFirstPinned(): boolean {
180
        return !this.grid.hasColumnLayouts ? this.column.isFirstPinned : false;
×
181
    }
182

183
    @HostBinding('style.display')
184
    public get groupDisplayStyle(): string {
185
        return this.grid.hasColumnLayouts && this.column.children ? 'flex' : '';
15!
186
    }
187

188
    /**
189
     * Gets whether the header group is stored in a pinned column.
190
     *
191
     * @memberof IgxGridHeaderGroupComponent
192
     */
193
    public get isPinned(): boolean {
UNCOV
194
        return this.column.pinned;
×
195
    }
196

197
    /**
198
     * Gets whether the header group belongs to a column that is moved.
199
     *
200
     * @memberof IgxGridHeaderGroupComponent
201
     */
202
    public get isHeaderDragged(): boolean {
203
        return this.grid.columnInDrag === this.column;
15✔
204
    }
205

206
    /**
207
     * @hidden
208
     */
209
    public get hasLastPinnedChildColumn(): boolean {
UNCOV
210
        return this.column.allChildren.some(child => child.isLastPinned);
×
211
    }
212

213
    /**
214
     * @hidden
215
     */
216
    public get hasFirstPinnedChildColumn(): boolean {
UNCOV
217
        return this.column.allChildren.some(child => child.isFirstPinned);
×
218
    }
219

220
    /**
221
     * @hidden
222
     */
223
    public get selectable() {
UNCOV
224
        const selectableChildren = this.column.allChildren.filter(c => !c.hidden && c.selectable && !c.columnGroup);
×
UNCOV
225
        return this.grid.columnSelection !== GridSelectionMode.none &&
×
226
            this.column.applySelectableClass
227
            && !this.selected && selectableChildren.length > 0
228
            && !this.grid.filteringService.isFilterRowVisible;
229
    }
230

231
    /**
232
     * @hidden
233
     */
234
    public get selected() {
UNCOV
235
        return this.column.selected;
×
236
    }
237

238
    /**
239
     * @hidden
240
     */
241
    public get height() {
UNCOV
242
        return this.nativeElement.getBoundingClientRect().height;
×
243
    }
244

245
    /**
246
     * @hidden
247
     */
248
    public get title() {
UNCOV
249
        return this.column.title || this.column.header;
×
250
    }
251

252
    public get nativeElement() {
253
        return this.ref.nativeElement;
2✔
254
    }
255

256
    /**
257
     * @hidden
258
     */
259
    @HostListener('mousedown', ['$event'])
260
    public onMouseDown(event: MouseEvent): void {
UNCOV
261
        if (!this.grid.allowFiltering ||
×
262
            (event.composedPath().findIndex(el =>
UNCOV
263
                (el as Element).tagName?.toLowerCase() === 'igx-grid-filtering-cell') < 1)) {
×
264
                // Hack for preventing text selection in IE and Edge while dragging the resize element
UNCOV
265
                event.preventDefault();
×
266
        }
267
    }
268

269
    /**
270
     * @hidden
271
     */
272
    public groupClicked(event: MouseEvent): void {
UNCOV
273
        const columnsToSelect = this.column.allChildren.filter(c => !c.hidden && c.selectable && !c.columnGroup).map(c => c.field);
×
UNCOV
274
        if (this.grid.columnSelection !== GridSelectionMode.none
×
275
            && columnsToSelect.length > 0 && !this.grid.filteringService.isFilterRowVisible) {
UNCOV
276
            const clearSelection = this.grid.columnSelection === GridSelectionMode.single || !event.ctrlKey;
×
UNCOV
277
            const rangeSelection = this.grid.columnSelection === GridSelectionMode.multiple && event.shiftKey;
×
UNCOV
278
            if (!this.selected) {
×
UNCOV
279
                this.grid.selectionService.selectColumns(columnsToSelect, clearSelection, rangeSelection, event);
×
280
            } else {
UNCOV
281
                const selectedFields = this.grid.selectionService.getSelectedColumns();
×
UNCOV
282
                if ((selectedFields.length === columnsToSelect.length) && selectedFields.every(el => columnsToSelect.includes(el))
×
283
                    || !clearSelection) {
UNCOV
284
                    this.grid.selectionService.deselectColumns(columnsToSelect, event);
×
285
                } else {
UNCOV
286
                    this.grid.selectionService.selectColumns(columnsToSelect, clearSelection, rangeSelection, event);
×
287
                }
288
            }
289
        }
290
    }
291

292
    /**
293
     * @hidden @internal
294
     */
295
    public onPointerDownIndicator(event) {
296
        // Stop propagation of pointer events to now allow column dragging using the header indicators.
297
        event.stopPropagation();
×
298
    }
299

300
    /**
301
     * @hidden @internal
302
     */
303
    public toggleExpandState(event: MouseEvent): void {
UNCOV
304
        event.stopPropagation();
×
UNCOV
305
        this.column.expanded = !this.column.expanded;
×
306
    }
307

308
    /**
309
     * @hidden @internal
310
     */
311
    public pointerdown(event: PointerEvent): void {
UNCOV
312
        event.stopPropagation();
×
UNCOV
313
        this.activate();
×
UNCOV
314
        this.grid.theadRow.nativeElement.focus();
×
315
    }
316

317
    /*
318
     * This method is necessary due to some specifics related with implementation of column moving
319
     * @hidden
320
     */
321
    public activate() {
UNCOV
322
        this.grid.navigation.setActiveNode(this.activeNode);
×
UNCOV
323
        this.grid.theadRow.nativeElement.focus();
×
324
    }
325

326
    public ngDoCheck() {
327
        this.cdr.markForCheck();
15✔
328
    }
329
    /**
330
     * @hidden
331
     */
332
    public onPinterEnter() {
UNCOV
333
        this.column.applySelectableClass = true;
×
334
    }
335

336
    /**
337
     * @hidden
338
     */
339
    public onPointerLeave() {
UNCOV
340
        this.column.applySelectableClass = false;
×
341
    }
342

343
    protected get activeNode() {
UNCOV
344
        return {
×
345
            row: -1, column: this.column.visibleIndex, level: this.column.level,
346
            mchCache: { level: this.column.level, visibleIndex: this.column.visibleIndex },
347
            layout: this.column.columnLayoutChild ? {
×
348
                rowStart: this.column.rowStart,
349
                colStart: this.column.colStart,
350
                rowEnd: this.column.rowEnd,
351
                colEnd: this.column.colEnd,
352
                columnVisibleIndex: this.column.visibleIndex
353
            } : null
354
        };
355
    }
356
}
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

© 2026 Coveralls, Inc