@@ -5,17 +5,20 @@ import Head from "next/head";
5
5
import { weatherTemplate , getWeatherIndex } from "../components/weatherTemplate" ;
6
6
import { OverlayPanel } from 'primereact/overlaypanel' ;
7
7
import MaintainerMapping from "../maintainers.yml" ;
8
+ import { basePath } from "../next.config.js" ;
8
9
9
10
10
11
export default function Home ( ) {
11
12
const [ loading , setLoading ] = useState ( true ) ;
12
13
const [ checks , setChecks ] = useState ( [ ] ) ;
13
14
const [ jobs , setJobs ] = useState ( [ ] ) ;
14
- const [ rowsPR , setRowsPR ] = useState ( [ ] ) ;
15
- const [ rowsNightly , setRowsNightly ] = useState ( [ ] ) ;
15
+ const [ rowsSingle , setRowsSingle ] = useState ( [ ] ) ;
16
+ const [ rowsPR , setRowsPR ] = useState ( [ ] ) ;
17
+ const [ rowsNightly , setRowsNightly ] = useState ( [ ] ) ;
16
18
const [ expandedRows , setExpandedRows ] = useState ( [ ] ) ;
17
19
const [ requiredFilter , setRequiredFilter ] = useState ( false ) ;
18
- const [ display , setDisplay ] = useState ( "nightly" ) ;
20
+ const [ display , setDisplay ] = useState ( "nightly" ) ;
21
+ const [ selectedPR , setSelectedPR ] = useState ( "" ) ;
19
22
20
23
useEffect ( ( ) => {
21
24
const fetchData = async ( ) => {
@@ -53,6 +56,19 @@ export default function Home() {
53
56
fetchData ( ) ;
54
57
} , [ ] ) ;
55
58
59
+ // Set the display based on the URL.
60
+ useEffect ( ( ) => {
61
+ const initialDisplay = new URLSearchParams ( window . location . search ) . get ( "display" ) ;
62
+ if ( initialDisplay ) {
63
+ if ( initialDisplay === "prsingle" ) {
64
+ const initialPR = new URLSearchParams ( window . location . search ) . get ( "pr" ) ;
65
+ if ( initialPR ) {
66
+ setSelectedPR ( initialPR ) ;
67
+ }
68
+ }
69
+ setDisplay ( initialDisplay ) ;
70
+ }
71
+ } , [ ] ) ;
56
72
57
73
// Filter based on required tag.
58
74
const filterRequired = ( filteredJobs ) => {
@@ -103,12 +119,47 @@ export default function Home() {
103
119
setLoading ( false ) ;
104
120
} , [ checks , requiredFilter ] ) ;
105
121
122
+ // Filter and set the rows for Single PR view.
123
+ useEffect ( ( ) => {
124
+ setLoading ( true ) ;
125
+
126
+ let filteredData = filterRequired ( checks ) ;
127
+
128
+ filteredData = filteredData . map ( ( check ) => {
129
+ // Only if the check include the run number, add it to the data.
130
+ const index = check . run_nums . indexOf ( Number ( selectedPR ) ) ;
131
+ return index !== - 1
132
+ ? {
133
+ name : check . name ,
134
+ required : check . required ,
135
+ result : check . results [ index ] ,
136
+ runs : check . reruns [ index ] + 1 ,
137
+ }
138
+ : null ;
139
+ } ) . filter ( Boolean ) ;
140
+
141
+ setRowsSingle ( filteredData ) ;
142
+ setLoading ( false ) ;
143
+ } , [ checks , selectedPR , requiredFilter ] ) ;
144
+
106
145
// Close all rows on view switch.
107
146
// Needed because if view is switched, breaks expanded row toggling.
108
147
useEffect ( ( ) => {
109
148
setExpandedRows ( [ ] )
110
149
} , [ display ] ) ;
111
150
151
+ // Update the URL on display change
152
+ const updateUrl = ( view , pr ) => {
153
+ const path = new URLSearchParams ( ) ;
154
+ path . append ( "display" , view ) ;
155
+ // Add PR number Single PR view and a PR is provided
156
+ if ( view === "prsingle" && pr ) {
157
+ path . append ( "pr" , pr ) ;
158
+ }
159
+ // Update the URL without reloading
160
+ window . history . pushState ( { } , '' , `${ basePath } /?${ path . toString ( ) } ` ) ;
161
+ } ;
162
+
112
163
const toggleRow = ( rowData ) => {
113
164
const isRowExpanded = expandedRows . includes ( rowData ) ;
114
165
@@ -432,6 +483,46 @@ export default function Home() {
432
483
</ DataTable >
433
484
) ;
434
485
486
+ // Make a list of all unique run numbers in the check data.
487
+ const runNumOptions = [ ...new Set ( checks . flatMap ( check => check . run_nums ) ) ] . sort ( ( a , b ) => b - a ) ;
488
+
489
+ // Render table for prsingle view
490
+ const renderSingleViewTable = ( ) => (
491
+ < DataTable
492
+ value = { rowsSingle }
493
+ expandedRows = { expandedRows }
494
+ stripedRows
495
+ rowExpansionTemplate = { rowExpansionTemplate }
496
+ onRowToggle = { ( e ) => setExpandedRows ( e . data ) }
497
+ loading = { loading }
498
+ emptyMessage = { selectedPR . length == 0 ? "Select a Pull Request above." : "No results found." }
499
+ >
500
+ < Column expander />
501
+ < Column
502
+ field = "name"
503
+ header = "Name"
504
+ body = { nameTemplate }
505
+ className = "select-all"
506
+ sortable
507
+ />
508
+ < Column
509
+ field = "required"
510
+ header = "Required"
511
+ sortable
512
+ />
513
+ < Column
514
+ field = "result"
515
+ header = "Result"
516
+ sortable
517
+ />
518
+ < Column
519
+ field = "runs"
520
+ header = "Total Runs"
521
+ sortable
522
+ />
523
+ </ DataTable >
524
+ ) ;
525
+
435
526
return (
436
527
< div className = "text-center" >
437
528
< Head >
@@ -457,21 +548,49 @@ export default function Home() {
457
548
</ h1 >
458
549
< div className = "flex flex-wrap mt-2 p-4 md:text-base text-xs" >
459
550
< div className = "space-x-2 pb-2 pr-3 mx-auto flex" >
460
- < button
461
- className = { tabClass ( display === "nightly" ) }
462
- onClick = { ( ) => {
463
- setDisplay ( "nightly" ) ;
464
- } } >
465
- Nightly Jobs
466
- </ button >
467
- < button
468
- className = { tabClass ( display === "prchecks" ) }
469
- onClick = { ( ) => {
470
- setDisplay ( "prchecks" ) ;
471
- } } >
472
- PR Checks
473
- </ button >
474
- </ div >
551
+ < button
552
+ className = { tabClass ( display === "nightly" ) }
553
+ onClick = { ( ) => {
554
+ setDisplay ( "nightly" ) ;
555
+ updateUrl ( "nightly" ) ;
556
+
557
+ } } >
558
+ Nightly Jobs
559
+ </ button >
560
+ < button
561
+ className = { tabClass ( display === "prchecks" ) }
562
+ onClick = { ( ) => {
563
+ setDisplay ( "prchecks" ) ;
564
+ updateUrl ( "prchecks" ) ;
565
+ } } >
566
+ PR Checks
567
+ </ button >
568
+ < button
569
+ className = { tabClass ( display === "prsingle" ) }
570
+ onClick = { ( ) => {
571
+ setDisplay ( "prsingle" ) ;
572
+ updateUrl ( "prsingle" , selectedPR ) ;
573
+ } } >
574
+ Single PR
575
+ </ button >
576
+ { display === "prsingle" && (
577
+ < div className = "bg-blue-500 p-2 rounded-xl h-fit" >
578
+ < select
579
+ id = "selectedrun"
580
+ className = "px-1 h-fit rounded-lg"
581
+ onChange = { ( e ) => {
582
+ setSelectedPR ( e . target . value ) ;
583
+ updateUrl ( "prsingle" , e . target . value ) ;
584
+ } }
585
+ value = { selectedPR } >
586
+ < option value = "" > Select PR</ option >
587
+ { runNumOptions . map ( num => (
588
+ < option key = { num } value = { num } > #{ num } </ option >
589
+ ) ) }
590
+ </ select >
591
+ </ div >
592
+ ) }
593
+ </ div >
475
594
</ div >
476
595
477
596
@@ -483,9 +602,9 @@ export default function Home() {
483
602
Required Jobs Only
484
603
</ button >
485
604
< div className = "mt-4 text-center md:text-lg text-base" >
486
- Total Rows: { display === "prchecks" ? rowsPR . length : rowsNightly . length }
605
+ Total Rows: { display === "prsingle" ? rowsSingle . length : display === "prchecks" ? rowsPR . length : rowsNightly . length }
487
606
</ div >
488
- < div > { display === "prchecks" ? renderPRTable ( ) : renderNightlyTable ( ) } </ div >
607
+ < div > { display === "prsingle" ? renderSingleViewTable ( ) : display === " prchecks" ? renderPRTable ( ) : renderNightlyTable ( ) } </ div >
489
608
</ div >
490
609
</ div >
491
610
) ;
0 commit comments