qualiteer/src/views/jobs/JobPipelineDisplay.jsx

192 lines
5.7 KiB
React
Raw Normal View History

2022-08-09 14:07:53 +00:00
import React, { useContext } from "react";
2022-08-09 17:59:36 +00:00
import { useNavigate } from "react-router-dom";
2022-08-10 11:00:22 +00:00
import JobContext, { jobStatus } from "../../ctx/JobContext.jsx";
2022-08-09 14:07:53 +00:00
import Box from "@mui/material/Box";
2022-08-09 17:59:36 +00:00
import AppBar from "@mui/material/AppBar";
import Toolbar from "@mui/material/Toolbar";
2022-08-09 14:07:53 +00:00
import Typography from "@mui/material/Typography";
2022-08-09 17:59:36 +00:00
import Accordion from "@mui/material/Accordion";
import AccordionSummary from "@mui/material/AccordionSummary";
2022-08-09 14:07:53 +00:00
import Stack from "@mui/material/Stack";
2022-08-09 17:59:36 +00:00
import ArrowBackIcon from "@mui/icons-material/ArrowBack";
2022-08-10 11:00:22 +00:00
import IconButton from "@mui/material/IconButton";
import CheckIcon from "@mui/icons-material/Check";
import ClearIcon from "@mui/icons-material/Clear";
import ViewColumnIcon from "@mui/icons-material/ViewColumn";
import PendingIcon from "@mui/icons-material/Pending";
import VisibilityIcon from "@mui/icons-material/Visibility";
import DoNotDisturbIcon from "@mui/icons-material/DoNotDisturb";
import Menu from "@mui/material/Menu";
import MenuItem from "@mui/material/MenuItem";
import ListItemText from "@mui/material/ListItemText";
import ListItemIcon from "@mui/material/ListItemIcon";
import MoreVertIcon from "@mui/icons-material/MoreVert";
import DeleteIcon from "@mui/icons-material/Delete";
2022-08-09 14:07:53 +00:00
function JobPipelineDisplay(props) {
2022-08-10 11:00:22 +00:00
const { pipeline } = props;
2022-08-09 17:59:36 +00:00
const {
state: jobState,
pipelineCancel,
pipelineDestroy,
} = useContext(JobContext);
2022-08-09 14:07:53 +00:00
const navigate = useNavigate();
2022-08-10 11:00:22 +00:00
const [anchorEl, setAnchorEl] = React.useState(null);
const open = Boolean(anchorEl);
const handleClick = (event) => {
setAnchorEl(event.currentTarget);
};
const handleClose = () => {
setAnchorEl(null);
};
2022-08-09 17:59:36 +00:00
const pipelineJobs = jobState.jobs.filter(
(j) => j.isPipeline && j.pipelineId === pipeline.id
);
const selectedBranches = () => {
return pipeline.branches.map((b) => {
return b.filter((t) => pipeline.selectedBranches.includes(t));
});
};
2022-08-10 11:00:22 +00:00
const findJob = (testName) =>
pipelineJobs.find((j) => j.branchId === testName);
2022-08-09 17:59:36 +00:00
const selectJob = (testName) => () => {
2022-08-10 11:00:22 +00:00
const job = findJob(testName);
2022-08-09 17:59:36 +00:00
if (!job) return;
navigate(`/qualiteer/jobs#${job.jobId}`);
};
function navigateToJobs() {
navigate(`/qualiteer/jobs`);
}
function cancelPipeline() {
pipelineCancel(pipeline.id);
2022-08-09 14:07:53 +00:00
}
2022-08-09 17:59:36 +00:00
function deletePipeline() {
pipelineDestroy(pipeline.id);
}
2022-08-10 11:00:22 +00:00
const menuSelect = (cb) => () => {
handleClose();
cb();
};
function pipelineActive() {
return pipelineJobs.find(
(j) => j.status === jobStatus.ACTIVE || j.status === jobStatus.PENDING
);
}
function jobIcon(name) {
const job = findJob(name);
const status = job ? job.status : null;
switch (status) {
case jobStatus.OK:
return <CheckIcon color="success" />;
case jobStatus.ERROR:
return <ClearIcon color="error" />;
case jobStatus.PENDING:
return <PendingIcon color="info" />;
case jobStatus.ACTIVE:
return <VisibilityIcon color="primary" />;
case jobStatus.CANCELED:
return <DoNotDisturbIcon color="warning" />;
case jobStatus.QUEUED:
return <ViewColumnIcon color="secondary" />;
default:
return <ViewColumnIcon color="secondary" />;
}
}
2022-08-09 14:07:53 +00:00
return (
2022-08-09 17:59:36 +00:00
<Box>
<AppBar
position="fixed"
sx={{
backgroundColor: "white",
boxShadow: "none",
color: "black",
}}
>
<Toolbar disableGutters />
<Box sx={{ flexGrow: 1, margin: "0 10px" }}>
<Toolbar disableGutters>
<IconButton onClick={navigateToJobs}>
<ArrowBackIcon />
</IconButton>
<Typography variant="h6" sx={{ ml: "auto", mr: "auto" }}>
{pipeline.id}
</Typography>
2022-08-10 11:00:22 +00:00
<IconButton onClick={handleClick}>
<MoreVertIcon />
2022-08-09 17:59:36 +00:00
</IconButton>
</Toolbar>
</Box>
</AppBar>
<Toolbar disableGutters />
{selectedBranches().map((track, i) => (
<React.Fragment key={i}>
<Typography variant="h6">{i + 1}</Typography>
<Box>
{track.map((test, j) => (
<Accordion
expanded={false}
disableGutters={true}
square
key={j}
onClick={selectJob(test)}
>
<AccordionSummary
style={{
backgroundColor: "rgba(0, 0, 0, .03)",
flexWrap: "wrap",
}}
2022-08-09 14:07:53 +00:00
>
2022-08-09 17:59:36 +00:00
<Typography
component={"span"}
style={{ wordBreak: "break-word", margin: "auto 0" }}
2022-08-09 14:07:53 +00:00
>
2022-08-09 17:59:36 +00:00
{test}
</Typography>
2022-08-10 11:00:22 +00:00
<Stack sx={{ ml: "auto" }}>
<IconButton aria-label="retry" component="span">
{jobIcon(test)}
</IconButton>
</Stack>
2022-08-09 17:59:36 +00:00
</AccordionSummary>
</Accordion>
))}
</Box>
</React.Fragment>
))}
2022-08-10 11:00:22 +00:00
<Menu anchorEl={anchorEl} open={open} onClose={handleClose}>
{pipelineActive() ? (
<MenuItem onClick={menuSelect(cancelPipeline)}>
<ListItemIcon>
<DoNotDisturbIcon fontSize="small" />
</ListItemIcon>
<ListItemText>Cancel</ListItemText>
</MenuItem>
) : null}
<MenuItem onClick={menuSelect(deletePipeline)}>
<ListItemIcon>
<DeleteIcon fontSize="small" />
</ListItemIcon>
<ListItemText>Delete</ListItemText>
</MenuItem>
</Menu>
2022-08-09 17:59:36 +00:00
</Box>
2022-08-09 14:07:53 +00:00
);
}
export default JobPipelineDisplay;