Fixed Cancel/Delete Bug

This commit is contained in:
Dunemask 2022-08-08 11:42:28 +00:00
parent 204bcbb7c1
commit d5ea0981e5
5 changed files with 77 additions and 25 deletions

View file

@ -17,6 +17,7 @@ export default class Initiator {
(() => { (() => {
console.log("job pipeline closed"); console.log("job pipeline closed");
}); });
this.sk = null;
} }
async newJob(jobRequest, onLog, onClose, onCreate) { async newJob(jobRequest, onLog, onClose, onCreate) {
@ -26,11 +27,11 @@ export default class Initiator {
onLog = onLog ?? this.onLog.bind(this); onLog = onLog ?? this.onLog.bind(this);
onClose = onClose ?? this.onClose.bind(this); onClose = onClose ?? this.onClose.bind(this);
onCreate = onCreate ?? this.onCreate.bind(this); onCreate = onCreate ?? this.onCreate.bind(this);
const sk = mgr.socket("/"); this.sk = mgr.socket("/");
sk.on(events.JOB_LOG, onLog); this.sk.on(events.JOB_LOG, onLog);
sk.on(events.JOB_CLS, onClose); this.sk.on(events.JOB_CLS, onClose);
return new Promise((res) => return new Promise((res) =>
sk.on(events.JOB_CRT, function onJobCreate(id) { this.sk.on(events.JOB_CRT, function onJobCreate(id) {
onCreate(id); onCreate(id);
res({ ...jobRequest, id }); res({ ...jobRequest, id });
}) })
@ -78,13 +79,13 @@ export default class Initiator {
); );
}); });
onPipelineClose = onPipelineClose ?? this.onPipelineClose.bind(this); onPipelineClose = onPipelineClose ?? this.onPipelineClose.bind(this);
const sk = mgr.socket("/"); this.sk = mgr.socket("/");
sk.on(events.JOB_LOG, onLog); this.sk.on(events.JOB_LOG, onLog);
sk.on(events.JOB_CLS, onClose); this.sk.on(events.JOB_CLS, onClose);
sk.on(events.PPL_TRG, onPipelineTrigger); this.sk.on(events.PPL_TRG, onPipelineTrigger);
sk.on(events.PPL_CLS, onPipelineClose); this.sk.on(events.PPL_CLS, onPipelineClose);
return new Promise((res) => return new Promise((res) =>
sk.on(events.JOB_CRT, function onJobCreate(id) { this.sk.on(events.JOB_CRT, function onJobCreate(id) {
onCreate(id); onCreate(id);
res({ ...jobRequest, id }); res({ ...jobRequest, id });
}) })

View file

@ -43,12 +43,12 @@ const reducer = (state, action) => {
return { ...state, jobs }; return { ...state, jobs };
case ACTIONS.UPDATE: case ACTIONS.UPDATE:
jobIndex = jobs.find((j) => j.id === (action.job.id ?? action.jobId)); jobIndex = jobs.findIndex((j) => j.jobId === (action.job.jobId ?? action.jobId));
jobs[jobIndex] = { ...jobs[jobIndex], ...action.job }; jobs[jobIndex] = { ...jobs[jobIndex], ...action.job };
return { ...state, jobs }; return { ...state, jobs };
case ACTIONS.DELETE: case ACTIONS.DELETE:
jobIndex = jobs.find((j) => j.id === action.jobId); jobIndex = jobs.findIndex((j) => j.jobId === action.jobId);
jobs.splice(jobIndex, 1); jobs.splice(jobIndex, 1);
return { ...state, jobs }; return { ...state, jobs };
@ -66,6 +66,25 @@ export const JobProvider = ({ children }) => {
dispatch({ type: ACTIONS.CREATE, job: { ...job, log: [] } }); dispatch({ type: ACTIONS.CREATE, job: { ...job, log: [] } });
const jobDelete = (jobId) => dispatch({ type: ACTIONS.DELETE, jobId }); const jobDelete = (jobId) => dispatch({ type: ACTIONS.DELETE, jobId });
function jobCancel(jobId){
const job = state.jobs.find((j)=>j.jobId===jobId);
if(job.initiator.sk)
job.initiator.sk.close();
job.status = jobStatus.CANCELED;
jobUpdate({ ...job }, jobId);
}
function jobDestroy(jobId){
const job = state.jobs.find((j)=>j.jobId===jobId);
if(job.initiator.sk && job.status !== jobStatus.OK && job.status !== jobStatus.ERROR && job.status !== jobStatus.CANCELED){
job.initiator.sk.close();
}
jobDelete(jobId);
}
function retryAll(failing) { function retryAll(failing) {
// Query Full Locator // Query Full Locator
console.log("Would retry all failing tests!"); console.log("Would retry all failing tests!");
@ -89,6 +108,7 @@ export const JobProvider = ({ children }) => {
jobId, jobId,
isPipeline: false, isPipeline: false,
builderCache, builderCache,
initiator: i,
}; };
const request = { const request = {
@ -141,6 +161,8 @@ export const JobProvider = ({ children }) => {
retryAll, retryAll,
retrySingle, retrySingle,
jobFactory, jobFactory,
jobCancel,
jobDestroy
}; };
const contextValue = useMemo(() => context, [state, dispatch]); const contextValue = useMemo(() => context, [state, dispatch]);

View file

@ -9,11 +9,11 @@ const localStorage = { setItem: () => {}, getItem: () => {} };
const localSettings = localStorage.getItem("settings"); const localSettings = localStorage.getItem("settings");
const defaultSettings = { const defaultSettings = {
focusJob: true, focusJob: false,
simplifiedControls: false, simplifiedControls: false,
logAppDetails: true, logAppDetails: true,
defaultRegion: "us", defaultRegion: "us",
defaultPage: "failing", defaultPage: "jobs",
}; };
const settings = localSettings ? JSON.parse(localSettings) : defaultSettings; const settings = localSettings ? JSON.parse(localSettings) : defaultSettings;

View file

@ -33,7 +33,7 @@ export default function Views() {
<Route <Route
exact exact
path="/" path="/"
element={<Navigate to="/qualiteer/failing" replace />} element={<Navigate to={`/qualiteer/${store.defaultPage}`} replace />}
/> />
<Route path="/qualiteer/failing" element={<Failing />} /> <Route path="/qualiteer/failing" element={<Failing />} />
<Route path="/qualiteer/alerting" element={<Alerting />} /> <Route path="/qualiteer/alerting" element={<Alerting />} />

View file

@ -1,6 +1,7 @@
import React, { useContext, useState, useEffect } from "react"; import React, { useContext, useState, useEffect } from "react";
import { useNavigate } from "react-router-dom"; import { useNavigate } from "react-router-dom";
import JobContext, { jobStatus } from "../../ctx/JobContext.jsx"; import JobContext, { jobStatus } from "../../ctx/JobContext.jsx";
import StoreContext from "../../ctx/StoreContext.jsx";
import Box from "@mui/material/Box"; import Box from "@mui/material/Box";
import AppBar from "@mui/material/AppBar"; import AppBar from "@mui/material/AppBar";
import Toolbar from "@mui/material/Toolbar"; import Toolbar from "@mui/material/Toolbar";
@ -16,12 +17,17 @@ import MoreVertIcon from "@mui/icons-material/MoreVert";
import DownloadIcon from "@mui/icons-material/Download"; import DownloadIcon from "@mui/icons-material/Download";
import ReplayIcon from "@mui/icons-material/Replay"; import ReplayIcon from "@mui/icons-material/Replay";
import ArrowBackIcon from "@mui/icons-material/ArrowBack"; import ArrowBackIcon from "@mui/icons-material/ArrowBack";
import DoNotDisturbIcon from "@mui/icons-material/DoNotDisturb";
import DeleteIcon from "@mui/icons-material/Delete";
import PlayArrowIcon from "@mui/icons-material/PlayArrow";
export default function JobView(props) { export default function JobView(props) {
const navigate = useNavigate(); const navigate = useNavigate();
const { job } = props; const { job } = props;
const { jobFactory } = useContext(JobContext); const { jobFactory, jobCancel, jobDestroy } = useContext(JobContext);
const {state: store} = useContext(StoreContext);
const [anchorEl, setAnchorEl] = React.useState(null); const [anchorEl, setAnchorEl] = React.useState(null);
const open = Boolean(anchorEl); const open = Boolean(anchorEl);
const handleClick = (event) => { const handleClick = (event) => {
@ -45,7 +51,8 @@ export default function JobView(props) {
} }
function retryJob() { function retryJob() {
jobFactory(job.builderCache); const jobId = jobFactory(job.builderCache);
if(store.focusJob) navigate(`/qualiteer/jobs#${jobId}`);
} }
function downloadLog() { function downloadLog() {
@ -53,6 +60,16 @@ export default function JobView(props) {
download(`${job.jobId}.txt`, job.log.join("\n")); download(`${job.jobId}.txt`, job.log.join("\n"));
} }
function cancelJob(){
jobCancel(job.jobId);
}
function deleteJob(){
jobDestroy(job.jobId);
navigateToJobs();
}
const menuSelect = (cb) => () => { const menuSelect = (cb) => () => {
handleClose(); handleClose();
cb(); cb();
@ -90,18 +107,30 @@ export default function JobView(props) {
<Toolbar disableGutters /> <Toolbar disableGutters />
<JobLogView log={job.log} status={job.status} /> <JobLogView log={job.log} status={job.status} />
<Menu anchorEl={anchorEl} open={open} onClose={handleClose}> <Menu anchorEl={anchorEl} open={open} onClose={handleClose}>
<MenuItem onClick={menuSelect(retryJob)}> <MenuItem onClick={menuSelect(downloadLog)}>
<ListItemIcon>
<ReplayIcon fontSize="small" />
</ListItemIcon>
<ListItemText>Retry</ListItemText>
</MenuItem>
<MenuItem onClick={menuSelect(downloadLog)}>
<ListItemIcon> <ListItemIcon>
<DownloadIcon fontSize="small" /> <DownloadIcon fontSize="small" />
</ListItemIcon> </ListItemIcon>
<ListItemText>Download Log</ListItemText> <ListItemText>Download Log</ListItemText>
</MenuItem> </MenuItem>
<MenuItem onClick={menuSelect(retryJob)}>
<ListItemIcon>
{job.status === jobStatus.OK || job.status === jobStatus.ERROR ? <ReplayIcon fontSize="small" /> : <PlayArrowIcon fontSize="small"/>}
</ListItemIcon>
<ListItemText> {job.status === jobStatus.ERROR? "Retry" : "Duplicate"}</ListItemText>
</MenuItem>
{job.status === jobStatus.OK || job.status === jobStatus.ERROR || job.status === jobStatus.CANCELED? null : <MenuItem onClick={menuSelect(cancelJob)}>
<ListItemIcon>
<DoNotDisturbIcon fontSize="small" />
</ListItemIcon>
<ListItemText>Cancel</ListItemText>
</MenuItem>}
<MenuItem onClick={menuSelect(deleteJob)}>
<ListItemIcon>
<DeleteIcon fontSize="small" />
</ListItemIcon>
<ListItemText>Delete</ListItemText>
</MenuItem>
</Menu> </Menu>
</Box> </Box>
); );