diff --git a/web/app/src/App.vue b/web/app/src/App.vue index e8cbd871..2bfac418 100644 --- a/web/app/src/App.vue +++ b/web/app/src/App.vue @@ -222,4 +222,38 @@ footer { background-color: #333333; color: #EEE; } + +section.action-bar button.action { + display: flex; + flex-direction: column; + align-items: center; + padding: 0.1rem 0.75rem; + border-radius: 0.3rem; + border: thin solid white; + + background: #6E6D70; + color: #DFDEDF; + touch-action: manipulation; + + transition-duration: 150ms; + transition-property: color, background-color, border-color, box-shadow +} + +section.action-bar button.action[disabled] { + background-color: #4c4b4d; + color: #858585; + border: thin solid #858585; +} + +section.action-bar button.action:focus { + background-color: cadetblue; +} + +section.action-bar button.action.dangerous { + background-color: darkred; +} + +section.action-bar button.action.dangerous[disabled] { + background-color: #53413e; +} diff --git a/web/app/src/components/JobActionsBar.vue b/web/app/src/components/JobActionsBar.vue new file mode 100644 index 00000000..3440edf2 --- /dev/null +++ b/web/app/src/components/JobActionsBar.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/web/app/src/components/JobsTable.vue b/web/app/src/components/JobsTable.vue index 6c093875..e98399ff 100644 --- a/web/app/src/components/JobsTable.vue +++ b/web/app/src/components/JobsTable.vue @@ -1,4 +1,5 @@ @@ -6,10 +7,14 @@ import { TabulatorFull as Tabulator } from 'tabulator-tables'; import * as datetime from "@/datetime"; import * as API from '@/manager-api' +import JobActionsBar from '@/components/JobActionsBar.vue' export default { emits: ["selectedJobChange"], props: ["apiClient"], + components: { + JobActionsBar, + }, data: () => { const options = { // See pkg/api/flamenco-manager.yaml, schemas Job and JobUpdate. diff --git a/web/app/src/stores/jobs.js b/web/app/src/stores/jobs.js index bd7e31a4..fa326883 100644 --- a/web/app/src/stores/jobs.js +++ b/web/app/src/stores/jobs.js @@ -1,5 +1,6 @@ import { defineStore } from 'pinia' +import * as urls from '@/urls' import * as API from '@/manager-api'; // 'use' prefix is idiomatic for Pinia stores. @@ -15,6 +16,9 @@ export const useJobs = defineStore('jobs', { numSelected() { return this.selectedJobs.length; }, + canDelete() { + return this._anyJobWithStatus(["queued", "paused", "failed", "completed"]) + }, }, actions: { // Selection of jobs. @@ -30,5 +34,17 @@ export const useJobs = defineStore('jobs', { this.selectedJobs = []; this.activeJob = null; }, + + // Actions on the selected jobs. + deleteJobs() { + const deletionPromise = new Promise( (resolutionFunc, rejectionFunc) => { + rejectionFunc({code: 327, message: "deleting jobs is not implemented in JS yet"}); + }); + return deletionPromise; + }, + // Internal methods. + _anyJobWithStatus(statuses) { + return this.selectedJobs.reduce((foundJob, job) => (foundJob || statuses.includes(job.status)), false); + } }, })