Files
Codex bd416f7327
Publish documentation / publish (push) Successful in 34s
Fix new-question landing and question-language HITL
Reset the activity panel when starting a new question so the landing navigation is restored. Detect and persist the original question language, pass it through runtime and widget descriptors, and scope HITL controls to that language.

Validated with gate, session, backend and frontend tests, TypeScript checks, Ruff and strict docs build. Rebuilt and restarted local core/frontend; both healthy and serving HTTP successfully.
2026-09-21 19:47:22 +02:00

7.7 KiB

Rendering full ed embedded

ThothII ha una sola applicazione React, una sola build Vite e gli stessi servizi backend. «Doppio rendering» significa due modi di ospitare quella applicazione, non due versioni delle pagine e non rendering React sul server. Django renderizza il contenitore Omics; React renderizza ThothII nel browser, dentro #root.

Tre decisioni indipendenti

Decisione Configurazione Effetto
Distribuzione profile: local oppure server Compose, percorsi e vincoli operativi
Presentazione shell.mode: full oppure embedded Proprietario di header e preferenze
Autenticazione auth.yaml local/OIDC oppure AUTH_MODE=upstream Chi verifica l'identità, come arriva al backend

Il Mac usa full + local, con lingua iniziale inglese. L'integrazione Omics usa embedded + upstream, con accesso già verificato dal portale. Un server autonomo può usare full + oidc. Cambiare shell.mode non abilita un metodo di autenticazione e non modifica permessi o proprietari delle sessioni.

Full con upstream può visualizzare un'identità già verificata dal proxy, ma non ha un logout ThothII disponibile: non è il profilo autonomo con login/logout. Embedded non avvia login locale o OIDC anche se il backend è configurato così; questa combinazione non realizza il login unico Omics e non va usata come fallback.

Composizione comune

flowchart TD
    CONFIG["config.js pubblico"] --> SHELL["ShellProvider"]
    FULL["Preferenze full nel browser"] --> SHELL
    HOST["Documento Omics"] --> ADAPTER["OmicsPortalAdapter: solo presentazione"]
    ADAPTER --> SHELL
    SHELL --> GATE["AuthGate: verifica GET /me"]
    GATE --> APP["AppShell: stesse pagine, sessioni e amministrazione"]
    AUTH["Backend: cookie locale/OIDC o identità upstream"] --> GATE

ShellProvider risolve la configurazione, applica lingua/tema e monta i contenuti solo dopo uno snapshot host valido in embedded. AuthGate verifica l'accesso; AppShell e le pagine non devono leggere selettori o eventi specifici di Omics. Il cambio utente smonta lo stato applicativo della precedente identità.

Full

  • Header ThothII rosso Omics #CB333B in entrambi i temi; logo interamente chiaro.
  • Selettore EN/IT, tema light/dark, fullscreen e nome verificato dell'utente.
  • Menu del nome con logout soltanto per local/OIDC; nessuna rotellina admin. L'amministrazione resta nella navigazione applicativa, secondo i permessi.
  • Margine sinistro vuoto e simmetrico al destro: max(20px, 1.5rem), normalmente 24px con radice a 16px. Non è una seconda sidebar di navigazione.
  • Lingua e tema ricordati sullo stesso origin in localStorage, nelle chiavi thothii:shell:locale e thothii:shell:theme. Non sono preferenze server per utente. In assenza di preferenze: defaultLocale e tema light.
  • Fullscreen usa document.documentElement.requestFullscreen() e document.exitFullscreen(): nasconde il contorno del browser dove supportato. L'icona cambia sullo stato reale, anche dopo Esc; un rifiuto mostra un errore. Non è un semplice ingrandimento CSS e non scatta automaticamente all'accesso.

