Fixed Cancel/Delete Bug
This commit is contained in:
parent
204bcbb7c1
commit
d5ea0981e5
5 changed files with 77 additions and 25 deletions
|
@ -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 });
|
||||||
})
|
})
|
||||||
|
|
|
@ -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]);
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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 />} />
|
||||||
|
|
|
@ -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>
|
||||||
);
|
);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue