@@ -4,17 +4,24 @@ import { Column } from "primereact/column";
4
4
import Head from "next/head" ;
5
5
import { weatherTemplate , getWeatherIndex } from "../components/weatherTemplate" ;
6
6
import { OverlayPanel } from 'primereact/overlaypanel' ;
7
+ import { basePath } from "../next.config.js" ;
8
+
7
9
8
10
9
11
10
12
export default function Home ( ) {
11
13
const [ loading , setLoading ] = useState ( true ) ;
14
+
12
15
const [ jobs , setJobs ] = useState ( [ ] ) ;
13
16
const [ checks , setChecks ] = useState ( [ ] ) ;
17
+
14
18
const [ rowsPR , setRowsPR ] = useState ( [ ] ) ;
15
19
const [ rowsNightly , setRowsNightly ] = useState ( [ ] ) ;
20
+ const [ rowsSingle , setRowsSingle ] = useState ( [ ] ) ;
21
+
16
22
const [ expandedRows , setExpandedRows ] = useState ( [ ] ) ;
17
23
const [ display , setDisplay ] = useState ( "nightly" ) ;
24
+ const [ selectedPR , setSelectedPR ] = useState ( "" ) ;
18
25
19
26
20
27
useEffect ( ( ) => {
@@ -51,46 +58,87 @@ export default function Home() {
51
58
fetchData ( ) ;
52
59
} , [ ] ) ;
53
60
54
- // Filter and set the rows for Nightly view.
55
- useEffect ( ( ) => {
56
- setLoading ( true ) ;
57
- let filteredJobs = jobs ;
58
- //Set the rows for the table.
59
- setRowsNightly (
60
- filteredJobs . map ( ( job ) => ( {
61
- name : job . name ,
62
- runs : job . runs ,
63
- fails : job . fails ,
64
- skips : job . skips ,
65
- required : job . required ,
66
- weather : getWeatherIndex ( job ) ,
67
- reruns : job . reruns ,
68
- total_reruns : job . reruns . reduce ( ( total , r ) => total + r , 0 ) ,
69
- } ) )
70
- ) ;
71
- setLoading ( false ) ;
72
- } , [ jobs ] ) ;
73
-
74
- // Filter and set the rows for PR Checks view.
75
- useEffect ( ( ) => {
76
- setLoading ( true ) ;
77
- let filteredChecks = checks
78
-
79
- //Set the rows for the table.
80
- setRowsPR (
81
- filteredChecks . map ( ( check ) => ( {
82
- name : check . name ,
83
- runs : check . runs ,
84
- fails : check . fails ,
85
- skips : check . skips ,
86
- required : check . required ,
87
- weather : getWeatherIndex ( check ) ,
88
- reruns : check . reruns ,
89
- total_reruns : check . reruns . reduce ( ( total , r ) => total + r , 0 ) ,
90
- } ) )
91
- ) ;
92
- setLoading ( false ) ;
93
- } , [ checks ] ) ;
61
+
62
+ // Set the display based on the URL.
63
+ useEffect ( ( ) => {
64
+ const initialDisplay = new URLSearchParams ( window . location . search ) . get ( "display" ) ;
65
+ if ( initialDisplay ) {
66
+ if ( initialDisplay === "prsingle" ) {
67
+ const initialPR = new URLSearchParams ( window . location . search ) . get ( "pr" ) ;
68
+ if ( initialPR ) {
69
+ setSelectedPR ( initialPR ) ;
70
+ }
71
+ }
72
+ setDisplay ( initialDisplay ) ;
73
+ }
74
+ } , [ ] ) ;
75
+
76
+
77
+
78
+ // Filter and set the rows for Nightly view.
79
+ useEffect ( ( ) => {
80
+ setLoading ( true ) ;
81
+ let filteredJobs = jobs ;
82
+ //Set the rows for the table.
83
+ setRowsNightly (
84
+ filteredJobs . map ( ( job ) => ( {
85
+ name : job . name ,
86
+ runs : job . runs ,
87
+ fails : job . fails ,
88
+ skips : job . skips ,
89
+ required : job . required ,
90
+ weather : getWeatherIndex ( job ) ,
91
+ reruns : job . reruns ,
92
+ total_reruns : job . reruns . reduce ( ( total , r ) => total + r , 0 ) ,
93
+ } ) )
94
+ ) ;
95
+ setLoading ( false ) ;
96
+ } , [ jobs ] ) ;
97
+
98
+ // Filter and set the rows for PR Checks view.
99
+ useEffect ( ( ) => {
100
+ setLoading ( true ) ;
101
+ let filteredChecks = checks
102
+
103
+ //Set the rows for the table.
104
+ setRowsPR (
105
+ filteredChecks . map ( ( check ) => ( {
106
+ name : check . name ,
107
+ runs : check . runs ,
108
+ fails : check . fails ,
109
+ skips : check . skips ,
110
+ required : check . required ,
111
+ weather : getWeatherIndex ( check ) ,
112
+ reruns : check . reruns ,
113
+ total_reruns : check . reruns . reduce ( ( total , r ) => total + r , 0 ) ,
114
+ } ) )
115
+ ) ;
116
+ setLoading ( false ) ;
117
+ } , [ checks ] ) ;
118
+
119
+
120
+ // Filter and set the rows for Single PR view.
121
+ useEffect ( ( ) => {
122
+ setLoading ( true ) ;
123
+
124
+ let filteredData = checks ;
125
+
126
+ filteredData = filteredData . map ( ( check ) => {
127
+ // Only if the check include the run number, add it to the data.
128
+ const index = check . run_nums . indexOf ( Number ( selectedPR ) ) ;
129
+ return index !== - 1
130
+ ? {
131
+ name : check . name ,
132
+ required : check . required ,
133
+ result : check . results [ index ] ,
134
+ runs : check . reruns [ index ] + 1 ,
135
+ }
136
+ : null ;
137
+ } ) . filter ( Boolean ) ;
138
+
139
+ setRowsSingle ( filteredData ) ;
140
+ setLoading ( false ) ;
141
+ } , [ checks , selectedPR ] ) ;
94
142
95
143
// Close all rows on view switch.
96
144
// Needed because if view is switched, breaks expanded row toggling.
@@ -99,6 +147,19 @@ useEffect(() => {
99
147
} , [ display ] ) ;
100
148
101
149
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
+
102
163
103
164
const tabClass = ( active ) => `tab md:px-4 px-2 py-2 border-b-2 focus:outline-none
104
165
${ active ? "border-blue-500 bg-gray-300"
@@ -306,6 +367,47 @@ useEffect(() => {
306
367
) ;
307
368
308
369
370
+
371
+ // Make a list of all unique run numbers in the check data.
372
+ const runNumOptions = [ ...new Set ( checks . flatMap ( check => check . run_nums ) ) ] . sort ( ( a , b ) => b - a ) ;
373
+
374
+ // Render table for prsingle view
375
+ const renderSingleViewTable = ( ) => (
376
+ < DataTable
377
+ value = { rowsSingle }
378
+ expandedRows = { expandedRows }
379
+ stripedRows
380
+ rowExpansionTemplate = { rowExpansionTemplate }
381
+ onRowToggle = { ( e ) => setExpandedRows ( e . data ) }
382
+ loading = { loading }
383
+ emptyMessage = { selectedPR . length == 0 ? "Select a Pull Request above." : "No results found." }
384
+ >
385
+ < Column expander />
386
+ < Column
387
+ field = "name"
388
+ header = "Name"
389
+ body = { nameTemplate }
390
+ className = "select-all"
391
+ sortable
392
+ />
393
+ < Column
394
+ field = "required"
395
+ header = "Required"
396
+ sortable
397
+ />
398
+ < Column
399
+ field = "result"
400
+ header = "Result"
401
+ sortable
402
+ />
403
+ < Column
404
+ field = "runs"
405
+ header = "Total Runs"
406
+ sortable
407
+ />
408
+ </ DataTable >
409
+ ) ;
410
+
309
411
return (
310
412
< >
311
413
@@ -334,26 +436,54 @@ useEffect(() => {
334
436
className = { tabClass ( display === "nightly" ) }
335
437
onClick = { ( ) => {
336
438
setDisplay ( "nightly" ) ;
439
+ updateUrl ( "nightly" ) ;
440
+
337
441
} } >
338
442
Nightly Jobs
339
443
</ button >
340
444
< button
341
445
className = { tabClass ( display === "prchecks" ) }
342
446
onClick = { ( ) => {
343
447
setDisplay ( "prchecks" ) ;
448
+ updateUrl ( "prchecks" ) ;
344
449
} } >
345
450
PR Checks
346
451
</ button >
347
- </ div >
452
+ < button
453
+ className = { tabClass ( display === "prsingle" ) }
454
+ onClick = { ( ) => {
455
+ setDisplay ( "prsingle" ) ;
456
+ updateUrl ( "prsingle" , selectedPR ) ;
457
+ } } >
458
+ Single PR
459
+ </ button >
460
+ { display === "prsingle" && (
461
+ < div className = "bg-blue-500 p-2 rounded-xl h-fit" >
462
+ < select
463
+ id = "selectedrun"
464
+ className = "px-1 h-fit rounded-lg"
465
+ onChange = { ( e ) => {
466
+ setSelectedPR ( e . target . value ) ;
467
+ updateUrl ( "prsingle" , e . target . value ) ;
468
+ } }
469
+ value = { selectedPR } >
470
+ < option value = "" > Select PR</ option >
471
+ { runNumOptions . map ( num => (
472
+ < option key = { num } value = { num } > #{ num } </ option >
473
+ ) ) }
474
+ </ select >
475
+ </ div >
476
+ ) }
477
+ </ div >
348
478
</ div >
349
479
350
480
< div className = "mt-1 text-center md:text-lg text-base" >
351
- Total Rows: { display === "prchecks" ? rowsPR . length : rowsNightly . length }
481
+ Total Rows: { display === "prsingle" ? rowsSingle . length : display === " prchecks" ? rowsPR . length : rowsNightly . length }
352
482
</ div >
353
483
354
484
< main className = { "m-0 h-full px-4 overflow-x-hidden overflow-y-auto \
355
485
bg-surface-ground antialiased select-text" } >
356
- < div > { display === "prchecks" ? renderPRTable ( ) : renderNightlyTable ( ) } </ div >
486
+ < div > { display === "prsingle" ? renderSingleViewTable ( ) : display === " prchecks" ? renderPRTable ( ) : renderNightlyTable ( ) } </ div >
357
487
</ main >
358
488
</ div >
359
489
</ >
0 commit comments