Use a Invocations-style provider for Jobs grid.

This commit is contained in:
John Chilton
2022-05-23 09:58:43 -04:00
parent 108803e05b
commit 2e2baecb7d
3 changed files with 80 additions and 19 deletions
+20 -19
View File
@@ -109,6 +109,7 @@ import JobLock from "./JobLock";
import JOB_STATES_MODEL from "mvc/history/job-states-model";
import { commonJobFields } from "./JobFields";
import { errorMessageAsString } from "utils/simple-error";
import { jobsProvider } from "components/providers/JobProvider";
function cancelJob(jobId, message) {
const url = `${getAppRoot()}api/jobs/${jobId}`;
@@ -199,31 +200,31 @@ export default {
this.update();
},
methods: {
update() {
async update() {
this.busy = true;
let params = [];
params.push("view=admin_job_list");
const params = { view: "admin_job_list" };
if (this.showAllRunning) {
params.push("state=running");
params.state = "running";
} else {
const cutoff = Math.floor(this.cutoffMin);
const dateRangeMin = new Date(Date.now() - cutoff * 60 * 1000).toISOString();
params.push(`date_range_min=${dateRangeMin}`);
params.date_range_min = `${dateRangeMin}`;
}
const ctx = {
root: getAppRoot(),
...params,
};
try {
const jobs = await jobsProvider(ctx);
this.jobs = jobs;
this.loading = false;
this.busy = false;
this.status = "info";
} catch (error) {
console.log(error);
this.message = errorMessageAsString(error);
this.status = "danger";
}
params = params.join("&");
axios
.get(`${getAppRoot()}api/jobs?${params}`)
.then((response) => {
this.jobs = response.data;
this.loading = false;
this.busy = false;
this.status = "info";
})
.catch((error) => {
this.message = errorMessageAsString(error);
this.status = "danger";
console.log(error.response);
});
},
onRefresh() {
this.update();
@@ -3,6 +3,7 @@ import { getAppRoot } from "onload/loadConfig";
import { SingleQueryProvider } from "components/providers/SingleQueryProvider";
import { rethrowSimple } from "utils/simple-error";
import { stateIsTerminal } from "./utils";
import { cleanPaginationParameters } from "./utils";
async function jobDetails({ jobid }) {
const url = `${getAppRoot()}api/jobs/${jobid}?full=True`;
@@ -26,3 +27,19 @@ async function jobProblems({ jobid }) {
export const JobDetailsProvider = SingleQueryProvider(jobDetails, stateIsTerminal);
export const JobProblemProvider = SingleQueryProvider(jobProblems, stateIsTerminal);
export function jobsProvider(ctx, callback, extraParams = {}) {
const { root, ...requestParams } = ctx;
const apiUrl = `${root}api/jobs`;
const cleanParams = cleanPaginationParameters(requestParams);
const promise = axios.get(apiUrl, { params: { ...cleanParams, ...extraParams } });
// Must return a promise that resolves to an array of items
return promise.then((data) => {
// Pluck the array of items off our axios response
const items = data.data;
callback && callback(data);
// Must return an array of items or an empty array if an error occurred
return items || [];
});
}
@@ -0,0 +1,43 @@
import axios from "axios";
import MockAdapter from "axios-mock-adapter";
import { jobsProvider } from "./JobProvider";
describe("JobProvider", () => {
let axiosMock;
beforeEach(async () => {
axiosMock = new MockAdapter(axios);
});
afterEach(() => {
axiosMock.restore();
});
describe("fetching jobs without an error", () => {
it("should make an API call and fire callback", async () => {
axiosMock
.onGet("/prefixj/api/jobs", {
params: { limit: 50, offset: 0, search: "tool_id:'cat1'" },
})
.reply(200, [{ model_class: "Job" }], { total_matches: "1" });
const ctx = {
root: "/prefixj/",
perPage: 50,
currentPage: 1,
};
const extras = {
search: "tool_id:'cat1'",
};
let called = false;
const callback = function () {
called = true;
};
const promise = jobsProvider(ctx, callback, extras);
await promise;
expect(called).toBeTruthy();
});
});
});