0070fb3aea
- 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
6.8 KiB
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)
- Mail route /mail renders folder tree + mail list + reading pane
- Mail: click folder → mail list updates with folder mails
- Mail: click mail → detail with sanitized HTML body + attachments
- Mail: compose button → editor with toolbar (bold, italic, link, template insert)
- Mail: reply/forward buttons → compose pre-filled
- Mail: template picker dropdown in compose → inserts template body
- Mail: signature manager in settings → create/edit/delete signatures
- Mail: rule editor → condition builder + action selector
- Mail: label manager → create labels with colors, assign to mails
- Mail: PGP settings → import private key, view contact public keys
- Mail: vacation responder toggle → date range + auto-reply text
- Mail: shared mailbox selector → switch between personal+shared accounts
- Mail: attachment download → file stream downloaded
- Mail: create event from mail → calendar event modal pre-filled
- Global search results page → tabs for companies/contacts/mails/files/events
- 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 sidebarsrc/components/mail/MailList.tsx— mail list with paginationsrc/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 dropdownsrc/components/mail/SignatureManager.tsx— signature CRUDsrc/components/mail/RuleEditor.tsx— rule condition builder + action selectorsrc/components/mail/LabelManager.tsx— label CRUD with colorssrc/components/mail/VacationResponder.tsx— vacation toggle + date rangesrc/components/mail/PgpSettings.tsx— PGP key import + contact keyssrc/components/mail/SharedMailboxSelector.tsx— account switchersrc/components/mail/MailSearchBar.tsx— mail search inputsrc/__tests__/mail/MailPage.test.tsx— mail page testssrc/__tests__/mail/ComposeModal.test.tsx— compose testssrc/__tests__/mail/MailSettings.test.tsx— settings testssrc/__tests__/search/GlobalSearchTabs.test.tsx— search tabs tests
Files to Modify
src/routes/index.tsx— Add /mail, /mail/settings routessrc/components/layout/Sidebar.tsx— Add Mail nav linksrc/pages/GlobalSearchResults.tsx— Add tabs (companies/contacts/mails/files/events)src/components/layout/AppShell.tsx— Add search autocomplete in TopBarsrc/i18n/locales/de.json— Mail translationssrc/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