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.
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
#CB333Bin 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 chiavithothii:shell:localeethothii:shell:theme. Non sono preferenze server per utente. In assenza di preferenze:defaultLocalee tema light. - Fullscreen usa
document.documentElement.requestFullscreen()edocument.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 servepostMessagené 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(fallback100dvh); 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.