2022-05-19 17:25:53 +02:00

96 lines
3.0 KiB
JavaScript

import { defineStore } from 'pinia'
import * as API from '@/manager-api';
import { apiClient } from '@/stores/api-query-count';
const jobsAPI = new API.JobsApi(apiClient);
// 'use' prefix is idiomatic for Pinia stores.
// See https://pinia.vuejs.org/core-concepts/
export const useJobs = defineStore('jobs', {
state: () => ({
/** @type {API.Job} */
activeJob: null,
/**
* ID of the active job. Easier to query than `activeJob ? activeJob.id : ""`.
* @type {string}
*/
activeJobID: "",
}),
getters: {
canDelete() {
return this._anyJobWithStatus(["queued", "paused", "failed", "completed", "canceled"])
},
canCancel() {
return this._anyJobWithStatus(["queued", "active", "failed"])
},
canRequeue() {
return this._anyJobWithStatus(["canceled", "completed", "failed", "paused"])
},
},
actions: {
setActiveJobID(jobID) {
this.$patch({
activeJob: {id: jobID, settings: {}, metadata: {}},
activeJobID: jobID,
});
},
setActiveJob(job) {
// The "function" form of $patch is necessary here, as otherwise it'll
// merge `job` into `state.activeJob`. As a result, it won't touch missing
// keys, which means that metadata fields that existed on the previous job
// but not on the new one will still linger around. By passing a function
// to `$patch` this is resolved.
this.$patch((state) => {
state.activeJob = job;
state.activeJobID = job.id;
state.hasChanged = true;
});
},
deselectAllJobs() {
this.$patch({
activeJob: null,
activeJobID: "",
});
},
/**
* Actions on the selected jobs.
*
* All the action functions return a promise that resolves when the action has been performed.
*
* TODO: actually have these work on all selected jobs. For simplicity, the
* code now assumes that only the active job needs to be operated on.
*/
cancelJobs() { return this._setJobStatus("cancel-requested"); },
requeueJobs() { return this._setJobStatus("requeueing"); },
// Internal methods.
/**
*
* @param {string[]} statuses
* @returns bool indicating whether there is a selected job with any of the given statuses.
*/
_anyJobWithStatus(statuses) {
return !!this.activeJob && !!this.activeJob.status && statuses.includes(this.activeJob.status);
// return this.selectedJobs.reduce((foundJob, job) => (foundJob || statuses.includes(job.status)), false);
},
/**
* Transition the selected job(s) to the new status.
* @param {string} newStatus
* @returns a Promise for the API request.
*/
_setJobStatus(newStatus) {
if (!this.activeJobID) {
console.warn(`_setJobStatus(${newStatus}) impossible, no active job ID`);
return;
}
const statuschange = new API.JobStatusChange(newStatus, "requested from web interface");
return jobsAPI.setJobStatus(this.activeJobID, statuschange);
},
},
})