Skip to content

Comunicazione Iframe - Toast

Panoramica

Questo documento descrive il sistema di comunicazione tra l'iframe e il parent window per mostrare notifiche toast nella SPA React.

Architettura

Hook: useToastBridge

L'hook useToastBridge è responsabile di:

  1. Registrare l'oggetto toast sul window globale
  2. Fornire le funzioni che l'iframe può chiamare per mostrare notifiche
  3. Utilizzare internamente l'hook useToast di @elerama/ui per mostrare i toast
  4. Pulire l'oggetto toast quando il componente viene smontato

Type Declaration

Il file app/types/window.d.ts estende l'interfaccia Window per includere l'oggetto toast:

typescript
toast?: {
    /**
     * Mostra un toast generico
     * @param message - Messaggio da mostrare
     * @param description - Descrizione opzionale
     */
    show: (message: string, description?: string) => void;
    /**
     * Mostra un toast di successo
     * @param message - Messaggio da mostrare
     * @param description - Descrizione opzionale
     */
    success: (message: string, description?: string) => void;
    /**
     * Mostra un toast informativo
     * @param message - Messaggio da mostrare
     * @param description - Descrizione opzionale
     */
    info: (message: string, description?: string) => void;
    /**
     * Mostra un toast di warning
     * @param message - Messaggio da mostrare
     * @param description - Descrizione opzionale
     */
    warning: (message: string, description?: string) => void;
    /**
     * Mostra un toast di errore
     * @param message - Messaggio da mostrare
     * @param description - Descrizione opzionale
     */
    error: (message: string, description?: string) => void;
    /**
     * Chiude tutti i toast attivi
     */
    dismiss: () => void;
};

Utilizzo

Nel Parent Window (React App)

L'hook useToastBridge viene utilizzato nell'AuthenticatedLayout:

typescript
export function AuthenticatedLayout({ children }: AuthenticatedLayoutProps) {
    // ... altri hook ...

    // Registra l'oggetto toast sul window per mostrare notifiche dall'iframe
    useToastBridge();

    // ...
}

Importante: L'hook deve essere chiamato all'interno dell'AuthenticatedLayout perché:

  • I toast sono disponibili solo per utenti autenticati
  • Il componente <Sonner /> (che renderizza i toast) è montato nel root.tsx

Nell'Iframe (PHP/JavaScript)

L'iframe può chiamare le funzioni toast tramite window.parent:

1. Toast generico

javascript
window.parent.toast.show('Operazione in corso...');
window.parent.toast.show('Titolo', 'Descrizione dettagliata');

2. Toast di successo

javascript
window.parent.toast.success('Salvataggio completato!');
window.parent.toast.success('Salvato', 'I dati sono stati salvati correttamente nel database.');

3. Toast informativo

javascript
window.parent.toast.info('Informazione importante');
window.parent.toast.info('Nota', 'Questa è una nota informativa per l\'utente.');

4. Toast di warning

javascript
window.parent.toast.warning('Attenzione');
window.parent.toast.warning('Attenzione', 'Questa operazione potrebbe avere conseguenze irreversibili.');

5. Toast di errore

javascript
window.parent.toast.error('Errore durante il salvataggio');
window.parent.toast.error('Errore di connessione', 'Impossibile raggiungere il server. Riprova più tardi.');

6. Chiudere tutti i toast

javascript
window.parent.toast.dismiss();

Esempio Completo

PHP nell'iframe

php
<!-- Mostra un toast di successo dopo un salvataggio -->
<script>
function salvaArticolo() {
    fetch('/api/articoli', { method: 'POST', body: formData })
        .then(response => {
            if (response.ok) {
                window.parent.toast.success('Articolo salvato', 'L\'articolo è stato salvato correttamente.');
            } else {
                window.parent.toast.error('Errore', 'Impossibile salvare l\'articolo.');
            }
        })
        .catch(error => {
            window.parent.toast.error('Errore di connessione', error.message);
        });
}
</script>

<!-- Toast informativo al caricamento della pagina -->
<script>
document.addEventListener('DOMContentLoaded', function() {
    const messaggioPendente = <?= json_encode($messaggio_pendente) ?>;
    if (messaggioPendente) {
        window.parent.toast.info('Nota', messaggioPendente);
    }
});
</script>

