• 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

59.7
/projects/igniteui-angular/src/lib/grids/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 { ColumnType, GridType, IGX_GRID_BASE } from '../common/grid.interface';
21
import { GridSelectionMode } from '../common/enums';
22
import { PlatformUtil } from '../../core/utils';
23
import { IgxHeaderGroupWidthPipe, IgxHeaderGroupStylePipe } from './pipes';
24
import { IgxResizeHandleDirective } from '../resizing/resize-handle.directive';
25
import { IgxIconComponent } from '../../icon/icon.component';
26
import { IgxColumnMovingDropDirective } from '../moving/moving.drop.directive';
27
import { IgxColumnMovingDragDirective } from '../moving/moving.drag.directive';
28
import { NgIf, NgClass, NgStyle, NgFor, NgTemplateOutlet } from '@angular/common';
29

30
const Z_INDEX = 9999;
2✔
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: [NgIf, NgClass, NgStyle, NgFor, IgxColumnMovingDragDirective, IgxColumnMovingDropDirective, IgxIconComponent, NgTemplateOutlet, IgxGridHeaderComponent, IgxGridFilteringCellComponent, IgxResizeHandleDirective, IgxHeaderGroupWidthPipe, IgxHeaderGroupStylePipe]
40
})
41
export class IgxGridHeaderGroupComponent implements DoCheck {
2✔
42

43
    @HostBinding('style.grid-row-end')
44
    public get rowEnd(): number {
45
        return this.column.rowEnd;
2,336✔
46
    }
47

48
    @HostBinding('style.grid-column-end')
49
    public get colEnd(): number {
50
        return this.column.colEnd;
2,336✔
51
    }
52

53
    @HostBinding('style.grid-row-start')
54
    public get rowStart(): number {
55
        return this.column.rowStart;
2,336✔
56
    }
57

58
    @HostBinding('style.grid-column-start')
59
    public get colStart(): number {
60
        return this.column.colStart;
2,336✔
61
    }
62

63
    @HostBinding('attr.id')
64
    public get headerID() {
65
        return `${this.grid.id}_-1_${this.column.level}_${this.column.visibleIndex}`;
2,336✔
66
    }
67

68
    /**
69
     * Gets the column of the header group.
70
     *
71
     * @memberof IgxGridHeaderGroupComponent
72
     */
73
    @Input()
74
    public column: ColumnType;
75

76
    @HostBinding('class.igx-grid-th--active')
77
    public get active() {
78
        const node = this.grid.navigation.activeNode;
2,336✔
79
        return node && !this.column.columnGroup ?
2,336✔
80
            node.row === -1 && node.column === this.column.visibleIndex && node.level === this.column.level : false;
2,327!
81
    }
82

83
    public get activeGroup() {
84
        const node = this.grid.navigation.activeNode;
9✔
85
        return node ? node.row === -1 && node.column === this.column.visibleIndex && node.level === this.column.level : false;
9!
86
    }
87

88
    /**
89
     * @hidden
90
     */
91
    @ViewChild(IgxGridHeaderComponent)
92
    public header: IgxGridHeaderComponent;
93

94
    /**
95
     * @hidden
96
     */
97
    @ViewChild(IgxGridFilteringCellComponent)
98
    public filter: IgxGridFilteringCellComponent;
99

100
    /**
101
     * @hidden
102
     */
103
    @ViewChildren(forwardRef(() => IgxGridHeaderGroupComponent), { read: IgxGridHeaderGroupComponent })
2✔
104
    public children: QueryList<IgxGridHeaderGroupComponent>;
105

106
    /**
107
     * Gets the width of the header group.
108
     *
109
     * @memberof IgxGridHeaderGroupComponent
110
     */
111
    public get width() {
112
        return this.grid.getHeaderGroupWidth(this.column);
×
113
    }
114

115
    @HostBinding('class.igx-grid-thead__item')
116
    public defaultCss = true;
247✔
117

118
    constructor(private cdr: ChangeDetectorRef,
247✔
119
        @Inject(IGX_GRID_BASE) public grid: GridType,
247✔
120
        private ref: ElementRef<HTMLElement>,
247✔
121
        public colResizingService: IgxColumnResizingService,
247✔
122
        public filteringService: IgxFilteringService,
247✔
123
        protected platform: PlatformUtil) { }
247✔
124

125
    @HostBinding('class.igx-grid-th--pinned')
126
    public get pinnedCss() {
127
        return this.isPinned;
2,336✔
128
    }
129

130
    @HostBinding('class.igx-grid-th--pinned-last')
131
    public get pinnedLastCss() {
132
        return this.isLastPinned;
2,336✔
133
    }
134

135
    @HostBinding('class.igx-grid-th--pinned-first')
136
    public get pinnedFirstCSS() {
137
        return this.isFirstPinned;
2,336✔
138
    }
139

140
    @HostBinding('class.igx-grid__drag-col-header')
141
    public get headerDragCss() {
142
        return this.isHeaderDragged;
2,336✔
143
    }
144

145
    @HostBinding('class.igx-grid-th--filtering')
146
    public get filteringCss() {
147
        return this.isFiltered;
2,336✔
148
    }
149

150
    /**
151
     * @hidden
152
     */
153
    @HostBinding('style.z-index')
154
    public get zIndex() {
155
        if (!this.column.pinned) {
2,336✔
156
            return null;
2,336✔
157
        }
UNCOV
158
        return Z_INDEX - this.grid.pinnedColumns.indexOf(this.column);
×
159
    }
160

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

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

179
    /**
180
     * Gets whether the header group is stored in the first column of the right pinned area.
181
     */
182
    public get isFirstPinned(): boolean {
183
        return !this.grid.hasColumnLayouts ? this.column.isFirstPinned : false;
2,336!
184
    }
185

186
    @HostBinding('style.display')
187
    public get groupDisplayStyle(): string {
188
        return this.grid.hasColumnLayouts && this.column.children ? 'flex' : '';
2,336!
189
    }
190

191
    /**
192
     * Gets whether the header group is stored in a pinned column.
193
     *
194
     * @memberof IgxGridHeaderGroupComponent
195
     */
196
    public get isPinned(): boolean {
197
        return this.column.pinned;
2,336✔
198
    }
199

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

209
    /**
210
     * @hidden
211
     */
212
    public get hasLastPinnedChildColumn(): boolean {
213
        return this.column.allChildren.some(child => child.isLastPinned);
18✔
214
    }
215

216
    /**
217
     * @hidden
218
     */
219
    public get hasFirstPinnedChildColumn(): boolean {
220
        return this.column.allChildren.some(child => child.isFirstPinned);
18✔
221
    }
222

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

234
    /**
235
     * @hidden
236
     */
237
    public get selected() {
238
        return this.column.selected;
9✔
239
    }
240

241
    /**
242
     * @hidden
243
     */
244
    public get height() {
UNCOV
245
        return this.nativeElement.getBoundingClientRect().height;
×
246
    }
247

248
    /**
249
     * @hidden
250
     */
251
    public get title() {
252
        return this.column.title || this.column.header;
9✔
253
    }
254

255
    public get nativeElement() {
256
        return this.ref.nativeElement;
106✔
257
    }
258

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

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

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

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

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

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

329
    public ngDoCheck() {
330
        this.cdr.markForCheck();
2,336✔
331
    }
332
    /**
333
     * @hidden
334
     */
335
    public onPinterEnter() {
UNCOV
336
        this.column.applySelectableClass = true;
×
337
    }
338

339
    /**
340
     * @hidden
341
     */
342
    public onPointerLeave() {
UNCOV
343
        this.column.applySelectableClass = false;
×
344
    }
345

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