feat: quick actions on email rows (read/unread, star, trash)

- EmailRow shared component with hover action buttons: mark read/unread, star/unstar, trash
- Optimistic UI — local state patches immediately on click; row fades and becomes non-interactive during the API call
- Trashed rows disappear from the current folder view via onRemove callback
- Backend: EmailController single-email endpoints (POST /email/{id}/read|unread|star|unstar|trash|untrash)
- Star/Unstar added to CleanupActionType enum and CleanupService (maps to STARRED Gmail label via BatchModifyAsync)
- UserId scope enforced in ResolveTargetsAsync — a user can only act on their own emails
- action buttons use stopPropagation so clicking them does not open Gmail

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
cesnimda
2026-06-30 20:18:44 +02:00
parent 498536451e
commit 2f6d6abdd3
8 changed files with 181 additions and 75 deletions
+9
View File
@@ -98,6 +98,15 @@ function folderToRequest(slug, page, pageSize) {
}
}
export const EmailApi = {
markRead: (id) => api.post(`/email/${id}/read`),
markUnread: (id) => api.post(`/email/${id}/unread`),
star: (id) => api.post(`/email/${id}/star`),
unstar: (id) => api.post(`/email/${id}/unstar`),
trash: (id) => api.post(`/email/${id}/trash`),
untrash: (id) => api.post(`/email/${id}/untrash`),
};
export const ExportApi = {
reportUrl: (format) => `/api/v1/export/report?format=${format}`
};