@@ -4,17 +4,24 @@ import { Column } from "primereact/column";
44import Head from "next/head" ;
55import { weatherTemplate , getWeatherIndex } from "../components/weatherTemplate" ;
66import { OverlayPanel } from 'primereact/overlaypanel' ;
7+ import { basePath } from "../next.config.js" ;
8+
79
810
911
1012export default function Home ( ) {
1113 const [ loading , setLoading ] = useState ( true ) ;
14+
1215 const [ jobs , setJobs ] = useState ( [ ] ) ;
1316 const [ checks , setChecks ] = useState ( [ ] ) ;
17+
1418 const [ rowsPR , setRowsPR ] = useState ( [ ] ) ;
1519 const [ rowsNightly , setRowsNightly ] = useState ( [ ] ) ;
20+ const [ rowsSingle , setRowsSingle ] = useState ( [ ] ) ;
21+
1622 const [ expandedRows , setExpandedRows ] = useState ( [ ] ) ;
1723 const [ display , setDisplay ] = useState ( "nightly" ) ;
24+ const [ selectedPR , setSelectedPR ] = useState ( "" ) ;
1825
1926
2027 useEffect ( ( ) => {
@@ -51,46 +58,87 @@ export default function Home() {
5158 fetchData ( ) ;
5259 } , [ ] ) ;
5360
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 ] ) ;
94142
95143 // Close all rows on view switch.
96144 // Needed because if view is switched, breaks expanded row toggling.
@@ -99,6 +147,19 @@ useEffect(() => {
99147 } , [ display ] ) ;
100148
101149
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+
102163
103164 const tabClass = ( active ) => `tab md:px-4 px-2 py-2 border-b-2 focus:outline-none
104165 ${ active ? "border-blue-500 bg-gray-300"
@@ -306,6 +367,47 @@ useEffect(() => {
306367 ) ;
307368
308369
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+
309411 return (
310412 < >
311413
@@ -334,26 +436,54 @@ useEffect(() => {
334436 className = { tabClass ( display === "nightly" ) }
335437 onClick = { ( ) => {
336438 setDisplay ( "nightly" ) ;
439+ updateUrl ( "nightly" ) ;
440+
337441 } } >
338442 Nightly Jobs
339443 </ button >
340444 < button
341445 className = { tabClass ( display === "prchecks" ) }
342446 onClick = { ( ) => {
343447 setDisplay ( "prchecks" ) ;
448+ updateUrl ( "prchecks" ) ;
344449 } } >
345450 PR Checks
346451 </ 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 >
348478 </ div >
349479
350480 < 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 }
352482 </ div >
353483
354484 < main className = { "m-0 h-full px-4 overflow-x-hidden overflow-y-auto \
355485 bg-surface-ground antialiased select-text" } >
356- < div > { display === "prchecks" ? renderPRTable ( ) : renderNightlyTable ( ) } </ div >
486+ < div > { display === "prsingle" ? renderSingleViewTable ( ) : display === " prchecks" ? renderPRTable ( ) : renderNightlyTable ( ) } </ div >
357487 </ main >
358488 </ div >
359489 </ >
0 commit comments