qualiteer/src/views/failing/Failing.jsx

136 lines
4.3 KiB
React
Raw Normal View History

2022-05-17 12:32:04 +00:00
import { useState, useContext } from "react";
2022-08-12 13:08:00 +00:00
import { useCurrentlyFailing, useSilencedAlerts } from "@qltr/queries";
import StoreContext from "@qltr/store";
import JobContext from "@qltr/jobs";
2022-08-13 20:43:35 +00:00
import { useJobNav } from "@qltr/util/JobTools";
2022-07-12 21:48:05 +00:00
import SilenceDialog from "../alerting/SilenceDialog.jsx";
import FailingBox from "./FailingBox.jsx";
2022-05-17 12:32:04 +00:00
2022-05-23 00:24:21 +00:00
import SpeedDial from "@mui/material/SpeedDial";
2022-05-17 12:32:04 +00:00
2022-05-23 00:24:21 +00:00
import Button from "@mui/material/Button";
import Dialog from "@mui/material/Dialog";
import DialogActions from "@mui/material/DialogActions";
import DialogContent from "@mui/material/DialogContent";
import DialogContentText from "@mui/material/DialogContentText";
import DialogTitle from "@mui/material/DialogTitle";
import ReplayIcon from "@mui/icons-material/Replay";
2022-08-06 21:21:41 +00:00
import Box from "@mui/material/Box";
import Typography from "@mui/material/Typography";
2022-05-23 00:24:21 +00:00
2022-05-17 12:32:04 +00:00
export default function Failing() {
2022-08-05 13:03:48 +00:00
const { state: jobState, retryAll } = useContext(JobContext);
2022-08-12 13:08:00 +00:00
const { state: store, silenceRequest } = useContext(StoreContext);
2022-08-09 04:29:10 +00:00
const { isLoading, data: failing } = useCurrentlyFailing();
const { isSilencedLoading, data: silencedAlerts } = useSilencedAlerts();
2022-08-13 20:43:35 +00:00
const jobNav = useJobNav();
2022-06-22 00:47:19 +00:00
const [silenceEntry, setSilenceEntry] = useState({ open: false });
const closeSilence = () => setSilenceEntry({ ...silenceEntry, open: false });
const handleSilenceClose = (silenceReq) => {
closeSilence();
if (!silenceReq) return;
silenceRequest(silenceReq);
};
const editSilence = (silence) => () => {
setSilenceEntry({ ...silence, open: true });
};
2022-05-17 12:32:04 +00:00
const [retryAllOpen, setRetryAllOpen] = useState(false);
const retryAllClick = () => setRetryAllOpen(!retryAllOpen);
2022-06-22 00:47:19 +00:00
2022-05-23 00:24:21 +00:00
const handleClose = (confirmed) => () => {
2022-05-17 12:32:04 +00:00
retryAllClick();
2022-05-23 00:24:21 +00:00
if (!confirmed) return;
2022-08-06 12:25:56 +00:00
const jobId = retryAll(store.failing);
if (!store.focusJob) return;
2022-08-13 20:43:35 +00:00
jobNav.toJob(jobId);
2022-05-23 00:24:21 +00:00
};
2022-08-06 22:09:37 +00:00
const failingTestsWithJobs = () => {
2022-08-13 20:43:35 +00:00
if (isLoading) return [];
2022-08-06 22:09:37 +00:00
const silences = silencedAlerts ?? [];
2022-08-09 04:29:10 +00:00
for (var test of failing) {
const silence = silences.find(
(s) => s.name === test.name || s.class === test.class
);
if (silence) test.silencedUntil = silence;
2022-08-10 12:39:09 +00:00
if (test.isPipeline) {
const pipeline = jobState.pipelines.find((p) =>
2022-08-13 20:43:35 +00:00
p.selectedBranches.find((b) => b.name === test.name)
2022-08-10 12:39:09 +00:00
);
if (!pipeline) continue;
const pipelineJob = jobState.jobs.find(
(j) =>
j.isPipeline &&
j.pipelineId === pipeline.id &&
j.branchId === test.name
);
if (!pipelineJob) test.pipeline = pipeline;
test.job = pipelineJob;
continue;
}
const job = jobState.jobs.find(
(j) => !j.isPipeline && j.builderCache.testNames.includes(test.name)
);
if (job) test.job = job;
2022-08-06 22:09:37 +00:00
}
return failing;
2022-08-09 04:29:10 +00:00
};
2022-08-06 22:09:37 +00:00
2022-05-17 12:32:04 +00:00
return (
<div className="failing">
2022-08-09 04:29:10 +00:00
{isLoading
? null
: failingTestsWithJobs().map((v, i) => (
<FailingBox key={i} failingTest={v} silenceClick={editSilence(v)} />
))}
2022-05-17 12:32:04 +00:00
<Dialog
open={retryAllOpen}
onClose={handleClose()}
2022-05-23 00:24:21 +00:00
sx={{ "& .MuiDialog-paper": { width: "80%", maxHeight: 435 } }}
maxWidth="xs"
2022-05-17 12:32:04 +00:00
>
2022-05-23 00:24:21 +00:00
<DialogTitle>Retry all failing tests?</DialogTitle>
2022-05-17 12:32:04 +00:00
<DialogContent>
<DialogContentText>
This will create x jobs and run y tests
</DialogContentText>
</DialogContent>
<DialogActions>
<Button onClick={handleClose()}>Cancel</Button>
<Button onClick={handleClose(true)} autoFocus>
Yes
</Button>
</DialogActions>
</Dialog>
2022-06-22 00:47:19 +00:00
<SilenceDialog
keepMounted
open={silenceEntry.open}
onClose={handleSilenceClose}
silence={silenceEntry}
/>
2022-08-09 04:29:10 +00:00
{(failing ?? []).length === 0 ? (
<Box display="flex" alignItems="center" justifyContent="center">
<Typography variant="h4">No tests failing!</Typography>
</Box>
) : null}
{(failing ?? []).length === 0 ? null : (
<SpeedDial
ariaLabel="Retry All"
sx={{ position: "fixed", bottom: 16, right: 16 }}
icon={<ReplayIcon />}
onClick={retryAllClick}
open={false}
/>
)}
2022-05-17 12:32:04 +00:00
</div>
);
}