major
#29693
TL Views: Große und mehrwertige Werte erscheinen in Tabellenzellen als einzeilige Vorschau mit einem Knopf, der den vollständigen Editor in einem Dialog öffnet
In einer Tabelle der TL Views (<table>, Zellenbearbeitung) werden Werte, deren Editor im Formular viel Platz braucht, unbrauchbar dargestellt: mehrzeilige Texte, HTML (auch internationalisiert), TL-Script- und Code-Editoren, internationalisierte Texte, mehrwertige Felder, die pro Element ein Eingabefeld zeigen, und Kompositionen sprengen die Zeilenhöhe. Kompositionen werden sogar als toString() der Teil-Liste angezeigt (siehe unten).
Nach dieser Änderung zeigt eine solche Zelle nur eine einzeilige, gekürzte Vorschau des Werts (bei HTML und mehrzeiligem Text die erste Zeile; ist die Vorschau zu lang, zeigt ein Tooltip den Text):
- Bearbeitungsmodus: die Zelle sieht aus wie ein Eingabefeld, am rechten Rand ein Stift-Knopf. Er öffnet einen Dialog mit dem Editor, der den Wert auch im Formular bearbeitet. "OK" übernimmt (ungültige Eingaben oder fehlende Pflichtwerte werden abgewiesen, der Dialog bleibt offen), "Abbrechen" verwirft.
- Anzeigemodus: reiner Text; ein unauffälliges Auge erscheint erst beim Überfahren der Zeile (oder bei Tastaturfokus) und öffnet den vollständigen Wert schreibgeschützt. Leere Werte und mehrwertige einfache Werte (Zahlen, Daten, kurze Texte), deren Vorschau schon der ganze Wert ist, haben keinen Knopf.
- Kompositionen: die Vorschau nennt die Teile; der Dialog zeigt die Tabelle der Teile, deren Kompositionsspalten wieder solche Zellen sind - beliebig tief verschachtelt, im Bearbeitungsmodus editierbar (Hinzufügen, Entfernen, Ändern), im Anzeigemodus schreibgeschützt. "Abbrechen" eines Dialogs verwirft auch alles, was in darin geöffneten Dialogen bestätigt wurde; gespeichert wird mit dem Speichern der Tabelle bzw. des Formulars.
- Mehrfachauswahl-Felder (Dropdown) bleiben in der Zelle; ihre schreibgeschützte Anzeige trennt die Werte durch Kommata.
Auf dem Weg behoben:
- Ein Attribut vom Typ tl.model.search:Expr (TL-Script) wird in Formularen und Tabellen mit dem TL-Script-Editor bearbeitet (bisher ein einfaches Textfeld); ein Syntaxfehler ist ein Eingabefehler des Felds, der Speichern verhindert, und der Editor folgt dem Bearbeitungsmodus.
- Ein Klick auf ein bedienbares Element in einer Tabellenzelle (Knopf, Eingabefeld, Checkbox) wählt die Zeile nicht mehr aus; ein Klick auf ein schreibgeschütztes Element wählt sie weiterhin aus.
- Eine <composition-table> ohne <columns> zeigt die Standardspalten des Teiltyps (bisher keine Datenspalten).
- Neue Zeilen einer Kompositionstabelle mit neuen Teilen werden vollständig gespeichert (bisher wurden Werte nur eine Ebene tief kopiert und Kopierfehler stillschweigend verworfen).
Ursprünglicher Befund: Kompositionsspalte
Found on 2026-09-29 against tl-layout-view 8.0.0-alpha8, in the BOS/Consulting application (issue #347).
A <table types="..."> offers every attribute of its row type in the column chooser (Spalten), compositions included. When the user ticks a composition, each cell shows the Java toString() of the part list:
AttributedWrapper(type:consulting:Section, id: Section:7047, name: Was Giulia Ferrante erzählt hat)AttributedWrapper(type:consulting:Section, ...
and after a re-render on a thread without an interaction:
Error in toString() of 'Section:8547': java.lang.IllegalStateException: KnowledgeBase operations require a valid InteractionContext
Cause: FieldControlService#displayModel asks selectOptionSource(part), which is null for a composition on purpose (compositions are not edited through a select), so the value was wrapped in a plain AbstractFieldModel and printed by the text control.
Lösung
- FieldSpec#isCompact(): das Feld wird auf kleinem Raum dargestellt. FieldControlService.cellSpec setzt es für bearbeitbare Zellen, FieldControlService.createDisplayControl(ReactContext, ColumnType, Object) für Anzeige-Zellen; Formulare bleiben unverändert.
- ReactFieldControlProvider meldet über isLarge(FieldSpec), ob sein Editor mehr Platz als eine Zeile braucht, liefert über previewText(FieldSpec, Object) die einzeilige Vorschau und über isEmpty(FieldSpec, Object), ob ein Wert leer ist. Groß sind: mehrzeiliger und internationalisierter Text, Code-Editor, WYSIWYG und internationalisiertes HTML (Vorschau: erster Block mit Text, ohne das Dokument ganz zu lesen), TL-Script, Konfigurationsformulare. Die Vorschau eines Passworts zeigt nie den Wert.
- FieldControlRegistry.createControl - die eine Stelle, an der jedes Feld-Control entsteht - ersetzt bei kompakter Darstellung ein großes Feld (oder ein mehrwertiges, das pro Element ein Eingabefeld zeigt) durch ReactCompactFieldControl, zusammengesetzt aus vorhandenen Controls. Der Dialog arbeitet über eine Editor-Sitzung (öffnen, übernehmen mit Prüfung, verwerfen); für einfache Werte bearbeitet sie eine gepufferte Kopie des Werts.
- Kompositionen werden flach gepuffert, ebenenweise wie in der klassischen Oberfläche, aber ohne tiefe Kopien: EditLevel ist eine Bearbeitungsebene (Formular/Tabelle oder ein Dialog). Ein Dialog legt nur für die Teile, die er zeigt, Puffer an (TLObjectOverlay für bestehende, transientes Objekt für neue); "OK" schreibt die Teilliste in den Puffer der übergeordneten Ebene, "Abbrechen" verwirft die Ebene. BufferSave speichert beim Speichern nur die berührten Objekte (geänderte Attribute bestehender Teile, neue Teile einmal angelegt, entfernte Teile gelöscht). Dasselbe Verfahren gilt für die <composition-table> im Formular, editierbare Tabellen und die Dateiliste (RowSetEditSession).
- TL-Script: TLScriptFieldControlProvider ist für den Modelltyp tl.model.search:Expr konfiguriert und liest/schreibt über dessen Storage-Mapping. Ein Java-Werttyp, den mehrere Datentypen des Modells teilen (z.B. SearchExpression für Expr, Template, Report), wird nicht mehr global für den Editor eines dieser Typen registriert.
Bekannte Grenze
- Annotationen (AnnotationsFieldControlProvider) bleiben in der Zelle in voller Größe: ihr Editor braucht das Attribut-Feldmodell und kann nicht auf einer gepufferten Kopie arbeiten.
Demo: tl-demo-react, Seitenleiste "Attribute", Reiter "Tabelle" (Anzeige), "Editierbare Tabelle" (Bearbeiten, dann eine Zeile anklicken) und "Auswahl + Formular"; demo.react:Demo hat dazu die Attribute script und die Komposition parts, deren Teile (DemoPart) wieder Teile haben.
Migration
- Eigene Implementierungen von com.top_logic.layout.view.form.RowSetBinding: updateMembership(FormControl, List) wird zu updateMembership(TLObject owner, List rows), commit(Transaction, FormControl, List, List) zu commit(TLObject owner, List persisted, List original). owner ist der Bearbeitungspuffer des Objekts, das die Zeilen hält (bisher form.getOverlay()); commit wird weiterhin in der speichernden Transaktion aufgerufen.
- Anwendungen, die den Workaround für Kompositionsspalten tragen (eigener ColumnProviderService für Kompositionen, z.B. BOS/Consulting CompositionColumnProviderService mit WEB-INF/autoconf/com.top_logic.layout.view.table.ColumnProviderService.config.xml), können ihn entfernen.