enhancement
major
minor
defect
critical
major
minor
minor
#30209
React-Tabelle: Spalten abhängig von Kanalwerten ein- und ausblenden (exists-if)
Problem
Die Spalten einer Tabelle stehen fest, wenn die Tabelle gebaut wird. Eine Spalte abhängig von einem Kanalwert ein- oder auszublenden (z. B. über einen Umschalter), geht nur durch Neuaufbau der ganzen Tabelle.
Version: 8.0.0-alpha12, React-View-Layer (tl-layout-view/tl-layout-react).
Reproduktion (Prime)
Dokumente und Links (prime/project/documents.view.xml): Die Spalte „Kontext“ soll nur bei eingeschaltetem Umschalter „inkl. untergeordneter Objekte“ erscheinen.
Prime: Beide Tabellen stehen in einem <switch rebuild="true"> auf dem Umschalter und bekommen die Spalte über <dynamic-columns>. Beim Umschalten wird die Tabelle neu gebaut.
Erwartetes Verhalten
Eine Spalte hat eine Bedingung über Kanäle, die ohne Neuaufbau der Tabelle ausgewertet wird.
Lösung
Spalten-Deklarationen einer React-Tabelle bekommen eine Existenzbedingung:
- exists-if an <column>, <computed-column> und <embedded-columns> (dort für alle eingebetteten Spalten; die eingebetteten Spalten-Deklarationen können zusätzlich je eine eigene Bedingung tragen, beide müssen erfüllt sein). Die Bedingung sieht keine Zeile, sondern die Eingänge: bei <computed-column> und <embedded-columns> die eigenen inputs der Deklaration, bei <column> (ohne eigene Eingänge) die der Tabelle bzw. der umgebenden Einbettung.
- column-exists-if an <dynamic-columns>: pro Spaltenobjekt ausgewertet, sieht das Spaltenobjekt als $column (bzw. den Namen aus column-as) und die eigenen inputs der Deklaration.
Beispiel:
<computed-column name="total" inputs="showApproved" exists-if="$showApproved" .../> <dynamic-columns name="milestones" column-as="milestone" inputs="showApproved" column-exists-if="$showApproved || !$milestone.get(`my:Milestone#approved`)" .../>
Solange die Bedingung nicht erfüllt ist, existiert die Spalte für die Tabelle nicht: Sie wird nicht angezeigt und nicht in der Spaltenauswahl angeboten; eine Sortierung, ein Filter oder eine Gruppierung nach ihr wirkt nicht. Die Anordnung des Benutzers (Reihenfolge, ein-/ausgeblendet, Breite, fixiert) bleibt erhalten und gilt wieder, sobald die Bedingung erfüllt ist; die Bedingung selbst wird nicht in der persönlichen Konfiguration gespeichert. Das bestehende visible="false" / column-visible (Spalte startet ausgeblendet, ist aber auswählbar) bleibt unverändert.
Die Bedingungen werden bei jeder Änderung ihrer Eingangskanäle neu ausgewertet; die Tabelle aktualisiert ihre Spaltenliste ohne Neuaufbau (Auswahl, Sortierung und Scrollposition bleiben). Das gilt für die lesende und die editierbare Tabelle sowie für <tree-table>.
Die Menge der Spaltenobjekte von <dynamic-columns> wird weiterhin beim Aufbau der Tabelle berechnet; live ausgewertet wird nur, welche davon existieren.
Mitbehoben
Ein Kanal, der nur als Eingang einer Spalte (nicht der Tabelle) angegeben ist, wurde bisher nicht beobachtet: Änderte er sich, zeigten Zellen, Filter usw. dieser Spalte weiter den alten Wert. Jetzt baut die Tabelle bei einer Änderung eines solchen Kanals ihre Zellen neu auf und filtert die Zeilen neu (ohne die Zeilen neu zu lesen).
Technisch
- TableView.setAbsentColumns(Set) / absentColumns(): nicht persistierte Menge von Spalten, die gerade nicht existieren.
- TableViewControl.setAbsentColumns(Set): überträgt Spalten und Zeilen in einem Update an den Client.
- ColumnSetup.exists() (ChannelCondition), ColumnExistence verfolgt die Bedingungen der Spalten einer Tabelle.
- Demo: tl-demo-react, Demos → Tabellenspalten, Reiter „Bedingte Spalten“.