Files
leocrm-bot 0070fb3aea T08c: Frontend Mail UI + Global Search UI — 44 tests, tsc clean, vite build pass
- Mail page: 3-pane layout (folder tree + mail list + reading pane)
- Compose modal: rich text editor (bold/italic/link), template picker, reply/forward pre-fill
- Mail settings: accounts, signatures, rules, labels, vacation, PGP (6 tabs)
- Shared mailbox selector: switch between personal + shared accounts
- Mail search bar + attachment download + create-event-from-mail
- Global search: tabs for companies/contacts/mails/files/events
- Search autocomplete in TopBar (existing SearchDropdown)
- API client: mail.ts (all endpoints)
- Routes: /mail, /mail/settings
- i18n: de.json + en.json mail + search translations
- 44 new tests (4 test files), full regression 318/318 pass
- tsc --noEmit: 0 errors, vite build: 267 modules
2026-07-01 20:43:49 +02:00

6.8 KiB

T08c: Frontend Mail UI + Global Search UI — Implementation Briefing

Task

Implement frontend UI for Mail plugin (folder tree, mail list, reading pane, compose, templates, signatures, rules, labels, PGP, vacation, shared mailbox, delegates) and enhance Global Search UI with tabs.

Acceptance Criteria (17 ACs — skip AC1/DMS and AC16/Docker, already done)

  1. Mail route /mail renders folder tree + mail list + reading pane
  2. Mail: click folder → mail list updates with folder mails
  3. Mail: click mail → detail with sanitized HTML body + attachments
  4. Mail: compose button → editor with toolbar (bold, italic, link, template insert)
  5. Mail: reply/forward buttons → compose pre-filled
  6. Mail: template picker dropdown in compose → inserts template body
  7. Mail: signature manager in settings → create/edit/delete signatures
  8. Mail: rule editor → condition builder + action selector
  9. Mail: label manager → create labels with colors, assign to mails
  10. Mail: PGP settings → import private key, view contact public keys
  11. Mail: vacation responder toggle → date range + auto-reply text
  12. Mail: shared mailbox selector → switch between personal+shared accounts
  13. Mail: attachment download → file stream downloaded
  14. Mail: create event from mail → calendar event modal pre-filled
  15. Global search results page → tabs for companies/contacts/mails/files/events
  16. Global search autocomplete in TopBar → dropdown with suggestions

Backend API Endpoints (all implemented, prefix /api/v1/mail)

Accounts

  • GET /accounts — list accounts (password never returned)
  • POST /accounts — create account (AES-256 encrypted password)
  • PATCH /accounts/{id} — update account
  • DELETE /accounts/{id} — delete account
  • GET /accounts/shared — list shared mailboxes
  • POST /accounts/{id}/users — assign shared mailbox users
  • POST /accounts/{id}/delegates — create delegate access
  • POST /accounts/{id}/send-permissions — grant send permission
  • POST /accounts/{id}/test-connection — test IMAP connection
  • POST /accounts/{id}/sync — trigger IMAP sync

Folders

  • GET /folders?account_id=X — list folders with counts
  • POST /folders — create folder
  • PATCH /folders/{id} — rename folder
  • DELETE /folders/{id} — delete folder

Mails

  • GET /?folder_id=X&page=1 — paginated mail list
  • GET /{id} — mail detail (sanitized HTML, attachments)
  • POST /send — send mail via SMTP
  • POST /{id}/reply — reply with In-Reply-To
  • POST /{id}/forward — forward mail
  • PATCH /{id}/flags — toggle seen/flagged
  • POST /{id}/link — link to contact/company
  • POST /{id}/create-event — create calendar event from mail
  • POST /{id}/labels — assign label to mail

Search & Threads

  • GET /search?q=text — FTS search
  • GET /threads — threaded view

Attachments

  • GET /{mail_id}/attachments/{att_id} — file stream download

Templates

  • POST /templates — create template
  • GET /templates — list templates
  • POST /templates/substitute — substitute variables

Signatures

  • POST /signatures — create signature
  • GET /signatures — list signatures

