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

IgniteUI / igniteui-angular / 19765807866

28 Nov 2025 01:54PM UTC coverage: 91.437% (-0.007%) from 91.444%
19765807866

push

github

web-flow
fix(igxGrid): Add check in case active target is a non-merged record. (#16537)

14169 of 16717 branches covered (84.76%)

1 of 1 new or added line in 1 file covered. (100.0%)

1313 existing lines in 138 files now uncovered.

28510 of 31180 relevant lines covered (91.44%)

34390.36 hits per line

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

91.43
/projects/igniteui-angular/grids/core/src/headers/grid-header-row.component.ts
1
import {
2
    ChangeDetectionStrategy,
3
    ChangeDetectorRef,
4
    Component,
5
    DoCheck,
6
    ElementRef,
7
    HostBinding,
8
    Input,
9
    QueryList,
10
    TemplateRef,
11
    ViewChild,
12
    ViewChildren,
13
    booleanAttribute,
14
    inject
15
} from '@angular/core';
16
import { GridType, IgxHeadSelectorTemplateContext } from '../common/grid.interface';
17
import { IgxGridFilteringCellComponent } from '../filtering/base/grid-filtering-cell.component';
18
import { IgxGridFilteringRowComponent } from '../filtering/base/grid-filtering-row.component';
19
import { IgxGridHeaderGroupComponent } from './grid-header-group.component';
20
import { IgxGridHeaderComponent } from './grid-header.component';
21
import { IgxHeaderGroupStylePipe } from './pipes';
22
import { IgxGridTopLevelColumns } from '../common/pipes';
23
import { IgxColumnMovingDropDirective } from '../moving/moving.drop.directive';
24
import { NgTemplateOutlet, NgClass, NgStyle } from '@angular/common';
25
import { IgxGridForOfDirective } from 'igniteui-angular/directives';
26
import { IgxCheckboxComponent } from 'igniteui-angular/checkbox';
27
import { ColumnType, flatten, trackByIdentity } from 'igniteui-angular/core';
28

29
/**
30
 *
31
 * For all intents & purposes treat this component as what a <thead> usually is in the default <table> element.
32
 *
33
 * This container holds the grid header elements and their behavior/interactions.
34
 *
35
 * @hidden @internal
36
 */
37
@Component({
38
    changeDetection: ChangeDetectionStrategy.OnPush,
39
    selector: 'igx-grid-header-row',
40
    templateUrl: './grid-header-row.component.html',
41
    imports: [IgxColumnMovingDropDirective, NgTemplateOutlet, NgClass, IgxGridHeaderGroupComponent, NgStyle, IgxGridForOfDirective, IgxGridFilteringRowComponent, IgxCheckboxComponent, IgxGridTopLevelColumns, IgxHeaderGroupStylePipe]
42
})
43
export class IgxGridHeaderRowComponent implements DoCheck {
3✔
44
    protected ref = inject<ElementRef<HTMLElement>>(ElementRef);
5,616✔
45
    protected cdr = inject(ChangeDetectorRef);
5,616✔
46

47

48
    /** The grid component containing this element. */
49
    @Input()
50
    public grid: GridType;
51

52
    /** Pinned columns of the grid at start. */
53
    @Input()
54
    public pinnedStartColumnCollection: ColumnType[] = [];
5,616✔
55

56
    /** Pinned columns of the grid at end. */
57
    @Input()
58
    public pinnedEndColumnCollection: ColumnType[] = [];
5,616✔
59

60

61
    /** Unpinned columns of the grid. */
62
    @Input()
63
    public unpinnedColumnCollection: ColumnType[] = [];
5,616✔
64

65
    @HostBinding('attr.aria-activedescendant')
66
    public get activeDescendant() {
67
        const activeElem = this.navigation.activeNode;
62,017✔
68

69
        if (!activeElem || !Object.keys(activeElem).length || activeElem.row >= 0) {
62,017✔
70
            return null;
60,520✔
71
        }
72
        return `${this.grid.id}_${activeElem.row}_${activeElem.level}_${activeElem.column}`;
1,497✔
73
    }
74

75
    @Input({ transform: booleanAttribute })
76
    public hasMRL: boolean;
77

78
    @Input()
79
    public width: number;
80

81
    /**
82
     * Header groups inside the header row.
83
     *
84
     * @remarks
85
     * Note: These are only the top level header groups in case there are multi-column headers
86
     * or a specific column layout. If you want to get the flattened collection use the `groups`
87
     * property below.
88
     *
89
     * @hidden @internal
90
     * */
91
    @ViewChildren(IgxGridHeaderGroupComponent)
92
    public _groups: QueryList<IgxGridHeaderGroupComponent>;
93

94
    /**
95
     * The flattened header groups collection.
96
     *
97
     * @hidden @internal
98
     */
99
    public get groups(): IgxGridHeaderGroupComponent[] {
100
        return flatten(this._groups?.toArray() ?? []);
21,377✔
101
    }
102

103
    /** Header components in the header row. */
104
    public get headers(): IgxGridHeaderComponent[] {
UNCOV
105
        return this.groups.map(group => group.header);
×
106
    }
107

108
    /** Filtering cell components in the header row. */
109
    public get filters(): IgxGridFilteringCellComponent[] {
UNCOV
110
        return this.groups.map(group => group.filter);
×
111
    }
112

113
    /**
114
     * Gets a list of all visible leaf columns in the grid.
115
     *
116
     * @hidden @internal
117
     */
118
    public get visibleLeafColumns(): ColumnType[] {
119
        const row = this.grid.gridAPI.get_row_by_index(this.grid.rowList.first?.index || 0);
7,559✔
120
        if (row && row.cells) {
7,559✔
121
            return row.cells.map(cell => cell.column);
26,356✔
122
        }
123
    }
124

125
    /**
126
    * @hidden
127
    * @internal
128
    */
129
    public get isLeafHeaderAriaHidden(): boolean {
130
        return this.grid.navigation.activeNode?.row === -1;
26,356✔
131
    }
132

133
    /** The virtualized part of the header row containing the unpinned header groups. */
134
    @ViewChild('headerVirtualContainer', { read: IgxGridForOfDirective, static: true })
135
    public headerContainer: IgxGridForOfDirective<ColumnType, ColumnType[]>;
136

137
    public get headerForOf() {
138
        return this.headerContainer;
14,811✔
139
    }
140

141
    @ViewChild('headerDragContainer')
142
    public headerDragContainer: ElementRef<HTMLElement>;
143

144
    @ViewChild('headerSelectorContainer')
145
    public headerSelectorContainer: ElementRef<HTMLElement>;
146

147
    @ViewChild('headerGroupContainer')
148
    public headerGroupContainer: ElementRef<HTMLElement>;
149

150
    @ViewChild('headSelectorBaseTemplate')
151
    public headSelectorBaseTemplate: TemplateRef<IgxHeadSelectorTemplateContext>;
152

153
    @ViewChild(IgxGridFilteringRowComponent)
154
    public filterRow: IgxGridFilteringRowComponent;
155

156
    /**
157
     * Expand/collapse all child grids area in a hierarchical grid.
158
     * `undefined` in the base and tree grids.
159
     *
160
     * @internal @hidden
161
     */
162
    @ViewChild('headerHierarchyExpander')
163
    public headerHierarchyExpander: ElementRef<HTMLElement>;
164

165
    public get navigation() {
166
        return this.grid.navigation;
66,803✔
167
    }
168

169
    public get nativeElement() {
170
        return this.ref.nativeElement;
11,476✔
171
    }
172

173
    /**
174
     * Returns whether the current grid instance is a hierarchical grid.
175
     * as only hierarchical grids have the `isHierarchicalRecord` method.
176
     *
177
     * @hidden @internal
178
     */
179
    public get isHierarchicalGrid() {
180
        return !!this.grid.isHierarchicalRecord;
47,206✔
181
    }
182

183
    public get indentationCSSClasses() {
184
        return `igx-grid__header-indentation igx-grid__row-indentation--level-${this.grid.groupingExpressions.length}`;
2,149✔
185
    }
186

187
    public get rowSelectorsContext(): IgxHeadSelectorTemplateContext {
188
        const ctx = {
3,345✔
189
            $implicit: {
190
                selectedCount: this.grid.selectionService.filteredSelectedRowIds.length as number,
191
                totalCount: this.grid.totalRowsCountAfterFilter as number
192
            }
193
        } as IgxHeadSelectorTemplateContext;
194

195
        if (this.isHierarchicalGrid) {
3,345✔
196
            ctx.$implicit.selectAll = () => this.grid.selectAllRows();
1,130✔
197
            ctx.$implicit.deselectAll = () => this.grid.deselectAllRows();
1,130✔
198
        }
199

200
        return ctx;
3,345✔
201
    }
202

203
    /**
204
     * This hook exists as a workaround for the unfortunate fact
205
     * that when we have pinned columns in the grid, the unpinned columns headers
206
     * are affected by a delayed change detection cycle after a horizontal scroll :(
207
     * Thus, we tell the parent grid change detector to check us at each cycle.
208
     *
209
     * @hidden @internal
210
     */
211
    public ngDoCheck() {
212
        this.cdr.markForCheck();
63,989✔
213
    }
214

215
    /**
216
     * @hidden @internal
217
     */
218
    public scroll(event: Event) {
UNCOV
219
        this.grid.preventHeaderScroll(event);
×
220
    }
221

222
    public headerRowSelection(event: MouseEvent) {
223
        if (!this.grid.isMultiRowSelectionEnabled) {
45✔
224
            return;
7✔
225
        }
226

227
        if (this.grid.selectionService.areAllRowSelected()) {
38✔
228
            this.grid.selectionService.clearRowSelection(event);
12✔
229
        } else {
230
            this.grid.selectionService.selectAllRows(event);
26✔
231
        }
232
    }
233

234
    /** state persistence switching all pinned columns resets collection */
235
    protected trackPinnedColumn = trackByIdentity;
5,616✔
236
}
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