enhancement
major
minor
major
minor
Sammelticket für ein generisches Formularelement der React-View-Schicht, das ein beliebiges ConfigurationItem bearbeitbar macht. Die einzelnen Punkte werden hier gesammelt und einzeln umgesetzt.
Ausgangslage
Ein Formular der React-View-Schicht kann bisher nur Modellattribute anzeigen: `<field attribute="…"/>` bindet über AttributeFieldControl an ein Attribut des Eingabeobjekts. Ein großer Teil dessen, was eine Anwendung ausmacht, steckt aber in `ConfigurationItem`s.
Das Modul com.top_logic.layout.configedit deckt davon bereits die Struktur ab — ConfigEditorControl baut das Formular über die Properties, ITEM und LIST als aufklappbare Gruppen, PolymorphicItemControl wählt die Implementierung, ConfigListEditorControl fügt Einträge hinzu, entfernt und sortiert sie. Genutzt wird das vom View-Designer (ConfigEditorElement).
Es fehlt aber das, was den Editor allgemein verwendbar macht:
- Kein allgemeiner Einstieg. ConfigEditorElement hängt am DesignTreeNode des View-Designers. Es gibt weder ein Element für eine beliebige Konfiguration aus einem Kanal noch ein Feld-Control, das den Editor für ein config-wertiges Modellattribut einbettet.
- Die Wert-Zuordnung ist dünn. ConfigFieldDispatch kennt boolean, ganze Zahlen, Gleitkommazahlen und Aufzählungen — alles Übrige bekommt eine Texteingabe. Damit landet eine Date-, ResKey-, ThemeImage-, Class- oder TLModelPartRef-Property in einem Textfeld, dessen Eingabe als roher String in eine typisierte Property geschrieben wird. Der ConfigurationValueProvider der Property wird nirgends benutzt, @Options-Optionslisten ebenso wenig — nur Aufzählungen bekommen eine Auswahl.
- Property-Arten fehlen: MAP, ARRAY und COMPLEX werden übersprungen.
- Kein Bearbeitungsmodus. ConfigFieldModel schreibt jede Eingabe sofort in das Item; es gibt keine Arbeitskopie und keine Anbindung an Bearbeiten/Übernehmen/Abbrechen eines <form>.
- Keine Validierung der Constraints beim Übernehmen (Pflichtfelder werden nur markiert).
Punkte
1. Wert-Zuordnung vollständig machen
Aus der festen Fallunterscheidung in ConfigFieldDispatch wird ein konfigurierbarer Dienst nach dem Vorbild von FieldControlService — konfigurierbar, weil der TL-Script-Editor in tl-model-search-react oberhalb von configedit liegt und sein Bedienelement von außen beitragen muss. Entschieden wird in dieser Reihenfolge: Annotation an der Property, Optionsliste der Property, konfigurierte Zuordnung nach Werttyp, eingebauter Fallback.
Der Kern steckt im Fallback: Hat eine Property einen ConfigurationValueProvider, wird er zum Parsen und Formatieren benutzt statt der Zuweisung eines rohen String; eine ungültige Eingabe wird zum Feldfehler wie bei einem Modellattribut. Die Optionsauflösung übernimmt Fields.optionProvider(…), das @Options samt Argument-Verweisen schon liefert. Darauf setzen auf: Datums- und Zeitselektor für Date-Werte (welche Art, sagt das Format), I18N-Control für ResKey, Implementierungs-Auswahl für Class- und Instanz-Properties, Passwortfeld bei @Encrypted.
Der Punkt behebt denselben Mangel auch im View-Designer.
2. Fehlende Property-Arten
- ARRAY
- wie LIST, derselbe Listen-Editor.
- MAP
- Einträge als Gruppen, Schlüssel aus der mit @Key annotierten Property; Hinzufügen über einen Schlüssel-Dialog (klassisches Vorbild: MapEntryBuilderDialog).
- COMPLEX
- Wert über den ConfigurationValueProvider, also dasselbe Format-Feld wie in (1).
DERIVED-Properties bleiben zunächst übersprungen.
3. Bearbeitungsmodus, Arbeitskopie, Validierung
Die Arbeitskopie wird eine Betriebsart des Editors, kein Zwang — der View-Designer speichert die Ansicht als Ganzes und braucht das sofortige Schreiben weiter. Beim Betreten des Bearbeitungsmodus entsteht eine Kopie, auf der alle Felder arbeiten. „Übernehmen" prüft Pflicht-Properties und die Constraints der Konfiguration; Verstöße erscheinen an den betreffenden Feldern und der Bearbeitungsmodus bleibt stehen. „Abbrechen" verwirft die Kopie.
4. Einstiegspunkte
- <config-form>
- ein UIElement, dessen Eingabekanal ein ConfigurationItem liefert; Bearbeitungsmodus optional wie bei <form withEditMode="true"/>. Damit sind auch Konfigurationen erreichbar, die an keinem Modellattribut hängen.
- Feld-Control
- ein ReactFieldControlProvider, im FieldControlService für config-wertige Typen registriert — bei einwertigem Attribut der Item-Editor, bei mehrwertigem der Listen-Editor. Damit trägt das gewöhnliche <form> ein config-wertiges Attribut, ohne vom Config-Editor zu wissen.
5. Erster Einsatz: Annotationen im Model-Editor
Der React-Model-Editor (admin/model/model-editor.view.xml in tl-dev-tools) zeigt in seinen Detail-Formularen bisher nur den Namen. Die eigentliche Aussage eines Modellelements steckt aber in seinen Annotationen: tl.model:TLModelPart#annotations ist ein mehrwertiges Attribut vom Datentyp tl.model:TLAnnotation, dessen Werte polymorphe Konfigurationen sind.
Mit (1) bis (4) werden sie bearbeitbar. Dazu kommt die kontextabhängige Liste der für ein Element zulässigen Annotationstypen — das Pendant zu PartAnnotationOptions der klassischen Oberfläche, gefiltert nach Elementart (Modul, Klasse, Enumeration, Attribut, Referenz, Klassifikator) und @TargetType. Nur diese bietet das „+" der Liste an.