@@ -5,6 +5,8 @@ import { HEADER_KEYS, ROW_COLLAPSE_KEYS, ROW_EXPAND_KEYS } from '../../core/util
55import { PivotUtil } from './pivot-util' ;
66import { IgxPivotRowDimensionMrlRowComponent } from './pivot-row-dimension-mrl-row.component' ;
77import { IMultiRowLayoutNode } from '../public_api' ;
8+ import { take , timeout } from 'rxjs' ;
9+
810
911@Injectable ( )
1012export 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 => {
0 commit comments