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