Skip to content

Comunicazione Iframe - Topbar Menu

Panoramica

Questo documento descrive il sistema di comunicazione tra l'iframe presente nella pagina 'r' e il parent window per aggiornare il menu della topbar.

Architettura

Hook: useTopbarMenu

L'hook useTopbarMenu è responsabile di:

  1. Registrare l'oggetto topbar sul window globale
  2. Fornire la funzione updateMenu che l'iframe può chiamare
  3. Pulire l'oggetto topbar quando il componente viene smontato

Type Declaration

Il file app/types/window.d.ts estende l'interfaccia Window per includere tutte le proprietà personalizzate utilizzate nell'applicazione:

typescript
declare global {
    interface Window {
        /**
         * ID della ditta attiva, impostato dopo setActiveCompany
         */
        id_company?: number;

        /**
         * Oggetto per la comunicazione con l'iframe nella pagina 'r'
         */
        topbar?: {
            updateMenu: (menuData: unknown, subMenuId: string) => void;
        };

        /**
         * Flag che indica se l'iframe utilizza il template 2020.
         * Deve essere true per permettere il caricamento del modulo.
         */
        template_2020?: boolean;
    }
}

Questo file centralizza tutte le estensioni del tipo Window, evitando dichiarazioni duplicate in altri file.

Utilizzo

Nel Parent Window (React App)

L'hook useTopbarMenu viene utilizzato nell'AuthenticatedLayout:

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

    // Registra l'oggetto topbar sul window per la comunicazione con l'iframe
    useTopbarMenu();

    // ... resto del componente ...
}

Nell'Iframe (PHP/JavaScript)

L'iframe può chiamare la funzione updateMenu tramite:

javascript
window.parent.topbar.updateMenu(menuData, subMenuId);

Dove:

  • menuData: array o oggetto contenente i dati del menu
  • subMenuId: ID del sottomenu da aggiornare

Esempio

Chiamata dall'iframe (PHP)

php
<script>
window.parent.topbar.updateMenu(<?= json_encode($sub_menu['dropdownmenu']) ?>, '<?= $id_sub_menu ?>');
</script>

Ricezione nel parent window

Per ora, i dati vengono solo loggati nella console:

typescript
const updateMenu = (menuData: unknown, subMenuId: string) => {
    console.log("[useTopbarMenu] updateMenu chiamata dall'iframe");
    console.log("[useTopbarMenu] menuData:", menuData);
    console.log("[useTopbarMenu] subMenuId:", subMenuId);

    // TODO: Implementare la gestione del menu
};

Prossimi Passi

  1. Definire lo schema dei dati del menu: Creare un type/interface per menuData
  2. Implementare lo store: Utilizzare Zustand per gestire lo stato del menu
  3. Aggiornare la UI: Mostrare il menu ricevuto nell'header della topbar
  4. Gestire errori: Validare i dati ricevuti dall'iframe

Note sulla Sicurezza

  • La comunicazione avviene tramite window.parent, quindi funziona solo se l'iframe è sullo stesso dominio o se configurato correttamente con CORS
  • Attualmente non c'è validazione dei dati ricevuti - da implementare quando si definirà lo schema
  • L'oggetto topbar viene rimosso quando il componente viene smontato per evitare memory leaks

Verifica Template 2020

Quando l'iframe viene caricato, viene verificata la presenza della proprietà template_2020 nel contentWindow dell'iframe. Se questa proprietà:

  • Non è definita (undefined)
  • È impostata a false

Viene eseguito automaticamente il logout dell'utente e il redirect alla pagina di login.

Questo controllo garantisce che vengano caricati solo moduli compatibili con il nuovo template.

Implementazione

typescript
// Nell'iframe deve essere presente:
window.template_2020 = true;

Se il controllo fallisce, viene loggato un warning e l'utente viene disconnesso:

[ModulePage] Controllo template_2020 fallito - eseguo logout
[ModulePage] template_2020: undefined (o false)

Gestione Errori

In caso di errore durante l'accesso al contentWindow (es. violazione same-origin policy), l'errore viene loggato ma non viene eseguito il logout. Questo evita logout indesiderati in caso di problemi di CORS o altre restrizioni di sicurezza del browser.

Test

Test Unitari

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

  • Registrazione dell'oggetto topbar sul window
  • Rimozione dell'oggetto quando l'hook viene smontato
  • Logging dei dati quando updateMenu viene chiamata
  • Gestione di chiamate multiple

Test Manuale con Pagina di Test

È disponibile una pagina di test interattiva per verificare la comunicazione tra iframe e parent:

  1. Avvia l'applicazione in modalità dev: npm run dev
  2. Naviga alla pagina di test: /test-iframe
  3. Usa i pulsanti nell'iframe per testare diversi scenari:
    • Test Menu Semplice
    • Test Menu Complesso
    • Test Menu Vuoto
    • Verifica presenza topbar

La pagina di test è disponibile in public/test-iframe.html e può essere caricata anche direttamente.

Debug

Quando carichi una pagina con iframe, dovresti vedere nella console:

[useTopbarMenu] Hook montato, registrazione topbar...
[useTopbarMenu] ✅ Oggetto topbar registrato sul window
[useTopbarMenu] ✅ window.topbar.updateMenu disponibile: function
[ModulePage] Iframe caricato: https://...
[ModulePage] window.topbar disponibile: true
[ModulePage] topbar.updateMenu è disponibile: function

Quando l'iframe chiama updateMenu:

================================================================================
[useTopbarMenu] 🎯 updateMenu chiamata dall'iframe!
[useTopbarMenu] 📦 menuData: [...]
[useTopbarMenu] 🆔 subMenuId: ...
================================================================================

Troubleshooting

Se non vedi i log quando l'iframe chiama updateMenu:

  1. Verifica che l'iframe sia sullo stesso dominio o configurato correttamente con CORS
  2. Controlla la console per errori di same-origin policy
  3. Verifica che l'hook sia montato - dovresti vedere i log di registrazione
  4. Usa la pagina di test /test-iframe per verificare che il sistema funzioni
  5. Controlla il timing - l'iframe potrebbe caricarsi prima che topbar sia disponibile

Documentazione Elerama Frontend