Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions components/ILIAS/UI/src/Component/ViewControl/Mode.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
namespace ILIAS\UI\Component\ViewControl;

use ILIAS\UI\Component\Component;
use ILIAS\UI\Component\JavaScriptBindable;
use Closure;

/**
* This describes a Mode Control
Expand Down Expand Up @@ -52,4 +54,19 @@ public function getLabelledActions(): array;
* Get the aria-label on the ViewControl
*/
public function getAriaLabel(): string;

public function withOnLoadCodeForAction(string $label, Closure $binder): static;
public function withAdditionalOnLoadCodeForAction(string $label, Closure $binder): static;

/**
* @param array<string, Closure> $label_binder_map
*/
public function withOnLoadCodeForActions(array $label_binder_map): static;

/**
* @param array<string, Closure> $label_binder_map
*/
public function withAdditionalOnLoadCodeForActions(array $label_binder_map): static;

public function getOnLoadCodeForAction(string $label): ?Closure;
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@

use ILIAS\UI\Component as C;
use ILIAS\UI\Implementation\Component\ComponentHelper;
use Closure;
use ILIAS\UI\Implementation\Component\JavaScriptBindable;
use ReflectionFunction;
use InvalidArgumentException;

class Mode implements C\ViewControl\Mode
{
Expand All @@ -30,6 +34,8 @@ class Mode implements C\ViewControl\Mode
protected array $labeled_actions;
protected string $aria_label;
protected ?string $active = null;
/** @var Closure[] */
private array $on_load_code_binder_by_label = [];

public function __construct($labelled_actions, string $aria_label)
{
Expand Down Expand Up @@ -58,4 +64,70 @@ public function getAriaLabel(): string
{
return $this->aria_label;
}

public function withOnLoadCodeForAction(string $label, Closure $binder): static
{
$this->checkLabelExists($label);
$this->checkBinder($binder);
$clone = clone $this;
$clone->on_load_code_binder_by_label[$label] = $binder;
return $clone;
}

public function withAdditionalOnLoadCodeForAction(string $label, Closure $binder): static
{
$current_binder = $this->getOnLoadCodeForAction($label);
if ($current_binder === null) {
return $this->withOnLoadCodeForAction($label, $binder);
}

$this->checkLabelExists($label);
$this->checkBinder($binder);
return $this->withOnLoadCodeForAction($label, static fn($id) => $binder($id) . "\n" . $current_binder($id));
}

public function getOnLoadCodeForAction(string $label): ?Closure
{
return $this->on_load_code_binder_by_label[$label] ?? null;
}

/**
* @throws \InvalidArgumentException if closure does not take one argument
*/
private function checkBinder(Closure $binder): void
{
$refl = new ReflectionFunction($binder);
$args = array_map(static fn($arg) => $arg->name, $refl->getParameters());
if (array("id") !== $args) {
throw new InvalidArgumentException('Expected closure "$binder" to have exactly one argument "$id".');
}
}

/**
* @throws InvalidArgumentException if the label does not exist
*/
private function checkLabelExists(string $label): void
{
if (!array_key_exists($label, $this->labeled_actions)) {
throw new InvalidArgumentException("Label '$label' does not exist in Mode control.");
}
}

public function withOnLoadCodeForActions(array $label_binder_map): static
{
$clone = clone $this;
foreach ($label_binder_map as $label => $binder) {
$clone = $clone->withOnLoadCodeForAction($label, $binder);
}
return $clone;
}

public function withAdditionalOnLoadCodeForActions(array $label_binder_map): static
{
$clone = clone $this;
foreach ($label_binder_map as $label => $binder) {
$clone = $clone->withAdditionalOnLoadCodeForAction($label, $binder);
}
return $clone;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,9 @@ protected function renderMode(Component\ViewControl\Mode $component, RendererInt
$tpl->setCurrentBlock("view_control");

$button = $f->button()->standard($label, $action);
if ($action = $component->getOnLoadCodeForAction($label)) {
$button = $button->withOnLoadCode($action);
}
if ($activate_first_item) {
$button = $button->withEngagedState(true);
$activate_first_item = false;
Expand Down