@@ -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
@@ -199,26 +250,6 @@ export default function Home() {
199
250
} , { } ) ;
200
251
201
252
202
- // Find maintainers for the given job
203
- const maintainerData = MaintainerMapping . mappings
204
- . filter ( ( { regex } ) => new RegExp ( regex ) . test ( job . name ) )
205
- . flatMap ( ( match ) =>
206
- match . owners . map ( ( owner ) => ( {
207
- ...owner ,
208
- group : match . group ,
209
- } ) )
210
- ) ;
211
-
212
- // Group maintainers by their group name
213
- const groupedMaintainers = maintainerData . reduce ( ( acc , owner ) => {
214
- if ( ! acc [ owner . group ] ) {
215
- acc [ owner . group ] = [ ] ;
216
- }
217
- acc [ owner . group ] . push ( owner ) ;
218
- return acc ;
219
- } , { } ) ;
220
-
221
-
222
253
return (
223
254
< div key = { `${ job . name } -runs` } className = "p-3 bg-gray-100" >
224
255
{ /* Display last 10 runs */ }
@@ -538,6 +569,46 @@ export default function Home() {
538
569
</ DataTable >
539
570
) ;
540
571
572
+ // Make a list of all unique run numbers in the check data.
573
+ const runNumOptions = [ ...new Set ( checks . flatMap ( check => check . run_nums ) ) ] . sort ( ( a , b ) => b - a ) ;
574
+
575
+ // Render table for prsingle view
576
+ const renderSingleViewTable = ( ) => (
577
+ < DataTable
578
+ value = { rowsSingle }
579
+ expandedRows = { expandedRows }
580
+ stripedRows
581
+ rowExpansionTemplate = { rowExpansionTemplate }
582
+ onRowToggle = { ( e ) => setExpandedRows ( e . data ) }
583
+ loading = { loading }
584
+ emptyMessage = { selectedPR . length == 0 ? "Select a Pull Request above." : "No results found." }
585
+ >
586
+ < Column expander />
587
+ < Column
588
+ field = "name"
589
+ header = "Name"
590
+ body = { nameTemplate }
591
+ className = "select-all"
592
+ sortable
593
+ />
594
+ < Column
595
+ field = "required"
596
+ header = "Required"
597
+ sortable
598
+ />
599
+ < Column
600
+ field = "result"
601
+ header = "Result"
602
+ sortable
603
+ />
604
+ < Column
605
+ field = "runs"
606
+ header = "Total Runs"
607
+ sortable
608
+ />
609
+ </ DataTable >
610
+ ) ;
611
+
541
612
return (
542
613
< div className = "text-center" >
543
614
< Head >
@@ -563,21 +634,49 @@ export default function Home() {
563
634
</ h1 >
564
635
< div className = "flex flex-wrap mt-2 p-4 md:text-base text-xs" >
565
636
< div className = "space-x-2 pb-2 pr-3 mx-auto flex" >
566
- < button
567
- className = { tabClass ( display === "nightly" ) }
568
- onClick = { ( ) => {
569
- setDisplay ( "nightly" ) ;
570
- } } >
571
- Nightly Jobs
572
- </ button >
573
- < button
574
- className = { tabClass ( display === "prchecks" ) }
575
- onClick = { ( ) => {
576
- setDisplay ( "prchecks" ) ;
577
- } } >
578
- PR Checks
579
- </ button >
580
- </ div >
637
+ < button
638
+ className = { tabClass ( display === "nightly" ) }
639
+ onClick = { ( ) => {
640
+ setDisplay ( "nightly" ) ;
641
+ updateUrl ( "nightly" ) ;
642
+
643
+ } } >
644
+ Nightly Jobs
645
+ </ button >
646
+ < button
647
+ className = { tabClass ( display === "prchecks" ) }
648
+ onClick = { ( ) => {
649
+ setDisplay ( "prchecks" ) ;
650
+ updateUrl ( "prchecks" ) ;
651
+ } } >
652
+ PR Checks
653
+ </ button >
654
+ < button
655
+ className = { tabClass ( display === "prsingle" ) }
656
+ onClick = { ( ) => {
657
+ setDisplay ( "prsingle" ) ;
658
+ updateUrl ( "prsingle" , selectedPR ) ;
659
+ } } >
660
+ Single PR
661
+ </ button >
662
+ { display === "prsingle" && (
663
+ < div className = "bg-blue-500 p-2 rounded-xl h-fit" >
664
+ < select
665
+ id = "selectedrun"
666
+ className = "px-1 h-fit rounded-lg"
667
+ onChange = { ( e ) => {
668
+ setSelectedPR ( e . target . value ) ;
669
+ updateUrl ( "prsingle" , e . target . value ) ;
670
+ } }
671
+ value = { selectedPR } >
672
+ < option value = "" > Select PR</ option >
673
+ { runNumOptions . map ( num => (
674
+ < option key = { num } value = { num } > #{ num } </ option >
675
+ ) ) }
676
+ </ select >
677
+ </ div >
678
+ ) }
679
+ </ div >
581
680
</ div >
582
681
583
682
@@ -589,9 +688,9 @@ export default function Home() {
589
688
Required Jobs Only
590
689
</ button >
591
690
< div className = "mt-4 text-center md:text-lg text-base" >
592
- Total Rows: { display === "prchecks" ? rowsPR . length : rowsNightly . length }
691
+ Total Rows: { display === "prsingle" ? rowsSingle . length : display === "prchecks" ? rowsPR . length : rowsNightly . length }
593
692
</ div >
594
- < div > { display === "prchecks" ? renderPRTable ( ) : renderNightlyTable ( ) } </ div >
693
+ < div > { display === "prsingle" ? renderSingleViewTable ( ) : display === " prchecks" ? renderPRTable ( ) : renderNightlyTable ( ) } </ div >
595
694
</ div >
596
695
</ div >
597
696
) ;
0 commit comments