Skip to content

Commit 31eb5c3

Browse files
authored
Merge branch 'master' into mdragnev/add-row-tests
2 parents be3947b + de253a6 commit 31eb5c3

14 files changed

+138
-43
lines changed

projects/igniteui-angular/src/lib/action-strip/grid-actions/grid-editing-actions.component.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ export class IgxGridEditingActionsComponent extends IgxGridActionsBaseDirective
104104
const context = this.strip.context;
105105
const grid = context.grid;
106106
if (!grid.rowEditable) {
107-
console.warn('The grid must be in row edit mode to perform row adding!');
107+
console.warn('The grid must use row edit mode to perform row adding! Please set rowEditable to true.');
108108
return;
109109
}
110110
grid.beginAddRowByIndex(context.rowID, context.index, asChild);

projects/igniteui-angular/src/lib/grids/common/pipes.ts

+7-3
Original file line numberDiff line numberDiff line change
@@ -370,9 +370,9 @@ export class IgxGridAddRowPipe implements PipeTransform {
370370

371371
constructor(private gridAPI: GridBaseAPIService<IgxGridBaseDirective & GridType>) { }
372372

373-
transform(collection: any, pipeTrigger: number) {
373+
transform(collection: any, isPinned = false, pipeTrigger: number) {
374374
const grid = this.gridAPI.grid;
375-
if (!grid.rowEditable || !grid.addRowParent || grid.cancelAddMode) {
375+
if (!grid.rowEditable || !grid.addRowParent || grid.cancelAddMode || isPinned !== grid.addRowParent.isPinned) {
376376
return collection;
377377
}
378378
const copy = collection.slice(0);
@@ -383,7 +383,11 @@ export class IgxGridAddRowPipe implements PipeTransform {
383383
addRow: true
384384
};
385385
copy.splice(parentIndex + 1, 0, rec);
386-
grid.unpinnedRecords = copy;
386+
if (isPinned) {
387+
grid.pinnedRecords = copy;
388+
} else {
389+
grid.unpinnedRecords = copy;
390+
}
387391
return copy;
388392
}
389393
}

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

+38-18
Original file line numberDiff line numberDiff line change
@@ -4082,33 +4082,43 @@ export abstract class IgxGridBaseDirective extends DisplayDensityBase implements
40824082
* @hidden @internal
40834083
*/
40844084
public beginAddRowByIndex(rowID: any, index: number, asChild?: boolean) {
4085+
if (!this.rowEditable) {
4086+
console.warn('The grid must use row edit mode to perform row adding! Please set rowEditable to true.');
4087+
return;
4088+
}
40854089
this.endEdit(true);
40864090
this.cancelAddMode = false;
4091+
const isInPinnedArea = this.isRecordPinnedByViewIndex(index);
4092+
const pinIndex = this.pinnedRecords.findIndex(x => x[this.primaryKey] === rowID);
4093+
const unpinIndex = this.getUnpinnedIndexById(rowID);
40874094

40884095
if (this.expansionStates.get(rowID)) {
40894096
this.collapseRow(rowID);
40904097
}
40914098

40924099
this.addRowParent = {
40934100
rowID: rowID,
4094-
index: index,
4095-
asChild: asChild
4101+
index: isInPinnedArea ? pinIndex : unpinIndex,
4102+
asChild: asChild,
4103+
isPinned: isInPinnedArea
40964104
};
4097-
this.verticalScrollContainer.onDataChanged.pipe(first()).subscribe(() => {
4098-
this.cdr.detectChanges();
4099-
const newRowIndex = this.addRowParent.index + 1;
4100-
// ensure adding row is in view.
4101-
const shouldScroll = this.navigation.shouldPerformVerticalScroll(newRowIndex, -1);
4102-
if (shouldScroll) {
4103-
this.navigateTo(newRowIndex, -1);
4104-
}
4105-
const row = this.getRowByIndex(newRowIndex);
4106-
const cell = row.cells.find(c => c.editable);
4105+
this._pipeTrigger++;
4106+
this.cdr.detectChanges();
4107+
if (isInPinnedArea) {
4108+
this.calculateGridHeight();
4109+
}
4110+
const newRowIndex = this.addRowParent.index + 1;
4111+
// ensure adding row is in view.
4112+
const shouldScroll = this.navigation.shouldPerformVerticalScroll(newRowIndex, -1);
4113+
if (shouldScroll) {
4114+
this.navigateTo(newRowIndex, -1);
4115+
}
4116+
const row = this.getRowByIndex(index + 1);
4117+
const cell = row.cells.find(c => c.editable);
4118+
if (cell) {
41074119
cell.setEditMode(true);
41084120
cell.activate();
4109-
});
4110-
this._pipeTrigger++;
4111-
this.notifyChanges();
4121+
}
41124122
}
41134123

41144124
/**
@@ -4404,6 +4414,7 @@ export abstract class IgxGridBaseDirective extends DisplayDensityBase implements
44044414
this.endEdit(true);
44054415
this.selectionService.clearHeaderCBState();
44064416
this.summaryService.clearSummaryCache();
4417+
this.cdr.detectChanges();
44074418
}
44084419

44094420
// TODO: We have return values here. Move them to event args ??
@@ -6594,9 +6605,11 @@ export abstract class IgxGridBaseDirective extends DisplayDensityBase implements
65946605
return;
65956606
}
65966607
if (commit) {
6597-
this.onRowAdded.pipe(first()).subscribe(rowData => {
6608+
this.onRowAdded.pipe(first()).subscribe((args: IRowDataEventArgs) => {
6609+
const rowData = args.data;
6610+
const pinnedIndex = this.pinnedRecords.findIndex(x => x[this.primaryKey] === rowData[this.primaryKey]);
65986611
// A check whether the row is in the current view
6599-
const viewIndex = this.findRecordIndexInView(rowData);
6612+
const viewIndex = pinnedIndex !== -1 ? pinnedIndex : this.findRecordIndexInView(rowData);
66006613
const dataIndex = this.filteredSortedData.findIndex(data => data[this.primaryKey] === rowData[this.primaryKey]);
66016614
const isInView = viewIndex !== -1 && !this.navigation.shouldPerformVerticalScroll(viewIndex, 0);
66026615
const showIndex = isInView ? -1 : dataIndex;
@@ -6605,6 +6618,9 @@ export abstract class IgxGridBaseDirective extends DisplayDensityBase implements
66056618
this.gridAPI.submit_add_value();
66066619
this.gridAPI.addRowToData(row.data, this.addRowParent.asChild ? this.addRowParent.rowID : undefined);
66076620
this.crudService.endRowEdit();
6621+
if (this.addRowParent.isPinned) {
6622+
this.pinRow(row.id);
6623+
}
66086624
this.addRowParent = null;
66096625
} else {
66106626
this.crudService.exitCellEdit();
@@ -6615,7 +6631,7 @@ export abstract class IgxGridBaseDirective extends DisplayDensityBase implements
66156631
this._pipeTrigger++;
66166632
if (!this.cancelAddMode) {
66176633
this.cdr.detectChanges();
6618-
this.onRowAdded.emit(row.data);
6634+
this.onRowAdded.emit({ data: row.data});
66196635
}
66206636
}
66216637

@@ -6640,6 +6656,10 @@ export abstract class IgxGridBaseDirective extends DisplayDensityBase implements
66406656
return this.dataView.findIndex(data => data[this.primaryKey] === rec[this.primaryKey]);
66416657
}
66426658

6659+
protected getUnpinnedIndexById(id) {
6660+
return this.unpinnedRecords.findIndex(x => x[this.primaryKey] === id);
6661+
}
6662+
66436663
/**
66446664
* @hidden
66456665
*/

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

+47-1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import { IgxStringFilteringOperand } from '../../data-operations/filtering-condi
1818
import { SortingDirection } from '../../data-operations/sorting-expression.interface';
1919
import { DefaultSortingStrategy } from '../../data-operations/sorting-strategy';
2020
import { TransactionType } from '../../services/public_api';
21+
import { IgxGridRowComponent } from './grid-row.component';
2122

2223

2324
describe('IgxGrid - Row Adding #grid', () => {
@@ -27,7 +28,7 @@ describe('IgxGrid - Row Adding #grid', () => {
2728
let gridContent: DebugElement;
2829
let actionStrip: IgxActionStripComponent;
2930
configureTestSuite();
30-
beforeAll(async(() => {
31+
beforeAll( async(() => {
3132
TestBed.configureTestingModule({
3233
declarations: [
3334
IgxAddRowComponent,
@@ -146,6 +147,51 @@ describe('IgxGrid - Row Adding #grid', () => {
146147
expect(grid.getRowByIndex(1).addRow).toBeFalse();
147148
});
148149

150+
it('Should allow adding row from pinned row.', () => {
151+
let row = grid.getRowByIndex(0);
152+
row.pin();
153+
fixture.detectChanges();
154+
expect(grid.pinnedRecords.length).toBe(1);
155+
156+
row = grid.getRowByIndex(0);
157+
row.beginAddRow();
158+
fixture.detectChanges();
159+
160+
// add row should be pinned
161+
const addRow = grid.getRowByIndex(1) as IgxGridRowComponent;
162+
expect(addRow.addRow).toBe(true);
163+
expect(grid.pinnedRows[1]).toBe(addRow);
164+
165+
grid.endEdit(true);
166+
fixture.detectChanges();
167+
168+
// added record should be pinned.
169+
expect(grid.pinnedRecords.length).toBe(2);
170+
expect(grid.pinnedRecords[1]).toBe(grid.data[grid.data.length - 1]);
171+
172+
});
173+
it('Should allow adding row from ghost row.', () => {
174+
const row = grid.getRowByIndex(0);
175+
row.pin();
176+
fixture.detectChanges();
177+
expect(grid.pinnedRecords.length).toBe(1);
178+
179+
const ghostRow = grid.getRowByIndex(1);
180+
ghostRow.beginAddRow();
181+
fixture.detectChanges();
182+
183+
// add row should be unpinned
184+
const addRow = grid.getRowByIndex(2);
185+
expect(addRow.addRow).toBe(true);
186+
expect(grid.pinnedRows.length).toBe(1);
187+
188+
grid.endEdit(true);
189+
fixture.detectChanges();
190+
191+
// added record should be unpinned.
192+
expect(grid.pinnedRecords.length).toBe(1);
193+
expect(grid.unpinnedRecords[grid.unpinnedRecords.length - 1]).toBe(grid.data[grid.data.length - 1]);
194+
});
149195
it('should navigate to added row on snackbar button click.', async() => {
150196
const rows = grid.rowList.toArray();
151197
const dataCount = grid.data.length;

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

+5-4
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,8 @@
117117
| visibleColumns:hasVisibleColumns
118118
| gridRowPinning:id:true:pipeTrigger
119119
| gridFiltering:filteringExpressionsTree:filterStrategy:advancedFilteringExpressionsTree:id:pipeTrigger:filteringPipeTrigger:true
120-
| gridSort:sortingExpressions:sortStrategy:id:pipeTrigger:true as pinnedData'>
120+
| gridSort:sortingExpressions:sortStrategy:id:pipeTrigger:true
121+
| gridAddRow:true:pipeTrigger as pinnedData'>
121122
<div #pinContainer *ngIf='pinnedData.length > 0'
122123
[ngClass]="{
123124
'igx-grid__tr--pinned-bottom': !isRowPinningToTop,
@@ -141,7 +142,7 @@
141142
| gridSummary:hasSummarizedColumns:summaryCalculationMode:summaryPosition:id:showSummaryOnCollapse:pipeTrigger:summaryPipeTrigger
142143
| gridDetails:hasDetails:expansionStates:pipeTrigger
143144
| gridRowPinning:id:false:pipeTrigger
144-
| gridAddRow:pipeTrigger"
145+
| gridAddRow:false:pipeTrigger"
145146
let-rowIndex="index" [igxForScrollOrientation]="'vertical'" [igxForScrollContainer]='verticalScroll'
146147
[igxForContainerSize]='calcHeight'
147148
[igxForItemSize]="hasColumnLayouts ? rowHeight * multiRowLayoutRowSize + 1 : renderedRowHeight"
@@ -161,8 +162,8 @@
161162
<igx-grid-row [gridID]="id" [index]="rowIndex" [rowData]="rowData" [disabled]="disabledRow" [addRow]="isAddRow" #row>
162163
</igx-grid-row>
163164
</ng-template>
164-
<ng-template #pinned_record_template let-rowIndex="index" let-rowData>
165-
<igx-grid-row [gridID]="id" [index]="rowIndex" [rowData]="rowData" #row #pinnedRow>
165+
<ng-template #pinned_record_template let-rowIndex="index" let-rowData let-isAddRow="addRow">
166+
<igx-grid-row [gridID]="id" [index]="rowIndex" [rowData]="rowData" [addRow]="isAddRow" #row #pinnedRow>
166167
</igx-grid-row>
167168
</ng-template>
168169
<ng-template #group_template let-rowIndex="index" let-rowData>

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

+5-4
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,8 @@
9999
| visibleColumns:hasVisibleColumns
100100
| gridRowPinning:id:true:pipeTrigger
101101
| gridFiltering:filteringExpressionsTree:filterStrategy:advancedFilteringExpressionsTree:id:pipeTrigger:filteringPipeTrigger:true
102-
| gridSort:sortingExpressions:sortStrategy:id:pipeTrigger:true as pinnedData">
102+
| gridSort:sortingExpressions:sortStrategy:id:pipeTrigger:true
103+
| gridAddRow:true:pipeTrigger as pinnedData">
103104
<div #pinContainer *ngIf='pinnedData.length > 0' class='igx-grid__tr--pinned'
104105
[ngClass]="{ 'igx-grid__tr--pinned-bottom': !isRowPinningToTop, 'igx-grid__tr--pinned-top': isRowPinningToTop }"
105106
[style.width.px]='calcWidth'>
@@ -120,7 +121,7 @@
120121
| gridHierarchicalPaging:page:perPage:id:pipeTrigger
121122
| gridHierarchical:expansionStates:id:primaryKey:childLayoutKeys:pipeTrigger
122123
| gridRowPinning:id:false:pipeTrigger
123-
| gridAddRow:pipeTrigger"
124+
| gridAddRow:false:pipeTrigger"
124125
[igxForScrollOrientation]="'vertical'" [igxForScrollContainer]='verticalScroll'
125126
[igxForContainerSize]='calcHeight' [igxForItemSize]="renderedRowHeight" [igxForTrackBy]='trackChanges'
126127
#verticalScrollContainer (onChunkPreload)="dataLoading($event)">
@@ -136,8 +137,8 @@
136137
</igx-hierarchical-grid-row>
137138
</ng-template>
138139

139-
<ng-template #pinned_hierarchical_record_template let-rowIndex="index" let-rowData>
140-
<igx-hierarchical-grid-row [gridID]="id" [index]="rowIndex" [rowData]="rowData" #row #pinnedRow>
140+
<ng-template #pinned_hierarchical_record_template let-rowIndex="index" let-rowData let-isAddRow="addRow">
141+
<igx-hierarchical-grid-row [gridID]="id" [index]="rowIndex" [rowData]="rowData" [addRow]="isAddRow" #row #pinnedRow>
141142
</igx-hierarchical-grid-row>
142143
</ng-template>
143144
<ng-template #child_record_template let-rowIndex="index" let-rowData>

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

-4
Original file line numberDiff line numberDiff line change
@@ -265,10 +265,6 @@ export class IgxTreeGridAPIService extends GridBaseAPIService<IgxTreeGridCompone
265265
}
266266
}
267267
} else {
268-
if (this.grid.primaryKey && this.grid.foreignKey) {
269-
const rowID = data[this.grid.foreignKey];
270-
this.grid.summaryService.clearSummaryCache({rowID: rowID});
271-
}
272268
super.addRowToData(data);
273269
}
274270
}

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

+6-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,12 @@ export class IgxTreeGridRowComponent extends IgxRowDirective<IgxTreeGridComponen
5050
* @hidden
5151
*/
5252
public get isRoot(): boolean {
53-
return this.treeRow.level === 0;
53+
let treeRec = this.treeRow;
54+
const isPinnedArea = this.pinned && !this.disabled;
55+
if (isPinnedArea) {
56+
treeRec = this.grid.unpinnedRecords.find(x => x.data === this.rowData);
57+
}
58+
return treeRec.level === 0;
5459
}
5560

5661
/**

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

+5-4
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,8 @@
8181
| treeGridNormalizeRecord:pipeTrigger
8282
| gridRowPinning:id:true:pipeTrigger
8383
| treeGridFiltering:filteringExpressionsTree:filterStrategy:advancedFilteringExpressionsTree:id:pipeTrigger:filteringPipeTrigger:true
84-
| treeGridSorting:sortingExpressions:sortStrategy:id:pipeTrigger:true as pinnedData'>
84+
| treeGridSorting:sortingExpressions:sortStrategy:id:pipeTrigger:true
85+
| gridAddRow:true:pipeTrigger as pinnedData'>
8586
<div #pinContainer *ngIf='pinnedData.length > 0'
8687
[ngClass]="{
8788
'igx-grid__tr--pinned-bottom': !isRowPinningToTop,
@@ -106,7 +107,7 @@
106107
| treeGridPaging:page:perPage:id:pipeTrigger
107108
| treeGridSummary:hasSummarizedColumns:summaryCalculationMode:summaryPosition:showSummaryOnCollapse:id:pipeTrigger:summaryPipeTrigger
108109
| gridRowPinning:id:false:pipeTrigger
109-
| gridAddRow:pipeTrigger"
110+
| gridAddRow:false:pipeTrigger"
110111
let-rowIndex="index" [igxForScrollOrientation]="'vertical'" [igxForScrollContainer]='verticalScroll'
111112
[igxForContainerSize]='calcHeight' [igxForItemSize]="renderedRowHeight" #verticalScrollContainer>
112113
<ng-template [igxTemplateOutlet]='isSummaryRow(rowData) ? summary_template : record_template'
@@ -119,8 +120,8 @@
119120
<igx-tree-grid-row [gridID]="id" [index]="rowIndex" [treeRow]="rowData" [disabled]="disabledRow" [addRow]="isAddRow" #row>
120121
</igx-tree-grid-row>
121122
</ng-template>
122-
<ng-template #pinned_record_template let-rowIndex="index" let-rowData>
123-
<igx-tree-grid-row [gridID]="id" [index]="rowIndex" [treeRow]="rowData" #row #pinnedRow>
123+
<ng-template #pinned_record_template let-rowIndex="index" let-rowData let-isAddRow="addRow">
124+
<igx-tree-grid-row [gridID]="id" [index]="rowIndex" [treeRow]="rowData" [addRow]="isAddRow" #row #pinnedRow>
124125
</igx-tree-grid-row>
125126
</ng-template>
126127
<ng-template #summary_template let-rowIndex="index" let-rowData>

projects/igniteui-angular/src/lib/grids/tree-grid/tree-grid.component.ts

+17
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,10 @@ export class IgxTreeGridComponent extends IgxGridBaseDirective implements GridTy
439439
return this.dataView.findIndex(x => x.data[this.primaryKey] === rec[this.primaryKey]);
440440
}
441441

442+
protected getUnpinnedIndexById(id) {
443+
return this.unpinnedRecords.findIndex(x => x.data[this.primaryKey] === id);
444+
}
445+
442446
private cloneMap(mapIn: Map<any, boolean>): Map<any, boolean> {
443447
const mapCloned: Map<any, boolean> = new Map<any, boolean>();
444448

@@ -479,6 +483,19 @@ export class IgxTreeGridComponent extends IgxGridBaseDirective implements GridTy
479483
this.expansionStates = new Map<any, boolean>();
480484
}
481485

486+
/**
487+
* @hidden
488+
*/
489+
public refreshGridState(args?) {
490+
super.refreshGridState();
491+
if (this.primaryKey && this.foreignKey) {
492+
const rowID = args.data[this.foreignKey];
493+
this.summaryService.clearSummaryCache({rowID: rowID});
494+
this._pipeTrigger++;
495+
this.cdr.detectChanges();
496+
}
497+
}
498+
482499
/**
483500
* Creates a new `IgxTreeGridRowComponent` with the given data. If a parentRowID is not specified, the newly created
484501
* row would be added at the root level. Otherwise, it would be added as a child of the row whose primaryKey matches

src/app/grid-add-row/grid-add-row.sample.html

+1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
</igx-column>
2525

2626
<igx-action-strip #actionstrip>
27+
<igx-grid-pinning-actions></igx-grid-pinning-actions>
2728
<igx-grid-editing-actions [addRow]="true"></igx-grid-editing-actions>
2829
</igx-action-strip>
2930
</igx-grid>

src/app/hierarchical-grid-add-row/hierarchical-grid-add-row.sample.html

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
[primaryKey]="'ID'"
44
[rowEditable]="true">
55
<igx-action-strip #actionstrip>
6-
<igx-grid-editing-actions [asMenuItems]='true' [addRow]="true"></igx-grid-editing-actions>
6+
<igx-grid-pinning-actions></igx-grid-pinning-actions>
7+
<igx-grid-editing-actions [addRow]="true"></igx-grid-editing-actions>
78
</igx-action-strip>
89
<igx-row-island #island [key]="'childData'" [autoGenerate]="true"
910
[allowFiltering]='true' [rowEditable]="true" [primaryKey]="'ID'">

src/app/tree-grid-add-row/tree-grid-add-row.sample.html

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<div>
2-
<igx-tree-grid #grid [allowFiltering]='true' [data]="data" primaryKey="employeeID" foreignKey="PID"
2+
<igx-tree-grid [pinning]="pinningConfig" #grid [allowFiltering]='true' [data]="data" primaryKey="employeeID" foreignKey="PID"
33
[paging]="false" [width]="'900px'" [height]="'800px'" [rowEditable]="true"
44
(mouseleave)="onMouseLeave(actionstrip)"
55
(mouseover)="onMouseOver($event, grid, actionstrip)">
@@ -9,6 +9,7 @@
99
[minWidth]="c.minWidth" [maxWidth]="c.maxWidth">
1010
</igx-column>
1111
<igx-action-strip #actionstrip>
12+
<igx-grid-pinning-actions></igx-grid-pinning-actions>
1213
<igx-grid-editing-actions [addRow]="true" [addChild]='true'></igx-grid-editing-actions>
1314
</igx-action-strip>
1415
</igx-tree-grid>

0 commit comments

Comments
 (0)