Skip to content

IBX-12039: Added table component extension api#29

Open
ciastektk wants to merge 8 commits into
5.0from
ibx-12039-table-component-extension-api
Open

IBX-12039: Added table component extension api#29
ciastektk wants to merge 8 commits into
5.0from
ibx-12039-table-component-extension-api

Conversation

@ciastektk

@ciastektk ciastektk commented Jul 9, 2026

Copy link
Copy Markdown
🎫 Issue IBX-12039

Related PRs:

Description:

Closes the gaps that blocked ibexa.Table from expressing the admin-ui Versions tab tables,
so the component can become the single canonical table extension point (instead of the
column-provider mechanism proposed in admin-ui#1960):

  • type / variant props — table identity for PostMount listeners. Guarding on
    getDataType() alone fails when different tables share a row type (all four versions
    tables carry VersionInfo) or when the dataset is empty (getDataType() returns null).
  • headline prop + header/header_actions template blocks — the table headline is
    rendered by the component and can be overwritten by a listener (used by ibexa/workflow's
    "Drafts to review"). Not rendered when null, so existing usages are untouched.
  • class prop (defaults to ibexa-table--last-column-sticky) — replaces the hardcoded modifier
    when set (versions tables use ibexa-table--draft-conflict), '' clears it; default output is
    byte-identical.
  • Column::$options (header_class / cell_class) via addColumn(..., options: [...])
    per-column th/td modifier classes (checkbox, close-left cells).
  • fullData mount prop + getFullData(): ?iterable — whole dataset next to the rendered page,
    so listeners can decide column applicability independently of pagination; null when the mount
    site gave none — falling back to page data is the caller's explicit choice (?? getData()).
  • before_table / after_table blocks — anchor points inside the scrollable wrapper
    (used to keep the admin-ui-versions-table-before component-group anchor).

All changes are additive with safe defaults — the existing render snapshots pass unchanged.
The integration test suite additionally proves the trickiest consumer pattern: a checkbox
column rendering form_widget() via TemplateWrapper::renderBlock() inside
form_start()/form_end() without widget duplication.

For QA:

Covered by admin-ui/workflow/TM PRs (this PR alone changes no rendered output).

Comment thread src/bundle/Templating/Twig/Components/Table/Column.php Outdated
Comment thread src/bundle/Templating/Twig/Components/Table.php Outdated
Comment thread src/bundle/Templating/Twig/Components/Table.php
*/
public function getFullData(): iterable
{
return $this->fullData ?? $this->data;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is that a secure fallback? If we don't have fullData (as it's optional), it could be misleading for callers that they want fullData but are receiving data silently instead.

I'd recommend to just return $this->fullData as ?iterable type and and caller side it can decide if is fallbacking to $this->data or not (that would be its explicit decision).

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed: f54a10a

Comment thread tests/bundle/Templating/Twig/Components/TableTest.php Outdated
Comment thread tests/integration/Templating/Twig/Components/TableFormWidgetRenderingTest.php Outdated
Comment thread tests/integration/Templating/Twig/Components/TableFormWidgetRenderingTest.php Outdated
Comment thread tests/integration/Templating/Twig/Components/TableTest.php Outdated
@ciastektk ciastektk force-pushed the ibx-12039-table-component-extension-api branch from 81b2ae2 to 00af091 Compare July 10, 2026 10:04
@ciastektk ciastektk requested a review from bnowak July 10, 2026 11:24

@bnowak bnowak left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💪

* @phpstan-param callable(mixed, Column): string $renderer
*
* @param array<string, string> $options presentation hints, see {@see Column::__construct()}
* @phpstan-param array{header_class?: string, cell_class?: string} $options presentation

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can get that phpstan type from Column definition as single source of truth

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed: 58ee183addColumn() now imports ColumnOptions from Column via @phpstan-import-type.

Comment thread src/bundle/Templating/Twig/Components/Table.php
<thead>
<tr class="ibexa-table__row ibexa-table__row--header">
<th class="ibexa-table__header-cell ">
<th class="ibexa-table__header-cell ">

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should there be additional space at the end of class? The same in <td/> tag below.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed: 031ed76 — class lists are now built with filter|join, so separators only appear between present classes. Only table_column_priority snapshot changed; the other four already had no trailing spaces.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants