chore: refactor search mehtod
This commit is contained in:
@@ -35,6 +35,6 @@ export class BulkActionDto {
|
||||
enum: BulkActionType,
|
||||
})
|
||||
@IsNotEmpty({ message: "Action type is required" })
|
||||
@IsEnum(BulkActionType, { message: "Action must be one of: seen, delete, archive, favorite, junk, trash" })
|
||||
@IsEnum(BulkActionType, { message: "Action must be one of: seen, delete, archive, favorite, unfavorite, junk, trash" })
|
||||
action: BulkActionType;
|
||||
}
|
||||
|
||||
@@ -137,11 +137,11 @@ export class EmailController {
|
||||
}
|
||||
|
||||
@Get("messages/favorite")
|
||||
@ApiOperation({ summary: "List messages in favorite mailbox" })
|
||||
@ApiResponse({ status: 200, description: "List of favorite messages" })
|
||||
@ApiResponse({ status: 404, description: "favorite mailbox not found" })
|
||||
getFavoriteMessages(@UserDec("wildduckUserId") userId: string, @Query() query: MessageListQueryDto) {
|
||||
return this.emailService.getFavoriteMessages(userId, query);
|
||||
@ApiOperation({ summary: "List messages in starred mailbox" })
|
||||
@ApiResponse({ status: 200, description: "List of starred messages" })
|
||||
@ApiResponse({ status: 404, description: "starred mailbox not found" })
|
||||
getStarredMessages(@UserDec("wildduckUserId") userId: string, @Query() query: MessageListQueryDto) {
|
||||
return this.emailService.getStarredMessages(userId, query);
|
||||
}
|
||||
|
||||
@Get("messages/drafts")
|
||||
@@ -189,15 +189,6 @@ export class EmailController {
|
||||
return this.emailService.moveMessageToArchive(userId, Number(params.messageId), query.mailbox);
|
||||
}
|
||||
|
||||
@Patch("messages/:messageId/favorite")
|
||||
@ApiOperation({ summary: "Move a message to favorite mailbox" })
|
||||
@ApiResponse({ status: 200, description: "Message moved to favorite successfully" })
|
||||
@ApiResponse({ status: 404, description: "Message not found" })
|
||||
@ApiResponse({ status: 403, description: "Not authorized to move message" })
|
||||
moveMessageToFavorite(@UserDec("wildduckUserId") userId: string, @Param() params: MessageParamDto, @Query() query: MailboxIdQueryDto) {
|
||||
return this.emailService.moveMessageToFavorite(userId, Number(params.messageId), query.mailbox);
|
||||
}
|
||||
|
||||
@Patch("messages/:messageId/trash")
|
||||
@ApiOperation({ summary: "Move a message to trash mailbox" })
|
||||
@ApiResponse({ status: 200, description: "Message moved to trash successfully" })
|
||||
@@ -216,20 +207,38 @@ export class EmailController {
|
||||
return this.emailService.moveMessageToInboxFromArchive(userId, Number(params.messageId), query.mailbox);
|
||||
}
|
||||
|
||||
@Patch("messages/:messageId/favorite")
|
||||
@ApiOperation({ summary: "Star a message (Gmail-like behavior)" })
|
||||
@ApiResponse({ status: 200, description: "Message starred successfully" })
|
||||
@ApiResponse({ status: 404, description: "Message not found" })
|
||||
@ApiResponse({ status: 403, description: "Not authorized to star message" })
|
||||
starMessage(@UserDec("wildduckUserId") userId: string, @Param() params: MessageParamDto, @Query() query: MailboxIdQueryDto) {
|
||||
return this.emailService.starMessage(userId, Number(params.messageId), query.mailbox);
|
||||
}
|
||||
|
||||
@Patch("messages/:messageId/unfavorite")
|
||||
@ApiOperation({ summary: "Move a message from favorite back to inbox" })
|
||||
@ApiResponse({ status: 200, description: "Message moved from favorite to inbox successfully" })
|
||||
@ApiResponse({ status: 404, description: "Message not found in favorite" })
|
||||
@ApiResponse({ status: 403, description: "Not authorized to move message" })
|
||||
moveMessageToInboxFromFavorite(@UserDec("wildduckUserId") userId: string, @Param() params: MessageParamDto, @Query() query: MailboxIdQueryDto) {
|
||||
return this.emailService.moveMessageToInboxFromFavorite(userId, Number(params.messageId), query.mailbox);
|
||||
@ApiOperation({ summary: "Unstar a message (Gmail-like behavior)" })
|
||||
@ApiResponse({ status: 200, description: "Message unstarred successfully" })
|
||||
@ApiResponse({ status: 404, description: "Message not found" })
|
||||
@ApiResponse({ status: 403, description: "Not authorized to unstar message" })
|
||||
unstarMessage(@UserDec("wildduckUserId") userId: string, @Param() params: MessageParamDto, @Query() query: MailboxIdQueryDto) {
|
||||
return this.emailService.unstarMessage(userId, Number(params.messageId), query.mailbox);
|
||||
}
|
||||
|
||||
@Patch("messages/:messageId/toggle-favorite")
|
||||
@ApiOperation({ summary: "Toggle star status of a message (Gmail-like behavior)" })
|
||||
@ApiResponse({ status: 200, description: "Message star status toggled successfully" })
|
||||
@ApiResponse({ status: 404, description: "Message not found" })
|
||||
@ApiResponse({ status: 403, description: "Not authorized to modify message" })
|
||||
toggleMessageStar(@UserDec("wildduckUserId") userId: string, @Param() params: MessageParamDto, @Query() query: MailboxIdQueryDto) {
|
||||
return this.emailService.toggleMessageStar(userId, Number(params.messageId), query.mailbox);
|
||||
}
|
||||
|
||||
@Patch("messages/:messageId/restore")
|
||||
@ApiOperation({ summary: "Restore a message from trash back to inbox" })
|
||||
@ApiResponse({ status: 200, description: "Message restored from trash to inbox successfully" })
|
||||
@ApiOperation({ summary: "Move a message from trash back to inbox" })
|
||||
@ApiResponse({ status: 200, description: "Message restored to inbox successfully" })
|
||||
@ApiResponse({ status: 404, description: "Message not found in trash" })
|
||||
@ApiResponse({ status: 403, description: "Not authorized to restore message" })
|
||||
@ApiResponse({ status: 403, description: "Not authorized to move message" })
|
||||
moveMessageToInboxFromTrash(@UserDec("wildduckUserId") userId: string, @Param() params: MessageParamDto, @Query() query: MailboxIdQueryDto) {
|
||||
return this.emailService.moveMessageToInboxFromTrash(userId, Number(params.messageId), query.mailbox);
|
||||
}
|
||||
@@ -264,51 +273,4 @@ export class EmailController {
|
||||
performBulkAction(@UserDec("wildduckUserId") userId: string, @Body() bulkActionDto: BulkActionDto, @Query() query: MailboxIdQueryDto) {
|
||||
return this.emailService.performBulkAction(userId, bulkActionDto, query.mailbox);
|
||||
}
|
||||
|
||||
// // Domain Access Management Endpoints
|
||||
// @Get("spam/domains/allowed")
|
||||
// @ApiOperation({ summary: "List domains in allowlist (never marked as spam)" })
|
||||
// @ApiResponse({ status: 200, description: "List of allowed domains" })
|
||||
// listAllowedDomains(@UserDec("id") userId: string, @Query() query: ListDomainAccessQueryDto) {
|
||||
// return this.emailSpamService.listAllowedDomains(userId, query);
|
||||
// }
|
||||
|
||||
// @Get("spam/domains/blocked")
|
||||
// @ApiOperation({ summary: "List domains in blocklist (always marked as spam)" })
|
||||
// @ApiResponse({ status: 200, description: "List of blocked domains" })
|
||||
// listBlockedDomains(@UserDec("id") userId: string, @Query() query: ListDomainAccessQueryDto) {
|
||||
// return this.emailSpamService.listBlockedDomains(userId, query);
|
||||
// }
|
||||
|
||||
// @Post("spam/domains/allowed")
|
||||
// @ApiOperation({ summary: "Add domain to allowlist" })
|
||||
// @ApiResponse({ status: 201, description: "Domain added to allowlist successfully" })
|
||||
// @ApiResponse({ status: 400, description: "Invalid domain data" })
|
||||
// addDomainToAllowlist(@UserDec("id") userId: string, @Body() createDomainDto: CreateDomainAccessDto) {
|
||||
// return this.emailSpamService.addDomainToAllowlist(createDomainDto.domain, createDomainDto.description, userId);
|
||||
// }
|
||||
|
||||
// @Post("spam/domains/blocked")
|
||||
// @ApiOperation({ summary: "Add domain to blocklist" })
|
||||
// @ApiResponse({ status: 201, description: "Domain added to blocklist successfully" })
|
||||
// @ApiResponse({ status: 400, description: "Invalid domain data" })
|
||||
// addDomainToBlocklist(@UserDec("id") userId: string, @Body() createDomainDto: CreateDomainAccessDto) {
|
||||
// return this.emailSpamService.addDomainToBlocklist(createDomainDto.domain, createDomainDto.description, userId);
|
||||
// }
|
||||
|
||||
// @Delete("spam/domains/allowed/:domain")
|
||||
// @ApiOperation({ summary: "Remove domain from allowlist" })
|
||||
// @ApiResponse({ status: 200, description: "Domain removed from allowlist successfully" })
|
||||
// @ApiResponse({ status: 404, description: "Domain not found in allowlist" })
|
||||
// removeDomainFromAllowlist(@UserDec("id") userId: string, @Param("domain") domain: string) {
|
||||
// return this.emailSpamService.removeDomainFromAllowlist(domain, userId);
|
||||
// }
|
||||
|
||||
// @Delete("spam/domains/blocked/:domain")
|
||||
// @ApiOperation({ summary: "Remove domain from blocklist" })
|
||||
// @ApiResponse({ status: 200, description: "Domain removed from blocklist successfully" })
|
||||
// @ApiResponse({ status: 404, description: "Domain not found in blocklist" })
|
||||
// removeDomainFromBlocklist(@UserDec("id") userId: string, @Param("domain") domain: string) {
|
||||
// return this.emailSpamService.removeDomainFromBlocklist(domain, userId);
|
||||
// }
|
||||
}
|
||||
|
||||
@@ -140,6 +140,16 @@ export class EmailGateway implements OnGatewayInit, OnGatewayConnection, OnGatew
|
||||
return await this.sendUserNotification(userId, WEBSOCKET_EVENTS.EMAIL_UNREAD, data, `Message ${data.messageId} marked as unread`);
|
||||
}
|
||||
|
||||
//************************************************************************ */
|
||||
async notifyEmailFlagged(userId: string, data: EmailStatusPayload) {
|
||||
return await this.sendUserNotification(userId, WEBSOCKET_EVENTS.EMAIL_FLAGGED, data, `Message ${data.messageId} flagged`);
|
||||
}
|
||||
|
||||
//************************************************************************ */
|
||||
async notifyEmailUnflagged(userId: string, data: EmailStatusPayload) {
|
||||
return await this.sendUserNotification(userId, WEBSOCKET_EVENTS.EMAIL_UNFLAGGED, data, `Message ${data.messageId} unflagged`);
|
||||
}
|
||||
|
||||
//************************************************************************ */
|
||||
async notifyEmailDeleted(userId: string, data: EmailDeletePayload) {
|
||||
return await this.sendUserNotification(userId, WEBSOCKET_EVENTS.EMAIL_DELETED, data, `Message ${data.messageId} deleted`);
|
||||
|
||||
@@ -5,5 +5,5 @@ export interface UserMailboxIds {
|
||||
trash: string;
|
||||
junk: string;
|
||||
archive: string;
|
||||
favorite: string;
|
||||
// starred: string;
|
||||
}
|
||||
|
||||
@@ -165,6 +165,76 @@ export class EmailNotificationService {
|
||||
}
|
||||
}
|
||||
|
||||
//************************************************************************ */
|
||||
async notifyEmailFlagged(params: EmailStatusNotificationParams) {
|
||||
try {
|
||||
// Find the user to get the correct User entity ID for websocket notifications
|
||||
const em = this.em.fork();
|
||||
const user = await em.findOne(User, {
|
||||
wildduckUserId: params.userId,
|
||||
emailEnabled: true,
|
||||
deletedAt: null,
|
||||
});
|
||||
|
||||
if (!user) {
|
||||
this.logger.warn(`User not found with wildduckUserId: ${params.userId}`);
|
||||
return;
|
||||
}
|
||||
|
||||
const payload: EmailStatusPayload = {
|
||||
userId: user.id, // Use User entity ID for websocket
|
||||
messageId: params.messageId,
|
||||
mailboxId: params.mailboxId,
|
||||
timestamp: new Date().toISOString(),
|
||||
};
|
||||
|
||||
const success = await this.emailGateway.notifyEmailFlagged(user.id, payload);
|
||||
|
||||
if (success) {
|
||||
this.logger.log(`Email flagged notification dispatched for user ${user.id}: message ${params.messageId}`);
|
||||
} else {
|
||||
this.logger.warn(`Failed to dispatch email flagged notification for user ${user.id}: user not connected`);
|
||||
}
|
||||
} catch (error) {
|
||||
this.logger.error(`Failed to notify email flagged for user ${params.userId}:`, error);
|
||||
}
|
||||
}
|
||||
|
||||
//************************************************************************ */
|
||||
async notifyEmailUnflagged(params: EmailStatusNotificationParams) {
|
||||
try {
|
||||
// Find the user to get the correct User entity ID for websocket notifications
|
||||
const em = this.em.fork();
|
||||
const user = await em.findOne(User, {
|
||||
wildduckUserId: params.userId,
|
||||
emailEnabled: true,
|
||||
deletedAt: null,
|
||||
});
|
||||
|
||||
if (!user) {
|
||||
this.logger.warn(`User not found with wildduckUserId: ${params.userId}`);
|
||||
return;
|
||||
}
|
||||
|
||||
const payload: EmailStatusPayload = {
|
||||
userId: user.id, // Use User entity ID for websocket
|
||||
messageId: params.messageId,
|
||||
mailboxId: params.mailboxId,
|
||||
timestamp: new Date().toISOString(),
|
||||
};
|
||||
|
||||
const success = await this.emailGateway.notifyEmailUnflagged(user.id, payload);
|
||||
|
||||
if (success) {
|
||||
this.logger.log(`Email unflagged notification dispatched for user ${user.id}: message ${params.messageId}`);
|
||||
} else {
|
||||
this.logger.warn(`Failed to dispatch email unflagged notification for user ${user.id}: user not connected`);
|
||||
}
|
||||
} catch (error) {
|
||||
this.logger.error(`Failed to notify email unflagged for user ${params.userId}:`, error);
|
||||
}
|
||||
}
|
||||
|
||||
//************************************************************************ */
|
||||
async notifyMailboxUpdate(params: MailboxUpdateNotificationParams) {
|
||||
try {
|
||||
|
||||
@@ -7,6 +7,7 @@ import { EmailNotificationService } from "./email-notification.service";
|
||||
import { EmailSpamService } from "./email-spam.service";
|
||||
import { MailboxResolverService } from "./mailbox-resolver.service";
|
||||
import { EmailMessage } from "../../../common/enums/message.enum";
|
||||
import { SearchMessagesMailServerQueryDto } from "../../mail-server/DTO/message.dto";
|
||||
import { MailServerService } from "../../mail-server/services/mail-server.service";
|
||||
import { TemplateProcessorService } from "../../templates/services/template-processor.service";
|
||||
import { User } from "../../users/entities/user.entity";
|
||||
@@ -102,20 +103,27 @@ export class EmailService {
|
||||
|
||||
//########################################################
|
||||
async searchMessages(wildduckUserId: string, query: SearchMessagesQueryDto) {
|
||||
const wildDuckQuery = {
|
||||
const wildDuckQuery: SearchMessagesMailServerQueryDto = {
|
||||
...query,
|
||||
limit: query.limit || 20,
|
||||
page: query.page || 1,
|
||||
order: query.order || "desc",
|
||||
query: query.search || query.q,
|
||||
from: query.from || query.search,
|
||||
to: query.to || query.search,
|
||||
subject: query.subject || query.search,
|
||||
mailbox: query.mailbox || "",
|
||||
};
|
||||
delete wildDuckQuery.mailbox;
|
||||
|
||||
if (wildDuckQuery.limit > 250) wildDuckQuery.limit = 250;
|
||||
if (wildDuckQuery.limit < 1) wildDuckQuery.limit = 1;
|
||||
if (wildDuckQuery.page < 1) wildDuckQuery.page = 1;
|
||||
if (query.search) {
|
||||
wildDuckQuery.query = query.search;
|
||||
wildDuckQuery.from = query.search;
|
||||
}
|
||||
if (query.q) {
|
||||
wildDuckQuery.query = query.q;
|
||||
wildDuckQuery.from = query.q;
|
||||
}
|
||||
|
||||
if (query.from) wildDuckQuery.from = query.from;
|
||||
if (query.to) wildDuckQuery.to = query.to;
|
||||
if (query.subject) wildDuckQuery.subject = query.subject;
|
||||
|
||||
const response = await firstValueFrom(this.mailServerService.messages.searchMessages(wildduckUserId, wildDuckQuery));
|
||||
|
||||
@@ -315,10 +323,17 @@ export class EmailService {
|
||||
}
|
||||
//==============================================
|
||||
|
||||
async getFavoriteMessages(wildduckUserId: string, query: MessageListQueryDto) {
|
||||
const favoriteMailboxId = await this.mailboxResolverService.getFavoriteMailboxId(wildduckUserId);
|
||||
const wildDuckQuery = this.transformPaginationQuery(query);
|
||||
const response = await firstValueFrom(this.mailServerService.messages.listMessages(wildduckUserId, favoriteMailboxId, wildDuckQuery));
|
||||
//==============================================
|
||||
async getStarredMessages(wildduckUserId: string, query: MessageListQueryDto) {
|
||||
const searchQuery = {
|
||||
...query,
|
||||
flagged: true,
|
||||
limit: query.limit || 20,
|
||||
page: query.page || 1,
|
||||
order: query.order || "desc",
|
||||
};
|
||||
|
||||
const response = await firstValueFrom(this.mailServerService.messages.searchMessages(wildduckUserId, searchQuery));
|
||||
|
||||
return {
|
||||
favoriteMails: response.results,
|
||||
@@ -451,23 +466,6 @@ export class EmailService {
|
||||
};
|
||||
}
|
||||
|
||||
//==============================================
|
||||
async moveMessageToFavorite(wildduckUserId: string, messageId: number, mailboxId: string) {
|
||||
const favoriteMailboxId = await this.mailboxResolverService.getFavoriteMailboxId(wildduckUserId);
|
||||
|
||||
const result = await firstValueFrom(
|
||||
this.mailServerService.messages.updateMessage(wildduckUserId, mailboxId, messageId, {
|
||||
moveTo: favoriteMailboxId,
|
||||
}),
|
||||
);
|
||||
|
||||
return {
|
||||
success: true,
|
||||
message: EmailMessage.MESSAGE_MOVED_TO_FAVORITE_SUCCESSFULLY,
|
||||
result,
|
||||
};
|
||||
}
|
||||
|
||||
//==============================================
|
||||
async moveMessageToTrash(wildduckUserId: string, messageId: number, mailboxId: string) {
|
||||
const trashMailboxId = await this.mailboxResolverService.getTrashMailboxId(wildduckUserId);
|
||||
@@ -503,22 +501,54 @@ export class EmailService {
|
||||
}
|
||||
|
||||
//==============================================
|
||||
async moveMessageToInboxFromFavorite(wildduckUserId: string, messageId: number, mailboxId: string) {
|
||||
const inboxMailboxId = await this.mailboxResolverService.getInboxMailboxId(wildduckUserId);
|
||||
async starMessage(wildduckUserId: string, messageId: number, mailboxId: string) {
|
||||
const result = await firstValueFrom(this.mailServerService.messages.updateMessage(wildduckUserId, mailboxId, messageId, { flagged: true }));
|
||||
|
||||
const result = await firstValueFrom(
|
||||
this.mailServerService.messages.updateMessage(wildduckUserId, mailboxId, messageId, {
|
||||
moveTo: inboxMailboxId,
|
||||
}),
|
||||
);
|
||||
await this.emailNotificationService.notifyEmailFlagged({
|
||||
userId: wildduckUserId,
|
||||
messageId,
|
||||
mailboxId,
|
||||
});
|
||||
|
||||
return {
|
||||
success: true,
|
||||
message: EmailMessage.MESSAGE_MOVED_TO_INBOX_FROM_FAVORITE_SUCCESSFULLY,
|
||||
message: EmailMessage.MESSAGE_MARKED_AS_FAVORITE_SUCCESSFULLY,
|
||||
result,
|
||||
};
|
||||
}
|
||||
|
||||
//==============================================
|
||||
async unstarMessage(wildduckUserId: string, messageId: number, mailboxId: string) {
|
||||
const result = await firstValueFrom(
|
||||
this.mailServerService.messages.updateMessage(wildduckUserId, mailboxId, messageId, {
|
||||
flagged: false,
|
||||
}),
|
||||
);
|
||||
|
||||
await this.emailNotificationService.notifyEmailUnflagged({
|
||||
userId: wildduckUserId,
|
||||
messageId,
|
||||
mailboxId,
|
||||
});
|
||||
|
||||
return {
|
||||
success: true,
|
||||
message: EmailMessage.MESSAGE_REMOVED_FROM_FAVORITE_SUCCESSFULLY,
|
||||
result,
|
||||
};
|
||||
}
|
||||
|
||||
//==============================================
|
||||
async toggleMessageStar(wildduckUserId: string, messageId: number, mailboxId: string) {
|
||||
const message = await firstValueFrom(this.mailServerService.messages.getMessage(wildduckUserId, mailboxId, messageId));
|
||||
|
||||
if (message.flagged) {
|
||||
return this.unstarMessage(wildduckUserId, messageId, mailboxId);
|
||||
} else {
|
||||
return this.starMessage(wildduckUserId, messageId, mailboxId);
|
||||
}
|
||||
}
|
||||
|
||||
//==============================================
|
||||
async moveMessageToInboxFromTrash(wildduckUserId: string, messageId: number, mailboxId: string) {
|
||||
const inboxMailboxId = await this.mailboxResolverService.getInboxMailboxId(wildduckUserId);
|
||||
@@ -588,8 +618,6 @@ export class EmailService {
|
||||
};
|
||||
}
|
||||
|
||||
//==============================================
|
||||
// BULK ACTIONS
|
||||
//==============================================
|
||||
async performBulkAction(wildduckUserId: string, bulkActionDto: BulkActionDto, mailboxId: string) {
|
||||
const results = {
|
||||
@@ -597,7 +625,6 @@ export class EmailService {
|
||||
failed: [] as { messageId: number; error: string }[],
|
||||
};
|
||||
|
||||
// Process each message ID
|
||||
for (const messageId of bulkActionDto.messageIds) {
|
||||
try {
|
||||
switch (bulkActionDto.action) {
|
||||
@@ -614,10 +641,10 @@ export class EmailService {
|
||||
await this.moveMessageToInboxFromArchive(wildduckUserId, messageId, mailboxId);
|
||||
break;
|
||||
case BulkActionType.FAVORITE:
|
||||
await this.moveMessageToFavorite(wildduckUserId, messageId, mailboxId);
|
||||
await this.starMessage(wildduckUserId, messageId, mailboxId);
|
||||
break;
|
||||
case BulkActionType.UNFAVORITE:
|
||||
await this.moveMessageToInboxFromFavorite(wildduckUserId, messageId, mailboxId);
|
||||
await this.unstarMessage(wildduckUserId, messageId, mailboxId);
|
||||
break;
|
||||
case BulkActionType.JUNK:
|
||||
await this.moveMessageToJunk(wildduckUserId, messageId, mailboxId);
|
||||
@@ -636,7 +663,6 @@ export class EmailService {
|
||||
}
|
||||
|
||||
results.successful.push(messageId);
|
||||
this.logger.log(`Successfully performed ${bulkActionDto.action} on message ${messageId}`);
|
||||
} catch (error) {
|
||||
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
||||
results.failed.push({ messageId, error: errorMessage });
|
||||
@@ -644,17 +670,22 @@ export class EmailService {
|
||||
}
|
||||
}
|
||||
|
||||
// Determine response message based on results
|
||||
let message: string;
|
||||
if (results.failed.length === 0) {
|
||||
message = EmailMessage.BULK_ACTION_COMPLETED_SUCCESSFULLY;
|
||||
} else if (results.successful.length > 0) {
|
||||
message = EmailMessage.BULK_ACTION_PARTIALLY_COMPLETED;
|
||||
} else {
|
||||
message = EmailMessage.BULK_ACTION_FAILED;
|
||||
}
|
||||
const actionName = this.getActionDisplayName(bulkActionDto.action);
|
||||
const totalCount = bulkActionDto.messageIds.length;
|
||||
const successCount = results.successful.length;
|
||||
const failedCount = results.failed.length;
|
||||
|
||||
this.logger.log(`Bulk action ${bulkActionDto.action} completed: ${results.successful.length} successful, ${results.failed.length} failed`);
|
||||
if (results.failed.length === 0) {
|
||||
message = EmailMessage.BULK_ACTION_COMPLETED_SUCCESSFULLY.replace("[count]", totalCount.toString()).replace("[action]", actionName);
|
||||
} else if (results.successful.length > 0) {
|
||||
message = EmailMessage.BULK_ACTION_PARTIALLY_COMPLETED.replace("[successful]", successCount.toString())
|
||||
.replace("[total]", totalCount.toString())
|
||||
.replace("[action]", actionName)
|
||||
.replace("[failed]", failedCount.toString());
|
||||
} else {
|
||||
message = EmailMessage.BULK_ACTION_FAILED.replace("[action]", actionName).replace("[total]", totalCount.toString());
|
||||
}
|
||||
|
||||
return {
|
||||
success: results.failed.length === 0,
|
||||
@@ -671,24 +702,47 @@ export class EmailService {
|
||||
|
||||
//########################################################
|
||||
|
||||
private getActionDisplayName(action: BulkActionType): string {
|
||||
switch (action) {
|
||||
case BulkActionType.SEEN:
|
||||
return EmailMessage.BULK_ACTION_SEEN;
|
||||
case BulkActionType.DELETE:
|
||||
return EmailMessage.BULK_ACTION_DELETE;
|
||||
case BulkActionType.ARCHIVE:
|
||||
return EmailMessage.BULK_ACTION_ARCHIVE;
|
||||
case BulkActionType.UNARCHIVE:
|
||||
return EmailMessage.BULK_ACTION_UNARCHIVE;
|
||||
case BulkActionType.FAVORITE:
|
||||
return EmailMessage.BULK_ACTION_FAVORITE;
|
||||
case BulkActionType.UNFAVORITE:
|
||||
return EmailMessage.BULK_ACTION_UNFAVORITE;
|
||||
case BulkActionType.JUNK:
|
||||
return EmailMessage.BULK_ACTION_JUNK;
|
||||
case BulkActionType.NOTJUNK:
|
||||
return EmailMessage.BULK_ACTION_NOTJUNK;
|
||||
case BulkActionType.TRASH:
|
||||
return EmailMessage.BULK_ACTION_TRASH;
|
||||
case BulkActionType.RESTORE:
|
||||
return EmailMessage.BULK_ACTION_RESTORE;
|
||||
default:
|
||||
return EmailMessage.BULK_ACTION_PROCESSED;
|
||||
}
|
||||
}
|
||||
|
||||
//==============================================
|
||||
private transformPaginationQuery(query: MessageListQueryDto): Record<string, unknown> {
|
||||
const transformedQuery: Record<string, any> = { ...query };
|
||||
|
||||
// Set default values if not provided
|
||||
if (!transformedQuery.page) transformedQuery.page = 1;
|
||||
if (!transformedQuery.limit) transformedQuery.limit = 20;
|
||||
|
||||
// Ensure limit is within WildDuck's bounds (1-250)
|
||||
if (transformedQuery.limit > 250) transformedQuery.limit = 250;
|
||||
if (transformedQuery.limit < 1) transformedQuery.limit = 1;
|
||||
|
||||
// Ensure page is at least 1
|
||||
if (transformedQuery.page < 1) transformedQuery.page = 1;
|
||||
|
||||
// Set default order if not provided
|
||||
if (!transformedQuery.order) transformedQuery.order = "desc";
|
||||
|
||||
// Remove undefined/null values
|
||||
Object.keys(transformedQuery).forEach((key) => {
|
||||
if (transformedQuery[key] === undefined || transformedQuery[key] === null) {
|
||||
delete transformedQuery[key];
|
||||
|
||||
@@ -34,7 +34,7 @@ export class MailboxResolverService {
|
||||
trash: this.findMailboxId(mailboxes.results, MailboxEnum.TRASH),
|
||||
junk: this.findMailboxId(mailboxes.results, MailboxEnum.Junk, false),
|
||||
archive: this.findMailboxId(mailboxes.results, MailboxEnum.ARCHIVE, false),
|
||||
favorite: this.findMailboxId(mailboxes.results, MailboxEnum.FAVORITE, false),
|
||||
// favorite: this.findMailboxId(mailboxes.results, MailboxEnum.FAVORITE, false),
|
||||
};
|
||||
|
||||
this.cacheMailboxIds(userId, mailboxIds);
|
||||
@@ -106,9 +106,9 @@ export class MailboxResolverService {
|
||||
return this.getMailboxId(userId, "archive");
|
||||
}
|
||||
|
||||
async getFavoriteMailboxId(userId: string): Promise<string> {
|
||||
return this.getMailboxId(userId, "favorite");
|
||||
}
|
||||
// async getFavoriteMailboxId(userId: string): Promise<string> {
|
||||
// return this.getMailboxId(userId, "favorite");
|
||||
// }
|
||||
|
||||
/**
|
||||
* Clear cache for a specific user
|
||||
|
||||
Reference in New Issue
Block a user