Files
PecHub/frontend/src/api/messages.api.ts
T

192 lines
6.6 KiB
TypeScript

import apiClient from './client'
import type {
AttachmentResponse,
MessageListResponse,
MessageResponse,
} from '@/types/api.types'
export interface MessageFilters {
page?: number
page_size?: number
/** Filtra per Virtual Box assegnata all'utente corrente */
vbox_id?: string
mailbox_id?: string
direction?: 'inbound' | 'outbound'
state?: string
pec_type?: string
is_read?: boolean
is_starred?: boolean
is_archived?: boolean
is_trashed?: boolean
/** Filtra per messaggi in attesa di conservazione (cartella Da Conservare) */
is_pending_conservation?: boolean
/** Filtra per messaggi gia' conservati (cartella Storico) */
is_conserved?: boolean
search?: string
/** Data minima nel formato ISO 8601 (es. "2026-01-01T00:00:00Z") */
date_from?: string
/** Data massima nel formato ISO 8601 */
date_to?: string
}
export interface MessageBulkUpdatePayload {
ids: string[]
is_read?: boolean
is_starred?: boolean
is_archived?: boolean
is_trashed?: boolean
is_pending_conservation?: boolean
is_conserved?: boolean
}
export interface MessageUpdatePayload {
is_read?: boolean
is_starred?: boolean
is_archived?: boolean
is_trashed?: boolean
is_pending_conservation?: boolean
is_conserved?: boolean
/** Rischio e Riservatezza (N3) — stringa vuota per resettare a null */
risk_level?: string
confidentiality?: string
}
export interface MessageBulkUpdateResponse {
updated: number
items: MessageResponse[]
}
export const messagesApi = {
list: (filters: MessageFilters = {}) =>
apiClient
.get<MessageListResponse>('/messages', { params: filters })
.then((r) => r.data),
get: (id: string) =>
apiClient.get<MessageResponse>(`/messages/${id}`).then((r) => r.data),
markRead: (id: string) =>
apiClient.patch<MessageResponse>(`/messages/${id}`, { is_read: true }).then((r) => r.data),
markUnread: (id: string) =>
apiClient.patch<MessageResponse>(`/messages/${id}`, { is_read: false }).then((r) => r.data),
toggleStar: (id: string, starred: boolean) =>
apiClient
.patch<MessageResponse>(`/messages/${id}`, { is_starred: starred })
.then((r) => r.data),
archive: (id: string) =>
apiClient
.patch<MessageResponse>(`/messages/${id}`, { is_archived: true })
.then((r) => r.data),
unarchive: (id: string) =>
apiClient
.patch<MessageResponse>(`/messages/${id}`, { is_archived: false })
.then((r) => r.data),
trash: (id: string) =>
apiClient
.patch<MessageResponse>(`/messages/${id}`, { is_trashed: true })
.then((r) => r.data),
untrash: (id: string) =>
apiClient
.patch<MessageResponse>(`/messages/${id}`, { is_trashed: false })
.then((r) => r.data),
/** Sposta un messaggio nella cartella Da Conservare */
conserve: (id: string) =>
apiClient
.patch<MessageResponse>(`/messages/${id}`, { is_pending_conservation: true })
.then((r) => r.data),
/** Rimuove un messaggio dalla cartella Da Conservare */
unconserve: (id: string) =>
apiClient
.patch<MessageResponse>(`/messages/${id}`, { is_pending_conservation: false })
.then((r) => r.data),
/** Aggiorna uno o piu' campi del messaggio (PATCH generico) — include risk_level/confidentiality (N3) */
update: (id: string, payload: MessageUpdatePayload) =>
apiClient
.patch<MessageResponse>(`/messages/${id}`, payload)
.then((r) => r.data),
/** Aggiorna in blocco is_starred e/o is_archived e/o is_trashed su più messaggi */
bulkUpdate: (payload: MessageBulkUpdatePayload) =>
apiClient
.patch<MessageBulkUpdateResponse>('/messages/bulk', payload)
.then((r) => r.data),
getAttachments: (id: string) =>
apiClient.get<AttachmentResponse[]>(`/messages/${id}/attachments`).then((r) => r.data),
/**
* Scarica un allegato autenticato e lo salva localmente.
* Utilizza apiClient (con Bearer token) per evitare il 401 che si ottiene
* navigando direttamente verso l'URL con un <a href>.
*/
downloadAttachment: async (messageId: string, attachmentId: string, filename: string): Promise<void> => {
const response = await apiClient.get(
`/messages/${messageId}/attachments/${attachmentId}/download`,
{ responseType: 'blob' },
)
const blobUrl = window.URL.createObjectURL(new Blob([response.data]))
const anchor = document.createElement('a')
anchor.href = blobUrl
anchor.setAttribute('download', filename)
document.body.appendChild(anchor)
anchor.click()
anchor.remove()
window.URL.revokeObjectURL(blobUrl)
},
getReceipts: (id: string) =>
apiClient.get<MessageResponse[]>(`/messages/${id}/receipts`).then((r) => r.data),
// ─── Feature 3: Thread ────────────────────────────────────────────────────
getThread: (id: string) =>
apiClient.get<MessageResponse[]>(`/messages/${id}/thread`).then((r) => r.data),
// ─── Feature 7: Preview allegati ─────────────────────────────────────────
getAttachmentPreviewUrl: (messageId: string, attachmentId: string) =>
apiClient.get<{
previewable: boolean
content_type: string
filename: string
url?: string
}>(`/messages/${messageId}/attachments/${attachmentId}/preview-url`).then((r) => r.data),
// ─── Feature 8: Stampa ────────────────────────────────────────────────────
/** Apre la vista di stampa HTML in una nuova tab. */
openPrint: (messageId: string, token: string) => {
const baseUrl = (window as any).__API_BASE_URL__ || '/api/v1'
window.open(`${baseUrl}/messages/${messageId}/print?token=${token}`, '_blank')
},
/**
* Scarica il pacchetto ZIP completo della PEC (postacert.eml, daticert.xml,
* ricevute di accettazione/consegna per le mail outbound).
*/
downloadPackage: async (messageId: string, subject?: string | null): Promise<void> => {
const response = await apiClient.get(
`/messages/${messageId}/download-package`,
{ responseType: 'blob' },
)
const blobUrl = window.URL.createObjectURL(new Blob([response.data], { type: 'application/zip' }))
const anchor = document.createElement('a')
anchor.href = blobUrl
const safeSubject = (subject || 'pec').replace(/[/\\]/g, '_').slice(0, 50)
anchor.setAttribute('download', `pec_${safeSubject}.zip`)
document.body.appendChild(anchor)
anchor.click()
anchor.remove()
window.URL.revokeObjectURL(blobUrl)
},
}