Add queue management dashboard (#15202)
Adds a comprehensive queue management interface to the admin panel for viewing and managing background jobs. **Features:** - Queue detail pages showing paginated job lists (50 per page) - Filter jobs by state: completed, failed, active, waiting, delayed, paused - Checkbox selection with bulk actions (delete jobs, retry failed jobs) - Per-job dropdown menu for individual retry/delete - Expandable rows showing error messages, stack traces, and job data - Relative timestamps with hover tooltips - Display attempt counts on failed jobs - Dynamic retention policy info from backend **Changes:** - Backend: New AdminPanelQueueService with GraphQL endpoints for job listing, retry, and delete - Frontend: Queue detail page with QueueJobsTable component - Updated retention policy: completed jobs kept 4 hours, failed jobs kept 7 days (max 1000 each) - Added JobState enum for type safety <img width="634" height="696" alt="Screenshot_2025-10-20_at_11 45 25" src="https://github.com/user-attachments/assets/c67bcd27-26cf-47f5-9575-3cd5684d006b" /> <img width="484" height="680" alt="Screenshot_2025-10-20_at_11 45 14" src="https://github.com/user-attachments/assets/68725cc6-b3ec-4098-99ca-f9a717d6f8f1" /> <img width="490" height="643" alt="Screenshot_2025-10-20_at_11 45 05" src="https://github.com/user-attachments/assets/b68a5809-33ff-4452-b48b-741aff7f1dd6" /> <img width="685" height="662" alt="Screenshot 2025-10-20 at 13 15 01" src="https://github.com/user-attachments/assets/eeb5207b-de5c-4b18-bdde-392892053dab" />
This commit is contained in:
@@ -23,6 +23,7 @@ describe('ClickHouseService', () => {
|
||||
let service: ClickHouseService;
|
||||
let twentyConfigService: TwentyConfigService;
|
||||
let mockClickHouseClient: jest.Mocked<ClickHouseClient>;
|
||||
let loggerErrorSpy: jest.SpyInstance;
|
||||
|
||||
beforeEach(async () => {
|
||||
jest.clearAllMocks();
|
||||
@@ -56,6 +57,11 @@ describe('ClickHouseService', () => {
|
||||
service = module.get<ClickHouseService>(ClickHouseService);
|
||||
twentyConfigService = module.get<TwentyConfigService>(TwentyConfigService);
|
||||
|
||||
// Mock logger error method to avoid polluting test output
|
||||
loggerErrorSpy = jest
|
||||
.spyOn((service as any).logger, 'error')
|
||||
.mockImplementation();
|
||||
|
||||
// Set the mock client
|
||||
(service as any).mainClient = mockClickHouseClient;
|
||||
});
|
||||
@@ -119,8 +125,10 @@ describe('ClickHouseService', () => {
|
||||
const result = await service.insert('test_table', testData);
|
||||
|
||||
expect(result).toEqual({ success: false });
|
||||
// Since the service uses logger.error instead of exceptionHandlerService.captureExceptions,
|
||||
// we don't need to assert on exceptionHandlerService
|
||||
expect(loggerErrorSpy).toHaveBeenCalledWith(
|
||||
'Error inserting data into ClickHouse',
|
||||
testError,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -161,8 +169,10 @@ describe('ClickHouseService', () => {
|
||||
const result = await service.select(query);
|
||||
|
||||
expect(result).toEqual([]);
|
||||
// Since the service uses logger.error instead of exceptionHandlerService.captureExceptions,
|
||||
// we don't need to assert on exceptionHandlerService
|
||||
expect(loggerErrorSpy).toHaveBeenCalledWith(
|
||||
'Error executing select query in ClickHouse',
|
||||
testError,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user