From 20478c04b1f03819eca457d6c8b9deb35977f77d Mon Sep 17 00:00:00 2001 From: Nils Haagen Date: Mon, 11 Nov 2024 13:16:35 +0100 Subject: [PATCH] UI/Navigation: add some Components to SegmentContent, expand example --- .../classes/Dependencies/InitUIFramework.php | 2 -- .../ILIAS/UI/src/Component/Image/Image.php | 4 +-- .../Input/Container/Form/Standard.php | 3 +- .../Listing/CharacteristicValue/Text.php | 4 +-- .../UI/src/Component/Navigation/Factory.php | 2 +- ...egmentContent.php => IsSegmentContent.php} | 4 +-- .../Component/Navigation/Sequence/Segment.php | 8 ++--- .../Navigation/Sequence/SegmentBuilder.php | 2 +- .../UI/src/Component/Table/Presentation.php | 3 +- .../ILIAS/UI/src/Component/Table/Table.php | 3 +- .../Navigation/Sequence/Renderer.php | 18 ++++++----- .../Component/Navigation/Sequence/Segment.php | 4 +-- .../Navigation/Sequence/SegmentBuilder.php | 2 +- .../Navigation/Sequence/Sequence.php | 14 ++++----- .../src/examples/Navigation/Sequence/base.php | 31 +++++++++++++++++-- .../default/Navigation/tpl.sequence.html | 11 +++++-- components/ILIAS/UI/tests/MainFactoryTest.php | 3 +- 17 files changed, 76 insertions(+), 42 deletions(-) rename components/ILIAS/UI/src/Component/Navigation/Sequence/{SegmentContent.php => IsSegmentContent.php} (91%) diff --git a/components/ILIAS/Init/classes/Dependencies/InitUIFramework.php b/components/ILIAS/Init/classes/Dependencies/InitUIFramework.php index a27835bb35be..da04d1bf0255 100755 --- a/components/ILIAS/Init/classes/Dependencies/InitUIFramework.php +++ b/components/ILIAS/Init/classes/Dependencies/InitUIFramework.php @@ -389,8 +389,6 @@ public function getRefreshIntervalInMs(): int ); }; - - // currently this is will be a session storage because we cannot store // data on the client, see https://mantis.ilias.de/view.php?id=38503. $c["ui.storage"] = function ($c): ArrayAccess { diff --git a/components/ILIAS/UI/src/Component/Image/Image.php b/components/ILIAS/UI/src/Component/Image/Image.php index 0a48ba1b2273..0991b37f7ce2 100755 --- a/components/ILIAS/UI/src/Component/Image/Image.php +++ b/components/ILIAS/UI/src/Component/Image/Image.php @@ -25,7 +25,7 @@ use ILIAS\UI\Component\Signal; use ILIAS\UI\Component\Component; use ILIAS\UI\Component\Layout\Alignment\Block; -use ILIAS\UI\Component\Navigation\Sequence\SegmentContent; +use ILIAS\UI\Component\Navigation\Sequence\IsSegmentContent; /** * This describes how a glyph could be modified during construction of UI. @@ -33,7 +33,7 @@ * Interface Image * @package ILIAS\UI\Component\Image */ -interface Image extends Component, JavaScriptBindable, Clickable, Block, SegmentContent +interface Image extends Component, JavaScriptBindable, Clickable, Block, IsSegmentContent { /** * Types of images diff --git a/components/ILIAS/UI/src/Component/Input/Container/Form/Standard.php b/components/ILIAS/UI/src/Component/Input/Container/Form/Standard.php index 9bcb697a9239..1f4a1f1ec2b5 100755 --- a/components/ILIAS/UI/src/Component/Input/Container/Form/Standard.php +++ b/components/ILIAS/UI/src/Component/Input/Container/Form/Standard.php @@ -21,11 +21,12 @@ namespace ILIAS\UI\Component\Input\Container\Form; use ILIAS\UI\Component\Prompt\IsPromptContent; +use ILIAS\UI\Component\Navigation\Sequence\IsSegmentContent; /** * This describes a standard form. */ -interface Standard extends FormWithPostURL, IsPromptContent +interface Standard extends FormWithPostURL, IsPromptContent, IsSegmentContent { /** * Sets the label of the submit button of the form diff --git a/components/ILIAS/UI/src/Component/Listing/CharacteristicValue/Text.php b/components/ILIAS/UI/src/Component/Listing/CharacteristicValue/Text.php index 60a2f74e1d2c..55008b74b357 100755 --- a/components/ILIAS/UI/src/Component/Listing/CharacteristicValue/Text.php +++ b/components/ILIAS/UI/src/Component/Listing/CharacteristicValue/Text.php @@ -22,12 +22,12 @@ use ILIAS\UI\Component\Component; use ILIAS\UI\Component\Layout\Alignment\Block; -use ILIAS\UI\Component\Navigation\Sequence\SegmentContent; +use ILIAS\UI\Component\Navigation\Sequence\IsSegmentContent; /** * Interface Text */ -interface Text extends Component, Block, SegmentContent +interface Text extends Component, Block, IsSegmentContent { /** * Gets the items as array of key value pairs for the list. diff --git a/components/ILIAS/UI/src/Component/Navigation/Factory.php b/components/ILIAS/UI/src/Component/Navigation/Factory.php index a9d9e0e42f5b..1a40bddb790d 100644 --- a/components/ILIAS/UI/src/Component/Navigation/Factory.php +++ b/components/ILIAS/UI/src/Component/Navigation/Factory.php @@ -57,7 +57,7 @@ interface Factory * usage: * 1: > * Use a sequence when the order of presentation is crucial or the - * sequencial presentation aids focus. The sequence is not more of + * sequencial presentation aids focus. The sequence is not of an * explorative nature but rather instructional. * interaction: * 1: > diff --git a/components/ILIAS/UI/src/Component/Navigation/Sequence/SegmentContent.php b/components/ILIAS/UI/src/Component/Navigation/Sequence/IsSegmentContent.php similarity index 91% rename from components/ILIAS/UI/src/Component/Navigation/Sequence/SegmentContent.php rename to components/ILIAS/UI/src/Component/Navigation/Sequence/IsSegmentContent.php index 684fbb7dcf9e..a8bb4a27f372 100644 --- a/components/ILIAS/UI/src/Component/Navigation/Sequence/SegmentContent.php +++ b/components/ILIAS/UI/src/Component/Navigation/Sequence/IsSegmentContent.php @@ -21,10 +21,10 @@ namespace ILIAS\UI\Component\Navigation\Sequence; /** - * SegmentContent is allowed in Segments. + * IsSegmentContent is allowed in Segments. * Any actions included/provided by (parts of) a Segment MUST NOT leave * the context of the sequence. */ -interface SegmentContent +interface IsSegmentContent { } diff --git a/components/ILIAS/UI/src/Component/Navigation/Sequence/Segment.php b/components/ILIAS/UI/src/Component/Navigation/Sequence/Segment.php index 8a8f584e7928..b0ab14724622 100644 --- a/components/ILIAS/UI/src/Component/Navigation/Sequence/Segment.php +++ b/components/ILIAS/UI/src/Component/Navigation/Sequence/Segment.php @@ -31,14 +31,14 @@ interface Segment public function getTitle(): string; /** - * The actual "contents" of the view displayed when operating a sequence. - * Valid Components are flagged with the SegmentContent interface. - * @return SegmentContent[] + * The actual "contents" of the displayed view when operating a sequence. + * Valid Components are flagged with the IsSegmentContent interface. + * @return IsSegmentContent[] */ public function getContents(): array; /** - * Segments may add actions to the sequence. + * Segments MAY add actions to the sequence. * Those actions MUST target the actually displayed contents rather * than changing context entirely (i.e. breaking the sequence). */ diff --git a/components/ILIAS/UI/src/Component/Navigation/Sequence/SegmentBuilder.php b/components/ILIAS/UI/src/Component/Navigation/Sequence/SegmentBuilder.php index d583a92048a1..5e4a6a0a2a4a 100644 --- a/components/ILIAS/UI/src/Component/Navigation/Sequence/SegmentBuilder.php +++ b/components/ILIAS/UI/src/Component/Navigation/Sequence/SegmentBuilder.php @@ -22,5 +22,5 @@ interface SegmentBuilder { - public function build(string $title, SegmentContent ...$contents): Segment; + public function build(string $title, IsSegmentContent ...$contents): Segment; } diff --git a/components/ILIAS/UI/src/Component/Table/Presentation.php b/components/ILIAS/UI/src/Component/Table/Presentation.php index 00e21a63b1be..571ff73e6076 100755 --- a/components/ILIAS/UI/src/Component/Table/Presentation.php +++ b/components/ILIAS/UI/src/Component/Table/Presentation.php @@ -24,12 +24,11 @@ use Closure; use ILIAS\UI\Implementation\Component\Signal; use ILIAS\UI\Component\JavaScriptBindable; -use ILIAS\UI\Component\Navigation\Sequence\SegmentContent; /** * This describes a Presentation Table */ -interface Presentation extends Table, HasViewControls, JavaScriptBindable, SegmentContent +interface Presentation extends Table, HasViewControls, JavaScriptBindable { /** * Get a table like this with the closure $row_mapping. diff --git a/components/ILIAS/UI/src/Component/Table/Table.php b/components/ILIAS/UI/src/Component/Table/Table.php index 3805fe1e1216..4fa6e4803f8e 100755 --- a/components/ILIAS/UI/src/Component/Table/Table.php +++ b/components/ILIAS/UI/src/Component/Table/Table.php @@ -21,8 +21,9 @@ namespace ILIAS\UI\Component\Table; use ILIAS\UI\Component\Component; +use ILIAS\UI\Component\Navigation\Sequence\IsSegmentContent; -interface Table extends Component +interface Table extends Component, IsSegmentContent { public function withTitle(string $title): self; diff --git a/components/ILIAS/UI/src/Implementation/Component/Navigation/Sequence/Renderer.php b/components/ILIAS/UI/src/Implementation/Component/Navigation/Sequence/Renderer.php index 3fb116870ad4..e4500443ddd1 100644 --- a/components/ILIAS/UI/src/Implementation/Component/Navigation/Sequence/Renderer.php +++ b/components/ILIAS/UI/src/Implementation/Component/Navigation/Sequence/Renderer.php @@ -33,13 +33,13 @@ class Renderer extends AbstractComponentRenderer public function render(Component\Component $component, RendererInterface $default_renderer): string { if ($component instanceof Component\Navigation\Sequence\Sequence) { - return $this->renderLinear($component, $default_renderer); + return $this->renderSequence($component, $default_renderer); } $this->cannotHandleComponent($component); } - protected function renderLinear( + protected function renderSequence( Component\Navigation\Sequence\Sequence $component, RendererInterface $default_renderer ): string { @@ -67,21 +67,20 @@ protected function renderLinear( ); $ui_factory = $this->getUIFactory(); - $back = $ui_factory->button()->standard('back', $component->getNext(-1)->__toString()) + $back = $ui_factory->button()->standard($this->txt('back'), $component->getNext(-1)->__toString()) ->withSymbol($ui_factory->symbol()->glyph()->back()) ->withUnavailableAction($position - 1 < 0); - $next = $ui_factory->button()->standard('next', $component->getNext(1)->__toString()) + $next = $ui_factory->button()->standard($this->txt('next'), $component->getNext(1)->__toString()) ->withSymbol($ui_factory->symbol()->glyph()->next()) ->withUnavailableAction($position + 1 === count($positions)); $tpl->setVariable('BACK', $default_renderer->render($back)); $tpl->setVariable('NEXT', $default_renderer->render($next)); - $tpl->setVariable('VIEWCONTROLS', $default_renderer->render($component->getViewControls())); - - $tpl->setVariable('SEGMENT_TITLLE', $segment->getTitle()); - $tpl->setVariable('SEGMENT_CONTENTS', $default_renderer->render($segment->getContents())); + if ($viewcontrols = $component->getViewControls()) { + $tpl->setVariable('VIEWCONTROLS', $default_renderer->render($viewcontrols)); + } if ($actions = $segment->getActions()) { $tpl->setVariable('ACTIONS_SEGMENT', $default_renderer->render($actions)); @@ -89,6 +88,9 @@ protected function renderLinear( if ($actions = $component->getActions()) { $tpl->setVariable('ACTIONS_GLOBAL', $default_renderer->render($actions)); } + + $tpl->setVariable('SEGMENT_TITLLE', $segment->getTitle()); + $tpl->setVariable('SEGMENT_CONTENTS', $default_renderer->render($segment->getContents())); return $tpl->get(); } } diff --git a/components/ILIAS/UI/src/Implementation/Component/Navigation/Sequence/Segment.php b/components/ILIAS/UI/src/Implementation/Component/Navigation/Sequence/Segment.php index bf79500341ad..6e22ccd39b34 100644 --- a/components/ILIAS/UI/src/Implementation/Component/Navigation/Sequence/Segment.php +++ b/components/ILIAS/UI/src/Implementation/Component/Navigation/Sequence/Segment.php @@ -27,13 +27,13 @@ class Segment implements ISequence\Segment protected ?array $actions = null; /** - * @var ISequence\SegmentContent[] + * @var ISequence\IsSegmentContent[] */ protected array $contents; public function __construct( protected string $title, - ISequence\SegmentContent ...$contents, + ISequence\IsSegmentContent ...$contents, ) { $this->contents = $contents; } diff --git a/components/ILIAS/UI/src/Implementation/Component/Navigation/Sequence/SegmentBuilder.php b/components/ILIAS/UI/src/Implementation/Component/Navigation/Sequence/SegmentBuilder.php index a75aca1e7bc1..e9e4b7a27567 100644 --- a/components/ILIAS/UI/src/Implementation/Component/Navigation/Sequence/SegmentBuilder.php +++ b/components/ILIAS/UI/src/Implementation/Component/Navigation/Sequence/SegmentBuilder.php @@ -26,7 +26,7 @@ class SegmentBuilder implements ISequence\SegmentBuilder { public function build( string $title, - ISequence\SegmentContent ...$contents + ISequence\IsSegmentContent ...$contents ): ISequence\Segment { return new Segment($title, ...$contents); } diff --git a/components/ILIAS/UI/src/Implementation/Component/Navigation/Sequence/Sequence.php b/components/ILIAS/UI/src/Implementation/Component/Navigation/Sequence/Sequence.php index 01d5539b3311..b50561fa22d7 100644 --- a/components/ILIAS/UI/src/Implementation/Component/Navigation/Sequence/Sequence.php +++ b/components/ILIAS/UI/src/Implementation/Component/Navigation/Sequence/Sequence.php @@ -121,7 +121,7 @@ public function withRequest(ServerRequestInterface $request): static protected function initFromRequest(): void { $base_uri = $this->data_factory->uri($this->request->getUri()->__toString()); - $namespace = ['sequence']; // add id + $namespace = ['sequence' . $this->getId() ?? '']; $url_builder = new URLBuilder($base_uri); list( $this->url_builder, @@ -140,12 +140,12 @@ protected function initFromRequest(): void ]) ); - - $this->viewcontrols = $this->applyValuesToViewcontrols( - $this->viewcontrols, - $this->request - ); - //$this->viewcontrols = $this->viewcontrols->withRequest($this->request); + if ($this->viewcontrols) { + $this->viewcontrols = $this->applyValuesToViewcontrols( + $this->viewcontrols, + $this->request + ); + } } public function getNext(int $direction): URI diff --git a/components/ILIAS/UI/src/examples/Navigation/Sequence/base.php b/components/ILIAS/UI/src/examples/Navigation/Sequence/base.php index 741a5ec80a15..538b5b1819a0 100644 --- a/components/ILIAS/UI/src/examples/Navigation/Sequence/base.php +++ b/components/ILIAS/UI/src/examples/Navigation/Sequence/base.php @@ -11,6 +11,19 @@ use ILIAS\UI\URLBuilder; use Psr\Http\Message\ServerRequestInterface; +/** + * --- + * description: > + * Base example for rendering a sequence navigation. + * + * expected output: > + * ILIAS shows a group of buttons and a characteristic value listing. + * Buttons are "back" and "next", of which the back button is inactive until + * the next button was clicked. + * A vieww control allows the user to select chunks of data, and an additional + * button (without real function) is labeled "a global action". + * --- + */ function base() { global $DIC; @@ -28,10 +41,13 @@ public function __construct( ) { $this->seq_data = [ ['c0', 'pos 1', [getListing($f)]], - ['c0', 'pos 2', [$f->legacy('some legacy content')]], + ['c0', 'pos 2', [ + $f->legacy('some legacy content'), + $f->legacy('some more legacy content'), + ]], ['c1', 'pos 3', [getImage($f)]], ['c2', 'pos 4', [getTable($f)]], - ['c1', 'pos 5', [$f->legacy('some more legacy content')]], + ['c1', 'pos 5', [getForm($f)]], ]; } @@ -200,3 +216,14 @@ function ($row, $record, $ui_factory, $environment) { //mapping-closure ] ); } + +function getForm(UIFactory $ui_factory): \ILIAS\UI\Component\Input\Container\Form\Standard +{ + return $ui_factory->input()->container()->form()->standard( + '#', + [ + $ui_factory->input()->field()->text('a text field'), + $ui_factory->input()->field()->numeric('a number field'), + ] + ); +} diff --git a/components/ILIAS/UI/src/templates/default/Navigation/tpl.sequence.html b/components/ILIAS/UI/src/templates/default/Navigation/tpl.sequence.html index a1cf21a806b7..c7a944578260 100644 --- a/components/ILIAS/UI/src/templates/default/Navigation/tpl.sequence.html +++ b/components/ILIAS/UI/src/templates/default/Navigation/tpl.sequence.html @@ -1,26 +1,29 @@
-
{BACK} {NEXT}
+
{VIEWCONTROLS}
+ +
{ACTIONS_SEGMENT}
+ +
{ACTIONS_GLOBAL}
- +
-
{SEGMENT_TITLLE} @@ -28,4 +31,6 @@
{SEGMENT_CONTENTS}
+
+
\ No newline at end of file diff --git a/components/ILIAS/UI/tests/MainFactoryTest.php b/components/ILIAS/UI/tests/MainFactoryTest.php index 57d56fbfdb96..589e1e0d91d1 100755 --- a/components/ILIAS/UI/tests/MainFactoryTest.php +++ b/components/ILIAS/UI/tests/MainFactoryTest.php @@ -36,7 +36,8 @@ class MainFactoryTest extends AbstractFactoryTestCase "layout" => ["rules" => false], "menu" => ["rules" => false], "symbol" => ["rules" => false], - "entity" => ["context" => true] + "entity" => ["context" => true], + "navigation" => ["rules" => false], ]; public static string $factory_title = 'ILIAS\\UI\\Factory';