diff --git a/components/ILIAS/UI/UI.php b/components/ILIAS/UI/UI.php index 395619bf91c2..91a455d14ae3 100644 --- a/components/ILIAS/UI/UI.php +++ b/components/ILIAS/UI/UI.php @@ -384,7 +384,9 @@ public function init( $internal[UI\Implementation\Component\Table\Action\Factory::class] = static fn() => new UI\Implementation\Component\Table\Action\Factory(); $internal[UI\Implementation\Component\Table\DataRowBuilder::class] = static fn() => - new UI\Implementation\Component\Table\DataRowBuilder(); + new UI\Implementation\Component\Table\DataRowBuilder( + $pull[Data\Factory::class] + ); $internal[UI\Implementation\Component\Table\OrderingRowBuilder::class] = static fn() => new UI\Implementation\Component\Table\OrderingRowBuilder(); diff --git a/components/ILIAS/UI/src/Component/Table/DataRetrievalWithHeaderSummary.php b/components/ILIAS/UI/src/Component/Table/DataRetrievalWithHeaderSummary.php new file mode 100644 index 000000000000..0522a201142a --- /dev/null +++ b/components/ILIAS/UI/src/Component/Table/DataRetrievalWithHeaderSummary.php @@ -0,0 +1,41 @@ + + */ + public function getHeaderSummary( + DataFactory $data_factory, + array $visible_column_ids, + mixed $filter_data, + mixed $additional_parameters + ): array; +} diff --git a/components/ILIAS/UI/src/Component/Table/DataRow.php b/components/ILIAS/UI/src/Component/Table/DataRow.php index 4662364f80c9..dccafcf9c495 100755 --- a/components/ILIAS/UI/src/Component/Table/DataRow.php +++ b/components/ILIAS/UI/src/Component/Table/DataRow.php @@ -20,9 +20,9 @@ namespace ILIAS\UI\Component\Table; -use ILIAS\UI\Component\Table\Column\Column; -use ILIAS\UI\Component\Table\Action\Action; -use ILIAS\UI\Component\Component; +use ILIAS\UI\Component\Table\Column\Column; +use ILIAS\UI\Component\Table\Action\Action; +use ILIAS\UI\Component\Component; interface DataRow extends Component { diff --git a/components/ILIAS/UI/src/Component/Table/DataRowBuilder.php b/components/ILIAS/UI/src/Component/Table/DataRowBuilder.php index 9775a9d5f429..988a1a4c7fc8 100755 --- a/components/ILIAS/UI/src/Component/Table/DataRowBuilder.php +++ b/components/ILIAS/UI/src/Component/Table/DataRowBuilder.php @@ -26,4 +26,9 @@ interface DataRowBuilder * @param array $record */ public function buildDataRow(string $id, array $record): DataRow; + + /** + * @param array $record + */ + public function buildSummaryRow(array $record): SummaryRow; } diff --git a/components/ILIAS/UI/src/Component/Table/SummaryRow.php b/components/ILIAS/UI/src/Component/Table/SummaryRow.php new file mode 100644 index 000000000000..fbf05859d154 --- /dev/null +++ b/components/ILIAS/UI/src/Component/Table/SummaryRow.php @@ -0,0 +1,34 @@ + + */ + public function getColumns(): array; + + public function getCellContent(string $col_id): ?WordOnlyMarkdown; +} diff --git a/components/ILIAS/UI/src/Implementation/Component/Table/DataRow.php b/components/ILIAS/UI/src/Implementation/Component/Table/DataRow.php index 04b3c1e5d50c..8cf138aef1b1 100755 --- a/components/ILIAS/UI/src/Implementation/Component/Table/DataRow.php +++ b/components/ILIAS/UI/src/Implementation/Component/Table/DataRow.php @@ -24,10 +24,8 @@ use ILIAS\UI\Component\Component; use ILIAS\UI\Implementation\Component\ComponentHelper; -class DataRow implements T\DataRow +class DataRow extends Row implements T\DataRow { - use ComponentHelper; - /** * @var array */ @@ -42,13 +40,19 @@ class DataRow implements T\DataRow * @param array $record */ public function __construct( - protected bool $table_has_singleactions, - protected bool $table_has_multiactions, - protected array $columns, + bool $table_has_singleactions, + bool $table_has_multiactions, + array $columns, protected array $actions, protected string $id, - protected array $record + array $record ) { + parent::__construct( + $table_has_singleactions, + $table_has_multiactions, + $columns, + $record, + ); } public function getId(): string @@ -66,20 +70,6 @@ public function withDisabledAction(string $action_id, bool $disable = true): sta return $clone; } - public function getColumns(): array - { - return $this->columns; - } - - public function tableHasSingleActions(): bool - { - return $this->table_has_singleactions; - } - public function tableHasMultiActions(): bool - { - return $this->table_has_multiactions; - } - public function getActions(): array { return array_filter( diff --git a/components/ILIAS/UI/src/Implementation/Component/Table/DataRowBuilder.php b/components/ILIAS/UI/src/Implementation/Component/Table/DataRowBuilder.php index a000b6e8197e..142950116bff 100755 --- a/components/ILIAS/UI/src/Implementation/Component/Table/DataRowBuilder.php +++ b/components/ILIAS/UI/src/Implementation/Component/Table/DataRowBuilder.php @@ -23,13 +23,19 @@ use ILIAS\UI\Component\Table as T; use ILIAS\UI\Component\Table\Column\Column; use ILIAS\UI\Component\Table\Action\Action; +use ILIAS\Data\Factory as DataFactory; class DataRowBuilder extends RowBuilder implements T\DataRowBuilder { + public function __construct( + protected DataFactory $data_factory + ) { + } + /** * @param array $record */ - public function buildDataRow(string $id, array $record): T\DataRow + public function buildDataRow(string $id, array $record): DataRow { return new DataRow( $this->row_actions !== [], @@ -40,4 +46,15 @@ public function buildDataRow(string $id, array $record): T\DataRow $record ); } + + public function buildSummaryRow(array $record): SummaryRow + { + return new SummaryRow( + $this->row_actions !== [], + $this->table_has_multiactions, + $this->columns, + $this->data_factory, + $record + ); + } } diff --git a/components/ILIAS/UI/src/Implementation/Component/Table/Renderer.php b/components/ILIAS/UI/src/Implementation/Component/Table/Renderer.php index 5f11031c401d..50d8bca4d3c5 100755 --- a/components/ILIAS/UI/src/Implementation/Component/Table/Renderer.php +++ b/components/ILIAS/UI/src/Implementation/Component/Table/Renderer.php @@ -30,6 +30,8 @@ use ILIAS\UI\Implementation\Component\Table\Action\Action; use ILIAS\UI\Implementation\Component\Input\ViewControl\Pagination; use ILIAS\UI\Implementation\Component\Input\NameSource; +use ILIAS\UI\Component\Table\DataRetrievalWithHeaderSummary; +use ILIAS\Data\Text\WordOnlyMarkdown; class Renderer extends AbstractComponentRenderer { @@ -52,6 +54,9 @@ public function render(Component\Component $component, RendererInterface $defaul ) { return $this->renderDataRow($component, $default_renderer); } + if ($component instanceof Component\Table\SummaryRow) { + return $this->renderSummaryRow($component, $default_renderer); + } if ($component instanceof Component\Table\Ordering) { return $this->renderOrderingTable($component, $default_renderer); } @@ -208,7 +213,8 @@ public function renderDataTable(Component\Table\Data $component, RendererInterfa $component->getAdditionalParameters() ); - $rows = $component->getDataRetrieval()->getRows( + $data_retrieval = $component->getDataRetrieval(); + $rows = $data_retrieval->getRows( $component->getRowBuilder(), array_keys($component->getVisibleColumns()), $component->getRange(), @@ -271,7 +277,16 @@ public function renderDataTable(Component\Table\Data $component, RendererInterfa } } - $this->renderTableHeader($default_renderer, $component, $tpl, $sortation_signal, $compensate_col_index); + $header_summary = []; + if ($data_retrieval instanceof DataRetrievalWithHeaderSummary) { + $header_summary = $data_retrieval->getHeaderSummary( + $this->getDataFactory(), + array_keys($component->getVisibleColumns()), + $component->getFilter(), + $component->getAdditionalParameters() + ); + } + $this->renderTableHeader($default_renderer, $component, $tpl, $sortation_signal, $compensate_col_index, $header_summary); return $tpl->get(); } @@ -281,6 +296,7 @@ protected function renderTableHeader( Template $tpl, ?Component\Signal $sortation_signal, int $compensate_col_index, + array $header_summary ): void { $order = $component->getOrder(); $glyph_factory = $this->getUIFactory()->symbol()->glyph(); @@ -324,6 +340,15 @@ protected function renderTableHeader( $tpl->setVariable('COL_TITLE', $col_title); $tpl->setVariable('COL_TYPE', strtolower($col->getType())); $tpl->parseCurrentBlock(); + + if ($header_summary !== []) { + $tpl->setCurrentBlock('header_summary_cell'); + $tpl->setVariable( + 'SUMMARY_CELL_CONTENT', + array_key_exists($col_id, $header_summary) ? $header_summary[$col_id]->toHTML() : '' + ); + $tpl->parseCurrentBlock(); + } } } @@ -333,9 +358,14 @@ protected function renderActionsHeader( Template $tpl, int $compensate_col_count, ): void { + $has_summary = $component instanceof Data + && $component->getDataRetrieval() instanceof DataRetrievalWithHeaderSummary; if ($component->hasSingleActions()) { $tpl->setVariable('COL_INDEX_ACTION', (string) $component->getColumnCount() + $compensate_col_count); $tpl->setVariable('COL_TITLE_ACTION', $this->txt('actions')); + if ($has_summary) { + $tpl->touchBlock('header_summary_singleact'); + } } if ($component->hasMultiActions()) { @@ -348,6 +378,9 @@ protected function renderActionsHeader( $select_none = $glyph_factory->close()->withOnClick($signal); $tpl->setVariable('SELECTION_CONTROL_SELECT', $default_renderer->render($select_all)); $tpl->setVariable('SELECTION_CONTROL_DESELECT', $default_renderer->render($select_none)); + if ($has_summary) { + $tpl->touchBlock('header_summary_multiact'); + } } if ($component instanceof Component\Table\Ordering) { @@ -549,16 +582,29 @@ public function renderDataRow(Component\Table\DataRow $component, RendererInterf { $cell_tpl = $this->getTemplate("tpl.datacell.html", true, true); $this->fillCells($component, $cell_tpl, $default_renderer); + $this->fillActions($component, $cell_tpl, $default_renderer); + return $cell_tpl->get(); + } - + public function renderSummaryRow(Component\Table\SummaryRow $component, RendererInterface $default_renderer): string + { + $cell_tpl = $this->getTemplate("tpl.summarycell.html", true, true); + $this->fillCells($component, $cell_tpl, $default_renderer); + if ($component->tableHasMultiActions()) { + $cell_tpl->touchBlock('rowselection_cell'); + } + if ($component->tableHasSingleActions()) { + $cell_tpl->touchBlock('rowaction_cell'); + } return $cell_tpl->get(); } + public function renderOrderingRow(Component\Table\OrderingRow $component, RendererInterface $default_renderer): string { $cell_tpl = $this->getTemplate("tpl.orderingcell.html", true, true); $this->fillCells($component, $cell_tpl, $default_renderer); - + $this->fillActions($component, $cell_tpl, $default_renderer); if ($component->isOrderingDisabled()) { return $cell_tpl->get(); @@ -582,12 +628,15 @@ public function getNewDedicatedName(string $dedicated_name): string ->withValue($component->getPosition() * 10); $cell_tpl->setVariable('ORDER_INPUT', $default_renderer->render($input)); + $drag_handle = $this->getUIFactory()->symbol()->glyph()->dragHandle(); + $drag_handle = $default_renderer->render($drag_handle); + $cell_tpl->setVariable('DRAG_HANDLE', $drag_handle); return $cell_tpl->get(); } protected function fillCells( - Component\Table\DataRow $row, + Component\Table\DataRow|Component\Table\SummaryRow $row, Template $cell_tpl, RendererInterface $default_renderer ) { @@ -602,11 +651,20 @@ protected function fillCells( if ($cell_content instanceof Component\Component) { $cell_content = $default_renderer->render($cell_content); } + if ($cell_content instanceof WordOnlyMarkdown) { + $cell_content = $cell_content->toHTML(); + } $cell_tpl->setVariable('CELL_CONTENT', $cell_content); $cell_tpl->setVariable('CELL_COL_TITLE', $row->getColumns()[$col_id]->getTitle()); $cell_tpl->parseCurrentBlock(); } + } + protected function fillActions( + Component\Table\DataRow|Component\Table\SummaryRow $row, + Template $cell_tpl, + RendererInterface $default_renderer + ) { if ($row->tableHasMultiActions()) { $cell_tpl->setVariable('ROW_ID', $row->getId()); } @@ -617,14 +675,6 @@ protected function fillCells( ); $cell_tpl->setVariable('ACTION_CONTENT', $default_renderer->render($row_actions_dropdown)); } - - if ($row instanceof Component\Table\OrderingRow) { - if (!$row->isOrderingDisabled()) { - $drag_handle = $this->getUIFactory()->symbol()->glyph()->dragHandle(); - $drag_handle = $default_renderer->render($drag_handle); - $cell_tpl->setVariable('DRAG_HANDLE', $drag_handle); - } - } } /** diff --git a/components/ILIAS/UI/src/Implementation/Component/Table/Row.php b/components/ILIAS/UI/src/Implementation/Component/Table/Row.php new file mode 100644 index 000000000000..b7924a93dbe3 --- /dev/null +++ b/components/ILIAS/UI/src/Implementation/Component/Table/Row.php @@ -0,0 +1,58 @@ + $columns + * @param array $record + */ + public function __construct( + protected bool $table_has_singleactions, + protected bool $table_has_multiactions, + protected array $columns, + protected array $record + ) { + } + + public function getColumns(): array + { + return $this->columns; + } + + public function tableHasSingleActions(): bool + { + return $this->table_has_singleactions; + } + + public function tableHasMultiActions(): bool + { + return $this->table_has_multiactions; + } +} diff --git a/components/ILIAS/UI/src/Implementation/Component/Table/SummaryRow.php b/components/ILIAS/UI/src/Implementation/Component/Table/SummaryRow.php new file mode 100644 index 000000000000..f74488d1b634 --- /dev/null +++ b/components/ILIAS/UI/src/Implementation/Component/Table/SummaryRow.php @@ -0,0 +1,53 @@ +record)) { + return null; + } + return $this->data_factory->text()->markdown()->wordOnly( + $this->record[$col_id] + ); + } +} diff --git a/components/ILIAS/UI/src/examples/Table/Data/base.php b/components/ILIAS/UI/src/examples/Table/Data/base.php index 4c2cc503725b..b0a5fa08e1d6 100755 --- a/components/ILIAS/UI/src/examples/Table/Data/base.php +++ b/components/ILIAS/UI/src/examples/Table/Data/base.php @@ -229,9 +229,11 @@ protected function getRecords(?Range $range = null, ?Order $order = null): array ]; if ($order) { list($order_field, $order_direction) = $order->join([], fn($ret, $key, $value) => [$key, $value]); - usort($records, fn($a, $b) => $a[$order_field] <=> $b[$order_field]); - if ($order_direction === 'DESC') { - $records = array_reverse($records); + if (array_key_exists($order_field, current($records))) { + usort($records, fn($a, $b) => $a[$order_field] <=> $b[$order_field]); + if ($order_direction === 'DESC') { + $records = array_reverse($records); + } } } if ($range) { diff --git a/components/ILIAS/UI/src/examples/Table/Data/summary_rows.php b/components/ILIAS/UI/src/examples/Table/Data/summary_rows.php new file mode 100644 index 000000000000..e14c5d31697e --- /dev/null +++ b/components/ILIAS/UI/src/examples/Table/Data/summary_rows.php @@ -0,0 +1,177 @@ + + * ILIAS shows the rendered Component. + * --- + */ +function summary_rows() +{ + global $DIC; + $f = $DIC['ui.factory']; + $r = $DIC['ui.renderer']; + $df = new DataFactory(); + $request = $DIC->http()->request(); + + $columns = [ + 'id' => $f->table()->column()->number("id"), + 'transaction' => $f->table()->column()->boolean( + "Transaction", + $f->symbol()->glyph()->down(), + $f->symbol()->glyph()->up()->withHighlight(), + ), + 'value' => $f->table()->column()->number("Value") + ->withUnit('€', I\Column\Number::UNIT_POSITION_FORE) + ->withDecimals(2) + ->withHighlight(true) + ]; + + $here_uri = $df->uri($DIC->http()->request()->getUri()->__toString()); + $url_builder = new URLBuilder($here_uri); + $ns = ['datatable', 'summary']; + list($url_builder, $action_parameter_token, $row_id_token) = + $url_builder->acquireParameters($ns, "ta", "ids"); + $actions = [ + 'some action' => $f->table()->action()->standard( + 'act', + $url_builder->withParameter($action_parameter_token, "act"), + $row_id_token + ) + ]; + + /** + * implement DataRetrievalWithHeaderSummary to add a summary-row to the header + */ + $data_retrieval = new class () implements I\DataRetrievalWithHeaderSummary { + public function getHeaderSummary( + DataFactory $data_factory, + array $visible_column_ids, + mixed $filter_data, + mixed $additional_parameters + ): array { + $sum_total = array_reduce( + $this->getRecords(), + fn($total, $r) => $total += $r['value'] + ); + $sum_total = $data_factory->text()->markdown()->wordOnly( + 'balance (all records): **€ ' . $sum_total . '**' + ); + return ['value' => $sum_total]; + } + + public function getRows( + I\DataRowBuilder $row_builder, + array $visible_column_ids, + Range $range, + Order $order, + mixed $additional_viewcontrol_data, + mixed $filter_data, + mixed $additional_parameters + ): \Generator { + $records = $this->getRecords($range, $order); + $counter = 0; + $sum = 0; + foreach ($records as $idx => $record) { + $row_id = (string) $record['id']; + $record['transaction'] = $record['value'] >= 0; + yield $row_builder->buildDataRow($row_id, $record); + + $sum += $record['value']; + $counter += 1; + $subtotal = 'subtotal: **€' . $sum . '**'; + if ($counter == 5) { + yield $row_builder->buildSummaryRow(['value' => $subtotal]); + $sum = 0; + $counter = 0; + } + } + if ($counter > 0) { + yield $row_builder->buildSummaryRow(['value' => $subtotal]); + } + + $total = 'total: **€' + . array_reduce($records, fn($total, $r) => $total += $r['value']) + . '**'; + yield $row_builder->buildSummaryRow(['value' => $total]); + } + + public function getTotalRowCount( + mixed $additional_viewcontrol_data, + mixed $filter_data, + mixed $additional_parameters + ): ?int { + return count($this->getRecords()); + } + + protected function getRecords(?Range $range = null, ?Order $order = null): array + { + $records = [ + ['id' => 482, 'value' => 712.23], + ['id' => 915, 'value' => 654.89], + ['id' => 237, 'value' => -128.45], + ['id' => 768, 'value' => 945.12], + ['id' => 391, 'value' => 523.77], + ['id' => 654, 'value' => -837.50], + ['id' => 102, 'value' => 275.64], + ['id' => 846, 'value' => 999.99], + ['id' => 529, 'value' => -412.08], + ['id' => 783, 'value' => -601.34], + ['id' => 315, 'value' => -350.70], + ['id' => 209, 'value' => -780.15] + ]; + + if ($order) { + list($order_field, $order_direction) = $order->join([], fn($ret, $key, $value) => [$key, $value]); + if (array_key_exists($order_field, current($records))) { + usort($records, fn($a, $b) => $a[$order_field] <=> $b[$order_field]); + if ($order_direction === 'DESC') { + $records = array_reverse($records); + } + } + } + if ($range) { + $records = array_slice($records, $range->getStart(), $range->getLength()); + } + return $records; + } + }; + + $table = $f->table() + ->data($data_retrieval, 'summaries', $columns) + ->withId('example_summary') + ->withActions($actions) + ->withRequest($request); + + return $r->render($table); +} diff --git a/components/ILIAS/UI/src/templates/default/Table/tpl.datatable.html b/components/ILIAS/UI/src/templates/default/Table/tpl.datatable.html index b3cbd734bfa4..ccce529faec3 100755 --- a/components/ILIAS/UI/src/templates/default/Table/tpl.datatable.html +++ b/components/ILIAS/UI/src/templates/default/Table/tpl.datatable.html @@ -33,6 +33,20 @@

{TITLE}

{COL_TITLE_ACTION} + + + + + + + + {SUMMARY_CELL_CONTENT} + + + + + + diff --git a/components/ILIAS/UI/src/templates/default/Table/tpl.summarycell.html b/components/ILIAS/UI/src/templates/default/Table/tpl.summarycell.html new file mode 100644 index 000000000000..680a8f537fb3 --- /dev/null +++ b/components/ILIAS/UI/src/templates/default/Table/tpl.summarycell.html @@ -0,0 +1,15 @@ + + + + + + +colspan="{COL_SPAN}" tabindex="-1"> + {CELL_COL_TITLE}: {CELL_CONTENT} + + + + + + + diff --git a/components/ILIAS/UI/tests/Component/Table/DataRendererTest.php b/components/ILIAS/UI/tests/Component/Table/DataRendererTest.php index 7ee5d2d11c2d..b04b3234f59e 100644 --- a/components/ILIAS/UI/tests/Component/Table/DataRendererTest.php +++ b/components/ILIAS/UI/tests/Component/Table/DataRendererTest.php @@ -58,9 +58,10 @@ public function p_renderTableHeader( TestDefaultRenderer $default_renderer, I\Table\Data $component, $tpl, - ?I\Signal $sortation_signal + ?I\Signal $sortation_signal, + array $header_summary ) { - $this->renderTableHeader($default_renderer, $component, $tpl, $sortation_signal, 1); + $this->renderTableHeader($default_renderer, $component, $tpl, $sortation_signal, 1, $header_summary); } public function p_renderActionsHeader( TestDefaultRenderer $default_renderer, @@ -197,7 +198,13 @@ public function getTotalRowCount( $sortation_signal->addOption('value', 'f1:ASC'); $table = $this->getUIFactory()->table()->data($data, '', $columns) ->withRequest($this->getDummyRequest()); - $renderer->p_renderTableHeader($this->getDefaultRenderer(), $table, $tpl, $sortation_signal); + $renderer->p_renderTableHeader( + $this->getDefaultRenderer(), + $table, + $tpl, + $sortation_signal, + [] + ); $actual = $this->brutallyTrimHTML($tpl->get()); $expected = <<getUIFactory()->table()->data($data, '', $columns) ->withRequest($this->getDummyRequest()); - $renderer->p_renderTableHeader($this->getDefaultRenderer(), $table, $tpl, $sortation_signal); + $renderer->p_renderTableHeader($this->getDefaultRenderer(), $table, $tpl, $sortation_signal, []); $actual = $this->brutallyTrimHTML($tpl->get()); $expected = << @@ -389,7 +396,7 @@ public function testDataTableRowBuilder() 'a2' => $f->standard('label2', $builder, $token) ]; - $rb = (new I\Table\DataRowBuilder()) + $rb = (new I\Table\DataRowBuilder($this->getDataFactory())) ->withMultiActionsPresent(true) ->withSingleActions($actions) ->withVisibleColumns($columns); @@ -505,4 +512,111 @@ public function getTotalRowCount( // check that the cell contains the default message. $this->assertTrue(str_contains($html, $translation)); } + + #[\PHPUnit\Framework\Attributes\Depends('testDataTableRowBuilder')] + public function testDataTableSummaryRowFromBuilder(array $params): I\Table\SummaryRow + { + list($rb, $columns, $actions) = $params; + $record = [ + 'f2' => 'v2', + ]; + $row = $rb->buildSummaryRow($record); + + $this->assertEquals( + $columns, + $row->getColumns() + ); + $this->assertInstanceOf( + \ILIAS\Data\Text\WordOnlyMarkdown::class, + $row->getCellContent('f2') + ); + $this->assertEquals( + "

{$record['f2']}

\n", + $row->getCellContent('f2')->toHTML()->__toString() + ); + return $row; + } + + #[\PHPUnit\Framework\Attributes\Depends('testDataTableSummaryRowFromBuilder')] + public function testDataTableRenderSummaryRow(I\Table\SummaryRow $row): void + { + $actual = $this->brutallyTrimHTML($this->getDefaultRenderer()->render($row)); + $expected = << +Field 1: +Field 2: +

v2

+ +Field 3: + +EOT; + $expected = $this->brutallyTrimHTML($expected); + $this->assertEquals($expected, $actual); + } + + + + public function testDataTableRenderHeaderSummaryRow(): void + { + $data = new class () implements ILIAS\UI\Component\Table\DataRetrievalWithHeaderSummary { + public function getRows( + Component\Table\DataRowBuilder $row_builder, + array $visible_column_ids, + Data\Range $range, + Data\Order $order, + mixed $additional_viewcontrol_data, + mixed $filter_data, + mixed $additional_parameters + ): \Generator { + yield from []; + } + public function getTotalRowCount( + mixed $additional_viewcontrol_data, + mixed $filter_data, + mixed $additional_parameters + ): ?int { + return 0; + } + public function getHeaderSummary( + \ILIAS\Data\Factory $data_factory, + array $visible_column_ids, + mixed $filter_data, + mixed $additional_parameters + ): array { + return [ + 'f1' => $data_factory->text()->markdown()->wordOnly('Summary F1'), + 'f2' => $data_factory->text()->markdown()->wordOnly('Summary F2') + ]; + } + + }; + + $f = $this->getColumnFactory(); + $columns = [ + 'f1' => $f->text("Field 1")->withIndex(1), + 'f2' => $f->text("Field 2")->withIndex(2)->withIsSortable(false), + 'f3' => $f->number("Field 3")->withIndex(3) + ]; + $table = $this->getUIFactory()->table()->data($data, '', $columns) + ->withRequest($this->getDummyRequest()); + + $actual = $this->brutallyTrimHTML( + $this->getDefaultRenderer()->render($table) + ); + $expected = << + +

Summary F1

+ + +

Summary F2

+ + + + +EOT; + $expected = $this->brutallyTrimHTML($expected); + $this->assertStringContainsString($expected, $actual); + } + } diff --git a/components/ILIAS/UI/tests/Component/Table/TableTestBase.php b/components/ILIAS/UI/tests/Component/Table/TableTestBase.php index a2b4b996d771..c3c330220a31 100755 --- a/components/ILIAS/UI/tests/Component/Table/TableTestBase.php +++ b/components/ILIAS/UI/tests/Component/Table/TableTestBase.php @@ -82,7 +82,9 @@ protected function getTableFactory(): C\Table\Factory new C\Table\Column\Factory($this->getLanguage()), new C\Table\Action\Factory(), $this->getMockStorage(), - new C\Table\DataRowBuilder(), + new C\Table\DataRowBuilder( + new \ILIAS\Data\Factory() + ), new C\Table\OrderingRowBuilder() ); } @@ -97,7 +99,7 @@ public function offsetExists(mixed $offset): bool } public function offsetGet(mixed $offset): mixed { - if(!$this->offsetExists($offset)) { + if (!$this->offsetExists($offset)) { return null; } return $this->data[$offset]; diff --git a/components/ILIAS/UI/tests/InitUIFramework.php b/components/ILIAS/UI/tests/InitUIFramework.php index 6fa475ecbc95..8bd094ef9ed3 100755 --- a/components/ILIAS/UI/tests/InitUIFramework.php +++ b/components/ILIAS/UI/tests/InitUIFramework.php @@ -177,7 +177,9 @@ public function getRefreshIntervalInMs(): int ); }; $c["ui.factory.table"] = function ($c) { - $data_row_builder = new ILIAS\UI\Implementation\Component\Table\DataRowBuilder(); + $data_row_builder = new ILIAS\UI\Implementation\Component\Table\DataRowBuilder( + $c["ui.data_factory"] + ); $ordering_row_builder = new ILIAS\UI\Implementation\Component\Table\OrderingRowBuilder(); return new ILIAS\UI\Implementation\Component\Table\Factory( $c["ui.signal_generator"],