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:
+4
-4
@@ -19,7 +19,7 @@ import {
|
||||
import { type AwsSesClientProvider } from 'src/engine/core-modules/emailing-domain/drivers/aws-ses/providers/aws-ses-client.provider';
|
||||
import { type AwsSesHandleErrorService } from 'src/engine/core-modules/emailing-domain/drivers/aws-ses/services/aws-ses-handle-error.service';
|
||||
import { EmailingDomainStatus } from 'src/engine/core-modules/emailing-domain/drivers/types/emailing-domain';
|
||||
import { type VerificationRecord } from 'src/engine/core-modules/emailing-domain/dtos/verification-record.dto';
|
||||
import { type VerificationRecordDTO } from 'src/engine/core-modules/emailing-domain/dtos/verification-record.dto';
|
||||
|
||||
export class AwsSesDriver implements EmailingDomainDriverInterface {
|
||||
private readonly logger = new Logger(AwsSesDriver.name);
|
||||
@@ -127,7 +127,7 @@ export class AwsSesDriver implements EmailingDomainDriverInterface {
|
||||
tenantName: string,
|
||||
): Promise<{
|
||||
isVerified: boolean;
|
||||
verificationRecords: VerificationRecord[];
|
||||
verificationRecords: VerificationRecordDTO[];
|
||||
}> {
|
||||
const sesClient = this.awsSesClientProvider.getSESClient();
|
||||
|
||||
@@ -161,7 +161,7 @@ export class AwsSesDriver implements EmailingDomainDriverInterface {
|
||||
tenantName: string,
|
||||
): Promise<{
|
||||
isVerified: boolean;
|
||||
verificationRecords: VerificationRecord[];
|
||||
verificationRecords: VerificationRecordDTO[];
|
||||
}> {
|
||||
const sesClient = this.awsSesClientProvider.getSESClient();
|
||||
|
||||
@@ -227,7 +227,7 @@ export class AwsSesDriver implements EmailingDomainDriverInterface {
|
||||
private buildVerificationRecords(
|
||||
domain: string,
|
||||
dkimTokens: string[],
|
||||
): VerificationRecord[] {
|
||||
): VerificationRecordDTO[] {
|
||||
return dkimTokens.map((token) => ({
|
||||
type: 'CNAME' as const,
|
||||
key: `${token}._domainkey.${domain}`,
|
||||
|
||||
+1
-1
@@ -26,7 +26,7 @@ export class EmailingDomainDriverFactory extends DriverFactoryBase<EmailingDomai
|
||||
|
||||
if (driver === EmailingDomainDriver.AWS_SES) {
|
||||
const awsConfigHash = this.getConfigGroupHash(
|
||||
ConfigVariablesGroup.AwsSesSettings,
|
||||
ConfigVariablesGroup.AWS_SES_SETTINGS,
|
||||
);
|
||||
|
||||
return `aws-ses|${awsConfigHash}`;
|
||||
|
||||
+3
-3
@@ -7,7 +7,7 @@ import {
|
||||
EmailingDomainDriver,
|
||||
EmailingDomainStatus,
|
||||
} from 'src/engine/core-modules/emailing-domain/drivers/types/emailing-domain';
|
||||
import { VerificationRecord } from 'src/engine/core-modules/emailing-domain/dtos/verification-record.dto';
|
||||
import { VerificationRecordDTO } from 'src/engine/core-modules/emailing-domain/dtos/verification-record.dto';
|
||||
|
||||
registerEnumType(EmailingDomainDriver, {
|
||||
name: 'EmailingDomainDriver',
|
||||
@@ -37,8 +37,8 @@ export class EmailingDomainDto {
|
||||
@Field(() => EmailingDomainStatus)
|
||||
status: EmailingDomainStatus;
|
||||
|
||||
@Field(() => [VerificationRecord], { nullable: true })
|
||||
verificationRecords: VerificationRecord[] | null;
|
||||
@Field(() => [VerificationRecordDTO], { nullable: true })
|
||||
verificationRecords: VerificationRecordDTO[] | null;
|
||||
|
||||
@Field(() => Date, { nullable: true })
|
||||
verifiedAt: Date | null;
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
import { Field, ObjectType } from '@nestjs/graphql';
|
||||
|
||||
@ObjectType()
|
||||
export class VerificationRecord {
|
||||
@ObjectType('VerificationRecord')
|
||||
export class VerificationRecordDTO {
|
||||
@Field(() => String)
|
||||
type: 'TXT' | 'CNAME' | 'MX';
|
||||
|
||||
|
||||
Reference in New Issue
Block a user