Skip to content

Commit 238d326

Browse files
authored
Merge pull request #6979 from IgniteUI/skrastev/hgrid-row-pinning
Implement Row Pinning for igxHierarchicalGrid.
2 parents 259d5a8 + ed6f4be commit 238d326

25 files changed

+649
-72
lines changed

projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-component.scss

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,10 @@
358358
@extend %igx-grid__td--editing !optional;
359359
}
360360

361+
@include e(tr, $m: disabled) {
362+
@extend %igx-grid__tr--disabled !optional;
363+
}
364+
361365
@include e(td, $m: number) {
362366
@extend %grid-cell-number !optional;
363367
}
@@ -392,6 +396,10 @@
392396
@extend %grid-cell--pinned--column-selected !optional;
393397
}
394398

399+
@include e(td, $m: pinned-chip) {
400+
@extend %grid-cell--pinned-chip !optional;
401+
}
402+
395403
@include e(td-text) {
396404
@extend %grid-cell-text !optional;
397405
}
@@ -558,6 +566,11 @@
558566
@extend %igx-grid__hierarchical-expander !optional;
559567
}
560568

569+
@include e(hierarchical-expander, $m: empty) {
570+
@extend %igx-grid__hierarchical-expander !optional;
571+
@extend %igx-grid__hierarchical-expander--empty !optional;
572+
}
573+
561574
@include e(hierarchical-expander, $m: header) {
562575
@extend %igx-grid__hierarchical-expander--header !optional;
563576
}
@@ -673,6 +686,11 @@
673686
@extend %igx-grid__hierarchical-expander--cosy !optional;
674687
}
675688

689+
@include e(hierarchical-expander, $m: empty) {
690+
@extend %igx-grid__hierarchical-expander--cosy !optional;
691+
@extend %igx-grid__hierarchical-expander--empty !optional;
692+
}
693+
676694
@include e(hierarchical-expander, $m: push) {
677695
@extend %igx-grid__hierarchical-expander--push--cosy !optional;
678696
}
@@ -688,6 +706,10 @@
688706
@extend %igx-grid__tree-cell-cosy--padding-level-#{$i} !optional;
689707
}
690708
}
709+
710+
@include e(td, $m: pinned-chip) {
711+
@extend %grid-cell--pinned-chip--cosy !optional;
712+
}
691713
}
692714

693715
@include m(compact) {
@@ -772,6 +794,11 @@
772794
@include e(hierarchical-expander) {
773795
@extend %igx-grid__hierarchical-expander--compact !optional;
774796
}
797+
798+
@include e(hierarchical-expander, $m: empty) {
799+
@extend %igx-grid__hierarchical-expander--compact !optional;
800+
@extend %igx-grid__hierarchical-expander--empty !optional;
801+
}
775802

776803
@include e(hierarchical-expander, $m: push) {
777804
@extend %igx-grid__hierarchical-expander--push--compact !optional;
@@ -788,6 +815,10 @@
788815
@extend %igx-grid__tree-cell-compact--padding-level-#{$i} !optional;
789816
}
790817
}
818+
819+
@include e(td, $m: pinned-chip) {
820+
@extend %grid-cell--pinned-chip--compact !optional;
821+
}
791822
}
792823

793824
@include _excel-filtering-partial();

projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-theme.scss

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,8 @@
4949
/// @param {Color} $cell-selected-background [null] - The selected cell background color.
5050
/// @param {Color} $cell-selected-text-color [null] - The selected cell text color.
5151
/// @param {Color} $cell-editing-background [null] - The background color of the cell being edited.
52-
/// @param {Color} $cell-edited-value-color [null] - The text color of a sell that has been edited.
52+
/// @param {Color} $cell-edited-value-color [null] - The text color of a cell that has been edited.
53+
/// @param {Color} $cell-disabled-color [null] - The text color of a disabled cell.
5354
///
5455
/// @param {Color} $edit-mode-color [null] - The color applied around the row when in editing mode.
5556
/// @param {Color} $edited-row-indicator [null] - The color applied to the edited row indicator line.
@@ -160,6 +161,7 @@
160161
$cell-selected-text-color: null,
161162
$cell-editing-background: null,
162163
$cell-edited-value-color: null,
164+
$cell-disabled-color: null,
163165
164166
$edit-mode-color: null,
165167
$edited-row-indicator: null,
@@ -505,6 +507,8 @@
505507
edited-row-indicator: $edited-row-indicator,
506508
cell-edited-value-color: $cell-edited-value-color,
507509