Embedded

  • Nessun header ThothII, selettore lingua, toggle tema, login o logout autonomo. I controlli rimangono nell'header generale Omics.
  • React è nello stesso documento della pagina /kokoro/datamart-builder/, non in un iframe. Non serve postMessage né un secondo protocollo di sessione.
  • L'adapter legge la lingua Django già confermata, osserva il tema del documento e ascolta il fullscreen reale. Le azioni rimangono di proprietà del portale.
  • Un contesto Omics mancante o invalido mostra un errore d'integrazione; non passa silenziosamente a full e non offre un secondo login.
  • Il portale assegna l'altezza disponibile sotto il proprio header: catena flex con min-height: 0, root contenuto e altezza applicativa vincolata al contenitore. Il contratto ThothII espone --thoth-app-height (fallback 100dvh); verificare il contenitore reale, non presumere che l'intera viewport appartenga a React. Il template Omics mantiene inoltre i suoi override di compatibilità.

Il reset CSS è limitato al mount React e ai popup dell'applicazione, senza richiedere CSS @scope. I token e i popup seguono il tema applicativo. Questo non rende indipendenti fogli di stile arbitrari caricati dal portale: la verifica del documento condiviso rimane necessaria a ogni integrazione.

Caricamento e configurazione pubblica

Il descrittore installato è la sorgente di verità. Il CLI genera generated/frontend/config.js e il suo mount di sola lettura nella proiezione generated/compose.models.yaml. Il file pubblico contiene solo backendBaseUrl e shell, mai identità, token, password o percorsi host. Va caricato prima del modulo React e servito senza cache. Nessuna build separata è richiesta per cambiare modalità; occorre rigenerare e applicare i mount tramite il lifecycle.

L'ordine Omics è: config pubblico → override del solo prefisso API → asset dal manifest Vite. L'override deve conservare shell; l'adapter non configura il proxy. Il default completo di shell omessa è embedded/en/omics-portal. Il CLI normalizza anche singoli campi omessi; un oggetto shell scritto manualmente nel browser deve invece contenere mode e defaultLocale, altrimenti viene rifiutato.

Lingua, continuità e dati

La lingua UI traduce il testo dell'applicazione, non i contenuti di dominio. Alla creazione, la lingua UI viene acquisita come interactionLanguage di ripiego. Il CLI riconosce la lingua della domanda originale e salva interaction_language nel manifest; usa il ripiego solo per input troppo brevi, ambigui o composti da codice. Questa lingua governa domande, spiegazioni, scelte e controlli HITL. Il gate la include nei descrittori e il frontend la applica al sottoalbero dei widget, senza cambiare la lingua della navigazione. Alla ripresa vale la lingua salvata, non l'ultima scelta dell'header. Per i manifest precedenti senza campo viene riconosciuta e fissata la lingua della domanda, con la lingua workspace disponibile alla prima ripresa come ripiego.

Il cambio lingua Omics invia il form Django e ricarica la pagina. ThothII conserva solo l'ID della selezione in sessionStorage, separato per pathname, issuer e subject. Riapre i documenti, non avvia una generazione. Bozze non inviate e modifiche non salvate richiedono conferma prima della navigazione; non sono una trascrizione salvata. La ripresa operativa resta esplicita.

Punti di implementazione e manutenzione

Sorgente Responsabilità
tools/tht/internal/config/shell.go Normalizzazione e validazione del descrittore
tools/tht/internal/modelprojection/projection.go Config pubblico e mount generati
frontend/src/api/runtime-config.ts Validazione browser e prefisso API same-origin
frontend/src/shell/host/ShellProvider.tsx Composizione, preferenze e tema
frontend/src/shell/host/FullHeader.tsx Controlli solo full
frontend/src/shell/host/OmicsPortalAdapter.ts Conoscenza del documento Omics
frontend/src/auth/AuthGate.tsx Accesso e ricontrolli al ritorno alla pagina
backend/src/auth/auth.ts e principal.ts Verifica server dell'identità

Per un altro portale servono un'implementazione del PortalAdapter, la sua registrazione nei validatori CLI/browser e nel punto di composizione, oltre al contratto di autenticazione server. Il nome di una classe non è un plugin caricabile dinamicamente da YAML.

Procedure: configurazione e deploy, autenticazione, accettazione.