Skip to content

Commit

Permalink
dashboard: Add single PR view
Browse files Browse the repository at this point in the history
Added a separate view to display all tests for a given PR.
Added the display to the URL, rowExpansionTemplate is unchanged.

Fixes: kata-containers#12

Signed-off-by: Anna Finn <[email protected]>
  • Loading branch information
afinn12 committed Dec 6, 2024
1 parent 362d9ab commit 39b18aa
Show file tree
Hide file tree
Showing 2 changed files with 147 additions and 42 deletions.
10 changes: 8 additions & 2 deletions next.config.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
module.exports = {
reactStrictMode: true,
output: 'export',
basePath: "",
// output: 'export',
basePath: process.env.NEXT_PUBLIC_BASE_PATH || "",
images: {
unoptimized: true,
},
webpack: (config, { dev }) => {

config.module.rules.push({
test: /\.yml$/,
use: 'yaml-loader',
});

if (dev) {
config.devtool = false;
}
Expand Down
179 changes: 139 additions & 40 deletions pages/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,20 @@ import Head from "next/head";
import { weatherTemplate, getWeatherIndex } from "../components/weatherTemplate";
import { OverlayPanel } from 'primereact/overlaypanel';
import MaintainerMapping from "../maintainers.yml";
import { basePath } from "../next.config.js";


export default function Home() {
const [loading, setLoading] = useState(true);
const [checks, setChecks] = useState([]);
const [jobs, setJobs] = useState([]);
const [rowsPR, setRowsPR] = useState([]);
const [rowsNightly, setRowsNightly] = useState([]);
const [rowsSingle, setRowsSingle] = useState([]);
const [rowsPR, setRowsPR] = useState([]);
const [rowsNightly, setRowsNightly] = useState([]);
const [expandedRows, setExpandedRows] = useState([]);
const [requiredFilter, setRequiredFilter] = useState(false);
const [display, setDisplay] = useState("nightly");
const [display, setDisplay] = useState("nightly");
const [selectedPR, setSelectedPR] = useState("");

useEffect(() => {
const fetchData = async () => {
Expand Down Expand Up @@ -53,6 +56,19 @@ export default function Home() {
fetchData();
}, []);

// Set the display based on the URL.
useEffect(() => {
const initialDisplay = new URLSearchParams(window.location.search).get("display");
if (initialDisplay) {
if(initialDisplay === "prsingle"){
const initialPR = new URLSearchParams(window.location.search).get("pr");
if(initialPR){
setSelectedPR(initialPR);
}
}
setDisplay(initialDisplay);
}
}, []);

// Filter based on required tag.
const filterRequired = (filteredJobs) => {
Expand Down Expand Up @@ -103,12 +119,47 @@ export default function Home() {
setLoading(false);
}, [checks, requiredFilter]);

// Filter and set the rows for Single PR view.
useEffect(() => {
setLoading(true);

let filteredData = filterRequired(checks);

filteredData = filteredData.map((check) => {
// Only if the check include the run number, add it to the data.
const index = check.run_nums.indexOf(Number(selectedPR));
return index !== -1
? {
name: check.name,
required: check.required,
result: check.results[index],
runs: check.reruns[index] + 1,
}
: null;
}).filter(Boolean);

setRowsSingle(filteredData);
setLoading(false);
}, [checks, selectedPR, requiredFilter]);

// Close all rows on view switch.
// Needed because if view is switched, breaks expanded row toggling.
useEffect(() => {
setExpandedRows([])
}, [display]);

// Update the URL on display change
const updateUrl = (view, pr) => {
const path = new URLSearchParams();
path.append("display", view);
// Add PR number Single PR view and a PR is provided
if (view === "prsingle" && pr) {
path.append("pr", pr);
}
// Update the URL without reloading
window.history.pushState({}, '', `${basePath}/?${path.toString()}`);
};

const toggleRow = (rowData) => {
const isRowExpanded = expandedRows.includes(rowData);

Expand Down Expand Up @@ -199,26 +250,6 @@ export default function Home() {
}, {});


// Find maintainers for the given job
const maintainerData = MaintainerMapping.mappings
.filter(({ regex }) => new RegExp(regex).test(job.name))
.flatMap((match) =>
match.owners.map((owner) => ({
...owner,
group: match.group,
}))
);

// Group maintainers by their group name
const groupedMaintainers = maintainerData.reduce((acc, owner) => {
if (!acc[owner.group]) {
acc[owner.group] = [];
}
acc[owner.group].push(owner);
return acc;
}, {});


return (
<div key={`${job.name}-runs`} className="p-3 bg-gray-100">
{/* Display last 10 runs */}
Expand Down Expand Up @@ -538,6 +569,46 @@ export default function Home() {
</DataTable>
);

// Make a list of all unique run numbers in the check data.
const runNumOptions = [...new Set(checks.flatMap(check => check.run_nums))].sort((a, b) => b - a);

// Render table for prsingle view
const renderSingleViewTable = () => (
<DataTable
value={rowsSingle}
expandedRows={expandedRows}
stripedRows
rowExpansionTemplate={rowExpansionTemplate}
onRowToggle={(e) => setExpandedRows(e.data)}
loading={loading}
emptyMessage={selectedPR.length == 0 ? "Select a Pull Request above." : "No results found."}
>
<Column expander />
<Column
field="name"
header="Name"
body={nameTemplate}
className="select-all"
sortable
/>
<Column
field="required"
header="Required"
sortable
/>
<Column
field="result"
header="Result"
sortable
/>
<Column
field="runs"
header="Total Runs"
sortable
/>
</DataTable>
);

return (
<div className="text-center">
<Head>
Expand All @@ -563,21 +634,49 @@ export default function Home() {
</h1>
<div className="flex flex-wrap mt-2 p-4 md:text-base text-xs">
<div className="space-x-2 pb-2 pr-3 mx-auto flex">
<button
className={tabClass(display === "nightly")}
onClick={() => {
setDisplay("nightly");
}}>
Nightly Jobs
</button>
<button
className={tabClass(display === "prchecks")}
onClick={() => {
setDisplay("prchecks");
}}>
PR Checks
</button>
</div>
<button
className={tabClass(display === "nightly")}
onClick={() => {
setDisplay("nightly");
updateUrl("nightly");

}}>
Nightly Jobs
</button>
<button
className={tabClass(display === "prchecks")}
onClick={() => {
setDisplay("prchecks");
updateUrl("prchecks");
}}>
PR Checks
</button>
<button
className={tabClass(display === "prsingle")}
onClick={() => {
setDisplay("prsingle");
updateUrl("prsingle", selectedPR);
}}>
Single PR
</button>
{display === "prsingle" && (
<div className="bg-blue-500 p-2 rounded-xl h-fit">
<select
id="selectedrun"
className="px-1 h-fit rounded-lg"
onChange={(e) => {
setSelectedPR(e.target.value);
updateUrl("prsingle", e.target.value);
}}
value={selectedPR} >
<option value="">Select PR</option>
{runNumOptions.map(num => (
<option key={num} value={num}>#{num}</option>
))}
</select>
</div>
)}
</div>
</div>


Expand All @@ -589,9 +688,9 @@ export default function Home() {
Required Jobs Only
</button>
<div className="mt-4 text-center md:text-lg text-base">
Total Rows: {display === "prchecks" ? rowsPR.length : rowsNightly.length}
Total Rows: {display === "prsingle" ? rowsSingle.length : display === "prchecks" ? rowsPR.length : rowsNightly.length}
</div>
<div>{display === "prchecks" ? renderPRTable() : renderNightlyTable()}</div>
<div>{display === "prsingle" ? renderSingleViewTable() : display === "prchecks" ? renderPRTable() : renderNightlyTable()}</div>
</div>
</div>
);
Expand Down

0 comments on commit 39b18aa

Please sign in to comment.