mirror of
https://github.com/idrainformatica/PecFlow.git
synced 2026-06-16 12:45:42 +02:00
Fix smtp
This commit is contained in:
@@ -12,6 +12,7 @@ import type {
|
||||
VirtualBoxUpdate,
|
||||
} from '@/types/api.types'
|
||||
|
||||
|
||||
export const virtualBoxesApi = {
|
||||
/** Crea una nuova Virtual Box. */
|
||||
create: (data: VirtualBoxCreate) =>
|
||||
@@ -27,6 +28,15 @@ export const virtualBoxesApi = {
|
||||
myVirtualBoxes: () =>
|
||||
apiClient.get<VirtualBoxResponse[]>('/virtual-boxes/my').then((r) => r.data),
|
||||
|
||||
/**
|
||||
* Caselle PEC attive da cui l'utente può inviare tramite le sue Virtual Box.
|
||||
* Usato nella pagina di composizione per mostrare le caselle mittente disponibili.
|
||||
*/
|
||||
getMyMailboxes: () =>
|
||||
apiClient
|
||||
.get<MailboxBriefResponse[]>('/virtual-boxes/my/mailboxes')
|
||||
.then((r) => r.data),
|
||||
|
||||
/** Dettaglio Virtual Box. */
|
||||
get: (id: string) =>
|
||||
apiClient.get<VirtualBoxResponse>(`/virtual-boxes/${id}`).then((r) => r.data),
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { useState, useRef } from 'react'
|
||||
import { useState, useRef, useMemo } from 'react'
|
||||
import { useNavigate, useLocation } from 'react-router-dom'
|
||||
import { useForm, useFieldArray } from 'react-hook-form'
|
||||
import { Send, X, Plus, ArrowLeft, AlertCircle, Paperclip, Upload } from 'lucide-react'
|
||||
import { Send, X, Plus, ArrowLeft, AlertCircle, Paperclip, Upload, Filter } from 'lucide-react'
|
||||
import { useQuery, useMutation } from '@tanstack/react-query'
|
||||
import toast from 'react-hot-toast'
|
||||
import { Button } from '@/components/ui/Button'
|
||||
@@ -10,9 +10,19 @@ import { Label } from '@/components/ui/Label'
|
||||
import { RichTextEditor } from '@/components/RichTextEditor/RichTextEditor'
|
||||
import { sendApi } from '@/api/send.api'
|
||||
import { mailboxesApi } from '@/api/mailboxes.api'
|
||||
import { virtualBoxesApi } from '@/api/virtual_boxes.api'
|
||||
import { getErrorMessage } from '@/api/client'
|
||||
import type { MessageResponse } from '@/types/api.types'
|
||||
|
||||
/** Tipo unificato casella mittente (sia da permessi diretti che da Virtual Box) */
|
||||
interface MailboxSelectItem {
|
||||
id: string
|
||||
email_address: string
|
||||
display_name: string | null
|
||||
status: string
|
||||
fromVbox?: boolean
|
||||
}
|
||||
|
||||
interface ComposeFormValues {
|
||||
mailbox_id: string
|
||||
to_addresses: { value: string }[]
|
||||
@@ -91,12 +101,18 @@ export function ComposePage() {
|
||||
remove: removeCc,
|
||||
} = useFieldArray({ control, name: 'cc_addresses' })
|
||||
|
||||
// Carica caselle disponibili per l'invio
|
||||
// Carica caselle disponibili per l'invio (permessi diretti)
|
||||
const { data: mailboxesData, isLoading: mailboxesLoading } = useQuery({
|
||||
queryKey: ['mailboxes'],
|
||||
queryFn: () => mailboxesApi.list(),
|
||||
})
|
||||
|
||||
// Carica caselle disponibili tramite Virtual Box (operatori senza permessi diretti)
|
||||
const { data: vboxMailboxes = [], isLoading: vboxMailboxesLoading } = useQuery({
|
||||
queryKey: ['virtual-boxes', 'my-mailboxes'],
|
||||
queryFn: () => virtualBoxesApi.getMyMailboxes(),
|
||||
})
|
||||
|
||||
const sendMutation = useMutation({
|
||||
mutationFn: (args: {
|
||||
data: Parameters<typeof sendApi.sendMultipart>[0]
|
||||
@@ -158,7 +174,36 @@ export function ComposePage() {
|
||||
})
|
||||
}
|
||||
|
||||
const activeCaselle = mailboxesData?.items.filter((m) => m.status === 'active') || []
|
||||
// ── Lista unificata caselle mittente ──────────────────────────────────────
|
||||
// Combina caselle con permesso diretto + caselle accessibili via VBox
|
||||
const activeCaselle = useMemo((): MailboxSelectItem[] => {
|
||||
const regularActive: MailboxSelectItem[] = (
|
||||
mailboxesData?.items.filter((m) => m.status === 'active') || []
|
||||
).map((m) => ({
|
||||
id: m.id,
|
||||
email_address: m.email_address,
|
||||
display_name: m.display_name,
|
||||
status: m.status,
|
||||
fromVbox: false,
|
||||
}))
|
||||
|
||||
const regularIds = new Set(regularActive.map((m) => m.id))
|
||||
|
||||
// Aggiungi caselle VBox non già presenti nella lista diretta
|
||||
const vboxActive: MailboxSelectItem[] = vboxMailboxes
|
||||
.filter((m) => m.status === 'active' && !regularIds.has(m.id))
|
||||
.map((m) => ({
|
||||
id: m.id,
|
||||
email_address: m.email_address,
|
||||
display_name: m.display_name,
|
||||
status: m.status,
|
||||
fromVbox: true,
|
||||
}))
|
||||
|
||||
return [...regularActive, ...vboxActive]
|
||||
}, [mailboxesData, vboxMailboxes])
|
||||
|
||||
const isLoadingMailboxes = mailboxesLoading || vboxMailboxesLoading
|
||||
|
||||
return (
|
||||
<div className="flex flex-col h-full">
|
||||
@@ -197,27 +242,35 @@ export function ComposePage() {
|
||||
{/* Casella mittente */}
|
||||
<div className="space-y-1.5">
|
||||
<Label htmlFor="mailbox_id">Casella mittente *</Label>
|
||||
{mailboxesLoading ? (
|
||||
{isLoadingMailboxes ? (
|
||||
<div className="h-10 rounded-md border bg-muted animate-pulse" />
|
||||
) : activeCaselle.length === 0 ? (
|
||||
<div className="rounded-md border border-destructive/50 bg-destructive/10 p-3 text-sm text-destructive">
|
||||
Nessuna casella PEC attiva disponibile. Contatta l'amministratore.
|
||||
</div>
|
||||
) : (
|
||||
<select
|
||||
id="mailbox_id"
|
||||
className="flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2"
|
||||
{...register('mailbox_id', {
|
||||
required: 'Seleziona una casella mittente',
|
||||
})}
|
||||
>
|
||||
<option value="">Seleziona casella...</option>
|
||||
{activeCaselle.map((mb) => (
|
||||
<option key={mb.id} value={mb.id}>
|
||||
{mb.display_name || mb.email_address} ({mb.email_address})
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
<>
|
||||
<select
|
||||
id="mailbox_id"
|
||||
className="flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2"
|
||||
{...register('mailbox_id', {
|
||||
required: 'Seleziona una casella mittente',
|
||||
})}
|
||||
>
|
||||
<option value="">Seleziona casella...</option>
|
||||
{activeCaselle.map((mb) => (
|
||||
<option key={mb.id} value={mb.id}>
|
||||
{mb.fromVbox ? '📥 ' : ''}{mb.display_name || mb.email_address} ({mb.email_address})
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
{activeCaselle.some((m) => m.fromVbox) && (
|
||||
<p className="text-xs text-purple-600 flex items-center gap-1">
|
||||
<Filter className="h-3 w-3" />
|
||||
Le caselle con 📥 sono accessibili tramite Virtual Box
|
||||
</p>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
{errors.mailbox_id && (
|
||||
<p className="text-xs text-destructive">{errors.mailbox_id.message}</p>
|
||||
|
||||
@@ -353,6 +353,7 @@ export interface MailboxBriefResponse {
|
||||
id: string
|
||||
email_address: string
|
||||
display_name: string | null
|
||||
status: string
|
||||
}
|
||||
|
||||
export interface VirtualBoxCreate {
|
||||
|
||||
Reference in New Issue
Block a user