@@ -24,6 +24,11 @@ type TableOutputProps = AbstractOutputProps & {
24
24
tableWidth ?: string ;
25
25
} ;
26
26
27
+ enum Direction {
28
+ NEXT ,
29
+ PREVIOUS
30
+ }
31
+
27
32
export class TableOutputComponent extends AbstractOutputComponent < TableOutputProps , TableOuputState > {
28
33
private debugMode = false ;
29
34
private columnIds : Array < number > = [ ] ;
@@ -83,7 +88,7 @@ export class TableOutputComponent extends AbstractOutputComponent<TableOutputPro
83
88
this . onModelUpdated = this . onModelUpdated . bind ( this ) ;
84
89
this . onKeyDown = this . onKeyDown . bind ( this ) ;
85
90
this . searchEvents = this . searchEvents . bind ( this ) ;
86
- this . findNextMatchedEvent = this . findNextMatchedEvent . bind ( this ) ;
91
+ this . findMatchedEvent = this . findMatchedEvent . bind ( this ) ;
87
92
}
88
93
89
94
renderMainArea ( ) : React . ReactNode {
@@ -314,7 +319,8 @@ export class TableOutputComponent extends AbstractOutputComponent<TableOutputPro
314
319
floatingFilterComponentParams : {
315
320
suppressFilterButton : true ,
316
321
onFilterChange : this . searchEvents ,
317
- onclickNext : this . findNextMatchedEvent ,
322
+ onclickNext : ( ) => this . findMatchedEvent ( Direction . NEXT ) ,
323
+ onclickPrevious : ( ) => this . findMatchedEvent ( Direction . PREVIOUS ) ,
318
324
colName : columnHeader . id . toString ( )
319
325
} ,
320
326
icons : {
@@ -409,7 +415,7 @@ export class TableOutputComponent extends AbstractOutputComponent<TableOutputPro
409
415
return lines [ 0 ] . index ;
410
416
}
411
417
412
- private fetchAdditionalParams ( isFiltered = false ) : ( { [ key : string ] : any } ) {
418
+ private fetchAdditionalParams ( direction ?: Direction ) : ( { [ key : string ] : any } ) {
413
419
let additionalParams : { [ key : string ] : any } = { } ;
414
420
const filterObj : { [ key : number ] : string } = { } ;
415
421
if ( this . filterModel ) {
@@ -419,8 +425,10 @@ export class TableOutputComponent extends AbstractOutputComponent<TableOutputPro
419
425
} ) ;
420
426
additionalParams = {
421
427
[ 'table_search_expressions' ] : filterObj ,
422
- [ 'isFiltered' ] : isFiltered
423
428
} ;
429
+ if ( direction !== undefined ) {
430
+ additionalParams [ 'table_search_direction' ] = Direction [ direction ] ;
431
+ }
424
432
}
425
433
return additionalParams ;
426
434
@@ -490,11 +498,11 @@ export class TableOutputComponent extends AbstractOutputComponent<TableOutputPro
490
498
}
491
499
}
492
500
493
- private async findNextMatchIndex ( currRowIndex : number ) {
501
+ private async findMatchIndex ( currRowIndex : number , direction = Direction . NEXT ) {
494
502
const traceUUID = this . props . traceId ;
495
503
const tspClient = this . props . tspClient ;
496
504
const outputId = this . props . outputDescriptor . id ;
497
- const additionalParams = this . fetchAdditionalParams ( true ) ;
505
+ const additionalParams = this . fetchAdditionalParams ( direction ) ;
498
506
const tspClientResponse = await tspClient . fetchTableLines ( traceUUID , outputId , QueryHelper . tableQuery ( this . columnIds , currRowIndex , 1 , additionalParams ) ) ;
499
507
const lineResponse = tspClientResponse . getModel ( ) ;
500
508
if ( ! tspClientResponse . isOk ( ) || ! lineResponse ) {
@@ -508,13 +516,56 @@ export class TableOutputComponent extends AbstractOutputComponent<TableOutputPro
508
516
return lines [ 0 ] . index ;
509
517
}
510
518
511
- private async findNextMatchedEvent ( ) {
519
+ private async findMatchedEvent ( direction : Direction ) {
512
520
let isFound = false ;
513
521
if ( this . gridApi ) {
514
- this . gridApi . deselectAll ( ) ;
522
+
523
+ // make sure that both index are either both -1 or both have a valid number
524
+ if ( this . selectStartIndex !== - 1 && this . selectEndIndex === - 1 ) {
525
+ this . selectEndIndex = this . selectStartIndex ;
526
+ }
527
+ if ( this . selectEndIndex !== - 1 && this . selectStartIndex === - 1 ) {
528
+ this . selectStartIndex = this . selectStartIndex ;
529
+ }
530
+
531
+ let currRowIndex = 0 ;
532
+ if ( this . selectStartIndex !== - 1 ) {
533
+ if ( direction === Direction . NEXT ) {
534
+ currRowIndex = Math . max ( this . selectStartIndex , this . selectEndIndex ) + 1 ;
535
+ } else {
536
+ currRowIndex = Math . min ( this . selectStartIndex , this . selectEndIndex ) - 1 ;
537
+ }
538
+ } else if ( direction === Direction . PREVIOUS ) {
539
+ // no backward search if there is no selection
540
+ return ;
541
+ }
542
+
543
+ let rowNodes : RowNode [ ] = [ ] ;
515
544
this . gridApi . forEachNode ( rowNode => {
516
- if ( rowNode . rowIndex > Math . max ( this . selectStartIndex , this . selectEndIndex ) && rowNode . data
517
- && rowNode . data [ 'isMatched' ] && ! isFound ) {
545
+ rowNodes . push ( rowNode ) ;
546
+ } ) ;
547
+
548
+ if ( direction === Direction . PREVIOUS ) {
549
+ rowNodes = rowNodes . reverse ( ) ;
550
+ }
551
+
552
+ this . gridApi . deselectAll ( ) ;
553
+ // consider only rows starting from the current row index and contiguous rows after that
554
+ let currRowIndexFound = false ;
555
+ rowNodes . forEach ( rowNode => {
556
+ if ( rowNode . rowIndex === currRowIndex ) {
557
+ currRowIndexFound = true ;
558
+ // update current row index to next/previous contiguous row
559
+ if ( direction === Direction . NEXT ) {
560
+ currRowIndex ++ ;
561
+ } else {
562
+ currRowIndex -- ;
563
+ }
564
+ } else {
565
+ // non-contiguous row found, stop searching in cache
566
+ currRowIndexFound = false ;
567
+ }
568
+ if ( currRowIndexFound && ! isFound && rowNode . data && rowNode . data [ 'isMatched' ] ) {
518
569
this . gridApi ?. ensureIndexVisible ( rowNode . rowIndex ) ;
519
570
this . selectStartIndex = this . selectEndIndex = rowNode . rowIndex ;
520
571
this . handleRowSelectionChange ( ) ;
@@ -524,14 +575,20 @@ export class TableOutputComponent extends AbstractOutputComponent<TableOutputPro
524
575
} ) ;
525
576
526
577
if ( isFound ) {
578
+ // match found in cache
527
579
return ;
528
580
}
581
+ // find match outside the cache
582
+ if ( currRowIndex >= 0 ) {
583
+ const lineIndex = await this . findMatchIndex ( currRowIndex , direction ) ;
584
+ if ( lineIndex !== undefined ) {
585
+ this . gridApi . ensureIndexVisible ( lineIndex ) ;
586
+ this . selectStartIndex = this . selectEndIndex = lineIndex ;
587
+ }
588
+ }
529
589
530
- const currRowIndex = this . gridApi ?. getLastDisplayedRow ( ) + 1 ;
531
- const lineIndex = await this . findNextMatchIndex ( currRowIndex ) ;
532
- if ( lineIndex ) {
533
- this . gridApi . ensureIndexVisible ( lineIndex ) ;
534
- this . selectStartIndex = this . selectEndIndex = lineIndex ;
590
+ // apply new or previous selection
591
+ if ( this . selectStartIndex !== - 1 && this . selectEndIndex !== - 1 ) {
535
592
this . handleRowSelectionChange ( ) ;
536
593
this . enableIndexSelection = true ;
537
594
this . selectRows ( ) ;
0 commit comments