Rules

  • POST /rules — create rule (conditions + actions)
  • GET /rules — list rules sorted by priority
  • DELETE /rules/{id} — delete rule

Vacation

  • POST /vacation — configure auto-reply
  • POST /vacation/test-dedup — test dedup

PGP

  • POST /pgp/keys — import private key (encrypted)
  • GET /pgp/keys — list PGP keys
  • POST /pgp/encrypt — encrypt message
  • POST /contacts/{contact_id}/pgp-key — store contact public key

Labels

  • POST /labels — create label (with color)
  • GET /labels — list labels

Frontend Architecture (follow existing patterns)

  • Framework: React + TypeScript + Vite
  • Routing: react-router-dom (src/routes/index.tsx)
  • State: TanStack Query (useQuery/useMutation)
  • HTTP: axios via src/api/client.ts (apiClient, baseURL /api/v1)
  • API pattern: See src/api/calendar.ts or src/api/dms.ts
  • UI components: src/components/ui/ (Button, Card, Input, Modal, Table, Badge, etc.)
  • Shared: src/components/shared/ (DataGrid, SearchDropdown, Tabs)
  • Layout: src/components/layout/AppShell.tsx + Sidebar.tsx
  • i18n: src/i18n/ (add de.json + en.json keys for Mail)
  • Existing search page: src/pages/GlobalSearchResults.tsx (enhance with tabs)

Files to Create

  • src/api/mail.ts — Mail API client (types + functions for all endpoints)
  • src/pages/Mail.tsx — Mail page (folder tree + mail list + reading pane)
  • src/pages/MailSettings.tsx — Mail settings (signatures, rules, PGP, vacation, labels)
  • src/components/mail/MailFolderTree.tsx — folder tree sidebar
  • src/components/mail/MailList.tsx — mail list with pagination
  • src/components/mail/MailDetail.tsx — reading pane (sanitized HTML, attachments)
  • src/components/mail/ComposeModal.tsx — compose editor (bold/italic/link/template)
  • src/components/mail/TemplatePicker.tsx — template dropdown
  • src/components/mail/SignatureManager.tsx — signature CRUD
  • src/components/mail/RuleEditor.tsx — rule condition builder + action selector
  • src/components/mail/LabelManager.tsx — label CRUD with colors
  • src/components/mail/VacationResponder.tsx — vacation toggle + date range
  • src/components/mail/PgpSettings.tsx — PGP key import + contact keys
  • src/components/mail/SharedMailboxSelector.tsx — account switcher
  • src/components/mail/MailSearchBar.tsx — mail search input
  • src/__tests__/mail/MailPage.test.tsx — mail page tests
  • src/__tests__/mail/ComposeModal.test.tsx — compose tests
  • src/__tests__/mail/MailSettings.test.tsx — settings tests
  • src/__tests__/search/GlobalSearchTabs.test.tsx — search tabs tests

Files to Modify

  • src/routes/index.tsx — Add /mail, /mail/settings routes
  • src/components/layout/Sidebar.tsx — Add Mail nav link
  • src/pages/GlobalSearchResults.tsx — Add tabs (companies/contacts/mails/files/events)
  • src/components/layout/AppShell.tsx — Add search autocomplete in TopBar
  • src/i18n/locales/de.json — Mail translations
  • src/i18n/locales/en.json — Mail translations

Test Spec

  • Run: cd /a0/usr/workdir/dev-projects/leocrm/frontend && npx vitest run src/__tests__/mail/ src/__tests__/search/ --reporter=verbose
  • Build: npx vite build
  • Type check: npx tsc --noEmit
  • Coverage target: 80%
  • Follow existing test pattern from src/tests/dms/ or src/tests/companies/

Forbidden Patterns

  • No inline styles — use Tailwind classes
  • No any types — use proper TypeScript interfaces
  • No direct fetch() — use apiClient from src/api/client.ts
  • No hardcoded strings — use i18n (t() function)
  • No Lorem Ipsum — use realistic test data
  • No missing loading/error/empty states
  • No dangerouslySetInnerHTML without sanitization check

Estimated Size

  • ~700 lines code (pages + components + API client)
  • ~350+ lines tests