diff --git a/src/client/app/admin/views/queue.vue b/src/client/app/admin/views/queue.vue index cec2ab4d7..17bf3709c 100644 --- a/src/client/app/admin/views/queue.vue +++ b/src/client/app/admin/views/queue.vue @@ -1,7 +1,7 @@ @@ -69,7 +98,7 @@ import i18n from '../../i18n'; import ApexCharts from 'apexcharts'; import * as tinycolor from 'tinycolor2'; import { faTasks, faInbox, faStopwatch, faPlayCircle as fasPlayCircle } from '@fortawesome/free-solid-svg-icons'; -import { faPaperPlane, faStopCircle, faPlayCircle as farPlayCircle } from '@fortawesome/free-regular-svg-icons'; +import { faPaperPlane, faStopCircle, faPlayCircle as farPlayCircle, faChartBar } from '@fortawesome/free-regular-svg-icons'; const limit = 150; @@ -81,7 +110,11 @@ export default Vue.extend({ stats: [], deliverChart: null, inboxChart: null, - faTasks, faPaperPlane, faInbox, faStopwatch, faStopCircle, farPlayCircle, fasPlayCircle + jobs: [], + jobsLimit: 50, + domain: 'deliver', + state: 'delayed', + faTasks, faPaperPlane, faInbox, faStopwatch, faStopCircle, farPlayCircle, fasPlayCircle, faChartBar }; }, @@ -127,10 +160,22 @@ export default Vue.extend({ type: 'line', data: stats.map((x, i) => ({ x: i, y: x.deliver.delayed })) }]); - } + }, + + domain() { + this.jobs = []; + this.fetchJobs(); + }, + + state() { + this.jobs = []; + this.fetchJobs(); + }, }, mounted() { + this.fetchJobs(); + const chartOpts = id => ({ chart: { id, @@ -238,7 +283,17 @@ export default Vue.extend({ for (const stats of statsLog.reverse()) { this.onStats(stats); } - } + }, + + fetchJobs() { + this.$root.api('admin/queue/jobs', { + domain: this.domain, + state: this.state, + limit: this.jobsLimit + }).then(jobs => { + this.jobs = jobs; + }); + }, } }); @@ -249,4 +304,8 @@ export default Vue.extend({ min-height 200px !important margin 0 -8px +.xvvuvgsv + > b + margin-right 16px + diff --git a/src/server/api/endpoints/admin/queue/jobs.ts b/src/server/api/endpoints/admin/queue/jobs.ts new file mode 100644 index 000000000..c2496d7ef --- /dev/null +++ b/src/server/api/endpoints/admin/queue/jobs.ts @@ -0,0 +1,40 @@ +import $ from 'cafy'; +import define from '../../../define'; +import { deliverQueue, inboxQueue } from '../../../../../queue'; + +export const meta = { + tags: ['admin'], + + requireCredential: true, + requireModerator: true, + + params: { + domain: { + validator: $.str, + }, + + state: { + validator: $.str, + }, + + limit: { + validator: $.optional.num, + default: 50 + }, + } +}; + +export default define(meta, async (ps) => { + const queue = + ps.domain === 'deliver' ? deliverQueue : + ps.domain === 'inbox' ? inboxQueue : + null; + + const jobs = await queue.getJobs([ps.state], 0, ps.limit); + + return jobs.map(job => ({ + id: job.id, + data: job.data, + attempts: job.attemptsMade, + })); +});