Skip to content

Commit 508c992

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 70fdee2 commit 508c992

File tree

1 file changed

+173
-43
lines changed

1 file changed

+173
-43
lines changed

pages/index.js

+173-43
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,24 @@ import { Column } from "primereact/column";
44
import Head from "next/head";
55
import { weatherTemplate, getWeatherIndex } from "../components/weatherTemplate";
66
import { OverlayPanel } from 'primereact/overlaypanel';
7+
import { basePath } from "../next.config.js";
8+
79

810

911

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

Comments
 (0)