From b276c5bfe2f2dea8e2e0d1701adb7fe3750814c8 Mon Sep 17 00:00:00 2001 From: roggervalf Date: Fri, 3 May 2024 00:33:53 -0500 Subject: [PATCH 1/2] feat(finished): add clean button --- public/dashboard.js | 50 +++++++++++++------ src/server/views/api/bulkAction.js | 7 ++- src/server/views/api/bulkJobsClean.js | 3 ++ src/server/views/api/index.js | 2 + .../views/dashboard/queueJobsByState.js | 6 +++ .../dashboard/templates/queueJobsByState.hbs | 6 +++ 6 files changed, 56 insertions(+), 18 deletions(-) create mode 100644 src/server/views/api/bulkJobsClean.js diff --git a/public/dashboard.js b/public/dashboard.js index 268abb5c..9f43ec5d 100644 --- a/public/dashboard.js +++ b/public/dashboard.js @@ -225,23 +225,41 @@ $(document).ready(() => { } in queue "${queueHost}/${queueName}"?` ); if (r) { - $.ajax({ - method: action === 'remove' ? 'POST' : 'PATCH', - url: `${basePath}/api/queue/${encodeURIComponent( - queueHost - )}/${encodeURIComponent(queueName)}/${ - action === 'promote' ? 'delayed/' : '' - }job/bulk`, - data: JSON.stringify(data), - contentType: 'application/json', - }) - .done(() => { - window.location.reload(); + if (action === 'clean') { + $.ajax({ + method: 'DELETE', + url: `${basePath}/api/queue/${encodeURIComponent( + queueHost + )}/${encodeURIComponent(queueName)}/jobs/bulk`, + data: JSON.stringify(data), + contentType: 'application/json', }) - .fail((jqXHR) => { - window.alert(`Request failed, check console for error.`); - console.error(jqXHR.responseText); - }); + .done(() => { + window.location.reload(); + }) + .fail((jqXHR) => { + window.alert(`Request failed, check console for error.`); + console.error(jqXHR.responseText); + }); + } else { + $.ajax({ + method: action === 'remove' ? 'POST' : 'PATCH', + url: `${basePath}/api/queue/${encodeURIComponent( + queueHost + )}/${encodeURIComponent(queueName)}/${ + action === 'promote' ? 'delayed/' : '' + }job/bulk`, + data: JSON.stringify(data), + contentType: 'application/json', + }) + .done(() => { + window.location.reload(); + }) + .fail((jqXHR) => { + window.alert(`Request failed, check console for error.`); + console.error(jqXHR.responseText); + }); + } } else { $(this).prop('disabled', false); } diff --git a/src/server/views/api/bulkAction.js b/src/server/views/api/bulkAction.js index ae8ae206..3b42153c 100644 --- a/src/server/views/api/bulkAction.js +++ b/src/server/views/api/bulkAction.js @@ -1,6 +1,6 @@ const _ = require('lodash'); -const ACTIONS = ['remove', 'retry', 'promote']; +const ACTIONS = ['clean', 'remove', 'retry', 'promote']; function bulkAction(action) { return async function handler(req, res) { @@ -19,7 +19,7 @@ function bulkAction(action) { const {jobs, queueState} = req.body; try { - if (!_.isEmpty(jobs)) { + if (!_.isEmpty(jobs) && job.length > 0) { const jobsPromises = jobs.map((id) => queue.getJob(decodeURIComponent(id)) ); @@ -39,6 +39,9 @@ function bulkAction(action) { : fetchedJobs.map((job) => job[action]()); await Promise.all(actionPromises); return res.sendStatus(200); + } else if (action === 'clean') { + await queue.clean(1000, queueState); + return res.sendStatus(200); } } catch (e) { const body = { diff --git a/src/server/views/api/bulkJobsClean.js b/src/server/views/api/bulkJobsClean.js new file mode 100644 index 00000000..92c5241a --- /dev/null +++ b/src/server/views/api/bulkJobsClean.js @@ -0,0 +1,3 @@ +const bulkAction = require('./bulkAction'); + +module.exports = bulkAction('clean'); diff --git a/src/server/views/api/index.js b/src/server/views/api/index.js index 12b53987..ef4b6350 100644 --- a/src/server/views/api/index.js +++ b/src/server/views/api/index.js @@ -8,6 +8,7 @@ const jobRetry = require('./jobRetry'); const jobRemove = require('./jobRemove'); const jobDataUpdate = require('./jobDataUpdate'); const repeatableJobRemove = require('./repeatableJobRemove'); +const bulkJobsClean = require('./bulkJobsClean'); const bulkJobsPromote = require('./bulkJobsPromote'); const bulkJobsRemove = require('./bulkJobsRemove'); const bulkJobsRetry = require('./bulkJobsRetry'); @@ -30,5 +31,6 @@ router.patch('/queue/:queueHost/:queueName/job/:id', jobRetry); router.put('/queue/:queueHost/:queueName/pause', queuePause); router.put('/queue/:queueHost/:queueName/resume', queueResume); router.delete('/queue/:queueHost/:queueName/job/:id', jobRemove); +router.delete('/queue/:queueHost/:queueName/jobs/bulk', bulkJobsClean); module.exports = router; diff --git a/src/server/views/dashboard/queueJobsByState.js b/src/server/views/dashboard/queueJobsByState.js index c9272724..8b25ea49 100644 --- a/src/server/views/dashboard/queueJobsByState.js +++ b/src/server/views/dashboard/queueJobsByState.js @@ -153,6 +153,11 @@ async function _html(req, res) { state === 'failed' || (state === 'delayed' && !queue.IS_BEE) ); + const disableClean = !( + state === 'failed' || + state === 'completed' || + !queue.IS_BULL + ); return res.render('dashboard/templates/queueJobsByState', { basePath, @@ -164,6 +169,7 @@ async function _html(req, res) { disablePagination: queue.IS_BEE && (state === 'succeeded' || state === 'failed'), disableOrdering: queue.IS_BEE, + disableClean, disablePromote, disableRetry, currentPage: page, diff --git a/src/server/views/dashboard/templates/queueJobsByState.hbs b/src/server/views/dashboard/templates/queueJobsByState.hbs index ca7a757a..d41dfa8d 100644 --- a/src/server/views/dashboard/templates/queueJobsByState.hbs +++ b/src/server/views/dashboard/templates/queueJobsByState.hbs @@ -50,6 +50,12 @@ data-queue-state="{{ state }}" class="js-bulk-action btn btn-danger"> Remove Jobs + {{#unless disableClean}} + + {{/unless}} {{#unless disableRetry}}