feat: mail phase 1 - HTML iframe display, bulk read/unread, IMAP flag sync

- Fix FlagUpdatePayload field names to match backend schema (is_seen/is_flagged)
- Replace dangerouslySetInnerHTML with sandboxed iframe (srcDoc, sandbox="")
- Add bulk mark read/unread with checkbox selection in MailList
- Add floating bulk action bar in Mail.tsx
- Add imap_sync_mail_flags() to push Seen/Flagged flags to IMAP server
- Call IMAP flag sync in PATCH /flags endpoint
- Add i18n keys for bulk actions (de/en)
This commit is contained in:
Agent Zero
2026-07-15 19:26:37 +02:00
parent 2108bdb9c2
commit df83cee10c
9 changed files with 364 additions and 135 deletions
+7
View File
@@ -57,6 +57,7 @@ from app.plugins.builtins.mail.schemas import (
TemplateSubstituteRequest,
VacationConfig,
)
import app.plugins.builtins.mail.services as mail_services
from app.plugins.builtins.mail.services import (
MAX_ATTACHMENT_SIZE,
_attachment_storage_path,
@@ -1216,6 +1217,12 @@ async def update_flags(
if data.is_forwarded is not None:
mail.is_forwarded = data.is_forwarded
await db.flush()
# Sync flags to IMAP server (non-critical — failures are logged but don't break the API)
try:
await mail_services.imap_sync_mail_flags(db, m_id, tenant_id)
except Exception as exc:
import logging
logging.getLogger(__name__).warning("IMAP flag sync failed for mail %s: %s", m_id, exc)
return mail_to_response(mail)