510+
cell-disabled-color: $cell-disabled-color,
511+
508512
resize-line-color: $resize-line-color,
509513

510514
drop-indicator-color: $drop-indicator-color,
@@ -1352,6 +1356,12 @@
13521356
}
13531357
}
13541358

1359+
%igx-grid__tr--disabled {
1360+
%grid-cell-text {
1361+
color: --var($theme, 'cell-disabled-color');
1362+
}
1363+
}
1364+
13551365
%igx-grid__td--editing {
13561366
background: --var($theme, 'cell-editing-background') !important;
13571367
box-shadow: inset 0 0 0 rem(2px) --var($theme, 'edit-mode-color');
@@ -1407,6 +1417,17 @@
14071417
}
14081418
}
14091419

1420+
%grid-cell--pinned-chip {
1421+
margin-#{$right}: rem(12px);
1422+
}
1423+
1424+
%grid-cell--pinned-chip--cosy {
1425+
margin-#{$right}: rem(8px);
1426+
}
1427+
1428+
%grid-cell--pinned-chip--compact {
1429+
margin-#{$right}: rem(4px);
1430+
}
14101431

14111432
%grid-cell-header {
14121433
flex-flow: row nowrap;
@@ -2495,6 +2516,11 @@
24952516
@include if-rtl() {
24962517
transform: scaleX(-1);
24972518
}
2519+
2520+
&--empty {
2521+
cursor: default;
2522+
pointer-events: none;
2523+
}
24982524
}
24992525

