enhancement
major
minor
major
minor
major
#29601
TL Views: Anzeige von HTML-Inhalten und HTML-Dokumenten (Agenten-Antworten, Exposés) mit Vorschau und Druck/PDF
Kontext
KI-Agenten liefern Inhalte als HTML: kurze Antworten (Berichts-Auskünfte) als Fragment und vollständige Dokumente (Exposés) mit eigenem Stil. Die React-Oberfläche kann HTML nicht anzeigen; es gibt <text> (nur Text), <pdf> (nur PDF-Anzeige) und keinen Druck- bzw. PDF-Export. Benötigt werden: eingebettete Anzeige von HTML-Fragmenten, isolierte Anzeige vollständiger Dokumente, verkleinerte Vorschaubilder in Listen und der Druck bzw. Export als PDF.
Erweiterung
Die View-Ebene (.view.xml) erhält das Element <html input="kanal" display="…">. Der Kanalwert ist ein String, ein HTML-Fragment aus einem TL-Script-Literal ({{{…}}}) oder ein BinaryData mit Inhaltstyp text/html (z. B. binary('expose.html', $quelltext, 'text/html') oder eine hochgeladene Datei). Drei Anzeigearten:
- display="inline" (Vorgabe): Das Fragment wird als Teil der umgebenden Ansicht in die Seite eingefügt (Agenten-Antworten, Berichtsnotizen) und vom Anwendungs-Theme gestaltet. Vor der Anzeige prüft der Server das Fragment mit dem SafeHTML-Dienst (dieselbe Whitelist wie im klassischen Editor und in TL-Script-HTML-Makros); ein abgewiesenes Fragment wird nicht angezeigt, stattdessen erscheint die Meldung der Prüfung.
- display="document": Das vollständige Dokument wird in einem isolierten, sandbox-geschützten Frame ohne Skriptausführung angezeigt, behält seine eigenen Stile und füllt die verfügbare Höhe wie <pdf>. Mit print="true" erhält die Anzeige eine Druck-Schaltfläche; der Druckdialog des Browsers liefert mit "Als PDF speichern" den PDF-Export mit den originalen Stilen des Dokuments.
- display="thumbnail": Das Dokument wird in der Seitengröße thumbnail-width × thumbnail-height (Vorgabe 800 × 1130 CSS-Pixel, eine Hochformatseite) gerendert und per CSS auf die Breite der Vorschaukachel verkleinert, deren Seitenverhältnis dem der Seite entspricht (nicht interaktiv, ohne Fokus, verzögert geladen) – für Karten in einer <object-list layout="grid">.
Alle Anzeigearten nehmen css-class an; ein nicht darstellbarer Kanalwert (anderer Typ, anderer Inhaltstyp) wird durch eine Meldung ersetzt.
Serverseitige PDF-Erzeugung bleibt über die vorhandene Script-Funktion pdfFile() in Verbindung mit <pdf> möglich (nur XHTML/CSS 2.1); die FAQ dokumentiert beide Wege.
Nicht Teil des Tickets: ein Download-Kommando in der View-Ebene, serverseitig gerenderte Vorschaubilder, Anzeige von StructuredText-Attributen über dieses Element (dafür bleibt das vorhandene schreibgeschützte WYSIWYG-Feld zuständig).
Lösung
- com.top_logic.layout.react: Control ReactHtmlControl (implementiert DataProvider; ein Dokument wird nicht mit dem Zustand übertragen, sondern vom Frame über /react-api/data mit dem Revisionszähler dataRevision als Cache-Buster geholt; nur im Inline-Modus reist das Fragment im Zustand html) und Client-Komponente TLHtml (inline: eingefügtes Fragment; document: <iframe sandbox="allow-same-origin allow-modals"> mit Füllvertrag und Druck-Schaltfläche, die den Frame an den Druckdialog übergibt; thumbnail: <iframe sandbox="allow-same-origin" loading="lazy"> in Seitengröße, per ResizeObserver gemessen und mit transform: scale() auf die Kachelbreite verkleinert). Stile im Block TLHtml von tlReactControls.css; Client-Texte js.html.*.
- com.top_logic.layout.view: Element HtmlElement (@TagName("html")) mit input, display (HtmlDisplay), print, css-class, thumbnail-width, thumbnail-height; Wertkonvertierung in HtmlValues (String / HTMLFragment / BinaryData(text/html) mit Zeichensatz aus dem Inhaltstyp); SafeHTML-Prüfung nur im Inline-Modus; Fehlertexte in I18NConstants. Test TestHtmlElement (Konvertierung, Abweisung, ausgeliefertes Dokument, Revisionszähler, Vorschaugröße).
- Demo (com.top_logic.demo.react): Seite "HTML-Inhalte" mit Agenten-Antwort (inline), abgewiesenem Fragment, Exposé-Raster als <object-list layout="grid"> mit Vorschaukarten und Auswahl über <write-channel> sowie Dokumentansicht mit Druck; die Dokumentanzeige (pdf-demo) erhält einen text/html-Fall und nimmt HTML-Dateien zum Hochladen an.
- Dokumentation: Abschnitt "Ready-made HTML: <html>" in docs/faq/react-view-layer.md.