enhancement
major
minor
defect
critical
major
minor
Problem
The columns of a table are fixed when the table is built. To show or hide a column based on a channel value (e.g., using a toggle switch), you must rebuild the entire table.
Version: 8.0.0-alpha12, React View Layer (tl-layout-view/tl-layout-react).
Reproduction (Prime)
Documents and Links (prime/project/documents.view.xml): The “Context” column should only appear when the “Include Subordinate Objects” toggle is enabled.
Prime: Both tables are contained within a <switch rebuild="true"> controlled by the toggle switch and receive the column via <dynamic-columns>. When the toggle is switched, the table is rebuilt.
Expected Behavior
A column has a condition based on channels that is evaluated without rebuilding the table.
Solution
Column declarations in a React table are given an existence condition:
- `exists-if` on `<column>`, `<computed-column> `, and `<embedded-columns> ` (where it applies to all embedded columns; the embedded column declarations can also each have their own condition, and both must be satisfied). The condition does not consider a row, but rather the inputs: for <computed-column> and <embedded-columns>, the declaration’s own inputs; for <column> (which has no inputs of its own), those of the table or the surrounding embedding.
- column-exists-if on <dynamic-columns>: evaluated per column object; treats the column object as $column (or the name from column-as) and the declaration’s own inputs.
Example:
<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`)" .../>
As long as the condition is not met, the column does not exist for the table: It is not displayed and is not offered in the column selection; sorting, filtering, or grouping based on it has no effect. The user’s configuration (order, shown/hidden, width, pinned) is preserved and takes effect again as soon as the condition is met; the condition itself is not saved in the user’s personal settings. The existing `visible="false" ` / `column-visible ` (column starts hidden but is selectable) remains unchanged.
The conditions are re-evaluated whenever their input channels change; the table updates its column list without being rebuilt (selection, sorting, and scroll position remain). This applies to both read-only and editable tables, as well as to <tree-table>.
The set of column objects from <dynamic-columns> is still calculated when the table is built; only which of them exist is evaluated in real time.
Also Fixed
A channel specified only as the input for a column (not for the table) was not previously monitored: If it changed, cells, filters, etc., for that column continued to display the old value. Now, when such a channel changes, the table rebuilds its cells and refilters the rows (without re-reading the rows).
Technical
- TableView.setAbsentColumns(Set) / absentColumns(): a non-persistent set of columns that do not currently exist.
- TableViewControl.setAbsentColumns(Set): transfers columns and rows to the client in an update.
- ColumnSetup.exists() (ChannelCondition), ColumnExistence tracks the conditions of a table’s columns.
- Demo: tl-demo-react, Demos → Table Columns, “Conditional Columns” tab.