25002526
%igx-grid__hierarchical-expander--cosy {

projects/igniteui-angular/src/lib/core/styles/themes/schemas/light/_grid.scss

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
/// @prop {Map} edit-mode-color [igx-color: ('secondary', 500)] - The text color in edit mode.
4848
/// @prop {Map} edited-row-indicator [igx-color: ('grays', 400)] - The indicator's color of edited row.
4949
/// @prop {Map} cell-edited-value-color [igx-color: ('grays', 600)] - The color of cell edited value.
50+
/// @prop {Map} cell-disabled-color [igx-color: ('grays', 500)] - The text color of a disabled cell.
5051
/// @prop {Map} resize-line-color [igx-color: ('secondary', 500)] - The table header resize line color.
5152
/// @prop {Map} drop-indicator-color [igx-color: ('secondary', 500)] - The color of the drop indicator.
5253
/// @prop {Map} grouparea-background [igx-color: ('grays', 100), hexrgba: #fff] - The grid group area background color.
@@ -233,6 +234,10 @@ $_light-grid: extend(
233234
igx-color: ('grays', 600)
234235
),
235236

237+
cell-disabled-color: (
238+
igx-color: ('grays', 500)
239+
),
240+
236241
resize-line-color: (
237242
igx-color: ('secondary', 500)
238243
),

projects/igniteui-angular/src/lib/grids/cell.component.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
<ng-template #defaultCell>
2+
<igx-chip *ngIf="displayPinnedChip" class="igx-grid__td--pinned-chip" [disabled]="true" [displayDensity]="'compact'">Pinned</igx-chip>
23
<div igxTextHighlight style="pointer-events: none" [cssClass]="highlightClass" [activeCssClass]="activeHighlightClass" [groupName]="gridID"
34
[value]="formatter ? formatter(value) : column.dataType === 'number' ? (value | igxdecimal: grid.locale) : column.dataType === 'date' ? (value | igxdate: grid.locale) : value"
45
[row]="rowData" [column]="this.column.field" [containerClass]="'igx-grid__td-text'"

projects/igniteui-angular/src/lib/grids/cell.component.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -374,7 +374,7 @@ export class IgxGridCellComponent implements OnInit, OnChanges, OnDestroy {
374374
*/
375375
@HostBinding('attr.aria-readonly')
376376
get readonly(): boolean {
377-
return !this.column.editable;
377+
return !this.editable;
378378
}
379379

380380
get gridRowSpan(): number {
@@ -523,7 +523,14 @@ export class IgxGridCellComponent implements OnInit, OnChanges, OnDestroy {
523523
* Returns whether the cell is editable.
524524
*/
525525
get editable(): boolean {
526-
return this.column.editable;
526+
return this.column.editable && !this.row.disabled;
527+
}
528+
529+
/**
530+
* @hidden
531+
*/
532+
public get displayPinnedChip() {
533+
return this.row.pinned && this.row.disabled && this.visibleColumnIndex === 0 && !(this.column as any).cellTemplate;
527534
}
528535

529536
@ViewChild('defaultCell', { read: TemplateRef, static: true })

projects/igniteui-angular/src/lib/grids/common/row.interface.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,12 @@ export interface RowType {
55
checkboxElement: IgxCheckboxComponent;
66
rowID: any;
77
rowData: any;
8+
disabled: boolean;
89
rowSelectable: boolean;
910
index: number;
1011
gridID: string;
1112
added: boolean;
13+
pinned: boolean;
1214
deleted: boolean;
1315
selected: boolean;
1416
focused: boolean;

projects/igniteui-angular/src/lib/grids/grid-base.directive.ts

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5140,6 +5140,17 @@ export class IgxGridBaseDirective extends DisplayDensityBase implements
51405140
return this.verticalScrollContainer.igxForOf;
51415141
}
51425142

5143+
/**
5144+
* Returns the currently transformed paged/filtered/sorted/grouped pinned data, displayed in the grid.
5145+
* @example
5146+
* ```typescript
5147+
* const pinnedDataView = this.grid.pinnedDataView;
5148+
* ```
5149+
*/
5150+
get pinnedDataView(): any[] {
5151+
return this.pinnedRows.map(row => row.rowData);
5152+
}
5153+
51435154
/**
51445155
* Get current selection state.
51455156
* @example
@@ -5344,8 +5355,8 @@ export class IgxGridBaseDirective extends DisplayDensityBase implements
53445355
columnsArray.forEach((col) => {
53455356
if (col) {
53465357
const key = headers ? col.header || col.field : col.field;
5347-
record[key] = formatters && col.formatter ? col.formatter(source[row][col.field])
5348-
: source[row][col.field];
5358+
const value = source[row].ghostRecord ? source[row].recordRef[col.field] : source[row][col.field];
5359+
record[key] = formatters && col.formatter ? col.formatter(value) : value;
53495360
}
53505361
});
53515362
}
@@ -5380,7 +5391,7 @@ export class IgxGridBaseDirective extends DisplayDensityBase implements
53805391
* If `headers` is enabled, it will use the column header (if any) instead of the column field.
53815392
*/
53825393
public getSelectedData(formatters = false, headers = false) {
5383-
const source = this.dataView;
5394+
const source = this.isRowPinningToTop ? [...this.pinnedDataView, ...this.dataView] : [...this.dataView, ...this.pinnedDataView];
53845395
return this.extractDataFromSelection(source, formatters, headers);
53855396
}
53865397

projects/igniteui-angular/src/lib/grids/grid-navigation.service.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -102,8 +102,8 @@ export class IgxGridNavigationService {
102102
break;
103103
case 'enter':
104104
case 'f2':
105-
if (!this.isDataRow(rowIndex)) { break; }
106105
const cell = this.grid.getCellByColumnVisibleIndex(this.activeNode.row, this.activeNode.column);
106+
if (!this.isDataRow(rowIndex) || !cell.editable) { break; }
107107
this.grid.crudService.enterEditMode(cell);
108108
break;
109109
case 'escape':
@@ -114,8 +114,8 @@ export class IgxGridNavigationService {
114114
case ' ':
115115
case 'spacebar':
116116
case 'space':
117-
if (this.grid.isRowSelectable && this.isDataRow(rowIndex)) {
118-
const rowObj = this.grid.getRowByIndex(this.activeNode.row);
117+
const rowObj = this.grid.getRowByIndex(this.activeNode.row);
118+
if (this.grid.isRowSelectable && this.isDataRow(rowIndex) && !rowObj.disabled) {
119119
rowObj && rowObj.selected ? this.grid.selectionService.deselectRow(rowObj.rowID, event) :
120120
this.grid.selectionService.selectRowById(rowObj.rowID, false, event);
121121
}

projects/igniteui-angular/src/lib/grids/grid/grid-row.component.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@
7777
[tabindex]="-1"
7878
[checked]="selected"
7979
[readonly]="true"
80-
[disabled]="deleted"
80+
[disabled]="disabled || deleted"
8181
disableRipple="true"
8282
[disableTransitions]="grid.disableTransitions"
8383
[aria-label]="rowCheckboxAriaLabel">

projects/igniteui-angular/src/lib/grids/grid/row-pinning.spec.ts

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import { IgxGridTransaction } from '../tree-grid';
1515
import { IgxTransactionService } from '../../services';
1616
import { GridSummaryFunctions } from '../../test-utils/grid-functions.spec';
1717
import { IgxStringFilteringOperand } from '../../data-operations/filtering-condition';
18+
import { IgxPaginatorComponent } from '../../paginator/paginator.component';
1819

1920
describe('Row Pinning #grid', () => {
2021
const FIXED_ROW_CONTAINER = '.igx-grid__tr--pinned ';
@@ -401,26 +402,40 @@ describe('Row Pinning #grid', () => {
401402
grid.paging = true;
402403
grid.perPage = 5;
403404
fix.detectChanges();
404-
let row = grid.getRowByIndex(1);
405-
row.pin();
405+
const paginator = fix.debugElement.query(By.directive(IgxPaginatorComponent));
406+
expect(paginator.componentInstance.totalPages).toEqual(6);
407+
408+
grid.getRowByIndex(1).pin();
406409
fix.detectChanges();
407410

408411
expect(grid.pinnedRows.length).toBe(1);
409412
let pinRowContainer = fix.debugElement.queryAll(By.css(FIXED_ROW_CONTAINER));
410413
expect(pinRowContainer.length).toBe(1);
411-
412414
expect(grid.dataView.length).toBe(4);
415+
expect(paginator.componentInstance.totalPages).toEqual(6);
416+
417+
grid.getRowByIndex(3).pin();
418+
fix.detectChanges();
419+
420+
expect(grid.pinnedRows.length).toBe(2);
421+
pinRowContainer = fix.debugElement.queryAll(By.css(FIXED_ROW_CONTAINER));
422+
expect(pinRowContainer.length).toBe(1);
423+
expect(grid.dataView.length).toBe(3);
424+
expect(paginator.componentInstance.totalPages).toEqual(5);
413425

414426
// unpin
415-
row = grid.getRowByIndex(0);
416-
row.unpin();
427+
grid.getRowByIndex(0).unpin();
428+
fix.detectChanges();
429+
430+
grid.getRowByIndex(0).unpin();
417431
fix.detectChanges();
418432

419433
expect(grid.pinnedRows.length).toBe(0);
420434
pinRowContainer = fix.debugElement.queryAll(By.css(FIXED_ROW_CONTAINER));
421435
expect(pinRowContainer.length).toBe(0);
422436

423437
expect(grid.dataView.length).toBe(5);
438+
expect(paginator.componentInstance.totalPages).toEqual(6);
424439
});
425440

426441
it('should apply sorting to both pinned and unpinned rows.', () => {

0 commit comments

Comments
 (0)