enhancement
major
minor
defect
critical
major
minor
minor
#30134
View layer: <composition-table> ignores the visibility (dynamic-visibility, hidden, read-only) of its composite attribute
Found 2026-11-03 against tl-layout-view 8.0.0-alpha12 in E-Home (haumacher/ehome #73).
Problem
A <field attribute="x"/> of a React view-layer <form> follows the visibility of its attribute (AttributeFieldControl): it is hidden while a <dynamic-visibility> answers hidden, read-only while it answers read-only. A <composition-table attribute="parts"/> in the same form does not: CompositionTableElement#createControl builds the RowSetTableControl without looking at the attribute's visibility annotations, so the table and its "Add"/delete buttons are shown and editable whatever the visibility says.
Reproduction
<reference name="parts" kind="composite" multiple="true" type="Part">
<annotations>
<dynamic-visibility>
<mode-selector class="com.top_logic.model.search.providers.ModeSelectorByExpression"
function="obj -> editMode -> if($obj.get(`m:Owner#manual`), null, 'hidden')"/>
</dynamic-visibility>
</annotations>
</reference>
A form over an Owner with <field attribute="manual"/>, a field of another attribute with the same annotation, and <composition-table attribute="parts"/>. With manual false the other field is hidden, the table is shown; in edit mode "Add" creates parts.
Also a static <visibility value="hidden"/> or read-only on the composite attribute is not honored (not checked separately, the code has no visibility path at all).
Expected
The composition table follows the mode of its attribute as a field does: hidden (with its title) for hidden, view only (no Add, no delete, read-only cells) for read-only, re-evaluated when the attributes the mode selector reads change.
Workaround in E-Home
The table of the archives of a datapoint's history (ehome.logical:GroupAddress#historyArchives) stays visible for a derived history; a constraint (runtimeArchiveProblem) refuses an archive entered there ("Archives are only used by a history set by hand"), and the image ignores them.
Lösung
Die Berechnung des Anzeigemodus eines Attributs im Formular (dynamische Sichtbarkeit über den ModeSelector mit Verfolgung seiner Abhängigkeiten, sonst die statische Sichtbarkeit bzw. die Sichtbarkeit beim Anlegen eines neuen Objekts, dazu die Zugriffsrechte: ohne Leserecht verborgen, ohne Schreibrecht nur lesbar) ist in AttributeModeTracker zusammengefasst. Feld (AttributeFieldControl) und Kompositionstabelle (AbstractCompositionControl / RowSetTableControl über eine AttributeRowSetBinding) nutzen ihn gemeinsam und verhalten sich daher gleich:
- Statisch verborgen, beim Anlegen verborgen oder ohne Leserecht: die Tabelle ist samt Titel ausgeblendet und zeigt keine Zeilen; es läuft keine Bearbeitungssitzung.
- Dynamischer Modus hidden: die Tabelle ist samt Titel ausgeblendet.
- read-only / disabled / ohne Schreibrecht: die Tabelle zeigt ihre Zeilen während der Bearbeitung nur an (kein Hinzufügen, kein Löschen, nicht editierbare Zellen; ein Detaildialog öffnet seine Zeile nur zur Ansicht).
- Der Modus wird bei jedem Zustandswechsel des Formulars neu berechnet und während der Bearbeitung sofort, wenn sich ein Attribut ändert, das der ModeSelector liest.
Wechselt der Modus während der Bearbeitung, bleiben bereits vorgenommene Änderungen an den Zeilen erhalten und werden beim Speichern übernommen - wie der Wert eines ausgeblendeten Felds.
Nebenbei behoben:
- Wechselt das Formular auf ein Objekt, dessen Typ das Attribut nicht hat (oder auf kein Objekt), zeigte die Tabelle weiter die Zeilen des vorigen Objekts; sie zeigt jetzt keine Zeilen.
- Die Client-Komponente TLPanel (Rahmen der Kompositionstabelle) beachtete den allgemeinen Zustand hidden eines Controls nicht; ein verborgenes Panel blieb sichtbar. Es wird jetzt ausgeblendet und behält dabei seinen Inhalt.
In der React-Demo (tl-demo-react, Reiter "Auswahl + Formular" bzw. Bearbeiten-Dialog im Reiter "Tabelle") blendet "Teile ausblenden" die Teile-Tabelle aus, "Felder gesperrt" macht sie nur lesbar.