192 lines
6.6 KiB
TypeScript
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)
|
|
},
|
|
}
|