Skip to content

Commit 01c0c77

Browse files
committed
fix(pivotGrid): Refactor pivot navigation a bit in order to scroll to merged cells for horizontal layout.
1 parent 48374c1 commit 01c0c77

File tree

3 files changed

+77
-26
lines changed

3 files changed

+77
-26
lines changed

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

Lines changed: 71 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import { HEADER_KEYS, ROW_COLLAPSE_KEYS, ROW_EXPAND_KEYS } from '../../core/util
55
import { PivotUtil } from './pivot-util';
66
import { IgxPivotRowDimensionMrlRowComponent } from './pivot-row-dimension-mrl-row.component';
77
import { IMultiRowLayoutNode } from '../public_api';
8+
import { take, timeout } from 'rxjs';
9+
810

911
@Injectable()
1012
export class IgxPivotGridNavigationService extends IgxGridNavigationService {
@@ -16,12 +18,16 @@ export class IgxPivotGridNavigationService extends IgxGridNavigationService {
1618
return this.grid.visibleRowDimensions.length - 1;
1719
}
1820

21+
public get lastRowDimensionMRLRowIndex() {
22+
return this.grid.verticalRowDimScrollContainers.first.igxGridForOf.length - 1;
23+
}
24+
1925
public focusOutRowHeader() {
2026
this.isRowHeaderActive = false;
2127
this.isRowDimensionHeaderActive = false;
2228
}
2329

24-
public override handleNavigation(event: KeyboardEvent) {
30+
public override async handleNavigation(event: KeyboardEvent) {
2531
if (this.isRowHeaderActive) {
2632
const key = event.key.toLowerCase();
2733
const ctrl = event.ctrlKey;
@@ -52,17 +58,17 @@ export class IgxPivotGridNavigationService extends IgxGridNavigationService {
5258
};
5359
verticalContainer = this.grid.verticalRowDimScrollContainers.first;
5460
if (key.includes('left')) {
55-
newPosition = this.getNextHorizontalPosition(true, ctrl);
61+
newPosition = await this.getNextHorizontalPosition(true, ctrl);
5662
}
5763
if (key.includes('right')) {
58-
newPosition = this.getNextHorizontalPosition(false, ctrl);
64+
newPosition = await this.getNextHorizontalPosition(false, ctrl);
5965
}
6066
if (key.includes('up') || key === 'home') {
61-
newPosition = this.getNextVerticalPosition(true, ctrl || key === 'home', key === 'home');
67+
newPosition = await this.getNextVerticalPosition(true, ctrl || key === 'home', key === 'home');
6268
}
6369

6470
if (key.includes('down') || key === 'end') {
65-
newPosition = this.getNextVerticalPosition(false, ctrl || key === 'end', key === 'end');
71+
newPosition = await this.getNextVerticalPosition(false, ctrl || key === 'end', key === 'end');
6672
}
6773

6874
newActiveNode.row = newPosition.row;
@@ -107,7 +113,7 @@ export class IgxPivotGridNavigationService extends IgxGridNavigationService {
107113
}
108114

109115
this.setActiveNode(newActiveNode);
110-
if (verticalContainer.isIndexOutsideView(newActiveNode.row)) {
116+
if (!this.grid.hasHorizontalLayout && verticalContainer.isIndexOutsideView(newActiveNode.row)) {
111117
verticalContainer.scrollTo(newActiveNode.row);
112118
}
113119
} else {
@@ -118,10 +124,17 @@ export class IgxPivotGridNavigationService extends IgxGridNavigationService {
118124
public override handleAlt(key: string, event: KeyboardEvent): void {
119125
event.preventDefault();
120126

121-
const rowIndex = this.grid.hasHorizontalLayout ? this.activeNode.row + this.activeNode.layout.rowStart - 1 : this.activeNode.row
122-
const row = this.grid.gridAPI.get_row_by_index(rowIndex);
123-
const dimIndex = this.grid.hasHorizontalLayout ? this.activeNode.layout.colStart - 1 : this.activeNode.column;
124-
const expansionRowKey = PivotUtil.getRecordKey(row.data, this.grid.visibleRowDimensions[dimIndex]);
127+
let rowData, dimIndex;
128+
if (!this.grid.hasHorizontalLayout) {
129+
rowData = this.grid.gridAPI.get_row_by_index(this.activeNode.row).data;
130+
dimIndex = this.activeNode.column;
131+
} else {
132+
const mrlRow = this.grid.rowDimensionMrlRowsCollection.find(mrl => mrl.rowIndex === this.activeNode.row);
133+
rowData = mrlRow.rowGroup[this.activeNode.layout.rowStart - 1];
134+
dimIndex = this.activeNode.layout.colStart - 1;
135+
}
136+
const dimension = this.grid.visibleRowDimensions[dimIndex];
137+
const expansionRowKey = PivotUtil.getRecordKey(rowData, dimension);
125138
const isExpanded = this.grid.expansionStates.get(expansionRowKey) ?? true;
126139

127140
if (ROW_EXPAND_KEYS.has(key) && !isExpanded) {
@@ -134,12 +147,12 @@ export class IgxPivotGridNavigationService extends IgxGridNavigationService {
134147
}
135148

136149
public updateActiveNodeLayout() {
137-
const mrlRow = this.grid.rowDimensionMrlRowsCollection.toArray()[this.activeNode.row];
150+
const mrlRow = this.grid.rowDimensionMrlRowsCollection.find(row => row.rowIndex === this.activeNode.row);
138151
const activeCell = mrlRow.contentCells.toArray()[this.activeNode.column];
139152
this.activeNode.layout = activeCell.layout;
140153
}
141154

142-
public override headerNavigation(event: KeyboardEvent) {
155+
public override async headerNavigation(event: KeyboardEvent) {
143156
const key = event.key.toLowerCase();
144157
const ctrl = event.ctrlKey;
145158
if (!HEADER_KEYS.has(key)) {
@@ -183,7 +196,7 @@ export class IgxPivotGridNavigationService extends IgxGridNavigationService {
183196
columnVisibleIndex: newActiveNode.column
184197
};
185198

186-
const newPosition = this.getNextVerticalPosition(true, ctrl || key === 'home', key === 'home');
199+
const newPosition = await this.getNextVerticalPosition(true, ctrl || key === 'home', key === 'home');
187200
newActiveNode.row = 0;
188201
newActiveNode.column = newPosition.column;
189202
newActiveNode.layout = newPosition.layout;
@@ -222,14 +235,15 @@ export class IgxPivotGridNavigationService extends IgxGridNavigationService {
222235
}
223236
}
224237

225-
public getNextVerticalPosition(previous, ctrl, homeEnd) {
226-
const parentRow = this.grid.rowDimensionMrlRowsCollection.toArray()[this.activeNode.row];
238+
public async getNextVerticalPosition(previous, ctrl, homeEnd) {
239+
const parentRow = this.grid.rowDimensionMrlRowsCollection.find(row => row.rowIndex === this.activeNode.row);
227240
const maxRowEnd = parentRow.rowGroup.length + 1;
241+
// Get current cell layout, because the actineNode the rowStart might be different, based on where we come from(might be smaller cell).
228242
const curCellLayout = this.getNextVerticalColumnIndex(parentRow, this.activeNode.layout.rowStart, this.activeNode.layout.colStart);
229243
const nextBlock = (previous && curCellLayout.rowStart === 1) || (!previous && curCellLayout.rowEnd === maxRowEnd);
230244
if (nextBlock &&
231245
((previous && this.activeNode.row === 0) ||
232-
(!previous && this.activeNode.row === this.grid.rowDimensionMrlRowsCollection.length - 1))) {
246+
(!previous && this.activeNode.row === this.lastRowDimensionMRLRowIndex))) {
233247
if (previous && this.grid.pivotUI.showRowHeaders) {
234248
this.isRowDimensionHeaderActive = true;
235249
this.isRowHeaderActive = false;
@@ -239,19 +253,35 @@ export class IgxPivotGridNavigationService extends IgxGridNavigationService {
239253
return { row: this.activeNode.row, column: this.activeNode.column, layout: this.activeNode.layout };
240254
}
241255

242-
const nextRowIndex = previous ?
256+
const nextMRLRowIndex = previous ?
243257
(ctrl ? 0 : this.activeNode.row - 1) :
244-
(ctrl ? this.grid.rowDimensionMrlRowsCollection.length - 1 : this.activeNode.row + 1) ;
245-
const nextRow = nextBlock || ctrl ? this.grid.rowDimensionMrlRowsCollection.toArray()[nextRowIndex] : parentRow;
246-
const nextRowStart = nextBlock ? (previous ? nextRow.rowGroup.length : 1) : curCellLayout.rowStart + (previous ? -1 : 1);
258+
(ctrl ? this.lastRowDimensionMRLRowIndex : this.activeNode.row + 1) ;
259+
let nextRow = nextBlock || ctrl ? this.grid.rowDimensionMrlRowsCollection.find(row => row.rowIndex === nextMRLRowIndex) : parentRow;
260+
if (!nextRow) {
261+
const nextDataViewIndex = previous ?
262+
(ctrl ? 0 : parentRow.rowGroup[curCellLayout.rowStart - 1].dataIndex - 1) :
263+
(ctrl ? this.grid.dataView.length - 1 : parentRow.rowGroup[curCellLayout.rowEnd - 2].dataIndex + 1);
264+
await this.scrollToNextHorizontalDimRow(nextDataViewIndex);
265+
nextRow = nextBlock || ctrl ? this.grid.rowDimensionMrlRowsCollection.find(row => row.rowIndex === nextMRLRowIndex) : parentRow;
266+
}
267+
268+
const nextRowStart = nextBlock ?
269+
(previous ? nextRow.rowGroup.length : 1) :
270+
(previous ? curCellLayout.rowStart - 1 : curCellLayout.rowEnd);
247271
const maxColEnd = Math.max(...nextRow.contentCells.map(cell => cell.layout.colEnd));
248272
const nextColumnLayout = this.getNextVerticalColumnIndex(
249273
nextRow,
250274
ctrl ? (previous ? 1 : nextRow.rowGroup.length) : nextRowStart,
251275
homeEnd ? (previous ? 1 : maxColEnd - 1) : this.activeNode.layout.colStart
252276
);
277+
278+
const nextDataViewIndex = previous ?
279+
nextRow.rowGroup[nextColumnLayout.rowStart - 1].dataIndex:
280+
nextRow.rowGroup[nextColumnLayout.rowEnd - 2].dataIndex;
281+
await this.scrollToNextHorizontalDimRow(nextDataViewIndex);
282+
253283
return {
254-
row: nextBlock || ctrl ? nextRowIndex : this.activeNode.row,
284+
row: nextBlock || ctrl ? nextMRLRowIndex : this.activeNode.row,
255285
column: nextColumnLayout.columnVisibleIndex,
256286
layout: {
257287
rowStart: nextColumnLayout.rowStart,
@@ -263,9 +293,10 @@ export class IgxPivotGridNavigationService extends IgxGridNavigationService {
263293
};
264294
}
265295

266-
public getNextHorizontalPosition(previous, ctrl) {
267-
const parentRow = this.grid.rowDimensionMrlRowsCollection.toArray()[this.activeNode.row];
296+
public async getNextHorizontalPosition(previous, ctrl) {
297+
const parentRow = this.grid.rowDimensionMrlRowsCollection.find(row => row.rowIndex === this.activeNode.row);
268298
const maxColEnd = Math.max(...parentRow.contentCells.map(cell => cell.layout.colEnd));
299+
// Get current cell layout, because the actineNode the rowStart might be different, based on where we come from(might be smaller cell).
269300
const curCellLayout = this.getNextVerticalColumnIndex(parentRow, this.activeNode.layout.rowStart, this.activeNode.layout.colStart);
270301

271302
if ((previous && curCellLayout.colStart === 1) || (!previous && curCellLayout.colEnd === maxColEnd)) {
@@ -278,6 +309,10 @@ export class IgxPivotGridNavigationService extends IgxGridNavigationService {
278309
this.activeNode.layout.rowStart,
279310
ctrl ? (previous ? 1 : maxColEnd - 1) : nextColStartNormal
280311
);
312+
313+
const nextDataViewIndex = parentRow.rowGroup[nextColumnLayout.rowStart - 1].dataIndex
314+
await this.scrollToNextHorizontalDimRow(nextDataViewIndex);
315+
281316
return {
282317
row: this.activeNode.row,
283318
column: nextColumnLayout.columnVisibleIndex,
@@ -291,6 +326,19 @@ export class IgxPivotGridNavigationService extends IgxGridNavigationService {
291326
};
292327
}
293328

329+
private async scrollToNextHorizontalDimRow(nextDataViewIndex: number) {
330+
const verticalContainer = this.grid.verticalScrollContainer;
331+
if (verticalContainer.isIndexOutsideView(nextDataViewIndex)) {
332+
verticalContainer.scrollTo(nextDataViewIndex);
333+
await new Promise((resolve) => {
334+
this.grid.gridScroll.pipe(take(1), timeout({ first: 10000 })).subscribe({
335+
next: (value) => resolve(value),
336+
error: (err) => resolve(err)
337+
});
338+
});
339+
}
340+
}
341+
294342

295343
private getNextVerticalColumnIndex(nextRow: IgxPivotRowDimensionMrlRowComponent, newRowStart, newColStart) {
296344
const nextCell = nextRow.contentCells.find(cell => {

projects/igniteui-angular/src/lib/grids/pivot-grid/pivot-grid.interface.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,8 @@ export interface IPivotGridRecord {
253253
dimensions: IPivotDimension[];
254254
/** Describes if this is a total record for a dimension */
255255
totalRecord?: boolean;
256+
/** The index of the record in the total view */
257+
dataIndex?: number;
256258
}
257259

258260
export interface IPivotGridGroupRecord extends IPivotGridRecord {

projects/igniteui-angular/src/lib/grids/pivot-grid/pivot-grid.pipes.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -193,14 +193,14 @@ export class IgxPivotCellMergingPipe implements PipeTransform {
193193
let groupData: IPivotGridGroupRecord[] = [];
194194
let prevId;
195195
const enabledRows = this.grid.hasHorizontalLayout ? (this.grid as any).visibleRowDimensions : config.rows?.filter(x => x.enabled);
196-
const index = enabledRows.indexOf(dim);
196+
const dimIndex = enabledRows.indexOf(dim);
197197
for (const rec of data) {
198198
let currentDim;
199199
if (this.grid.hasHorizontalLayout) {
200200
currentDim = dim;
201201
rec.dimensions = enabledRows;
202202
} else {
203-
currentDim = rec.dimensions[index];
203+
currentDim = rec.dimensions[dimIndex];
204204
}
205205

206206
const id = PivotUtil.getRecordKey(rec, currentDim);
@@ -246,7 +246,8 @@ export class IgxPivotGridHorizontalRowGrouping implements PipeTransform {
246246
const groupDim = config.rows.filter(dim => dim.enabled)[0];
247247
let curGroup = [];
248248
let curGroupValue = data[0].dimensionValues.get(groupDim.memberName);
249-
for (const curRec of data) {
249+
for (const [index, curRec] of data.entries()) {
250+
curRec.dataIndex = index;
250251
const curRecValue = curRec.dimensionValues.get(groupDim.memberName);
251252
if (curGroup.length === 0 || curRecValue === curGroupValue) {
252253
curGroup.push(curRec);

0 commit comments

Comments
 (0)