@@ -5,17 +5,20 @@ import Head from "next/head";
55import  {  weatherTemplate ,  getWeatherIndex  }  from  "../components/weatherTemplate" ; 
66import  {  OverlayPanel  }  from  'primereact/overlaypanel' ; 
77import  MaintainerMapping  from  "../maintainers.yml" ; 
8+ import  {  basePath  }  from  "../next.config.js" ; 
89
910
1011export  default  function  Home ( )  { 
1112  const  [ loading ,  setLoading ]  =  useState ( true ) ; 
1213  const  [ checks ,  setChecks ]  =  useState ( [ ] ) ; 
1314  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 ( [ ] ) ; 
1618  const  [ expandedRows ,  setExpandedRows ]  =  useState ( [ ] ) ; 
1719  const  [ requiredFilter ,  setRequiredFilter ]  =  useState ( false ) ; 
18-   const  [ display ,        setDisplay ]        =  useState ( "nightly" ) ; 
20+   const  [ display ,  setDisplay ]  =  useState ( "nightly" ) ; 
21+   const  [ selectedPR ,  setSelectedPR ]  =  useState ( "" ) ; 
1922
2023  useEffect ( ( )  =>  { 
2124    const  fetchData  =  async  ( )  =>  { 
@@ -53,6 +56,19 @@ export default function Home() {
5356    fetchData ( ) ; 
5457  } ,  [ ] ) ; 
5558
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+   } ,  [ ] ) ; 
5672
5773  // Filter based on required tag. 
5874  const  filterRequired  =  ( filteredJobs )  =>  { 
@@ -103,12 +119,47 @@ export default function Home() {
103119    setLoading ( false ) ; 
104120  } ,  [ checks ,  requiredFilter ] ) ; 
105121
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+ 
106145  // Close all rows on view switch.  
107146  // Needed because if view is switched, breaks expanded row toggling. 
108147  useEffect ( ( )  =>  { 
109148    setExpandedRows ( [ ] ) 
110149  } ,  [ display ] ) ;  
111150
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+ 
112163  const  toggleRow  =  ( rowData )  =>  { 
113164    const  isRowExpanded  =  expandedRows . includes ( rowData ) ; 
114165
@@ -432,6 +483,46 @@ export default function Home() {
432483    </ DataTable > 
433484  ) ; 
434485
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+ 
435526  return  ( 
436527    < div  className = "text-center" > 
437528      < Head > 
@@ -457,21 +548,49 @@ export default function Home() {
457548      </ h1 > 
458549      < div  className = "flex flex-wrap mt-2 p-4 md:text-base text-xs" > 
459550        < 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 > 
475594      </ div > 
476595
477596
@@ -483,9 +602,9 @@ export default function Home() {
483602          Required Jobs Only
484603        </ button > 
485604        < 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 } 
487606        </ div > 
488-         < div > { display  ===  "prchecks"  ? renderPRTable ( )  : renderNightlyTable ( ) } </ div > 
607+         < div > { display  ===  "prsingle"   ?  renderSingleViewTable ( )  :  display   ===   " prchecks"renderPRTable ( )  : renderNightlyTable ( ) } </ div > 
489608      </ div > 
490609    </ div > 
491610  ) ; 
0 commit comments