Files
smoothschedule/frontend/src/api/platformEmailAddresses.ts
poduck 18eeda62e8 Add staff email client with WebSocket real-time updates
Implements a complete email client for platform staff members:

Backend:
- Add routing_mode field to PlatformEmailAddress (PLATFORM/STAFF)
- Create staff_email app with models for folders, emails, attachments, labels
- IMAP service for fetching emails with folder mapping
- SMTP service for sending emails with attachment support
- Celery tasks for periodic sync and full sync operations
- WebSocket consumer for real-time notifications
- Comprehensive API viewsets with filtering and actions

Frontend:
- Thunderbird-style three-pane email interface
- Multi-account support with drag-and-drop ordering
- Email composer with rich text editor
- Email viewer with thread support
- Real-time WebSocket updates for new emails and sync status
- 94 unit tests covering models, serializers, views, services, and consumers

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-21 23:40:27 -05:00

254 lines
6.6 KiB
TypeScript

/**
* API client for Platform Email Addresses
* These are email addresses managed directly on the mail.talova.net server
*/
import apiClient from './client';
export interface PlatformEmailAddress {
id: number;
display_name: string;
sender_name: string;
effective_sender_name: string;
local_part: string;
domain: string;
email_address: string;
color: string;
is_active: boolean;
is_default: boolean;
mail_server_synced: boolean;
last_sync_error?: string;
last_synced_at?: string;
last_check_at?: string;
emails_processed_count: number;
created_at: string;
updated_at: string;
imap_settings?: {
host: string;
port: number;
use_ssl: boolean;
username: string;
folder: string;
};
smtp_settings?: {
host: string;
port: number;
use_tls: boolean;
use_ssl: boolean;
username: string;
};
}
export interface AssignedUser {
id: number;
email: string;
first_name: string;
last_name: string;
full_name: string;
}
export interface AssignableUser extends AssignedUser {
role: string;
}
export interface PlatformEmailAddressListItem {
id: number;
display_name: string;
sender_name: string;
effective_sender_name: string;
local_part: string;
domain: string;
email_address: string;
color: string;
assigned_user?: AssignedUser | null;
routing_mode: 'PLATFORM' | 'STAFF';
is_active: boolean;
is_default: boolean;
mail_server_synced: boolean;
last_check_at?: string;
emails_processed_count: number;
created_at: string;
updated_at: string;
}
export interface PlatformEmailAddressCreate {
display_name: string;
sender_name?: string;
assigned_user_id?: number | null;
local_part: string;
domain: string;
color: string;
password: string;
routing_mode?: 'PLATFORM' | 'STAFF';
is_active: boolean;
is_default: boolean;
}
export interface PlatformEmailAddressUpdate {
display_name?: string;
sender_name?: string;
assigned_user_id?: number | null;
color?: string;
password?: string;
routing_mode?: 'PLATFORM' | 'STAFF';
is_active?: boolean;
is_default?: boolean;
}
export interface EmailDomain {
value: string;
label: string;
}
export interface TestConnectionResponse {
success: boolean;
message: string;
}
export interface SyncResponse {
success: boolean;
message: string;
mail_server_synced?: boolean;
last_synced_at?: string;
last_sync_error?: string;
}
export interface MailServerAccountsResponse {
success: boolean;
accounts: { email: string; raw_line: string }[];
count: number;
}
export interface ImportFromMailServerResponse {
success: boolean;
imported: { id: number; email: string; display_name: string }[];
imported_count: number;
skipped: { email: string; reason: string }[];
skipped_count: number;
message: string;
}
/**
* Get all platform email addresses
*/
export const getPlatformEmailAddresses = async (): Promise<PlatformEmailAddressListItem[]> => {
const response = await apiClient.get('/platform/email-addresses/');
return response.data;
};
/**
* Get a specific platform email address by ID
*/
export const getPlatformEmailAddress = async (id: number): Promise<PlatformEmailAddress> => {
const response = await apiClient.get(`/platform/email-addresses/${id}/`);
return response.data;
};
/**
* Create a new platform email address
*/
export const createPlatformEmailAddress = async (
data: PlatformEmailAddressCreate
): Promise<PlatformEmailAddress> => {
const response = await apiClient.post('/platform/email-addresses/', data);
return response.data;
};
/**
* Update an existing platform email address
*/
export const updatePlatformEmailAddress = async (
id: number,
data: PlatformEmailAddressUpdate
): Promise<PlatformEmailAddress> => {
const response = await apiClient.patch(`/platform/email-addresses/${id}/`, data);
return response.data;
};
/**
* Delete a platform email address (also removes from mail server)
*/
export const deletePlatformEmailAddress = async (id: number): Promise<void> => {
await apiClient.delete(`/platform/email-addresses/${id}/`);
};
/**
* Remove email address from database only (keeps mail server account)
*/
export const removeLocalPlatformEmailAddress = async (id: number): Promise<{ success: boolean; message: string }> => {
const response = await apiClient.post(`/platform/email-addresses/${id}/remove_local/`);
return response.data;
};
/**
* Sync email address to mail server
*/
export const syncPlatformEmailAddress = async (id: number): Promise<SyncResponse> => {
const response = await apiClient.post(`/platform/email-addresses/${id}/sync/`);
return response.data;
};
/**
* Test IMAP connection for a platform email address
*/
export const testImapConnection = async (id: number): Promise<TestConnectionResponse> => {
const response = await apiClient.post(`/platform/email-addresses/${id}/test_imap/`);
return response.data;
};
/**
* Test SMTP connection for a platform email address
*/
export const testSmtpConnection = async (id: number): Promise<TestConnectionResponse> => {
const response = await apiClient.post(`/platform/email-addresses/${id}/test_smtp/`);
return response.data;
};
/**
* Set a platform email address as the default
*/
export const setAsDefault = async (id: number): Promise<{ success: boolean; message: string }> => {
const response = await apiClient.post(`/platform/email-addresses/${id}/set_as_default/`);
return response.data;
};
/**
* Test SSH connection to the mail server
*/
export const testMailServerConnection = async (): Promise<TestConnectionResponse> => {
const response = await apiClient.post('/platform/email-addresses/test_mail_server/');
return response.data;
};
/**
* Get all email accounts from the mail server
*/
export const getMailServerAccounts = async (): Promise<MailServerAccountsResponse> => {
const response = await apiClient.get('/platform/email-addresses/mail_server_accounts/');
return response.data;
};
/**
* Get available email domains
*/
export const getAvailableDomains = async (): Promise<{ domains: EmailDomain[] }> => {
const response = await apiClient.get('/platform/email-addresses/available_domains/');
return response.data;
};
/**
* Get assignable users (platform users who can be assigned to email addresses)
*/
export const getAssignableUsers = async (): Promise<{ users: AssignableUser[] }> => {
const response = await apiClient.get('/platform/email-addresses/assignable_users/');
return response.data;
};
/**
* Import email addresses from the mail server
*/
export const importFromMailServer = async (): Promise<ImportFromMailServerResponse> => {
const response = await apiClient.post('/platform/email-addresses/import_from_mail_server/');
return response.data;
};