From ba02f8d4a6ef976ec0a7843e7a6222842eafab4a Mon Sep 17 00:00:00 2001
From: ahmad anwar <7552088+AhmedAnwarHafez@users.noreply.github.com>
Date: Thu, 2 Jan 2025 18:27:12 +1300
Subject: [PATCH 1/5] feat(OverviewActions): add OverviewActions component with
pause and resume functionality; update OverviewPage layout and styles
- Introduced a new `OverviewActions` component that provides pause and resume actions for queues.
- Updated `OverviewPage` to include the new `OverviewActions` component in the header.
- Enhanced CSS for the header layout to improve UI alignment and spacing.
- Added new translation keys for pause and resume actions in the localization files.
---
.../OverviewActions/OverviewActions.tsx | 37 +++++++++++++++++++
.../OverviewPage/OverviewPage.module.css | 6 +++
.../src/pages/OverviewPage/OverviewPage.tsx | 7 +++-
.../ui/src/static/locales/en-US/messages.json | 6 ++-
4 files changed, 53 insertions(+), 3 deletions(-)
create mode 100644 packages/ui/src/components/OverviewActions/OverviewActions.tsx
diff --git a/packages/ui/src/components/OverviewActions/OverviewActions.tsx b/packages/ui/src/components/OverviewActions/OverviewActions.tsx
new file mode 100644
index 000000000..9ed46df8d
--- /dev/null
+++ b/packages/ui/src/components/OverviewActions/OverviewActions.tsx
@@ -0,0 +1,37 @@
+import React from 'react';
+import { Item, Portal, Root, Trigger } from '@radix-ui/react-dropdown-menu';
+import { Button } from '../Button/Button';
+import { DropdownContent } from '../DropdownContent/DropdownContent';
+import { EllipsisVerticalIcon } from '../Icons/EllipsisVertical';
+import { PauseIcon } from '../Icons/Pause';
+import { PlayIcon } from '../Icons/Play';
+import { useTranslation } from 'react-i18next';
+
+export const OverviewActions = () => {
+ const { t } = useTranslation();
+
+ return (
+
+
+
+
+
+
+
+ -
+
+ {t('QUEUE.ACTIONS.PAUSE_ALL')}
+
+ -
+
+ {t('QUEUE.ACTIONS.RESUME_ALL')}
+
+
+
+
+ );
+};
+
+export default OverviewActions;
diff --git a/packages/ui/src/pages/OverviewPage/OverviewPage.module.css b/packages/ui/src/pages/OverviewPage/OverviewPage.module.css
index bac24fe63..2300ac68c 100644
--- a/packages/ui/src/pages/OverviewPage/OverviewPage.module.css
+++ b/packages/ui/src/pages/OverviewPage/OverviewPage.module.css
@@ -21,3 +21,9 @@
}
}
}
+
+.header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+}
diff --git a/packages/ui/src/pages/OverviewPage/OverviewPage.tsx b/packages/ui/src/pages/OverviewPage/OverviewPage.tsx
index 56068b045..620980502 100644
--- a/packages/ui/src/pages/OverviewPage/OverviewPage.tsx
+++ b/packages/ui/src/pages/OverviewPage/OverviewPage.tsx
@@ -8,6 +8,7 @@ import { useQuery } from '../../hooks/useQuery';
import { useQueues } from '../../hooks/useQueues';
import { links } from '../../utils/links';
import s from './OverviewPage.module.css';
+import OverviewActions from '../../components/OverviewActions/OverviewActions';
export const OverviewPage = () => {
const { t } = useTranslation();
@@ -20,8 +21,10 @@ export const OverviewPage = () => {
queues?.filter((queue) => !selectedStatus || queue.counts[selectedStatus] > 0) || [];
return (
-
-
+
+
+
+
{queuesToView.length > 0 && (
{queuesToView.map((queue) => (
diff --git a/packages/ui/src/static/locales/en-US/messages.json b/packages/ui/src/static/locales/en-US/messages.json
index d3caa4a71..eeb6a7f0b 100644
--- a/packages/ui/src/static/locales/en-US/messages.json
+++ b/packages/ui/src/static/locales/en-US/messages.json
@@ -63,6 +63,8 @@
"CLEAN_ALL": "Clean all",
"RESUME": "Resume",
"PAUSE": "Pause",
+ "RESUME_ALL": "Resume all",
+ "PAUSE_ALL": "Pause all",
"EMPTY": "Empty",
"ADD_JOB": "Add job",
"CONFIRM": {
@@ -71,7 +73,9 @@
"PROMOTE_ALL": "Are you sure that you want to promote all delayed jobs?",
"PAUSE_QUEUE": "Are you sure that you want to pause queue processing?",
"EMPTY_QUEUE": "Are you sure that you want to empty the queue?",
- "RESUME_QUEUE": "Are you sure that you want to resume queue processing?"
+ "RESUME_QUEUE": "Are you sure that you want to resume queue processing?",
+ "PAUSE_ALL": "Are you sure that you want to pause all queues?",
+ "RESUME_ALL": "Are you sure that you want to resume all queues?"
}
},
"STATUS": {
From f416f3e44abc06429b0ded898a00517261961189 Mon Sep 17 00:00:00 2001
From: ahmad anwar <7552088+AhmedAnwarHafez@users.noreply.github.com>
Date: Thu, 2 Jan 2025 18:38:56 +1300
Subject: [PATCH 2/5] feat(OverviewActions): integrate pause and resume actions
into OverviewActions component
- Updated the OverviewActions component to accept actions as props, enabling pause and resume functionality for queues.
- Implemented pauseAll and resumeAll actions in the useQueues hook.
- Modified OverviewPage to pass the actions prop to OverviewActions, enhancing the user interface for queue management.
---
.../components/OverviewActions/OverviewActions.tsx | 11 ++++++++---
packages/ui/src/hooks/useQueues.ts | 5 +++++
packages/ui/src/pages/OverviewPage/OverviewPage.tsx | 2 +-
packages/ui/typings/app.d.ts | 2 ++
4 files changed, 16 insertions(+), 4 deletions(-)
diff --git a/packages/ui/src/components/OverviewActions/OverviewActions.tsx b/packages/ui/src/components/OverviewActions/OverviewActions.tsx
index 9ed46df8d..b6e010064 100644
--- a/packages/ui/src/components/OverviewActions/OverviewActions.tsx
+++ b/packages/ui/src/components/OverviewActions/OverviewActions.tsx
@@ -6,8 +6,13 @@ import { EllipsisVerticalIcon } from '../Icons/EllipsisVertical';
import { PauseIcon } from '../Icons/Pause';
import { PlayIcon } from '../Icons/Play';
import { useTranslation } from 'react-i18next';
+import { useQueues } from '../../hooks/useQueues';
-export const OverviewActions = () => {
+export const OverviewActions = ({
+ actions,
+}: {
+ actions: ReturnType['actions'];
+}) => {
const { t } = useTranslation();
return (
@@ -20,11 +25,11 @@ export const OverviewActions = () => {
- -
+
-
{t('QUEUE.ACTIONS.PAUSE_ALL')}
- -
+
-
{t('QUEUE.ACTIONS.RESUME_ALL')}
diff --git a/packages/ui/src/hooks/useQueues.ts b/packages/ui/src/hooks/useQueues.ts
index 9f811c271..06e1243fb 100644
--- a/packages/ui/src/hooks/useQueues.ts
+++ b/packages/ui/src/hooks/useQueues.ts
@@ -115,10 +115,15 @@ export function useQueues(): Omit & { actions: Queu
jobOptions: Record
) => withConfirmAndUpdate(() => api.addJob(queueName, jobName, jobData, jobOptions), '', false);
+ const pauseAll = withConfirmAndUpdate(() => console.log('pauseAll'), '', true);
+ const resumeAll = withConfirmAndUpdate(() => console.log('resumeAll'), '', true);
+
return {
queues,
loading,
actions: {
+ pauseAll,
+ resumeAll,
updateQueues,
pollQueues,
retryAll,
diff --git a/packages/ui/src/pages/OverviewPage/OverviewPage.tsx b/packages/ui/src/pages/OverviewPage/OverviewPage.tsx
index 620980502..f73cd750f 100644
--- a/packages/ui/src/pages/OverviewPage/OverviewPage.tsx
+++ b/packages/ui/src/pages/OverviewPage/OverviewPage.tsx
@@ -23,7 +23,7 @@ export const OverviewPage = () => {
-
+
{queuesToView.length > 0 && (
diff --git a/packages/ui/typings/app.d.ts b/packages/ui/typings/app.d.ts
index 3acd255c4..723535feb 100644
--- a/packages/ui/typings/app.d.ts
+++ b/packages/ui/typings/app.d.ts
@@ -11,6 +11,8 @@ export { Status } from '@bull-board/api/typings/app';
export type SelectedStatuses = Record;
export interface QueueActions {
+ pauseAll: () => Promise;
+ resumeAll: () => Promise;
retryAll: (queueName: string, status: JobRetryStatus) => () => Promise;
promoteAll: (queueName: string) => () => Promise;
cleanAll: (queueName: string, status: JobCleanStatus) => () => Promise;
From 9c26e54e30b80bb03a016c53577a0412693e8d9f Mon Sep 17 00:00:00 2001
From: ahmad anwar <7552088+AhmedAnwarHafez@users.noreply.github.com>
Date: Thu, 2 Jan 2025 20:36:42 +1300
Subject: [PATCH 3/5] feat(api): add pause and resume queue functionality
- Introduced `pauseAllHandler` and `resumeAllHandler` to handle pausing and resuming all queues.
- Updated `appRoutes` to include new API endpoints for pausing and resuming queues.
- Enhanced `useQueues` hook to integrate API calls for pausing and resuming queues with user confirmation.
- Added corresponding methods in the `Api` service for making requests to the new endpoints.
---
packages/api/src/handlers/pauseAll.ts | 8 ++++++++
packages/api/src/handlers/resumeAll.ts | 8 ++++++++
packages/api/src/routes.ts | 4 ++++
packages/ui/src/hooks/useQueues.ts | 12 ++++++++++--
packages/ui/src/services/Api.ts | 8 ++++++++
5 files changed, 38 insertions(+), 2 deletions(-)
create mode 100644 packages/api/src/handlers/pauseAll.ts
create mode 100644 packages/api/src/handlers/resumeAll.ts
diff --git a/packages/api/src/handlers/pauseAll.ts b/packages/api/src/handlers/pauseAll.ts
new file mode 100644
index 000000000..2b47a3064
--- /dev/null
+++ b/packages/api/src/handlers/pauseAll.ts
@@ -0,0 +1,8 @@
+import { BullBoardRequest, ControllerHandlerReturnType } from '../../typings/app';
+
+async function pauseAll(req: BullBoardRequest): Promise {
+ req.queues.forEach((queue) => queue.pause());
+ return { status: 200, body: { message: 'All queues paused' } };
+}
+
+export const pauseAllHandler = pauseAll;
diff --git a/packages/api/src/handlers/resumeAll.ts b/packages/api/src/handlers/resumeAll.ts
new file mode 100644
index 000000000..0109b5c9c
--- /dev/null
+++ b/packages/api/src/handlers/resumeAll.ts
@@ -0,0 +1,8 @@
+import { BullBoardRequest, ControllerHandlerReturnType } from '../../typings/app';
+
+async function resumeAll(req: BullBoardRequest): Promise {
+ req.queues.forEach((queue) => queue.resume());
+ return { status: 200, body: { message: 'All queues resumed' } };
+}
+
+export const resumeAllHandler = resumeAll;
diff --git a/packages/api/src/routes.ts b/packages/api/src/routes.ts
index bb33fd5da..141ebf31a 100644
--- a/packages/api/src/routes.ts
+++ b/packages/api/src/routes.ts
@@ -15,6 +15,8 @@ import { retryAllHandler } from './handlers/retryAll';
import { retryJobHandler } from './handlers/retryJob';
import { promoteAllHandler } from './handlers/promoteAll';
import { updateJobDataHandler } from './handlers/updateJobData';
+import { pauseAllHandler } from './handlers/pauseAll';
+import { resumeAllHandler } from './handlers/resumeAll';
export const appRoutes: AppRouteDefs = {
entryPoint: {
@@ -25,6 +27,8 @@ export const appRoutes: AppRouteDefs = {
api: [
{ method: 'get', route: '/api/redis/stats', handler: redisStatsHandler },
{ method: 'get', route: '/api/queues', handler: queuesHandler },
+ { method: 'put', route: '/api/queues/pause', handler: pauseAllHandler },
+ { method: 'put', route: '/api/queues/resume', handler: resumeAllHandler },
{
method: 'get',
route: '/api/queues/:queueName/:jobId/logs',
diff --git a/packages/ui/src/hooks/useQueues.ts b/packages/ui/src/hooks/useQueues.ts
index 06e1243fb..f0e704b43 100644
--- a/packages/ui/src/hooks/useQueues.ts
+++ b/packages/ui/src/hooks/useQueues.ts
@@ -115,8 +115,16 @@ export function useQueues(): Omit & { actions: Queu
jobOptions: Record
) => withConfirmAndUpdate(() => api.addJob(queueName, jobName, jobData, jobOptions), '', false);
- const pauseAll = withConfirmAndUpdate(() => console.log('pauseAll'), '', true);
- const resumeAll = withConfirmAndUpdate(() => console.log('resumeAll'), '', true);
+ const pauseAll = withConfirmAndUpdate(
+ () => api.pauseAllQueues(),
+ t('QUEUE.ACTIONS.CONFIRM.PAUSE_ALL'),
+ confirmQueueActions
+ );
+ const resumeAll = withConfirmAndUpdate(
+ () => api.resumeAllQueues(),
+ t('QUEUE.ACTIONS.CONFIRM.RESUME_ALL'),
+ confirmQueueActions
+ );
return {
queues,
diff --git a/packages/ui/src/services/Api.ts b/packages/ui/src/services/Api.ts
index 13896dd98..77676839d 100644
--- a/packages/ui/src/services/Api.ts
+++ b/packages/ui/src/services/Api.ts
@@ -111,6 +111,14 @@ export class Api {
return this.axios.put(`/queues/${encodeURIComponent(queueName)}/resume`);
}
+ public pauseAllQueues() {
+ return this.axios.put(`/queues/pause`);
+ }
+
+ public resumeAllQueues() {
+ return this.axios.put(`/queues/resume`);
+ }
+
public emptyQueue(queueName: string) {
return this.axios.put(`/queues/${encodeURIComponent(queueName)}/empty`);
}
From b06dcd9e35d0a0d6738a82e93d9b41d55bfed87c Mon Sep 17 00:00:00 2001
From: ahmad anwar <7552088+AhmedAnwarHafez@users.noreply.github.com>
Date: Fri, 3 Jan 2025 09:03:25 +1300
Subject: [PATCH 4/5] refactor: renamed component
OverviewActions is renamed to OverviewDropDownActions
---
.../OverviewDropDownActions.tsx} | 0
packages/ui/src/pages/OverviewPage/OverviewPage.tsx | 4 ++--
2 files changed, 2 insertions(+), 2 deletions(-)
rename packages/ui/src/components/{OverviewActions/OverviewActions.tsx => OverviewDropDownActions/OverviewDropDownActions.tsx} (100%)
diff --git a/packages/ui/src/components/OverviewActions/OverviewActions.tsx b/packages/ui/src/components/OverviewDropDownActions/OverviewDropDownActions.tsx
similarity index 100%
rename from packages/ui/src/components/OverviewActions/OverviewActions.tsx
rename to packages/ui/src/components/OverviewDropDownActions/OverviewDropDownActions.tsx
diff --git a/packages/ui/src/pages/OverviewPage/OverviewPage.tsx b/packages/ui/src/pages/OverviewPage/OverviewPage.tsx
index f73cd750f..3dc0b7961 100644
--- a/packages/ui/src/pages/OverviewPage/OverviewPage.tsx
+++ b/packages/ui/src/pages/OverviewPage/OverviewPage.tsx
@@ -8,7 +8,7 @@ import { useQuery } from '../../hooks/useQuery';
import { useQueues } from '../../hooks/useQueues';
import { links } from '../../utils/links';
import s from './OverviewPage.module.css';
-import OverviewActions from '../../components/OverviewActions/OverviewActions';
+import OverviewDropDownActions from '../../components/OverviewDropDownActions/OverviewDropDownActions';
export const OverviewPage = () => {
const { t } = useTranslation();
@@ -23,7 +23,7 @@ export const OverviewPage = () => {
-
+
{queuesToView.length > 0 && (
From 53f4804b2a2f446c3d10d3a9cb06312159866a58 Mon Sep 17 00:00:00 2001
From: ahmad anwar <7552088+AhmedAnwarHafez@users.noreply.github.com>
Date: Fri, 3 Jan 2025 09:17:38 +1300
Subject: [PATCH 5/5] feat: check for the queue pause state before resuming or
pausing
---
packages/api/src/handlers/pauseAll.ts | 7 ++++++-
packages/api/src/handlers/resumeAll.ts | 7 ++++++-
2 files changed, 12 insertions(+), 2 deletions(-)
diff --git a/packages/api/src/handlers/pauseAll.ts b/packages/api/src/handlers/pauseAll.ts
index 2b47a3064..d0343f3de 100644
--- a/packages/api/src/handlers/pauseAll.ts
+++ b/packages/api/src/handlers/pauseAll.ts
@@ -1,7 +1,12 @@
import { BullBoardRequest, ControllerHandlerReturnType } from '../../typings/app';
async function pauseAll(req: BullBoardRequest): Promise {
- req.queues.forEach((queue) => queue.pause());
+ req.queues.forEach(async (queue) => {
+ const isPaused = await queue.isPaused();
+ if (!isPaused) {
+ queue.pause();
+ }
+ });
return { status: 200, body: { message: 'All queues paused' } };
}
diff --git a/packages/api/src/handlers/resumeAll.ts b/packages/api/src/handlers/resumeAll.ts
index 0109b5c9c..7a9f2a7f6 100644
--- a/packages/api/src/handlers/resumeAll.ts
+++ b/packages/api/src/handlers/resumeAll.ts
@@ -1,7 +1,12 @@
import { BullBoardRequest, ControllerHandlerReturnType } from '../../typings/app';
async function resumeAll(req: BullBoardRequest): Promise {
- req.queues.forEach((queue) => queue.resume());
+ req.queues.forEach(async (queue) => {
+ const isPaused = await queue.isPaused();
+ if (isPaused) {
+ await queue.resume();
+ }
+ });
return { status: 200, body: { message: 'All queues resumed' } };
}