• 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

38.03
/projects/igniteui-angular/src/lib/grids/headers/grid-header.component.ts
1
import {
2
    ChangeDetectionStrategy,
3
    ChangeDetectorRef,
4
    Component,
5
    DoCheck,
6
    ElementRef,
7
    HostBinding,
8
    HostListener,
9
    Inject,
10
    Input,
11
    OnDestroy,
12
    TemplateRef,
13
    ViewChild
14
} from '@angular/core';
15
import { GridColumnDataType } from '../../data-operations/data-util';
16
import { IgxColumnResizingService } from '../resizing/resizing.service';
17
import { Subject } from 'rxjs';
18
import { ColumnType, GridType, IGX_GRID_BASE } from '../common/grid.interface';
19
import { GridSelectionMode } from '../common/enums';
20
import { SortingDirection } from '../../data-operations/sorting-strategy';
21
import { SortingIndexPipe } from './pipes';
22
import { NgTemplateOutlet, NgIf, NgClass } from '@angular/common';
23
import { IgxIconComponent } from '../../icon/icon.component';
24
import { ExpressionsTreeUtil } from '../../data-operations/expressions-tree-util';
25

26
/**
27
 * @hidden
28
 */
29
@Component({
30
    changeDetection: ChangeDetectionStrategy.OnPush,
31
    selector: 'igx-grid-header',
32
    templateUrl: 'grid-header.component.html',
33
    imports: [IgxIconComponent, NgTemplateOutlet, NgIf, NgClass, SortingIndexPipe]
34
})
35
export class IgxGridHeaderComponent implements DoCheck, OnDestroy {
2✔
36

37
    @Input()
38
    public column: ColumnType;
39

40
    /**
41
     * @hidden
42
     */
43
    @ViewChild('defaultESFHeaderIconTemplate', { read: TemplateRef, static: true })
44
    protected defaultESFHeaderIconTemplate: TemplateRef<any>;
45

46
    /**
47
     * @hidden
48
     */
49
    @ViewChild('defaultSortHeaderIconTemplate', { read: TemplateRef, static: true })
50
    protected defaultSortHeaderIconTemplate;
51

52
    /**
53
     * @hidden
54
     */
55
    @ViewChild('sortIconContainer', { read: ElementRef })
56
    protected sortIconContainer: ElementRef;
57

58
    /**
59
     * Returns the `aria-selected` of the header.
60
     */
61
    @HostBinding('attr.aria-selected')
62
    public get ariaSelected(): boolean {
63
        return this.column.selected;
2,327✔
64
    }
65

66
    @HostBinding('class.igx-grid-th')
67
    public get columnGroupStyle() {
68
        return !this.column.columnGroup;
2,327✔
69
    }
70

71
    @HostBinding('class.asc')
72
    public get sortAscendingStyle() {
73
        return this.sortDirection === SortingDirection.Asc;
2,327✔
74
    }
75

76
    @HostBinding('class.desc')
77
    public get sortDescendingStyle() {
78
        return this.sortDirection === SortingDirection.Desc;
2,327✔
79
    }
80

81
    @HostBinding('class.igx-grid-th--number')
82
    public get numberStyle() {
83
        return this.column.dataType === GridColumnDataType.Number;
2,327✔
84
    }
85

86
    @HostBinding('class.igx-grid-th--sortable')
87
    public get sortableStyle() {
88
        return this.column.sortable;
2,327✔
89
    }
90

91
    @HostBinding('class.igx-grid-th--selectable')
92
    public get selectableStyle() {
93
        return this.selectable;
2,327✔
94
    }
95

96
    @HostBinding('class.igx-grid-th--filtrable')
97
    public get filterableStyle() {
98
        return this.column.filterable && this.grid.filteringService.isFilterRowVisible;
2,327✔
99
    }
100

101
    @HostBinding('class.igx-grid-th--sorted')
102
    public get sortedStyle() {
103
        return this.sorted;
2,327✔
104
    }
105

106
    @HostBinding('class.igx-grid-th--selected')
107
    public get selectedStyle() {
108
        return this.selected;
2,327✔
109
    }
110

111
    /**
112
     * @hidden
113
     */
114
    public get esfIconTemplate() {
UNCOV
115
        return this.grid.excelStyleHeaderIconTemplate || this.defaultESFHeaderIconTemplate;
×
116
    }
117

118
    /**
119
     * @hidden
120
     */
121
    public get sortIconTemplate() {
UNCOV
122
        if (this.sortDirection === SortingDirection.None && this.grid.sortHeaderIconTemplate) {
×
UNCOV
123
            return this.grid.sortHeaderIconTemplate;
×
UNCOV
124
        } else if (this.sortDirection === SortingDirection.Asc && this.grid.sortAscendingHeaderIconTemplate) {
×
UNCOV
125
            return this.grid.sortAscendingHeaderIconTemplate;
×
UNCOV
126
        } else if (this.sortDirection === SortingDirection.Desc && this.grid.sortDescendingHeaderIconTemplate) {
×
UNCOV
127
            return this.grid.sortDescendingHeaderIconTemplate;
×
128
        } else {
UNCOV
129
            return this.defaultSortHeaderIconTemplate;
×
130
        }
131
    }
132
    /**
133
     * @hidden
134
     */
135
    public get disabled() {
UNCOV
136
        const groupArea = this.grid.groupArea || this.grid.treeGroupArea;
×
UNCOV
137
        if (groupArea?.expressions && groupArea.expressions.length && groupArea.expressions.map(g => g.fieldName).includes(this.column.field)) {
×
UNCOV
138
            return true;
×
139
        }
UNCOV
140
        return false;
×
141
    }
142

143
    public get sorted() {
144
        return this.sortDirection !== SortingDirection.None;
2,327✔
145
    }
146

147
    public get filterIconClassName() {
UNCOV
148
        return this.column.filteringExpressionsTree || this.isAdvancedFilterApplied() ? 'igx-excel-filter__icon--filtered' : 'igx-excel-filter__icon';
×
149
    }
150

151
    public get selectable() {
152
        return this.grid.columnSelection !== GridSelectionMode.none &&
2,327!
153
            this.column.applySelectableClass &&
154
            !this.column.selected &&
155
            !this.grid.filteringService.isFilterRowVisible;
156
    }
157

158
    public get selected() {
159
        return this.column.selected
2,327!
160
            && (!this.grid.filteringService.isFilterRowVisible || this.grid.filteringService.filteredColumn !== this.column);
161
    }
162

163
    public get title() {
164
        return this.column.title || this.column.header || this.column.field;
2,327✔
165
    }
166

167
    public get nativeElement() {
UNCOV
168
        return this.ref.nativeElement;
×
169
    }
170

171
    public sortDirection = SortingDirection.None;
246✔
172
    protected _destroy$ = new Subject<boolean>();
246✔
173

174
    constructor(
175
        @Inject(IGX_GRID_BASE) public grid: GridType,
246✔
176
        public colResizingService: IgxColumnResizingService,
246✔
177
        public cdr: ChangeDetectorRef,
246✔
178
        private ref: ElementRef<HTMLElement>
246✔
179
    ) { }
180

181
    @HostListener('click', ['$event'])
182
    public onClick(event: MouseEvent) {
UNCOV
183
        if (!this.colResizingService.isColumnResizing) {
×
184

UNCOV
185
            if (this.grid.filteringService.isFilterRowVisible) {
×
UNCOV
186
                if (this.column.filterCellTemplate) {
×
UNCOV
187
                    this.grid.filteringRow.close();
×
UNCOV
188
                    return;
×
189
                }
190

UNCOV
191
                if (this.column.filterable && !this.column.columnGroup &&
×
192
                    !this.grid.filteringService.isFilterComplex(this.column.field)) {
UNCOV
193
                    this.grid.filteringService.filteredColumn = this.column;
×
194
                }
UNCOV
195
            } else if (this.grid.columnSelection !== GridSelectionMode.none && this.column.selectable) {
×
UNCOV
196
                const clearSelection = this.grid.columnSelection === GridSelectionMode.single || !event.ctrlKey;
×
UNCOV
197
                const rangeSelection = this.grid.columnSelection === GridSelectionMode.multiple && event.shiftKey;
×
198

UNCOV
199
                if (!this.column.selected || (this.grid.selectionService.getSelectedColumns().length > 1 && clearSelection)) {
×
UNCOV
200
                    this.grid.selectionService.selectColumn(this.column.field, clearSelection, rangeSelection, event);
×
201
                } else {
UNCOV
202
                    this.grid.selectionService.deselectColumn(this.column.field, event);
×
203
                }
204
            }
205
        }
UNCOV
206
        this.grid.theadRow.nativeElement.focus();
×
207
    }
208

209
    /**
210
     * @hidden
211
     */
212
    @HostListener('pointerenter')
213
    public onPinterEnter() {
UNCOV
214
        this.column.applySelectableClass = true;
×
215
    }
216

217
    /**
218
     * @hidden
219
     */
220
    @HostListener('pointerleave')
221
    public onPointerLeave() {
UNCOV
222
        this.column.applySelectableClass = false;
×
223
    }
224

225
    /**
226
     * @hidden @internal
227
     */
228
    public ngDoCheck() {
229
        this.getSortDirection();
2,327✔
230
        this.cdr.markForCheck();
2,327✔
231
    }
232

233
    /**
234
     * @hidden @internal
235
     */
236
    public ngOnDestroy(): void {
237
        this._destroy$.next(true);
246✔
238
        this._destroy$.complete();
246✔
239
    }
240

241
    /**
242
     * @hidden @internal
243
     */
244
    public onPointerDownIndicator(event) {
245
        // Stop propagation of pointer events to now allow column dragging using the header indicators.
UNCOV
246
        event.stopPropagation();
×
247
    }
248

249
    /**
250
     * @hidden @internal
251
     */
252
    public onFilteringIconClick(event) {
UNCOV
253
        event.stopPropagation();
×
UNCOV
254
        this.grid.filteringService.toggleFilterDropdown(this.nativeElement, this.column);
×
255
    }
256

257
    /**
258
     * @hidden @internal
259
     */
260
    public onSortingIconClick(event) {
UNCOV
261
        event.stopPropagation();
×
UNCOV
262
        this.triggerSort();
×
263
    }
264

265
    protected getSortDirection() {
266
        const expr = this.grid.sortingExpressions.find((x) => x.fieldName === this.column.field);
2,327✔
267
        this.sortDirection = expr ? expr.dir : SortingDirection.None;
2,327!
268
    }
269

270
    protected isAdvancedFilterApplied() {
UNCOV
271
        if(!this.grid.advancedFilteringExpressionsTree) {
×
UNCOV
272
            return false;
×
273
        }
274
        return !!ExpressionsTreeUtil.find(this.grid.advancedFilteringExpressionsTree, this.column.field);
×
275
    }
276

277
    private triggerSort() {
UNCOV
278
        const groupingExpr = this.grid.groupingExpressions ?
×
279
            this.grid.groupingExpressions.find((expr) => expr.fieldName === this.column.field) :
×
280
            this.grid.groupArea?.expressions ? this.grid.groupArea?.expressions.find((expr) => expr.fieldName === this.column.field) : null;
×
UNCOV
281
        const sortDir = groupingExpr ?
×
282
            this.sortDirection + 1 > SortingDirection.Desc ? SortingDirection.Asc : SortingDirection.Desc
×
283
            : this.sortDirection + 1 > SortingDirection.Desc ? SortingDirection.None : this.sortDirection + 1;
×
UNCOV
284
        this.sortDirection = sortDir;
×
UNCOV
285
        this.grid.sort({
×
286
            fieldName: this.column.field, dir: this.sortDirection, ignoreCase: this.column.sortingIgnoreCase,
287
            strategy: this.column.sortStrategy
288
        });
289
    }
290
}
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