<!-- Toast di warning per operazioni rischiose -->
<script>
function eliminaArticolo(id) {
    if (confirm('Sei sicuro di voler eliminare questo articolo?')) {
        fetch('/api/articoli/' + id, { method: 'DELETE' })
            .then(response => {
                if (response.ok) {
                    window.parent.toast.success('Articolo eliminato');
                    // Ricarica la lista
                    location.reload();
                } else {
                    window.parent.toast.error('Errore', 'Impossibile eliminare l\'articolo.');
                }
            });
    }
}
</script>

Verificare la disponibilità dell'API

Prima di chiamare le funzioni toast, è buona pratica verificare che l'API sia disponibile:

javascript
function mostraToast(tipo, messaggio, descrizione) {
    if (window.parent && window.parent.toast && typeof window.parent.toast[tipo] === 'function') {
        window.parent.toast[tipo](messaggio, descrizione);
    } else {
        // Fallback: usa alert o console.log
        console.log('[Toast ' + tipo + ']', messaggio, descrizione);
    }
}

// Utilizzo
mostraToast('success', 'Operazione completata');
mostraToast('error', 'Errore', 'Descrizione dell\'errore');

Comportamento dei Toast

I toast utilizzano la libreria Sonner tramite il componente <Sonner /> di @elerama/ui:

  • Posizione: In basso a destra dello schermo
  • Durata: Auto-dismiss dopo alcuni secondi (configurabile)
  • Stacking: I toast si impilano verticalmente
  • Animazioni: Entrata/uscita animate

Varianti Stilistiche

MetodoColoreIconaUso consigliato
show()Neutro-Messaggi generici
success()VerdeOperazioni completate con successo
info()BluInformazioni non critiche
warning()ArancioneAvvisi e attenzioni
error()RossoErrori e problemi

Test

Test Unitari

Il file tests/hooks/useToastBridge.test.ts contiene i test per verificare:

  • ✅ Registrazione dell'oggetto toast sul window
  • ✅ Rimozione dell'oggetto quando l'hook viene smontato
  • show() chiama la funzione toast corretta
  • success() chiama la funzione success con i parametri corretti
  • info() chiama la funzione info con i parametri corretti
  • warning() chiama la funzione warning con i parametri corretti
  • error() chiama la funzione error con i parametri corretti
  • dismiss() chiude tutti i toast
  • ✅ Scenario completo di operazioni
  • ✅ Stabilità delle funzioni tra i render

Esecuzione Test

bash
# Esegui solo i test di useToastBridge
npm run test:run -- tests/hooks/useToastBridge.test.ts

# Esegui tutti i test
npm run test:run

Test Manuali

Usa la pagina /test-iframe per testare manualmente:

  1. Vai alla pagina /test-iframe
  2. Clicca sul tab "Toast"
  3. Testa i vari tipi di toast:
    • Toast Generico - chiama show()
    • Toast Successo - chiama success()
    • Toast Info - chiama info()
    • Toast Warning - chiama warning()
    • Toast Errore - chiama error()
    • Successo con Descrizione - chiama success() con descrizione
    • Errore con Descrizione - chiama error() con descrizione
    • Chiudi Tutti i Toast - chiama dismiss()

Note sulla Sicurezza

  • La comunicazione avviene tramite window.parent, quindi funziona solo se l'iframe è sullo stesso dominio o configurato con CORS
  • L'oggetto toast viene rimosso quando il componente viene smontato per evitare memory leaks
  • I messaggi passati ai toast vengono visualizzati così come sono (non vengono sanitizzati per HTML)

Logging

L'hook logga automaticamente tutte le operazioni nella console:

[useToastBridge] Hook montato, registrazione toast...
[useToastBridge] ✅ Oggetto toast registrato sul window
[useToastBridge] ✅ success chiamata dall'iframe: Operazione completata
[useToastBridge] ❌ error chiamata dall'iframe: Errore di connessione
[useToastBridge] ⚠️ Cleanup: rimozione toast...
[useToastBridge] ❌ Oggetto toast rimosso dal window

Questi log sono utili per il debugging durante lo sviluppo.

Relazione con Altri Bridge

Il sistema di toast bridge segue lo stesso pattern degli altri bridge per la comunicazione iframe:

BridgeOggetto WindowScopo
useTopbarMenuwindow.topbarAggiornamento menu dinamico
useTopbarMessageswindow.messagesGestione messaggi non letti
useTopbarCartwindow.cartGestione carrello
useIframeNavigationwindow.navigationNavigazione tra pagine
useTopbarSidebarwindow.sidebarControllo sidebar
useToastBridgewindow.toastNotifiche toast

Tutti questi hook vengono chiamati nell'AuthenticatedLayout per garantire che siano disponibili solo per utenti autenticati.

Documentazione Elerama Frontend