Skip to content

Commit e8f2314

Browse files
committed
dashboard: Add single PR view
Added a separate view to display all tests for a given PR. Added the display to the URL, rowExpansionTemplate is unchanged. Fixes: #12 Signed-off-by: Anna Finn <[email protected]>
1 parent 5f9bf61 commit e8f2314

File tree

1 file changed

+139
-20
lines changed

1 file changed

+139
-20
lines changed

pages/index.js

+139-20
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,20 @@ import Head from "next/head";
55
import { weatherTemplate, getWeatherIndex } from "../components/weatherTemplate";
66
import { OverlayPanel } from 'primereact/overlaypanel';
77
import MaintainerMapping from "../maintainers.yml";
8+
import { basePath } from "../next.config.js";
89

910

1011
export 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

Comments
 (0)