diff --git a/components/ILIAS/UI/src/Component/Image/Image.php b/components/ILIAS/UI/src/Component/Image/Image.php index 0991b37f7ce2..e2552441593a 100755 --- a/components/ILIAS/UI/src/Component/Image/Image.php +++ b/components/ILIAS/UI/src/Component/Image/Image.php @@ -25,7 +25,6 @@ use ILIAS\UI\Component\Signal; use ILIAS\UI\Component\Component; use ILIAS\UI\Component\Layout\Alignment\Block; -use ILIAS\UI\Component\Navigation\Sequence\IsSegmentContent; /** * This describes how a glyph could be modified during construction of UI. @@ -33,7 +32,7 @@ * Interface Image * @package ILIAS\UI\Component\Image */ -interface Image extends Component, JavaScriptBindable, Clickable, Block, IsSegmentContent +interface Image extends Component, JavaScriptBindable, Clickable, Block { /** * 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 1f4a1f1ec2b5..9bcb697a9239 100755 --- a/components/ILIAS/UI/src/Component/Input/Container/Form/Standard.php +++ b/components/ILIAS/UI/src/Component/Input/Container/Form/Standard.php @@ -21,12 +21,11 @@ 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, IsSegmentContent +interface Standard extends FormWithPostURL, IsPromptContent { /** * Sets the label of the submit button of the form diff --git a/components/ILIAS/UI/src/Component/Legacy/Factory.php b/components/ILIAS/UI/src/Component/Legacy/Factory.php index 4a5417c2fdfd..46f2a58776bf 100755 --- a/components/ILIAS/UI/src/Component/Legacy/Factory.php +++ b/components/ILIAS/UI/src/Component/Legacy/Factory.php @@ -47,4 +47,28 @@ interface Factory */ public function legacyContent(string $content): LegacyContent; + /** + * --- + * description: + * purpose: > + * The legacy segment is used as container for visible content in + * the context of sequence nvigations. + * We currently lack quite a lot of UI components for describing the + * actual contents of the page, e.g. questions, combinations of text/table/form, etc. + * Until these components exist an enable us to better describe the + * correlations to navigations, the legacy segment is used to contain + * rendered HTML. + * composition: > + * The legacy segment contains html (or any other content) as string; + * it also has a title. + * + * context: + * - A segment is the content affected by operating the sequence navigation. + * --- + * @param string $title the title of the legacy segment + * @param string $content the content of the legacy segment + * @return \ILIAS\UI\Component\Legacy\LegacySegment + */ + public function legacySegment(string $title, string $content): LegacySegment; + } diff --git a/components/ILIAS/UI/src/Implementation/Component/Navigation/Sequence/SegmentBuilder.php b/components/ILIAS/UI/src/Component/Legacy/LegacySegment.php similarity index 53% rename from components/ILIAS/UI/src/Implementation/Component/Navigation/Sequence/SegmentBuilder.php rename to components/ILIAS/UI/src/Component/Legacy/LegacySegment.php index e9e4b7a27567..c2d083ea469d 100644 --- a/components/ILIAS/UI/src/Implementation/Component/Navigation/Sequence/SegmentBuilder.php +++ b/components/ILIAS/UI/src/Component/Legacy/LegacySegment.php @@ -18,16 +18,18 @@ declare(strict_types=1); -namespace ILIAS\UI\Implementation\Component\Navigation\Sequence; +namespace ILIAS\UI\Component\Legacy; -use ILIAS\UI\Component\Navigation\Sequence as ISequence; +use ILIAS\UI\Component\Component; +use ILIAS\UI\Component\Navigation\Sequence\Segment; +use ILIAS\UI\Component\Button; -class SegmentBuilder implements ISequence\SegmentBuilder +interface LegacySegment extends Component, Segment { - public function build( - string $title, - ISequence\IsSegmentContent ...$contents - ): ISequence\Segment { - return new Segment($title, ...$contents); - } + /** + * 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). + */ + public function withSegmentActions(Button\Standard ...$actions): static; } diff --git a/components/ILIAS/UI/src/Component/Listing/CharacteristicValue/Text.php b/components/ILIAS/UI/src/Component/Listing/CharacteristicValue/Text.php index 55008b74b357..3279f457a147 100755 --- a/components/ILIAS/UI/src/Component/Listing/CharacteristicValue/Text.php +++ b/components/ILIAS/UI/src/Component/Listing/CharacteristicValue/Text.php @@ -22,12 +22,11 @@ use ILIAS\UI\Component\Component; use ILIAS\UI\Component\Layout\Alignment\Block; -use ILIAS\UI\Component\Navigation\Sequence\IsSegmentContent; /** * Interface Text */ -interface Text extends Component, Block, IsSegmentContent +interface Text extends Component, Block { /** * 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 1a40bddb790d..4a9571b9558a 100644 --- a/components/ILIAS/UI/src/Component/Navigation/Factory.php +++ b/components/ILIAS/UI/src/Component/Navigation/Factory.php @@ -26,18 +26,18 @@ interface Factory * --- * description: * purpose: > - * The Sequence Navigation is used to guide users through a process in a - * structured manner, ensuring they complete tasks or gather information - * in the intended order. - * Elements (or the amount of) may change during the process, however, + * The Sequence Navigation is used to move through a series of elements + * in a particular order. + * Elements (or the amount of) may change during navigation, however, * they will remain in a consecutive order. * composition: > * Sequence Navigation consists of several groups of buttons, mainly. * First of all, there is the primary navigation of back- and next buttons * to navigate through the parts of the sequence; a part is called a "Segment". - * While every Segment of a sequence is part of a bigger process, there - * might be additional buttons for actions targeting this outer context, or - * terminating the browsing of the sequence. + * While every Segment of a sequence is part of a bigger process (i.e. + * the perception of the entire sequence), there might be additional buttons + * for actions targeting outer context, or terminating the browsing + * of the sequence. * Every shown segement may also add buttons with actions regarding the * current segement. * Finally, there may be view controls and filters to change the amount of diff --git a/components/ILIAS/UI/src/Component/Navigation/Sequence/Binding.php b/components/ILIAS/UI/src/Component/Navigation/Sequence/Binding.php index 6853356e1fb5..5eb7416fa010 100644 --- a/components/ILIAS/UI/src/Component/Navigation/Sequence/Binding.php +++ b/components/ILIAS/UI/src/Component/Navigation/Sequence/Binding.php @@ -40,7 +40,6 @@ public function getSequencePositions( * Receives position data (provided by getSequencePositions) and builds a segment. */ public function getSegment( - SegmentBuilder $builder, mixed $position_data, array $viewcontrol_values, array $filter_values diff --git a/components/ILIAS/UI/src/Component/Navigation/Sequence/IsSegmentContent.php b/components/ILIAS/UI/src/Component/Navigation/Sequence/IsSegmentContent.php deleted file mode 100644 index a8bb4a27f372..000000000000 --- a/components/ILIAS/UI/src/Component/Navigation/Sequence/IsSegmentContent.php +++ /dev/null @@ -1,30 +0,0 @@ -signal_generator); } + + /** + * @inheritdoc + */ + public function legacySegment(string $title, string $content): C\Legacy\LegacySegment + { + return new LegacySegment($title, $content); + } } diff --git a/components/ILIAS/UI/src/Implementation/Component/Navigation/Sequence/Segment.php b/components/ILIAS/UI/src/Implementation/Component/Legacy/LegacySegment.php similarity index 61% rename from components/ILIAS/UI/src/Implementation/Component/Navigation/Sequence/Segment.php rename to components/ILIAS/UI/src/Implementation/Component/Legacy/LegacySegment.php index 6e22ccd39b34..70670e51eaab 100644 --- a/components/ILIAS/UI/src/Implementation/Component/Navigation/Sequence/Segment.php +++ b/components/ILIAS/UI/src/Implementation/Component/Legacy/LegacySegment.php @@ -18,44 +18,43 @@ declare(strict_types=1); -namespace ILIAS\UI\Implementation\Component\Navigation\Sequence; +namespace ILIAS\UI\Implementation\Component\Legacy; -use ILIAS\UI\Component\Navigation\Sequence as ISequence; +use ILIAS\UI\Component\Legacy\LegacySegment as ISegment; +use ILIAS\UI\Implementation\Component\ComponentHelper; +use ILIAS\UI\Component\Button; -class Segment implements ISequence\Segment +class LegacySegment implements ISegment { + use ComponentHelper; + protected ?array $actions = null; - /** - * @var ISequence\IsSegmentContent[] - */ - protected array $contents; public function __construct( protected string $title, - ISequence\IsSegmentContent ...$contents, + protected string $content ) { - $this->contents = $contents; } - public function getContents(): array + public function getSegmentTitle(): string { - return $this->contents; + return $this->title; } - public function getTitle(): string + public function getSegmentContent(): string { - return $this->title; + return $this->content; } - public function withActions(...$actions): static + public function withSegmentActions(Button\Standard ...$actions): static { $clone = clone $this; $clone->actions = $actions; return $clone; } - public function getActions(): ?array + public function getSegmentActions(): ?array { return $this->actions; } diff --git a/components/ILIAS/UI/src/Implementation/Component/Legacy/Renderer.php b/components/ILIAS/UI/src/Implementation/Component/Legacy/Renderer.php index aab81bc60406..b12e8d36a676 100755 --- a/components/ILIAS/UI/src/Implementation/Component/Legacy/Renderer.php +++ b/components/ILIAS/UI/src/Implementation/Component/Legacy/Renderer.php @@ -35,10 +35,19 @@ class Renderer extends AbstractComponentRenderer */ public function render(Component\Component $component, RendererInterface $default_renderer): string { - if (!$component instanceof Component\Legacy\LegacyContent) { - $this->cannotHandleComponent($component); + if ($component instanceof Component\Legacy\LegacyContent) { + return $this->renderLegacyContent($component, $default_renderer); } + if ($component instanceof Component\Legacy\LegacySegment) { + return $this->renderLegacySegment($component, $default_renderer); + } + + $this->cannotHandleComponent($component); + } + + protected function renderLegacyContent(LegacyContent $component, RendererInterface $default_renderer): string + { $component = $this->registerSignals($component); $this->bindJavaScript($component); return $component->getContent(); @@ -58,4 +67,10 @@ protected function registerSignals(LegacyContent $component): Component\JavaScri return $code; }); } + + protected function renderLegacySegment(LegacySegment $component, RendererInterface $default_renderer): string + { + return 'a legacy segment is not rendered by itself, it\'s used with sequence navigation'; + } + } diff --git a/components/ILIAS/UI/src/Implementation/Component/Navigation/Factory.php b/components/ILIAS/UI/src/Implementation/Component/Navigation/Factory.php index 02160a1b4581..e5f588c1a0c0 100644 --- a/components/ILIAS/UI/src/Implementation/Component/Navigation/Factory.php +++ b/components/ILIAS/UI/src/Implementation/Component/Navigation/Factory.php @@ -40,7 +40,6 @@ public function sequence( INavigation\Sequence\Binding $binding ): INavigation\Sequence\Sequence { return new Sequence\Sequence( - new Sequence\SegmentBuilder(), $this->data_factory, $this->refinery, $this->storage, 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 e4500443ddd1..055170d0b6df 100644 --- a/components/ILIAS/UI/src/Implementation/Component/Navigation/Sequence/Renderer.php +++ b/components/ILIAS/UI/src/Implementation/Component/Navigation/Sequence/Renderer.php @@ -60,7 +60,6 @@ protected function renderSequence( } $segment = $component->getBinding()->getSegment( - $component->getSegmentBuilder(), $positions[$position], $vc_data, $filter_data @@ -82,15 +81,16 @@ protected function renderSequence( $tpl->setVariable('VIEWCONTROLS', $default_renderer->render($viewcontrols)); } - if ($actions = $segment->getActions()) { - $tpl->setVariable('ACTIONS_SEGMENT', $default_renderer->render($actions)); - } 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())); + if ($actions = $segment->getSegmentActions()) { + $tpl->setVariable('ACTIONS_SEGMENT', $default_renderer->render($actions)); + } + + $tpl->setVariable('SEGMENT_TITLLE', $segment->getSegmentTitle()); + $tpl->setVariable('SEGMENT_CONTENTS', $segment->getSegmentContent()); return $tpl->get(); } } 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 b50561fa22d7..1f48662ce81e 100644 --- a/components/ILIAS/UI/src/Implementation/Component/Navigation/Sequence/Sequence.php +++ b/components/ILIAS/UI/src/Implementation/Component/Navigation/Sequence/Sequence.php @@ -47,7 +47,6 @@ class Sequence implements ISequence\Sequence protected ?string $id = null; public function __construct( - protected ISequence\SegmentBuilder $segment_builder, protected DataFactory $data_factory, protected Refinery $refinery, protected \ArrayAccess $storage, @@ -55,11 +54,6 @@ public function __construct( ) { } - public function getSegmentBuilder(): ISequence\SegmentBuilder - { - return $this->segment_builder; - } - public function getBinding(): ISequence\Binding { return $this->binding; diff --git a/components/ILIAS/UI/src/examples/Legacy/LegacySegment/base.php b/components/ILIAS/UI/src/examples/Legacy/LegacySegment/base.php new file mode 100644 index 000000000000..aeffa3af4699 --- /dev/null +++ b/components/ILIAS/UI/src/examples/Legacy/LegacySegment/base.php @@ -0,0 +1,25 @@ + + * Example for rendering a legacy segment. + * + * expected output: > + * ILIAS shows a box titled "Panel Title" and a grey background. In the lower part of the box the text "Legacy Content" + * on a white background is written. + * --- + */ +function base() +{ + global $DIC; + $f = $DIC->ui()->factory(); + $renderer = $DIC->ui()->renderer(); + + $legacy = $f->legacy()->legacySegment('title', 'content'); + return $renderer->render($legacy); +} diff --git a/components/ILIAS/UI/src/examples/Navigation/Sequence/base.php b/components/ILIAS/UI/src/examples/Navigation/Sequence/base.php index 538b5b1819a0..acec1fd34d7a 100644 --- a/components/ILIAS/UI/src/examples/Navigation/Sequence/base.php +++ b/components/ILIAS/UI/src/examples/Navigation/Sequence/base.php @@ -5,6 +5,7 @@ namespace ILIAS\UI\examples\Navigation\Sequence; use ILIAS\UI\Factory as UIFactory; +use ILIAS\UI\Renderer as UIRenderer; use ILIAS\UI\Component\Navigation\Sequence\Binding; use ILIAS\UI\Component\Navigation\Sequence\SegmentBuilder; use ILIAS\UI\Component\Navigation\Sequence\Segment; @@ -33,21 +34,19 @@ function base() $refinery = $DIC['refinery']; $request = $DIC->http()->request(); - $binding = new class ($f) implements Binding { + $binding = new class ($f, $r) implements Binding { private array $seq_data; public function __construct( - protected UIFactory $f + protected UIFactory $f, + protected UIRenderer $r ) { $this->seq_data = [ - ['c0', 'pos 1', [getListing($f)]], - ['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', [getForm($f)]], + ['c0', 'pos 1', getListing($f)], + //['c0', 'pos 2', 'some legacy content'], + ['c1', 'pos 3', getImage($f)], + ['c2', 'pos 4', getTable($f)], + ['c1', 'pos 5', getForm($f)], ]; } @@ -66,19 +65,18 @@ public function getSequencePositions( } public function getSegment( - SegmentBuilder $builder, mixed $position_data, array $viewcontrol_values, array $filter_values ): Segment { list($chunk, $title, $data) = $position_data; - $segment = $builder->build($title, ...$data); + $segment = $this->f->legacy()->legacySegment($title, $this->r->render($data)); if ($chunk === 'c1') { - $segment = $segment->withActions([ - $action = $this->f->button()->standard('a segment action for ' . $title, '#') - ]); + $segment = $segment->withSegmentActions( + $this->f->button()->standard('a segment action for ' . $title, '#') + ); } return $segment; }