TF-2469 Fix email set into root mailbox's SENT instead of team mailbox's SENT (#3482)

This commit is contained in:
Dat Dang
2025-02-18 14:06:08 +07:00
committed by GitHub
parent ca3905cb7a
commit 636df94458
6 changed files with 106 additions and 9 deletions
+26
View File
@@ -0,0 +1,26 @@
# 57. Team Mailboxes Matching
Date: 2025-02-18
## Status
Accepted
## Context
- Team mailboxes were not considered when sending emails
- Sent emails were saved to default sent mailbox, although selected identity's email was based on team mailbox email
- User does not have permission to edit mailboxes of team mailboxes
## Decision
- Instead of hard coding default sent mailbox, sent emails will be saved to mailbox based on
- identity's email
- mailbox's name (hard coded English)
- Only when there's no matching mailbox, default sent mailbox will be used
- Same logic is applied to drafts mailbox and outbox mailbox
## Consequences
- Team mailboxes will be considered when sending emails
- Potentially, if team mailboxes existed but the name is not in English, sent emails will be saved to default sent mailbox
@@ -56,6 +56,9 @@ import 'package:tmail_ui_user/features/composer/domain/usecases/save_composer_ca
import 'package:tmail_ui_user/features/composer/presentation/controller/rich_text_mobile_tablet_controller.dart';
import 'package:tmail_ui_user/features/composer/presentation/controller/rich_text_web_controller.dart';
import 'package:tmail_ui_user/features/composer/presentation/extensions/email_action_type_extension.dart';
import 'package:tmail_ui_user/features/composer/presentation/extensions/get_draft_mailbox_id_for_composer_extension.dart';
import 'package:tmail_ui_user/features/composer/presentation/extensions/get_outbox_mailbox_id_for_composer_extension.dart';
import 'package:tmail_ui_user/features/composer/presentation/extensions/get_sent_mailbox_id_for_composer_extension.dart';
import 'package:tmail_ui_user/features/composer/presentation/extensions/list_identities_extension.dart';
import 'package:tmail_ui_user/features/composer/presentation/extensions/list_shared_media_file_extension.dart';
import 'package:tmail_ui_user/features/composer/presentation/mixin/drag_drog_file_mixin.dart';
@@ -481,9 +484,9 @@ class ComposerController extends BaseController
identity: identitySelected.value,
attachments: uploadController.attachmentsUploaded,
inlineAttachments: uploadController.mapInlineAttachments,
outboxMailboxId: mailboxDashBoardController.outboxMailbox?.mailboxId,
sentMailboxId: mailboxDashBoardController.mapDefaultMailboxIdByRole[PresentationMailbox.roleSent],
draftsMailboxId: mailboxDashBoardController.mapDefaultMailboxIdByRole[PresentationMailbox.roleDrafts],
outboxMailboxId: getOutboxMailboxIdForComposer(),
sentMailboxId: getSentMailboxIdForComposer(),
draftsMailboxId: getDraftMailboxIdForComposer(),
draftsEmailId: getDraftEmailId(),
answerForwardEmailId: composerArguments.value!.presentationEmail?.id,
unsubscribeEmailId: composerArguments.value!.previousEmailId,
@@ -1059,8 +1062,8 @@ class ComposerController extends BaseController
identity: identitySelected.value,
attachments: uploadController.attachmentsUploaded,
inlineAttachments: uploadController.mapInlineAttachments,
outboxMailboxId: mailboxDashBoardController.outboxMailbox?.mailboxId,
sentMailboxId: mailboxDashBoardController.mapDefaultMailboxIdByRole[PresentationMailbox.roleSent],
outboxMailboxId: getOutboxMailboxIdForComposer(),
sentMailboxId: getSentMailboxIdForComposer(),
draftsEmailId: getDraftEmailId(),
answerForwardEmailId: composerArguments.value!.presentationEmail?.id,
unsubscribeEmailId: composerArguments.value!.previousEmailId,
@@ -1309,7 +1312,7 @@ class ComposerController extends BaseController
if (composerArguments.value == null ||
mailboxDashBoardController.sessionCurrent == null ||
mailboxDashBoardController.accountId.value == null ||
mailboxDashBoardController.mapDefaultMailboxIdByRole[PresentationMailbox.roleDrafts] == null
getDraftMailboxIdForComposer() == null
) {
log('ComposerController::handleClickSaveAsDraftsButton: SESSION or ACCOUNT_ID or ARGUMENTS is NULL');
_saveToDraftButtonState = ButtonState.enabled;
@@ -2309,7 +2312,7 @@ class ComposerController extends BaseController
if (composerArguments.value == null ||
mailboxDashBoardController.sessionCurrent == null ||
mailboxDashBoardController.accountId.value == null ||
mailboxDashBoardController.mapDefaultMailboxIdByRole[PresentationMailbox.roleDrafts] == null
getDraftMailboxIdForComposer() == null
) {
log('ComposerController::_handleSaveMessageToDraft: SESSION or ACCOUNT_ID or ARGUMENTS is NULL');
_closeComposerButtonState = ButtonState.enabled;
@@ -2381,8 +2384,8 @@ class ComposerController extends BaseController
identity: identitySelected.value,
attachments: uploadController.attachmentsUploaded,
inlineAttachments: uploadController.mapInlineAttachments,
sentMailboxId: mailboxDashBoardController.mapDefaultMailboxIdByRole[PresentationMailbox.roleSent],
draftsMailboxId: mailboxDashBoardController.mapDefaultMailboxIdByRole[PresentationMailbox.roleDrafts],
sentMailboxId: getSentMailboxIdForComposer(),
draftsMailboxId: getDraftMailboxIdForComposer(),
draftsEmailId: draftEmailId,
answerForwardEmailId: composerArguments.value!.presentationEmail?.id,
unsubscribeEmailId: composerArguments.value!.previousEmailId,
@@ -0,0 +1,22 @@
import 'package:collection/collection.dart';
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
import 'package:model/extensions/presentation_mailbox_extension.dart';
import 'package:model/mailbox/presentation_mailbox.dart';
import 'package:tmail_ui_user/features/composer/presentation/composer_controller.dart';
extension GetDraftMailboxIdForComposerExtension on ComposerController {
MailboxId? getDraftMailboxIdForComposer() {
final defaultDraftsMailbox = mailboxDashBoardController.mapDefaultMailboxIdByRole[
PresentationMailbox.roleDrafts
];
final lowercaseDraftsRole = PresentationMailbox.roleDrafts.value.toLowerCase();
return mailboxDashBoardController.mapMailboxById.entries
.firstWhereOrNull((entry) {
final mailbox = entry.value;
return mailbox.emailTeamMailBoxes == identitySelected.value?.email &&
mailbox.name?.name.toLowerCase() == lowercaseDraftsRole;
})
?.key ?? defaultDraftsMailbox;
}
}
@@ -0,0 +1,22 @@
import 'package:collection/collection.dart';
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
import 'package:model/extensions/presentation_mailbox_extension.dart';
import 'package:model/mailbox/presentation_mailbox.dart';
import 'package:tmail_ui_user/features/composer/presentation/composer_controller.dart';
extension GetOutboxMailboxIdForComposerExtension on ComposerController {
MailboxId? getOutboxMailboxIdForComposer() {
final defaultOutboxMailbox = mailboxDashBoardController.mapDefaultMailboxIdByRole[
PresentationMailbox.roleOutbox
];
final lowercaseOutboxRole = PresentationMailbox.roleOutbox.value.toLowerCase();
return mailboxDashBoardController.mapMailboxById.entries
.firstWhereOrNull((entry) {
final mailbox = entry.value;
return mailbox.emailTeamMailBoxes == identitySelected.value?.email &&
mailbox.name?.name.toLowerCase() == lowercaseOutboxRole;
})
?.key ?? defaultOutboxMailbox;
}
}
@@ -0,0 +1,21 @@
import 'package:collection/collection.dart';
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
import 'package:model/model.dart';
import 'package:tmail_ui_user/features/composer/presentation/composer_controller.dart';
extension GetSentMailboxIdForComposerExtension on ComposerController {
MailboxId? getSentMailboxIdForComposer() {
final defaultSentMailbox = mailboxDashBoardController.mapDefaultMailboxIdByRole[
PresentationMailbox.roleSent
];
final lowercaseSentRole = PresentationMailbox.roleSent.value.toLowerCase();
return mailboxDashBoardController.mapMailboxById.entries
.firstWhereOrNull((entry) {
final mailbox = entry.value;
return mailbox.emailTeamMailBoxes == identitySelected.value?.email &&
mailbox.name?.name.toLowerCase() == lowercaseSentRole;
})
?.key ?? defaultSentMailbox;
}
}
@@ -127,6 +127,9 @@ class MockMailboxDashBoardController extends Mock implements MailboxDashBoardCon
@override
int get minInputLengthAutocomplete => AppConfig.defaultMinInputLengthAutocomplete;
@override
Map<MailboxId, PresentationMailbox> get mapMailboxById => {};
}
@GenerateNiceMocks([