diff --git a/components/ILIAS/MetaData/classes/OERHarvester/ControlCenter/Content/ContentFactory.php b/components/ILIAS/MetaData/classes/OERHarvester/ControlCenter/Content/ContentFactory.php
index 65166a5bde3f..5ea3a541f7a1 100644
--- a/components/ILIAS/MetaData/classes/OERHarvester/ControlCenter/Content/ContentFactory.php
+++ b/components/ILIAS/MetaData/classes/OERHarvester/ControlCenter/Content/ContentFactory.php
@@ -21,7 +21,6 @@
namespace ILIAS\MetaData\OERHarvester\ControlCenter\Content;
use ILIAS\MetaData\OERHarvester\ControlCenter\State\Status;
-use ILIAS\UI\Component\Modal\RoundTrip as RoundTripModal;
use ILIAS\UI\Factory as UIFactory;
use ILIAS\MetaData\OERHarvester\ControlCenter\State\StateInfoInterface;
use ILIAS\MetaData\Presentation\UtilitiesInterface as PresentationUtilities;
@@ -31,6 +30,7 @@
use ILIAS\MetaData\OERHarvester\ControlCenter\Http\LinkFactoryInterface;
use ILIAS\MetaData\OERHarvester\ControlCenter\State\Action;
use ILIAS\MetaData\Copyright\RepositoryInterface;
+use ILIAS\UI\Component\Prompt\State\State as PromptState;
class ContentFactory implements ContentFactoryInterface
{
@@ -42,20 +42,20 @@ public function __construct(
) {
}
- public function getInfoContent(
+ public function getInfoShowState(
int $ref_id,
int $obj_id,
string $type,
StateInfoInterface $state_info
- ): RoundTripModal {
+ ): PromptState {
$message = $this->getStatusMessage($state_info);
$scale = $this->getStatusOverview($state_info);
$actions = $this->getActions($ref_id, $obj_id, $type, $state_info);
- return $this->ui_factory->modal()->roundtrip(
- $this->presentation_utilities->txt('md_publishing_center_title'),
- [$message, $scale]
- )->withActionButtons($actions);
+ return $this->ui_factory->prompt()->state()->show(
+ $message->withButtons($actions),
+ $scale
+ )->withTitle($this->presentation_utilities->txt('md_publishing_center_title'));
}
protected function getStatusOverview(StateInfoInterface $state_info): ScaleBar
@@ -136,21 +136,20 @@ protected function getActions(
return $buttons;
}
- public function getConfirmationContent(
+ public function getConfirmationShowState(
int $ref_id,
int $obj_id,
string $type,
Action $action,
bool $is_last_reference
- ): RoundTripModal {
- $modal_content = [];
+ ): PromptState {
$message = match ($action) {
Action::WITHDRAW => $this->presentation_utilities->txt('md_publishing_confirmation_info_withdraw'),
Action::ACCEPT => $this->presentation_utilities->txt('md_publishing_confirmation_info_accept'),
Action::REJECT => $this->presentation_utilities->txt('md_publishing_confirmation_info_reject'),
default => ''
};
- $modal_content[] = $this->ui_factory->messageBox()->confirmation($message);
+ $primary_message_box = $this->ui_factory->messageBox()->confirmation($message);
$title = match ($action) {
Action::WITHDRAW => $this->presentation_utilities->txt('md_publishing_confirmation_withdraw'),
Action::ACCEPT => $this->presentation_utilities->txt('md_publishing_confirmation_accept'),
@@ -158,11 +157,12 @@ public function getConfirmationContent(
default => ''
};
+ $secondary_message_boxes = [];
if (
($action === Action::REJECT || $action === Action::WITHDRAW) &&
$is_last_reference
) {
- $modal_content[] = $this->ui_factory->messageBox()->info(
+ $secondary_message_boxes[] = $this->ui_factory->messageBox()->info(
$this->presentation_utilities->txt('md_publishing_last_reference_info')
);
}
@@ -180,7 +180,10 @@ public function getConfirmationContent(
il.UI.prompt.get(promptId).show('$action');
});"
);
- return $this->ui_factory->modal()->roundtrip($title, $modal_content)->withActionButtons([$button]);
+ return $this->ui_factory->prompt()->state()->show(
+ $primary_message_box->withButtons([$button]),
+ ...$secondary_message_boxes
+ )->withTitle($title);
}
public function getSuccessMessage(Action $action): string
diff --git a/components/ILIAS/MetaData/classes/OERHarvester/ControlCenter/Content/ContentFactoryInterface.php b/components/ILIAS/MetaData/classes/OERHarvester/ControlCenter/Content/ContentFactoryInterface.php
index 940bface1d36..b0534cd86074 100644
--- a/components/ILIAS/MetaData/classes/OERHarvester/ControlCenter/Content/ContentFactoryInterface.php
+++ b/components/ILIAS/MetaData/classes/OERHarvester/ControlCenter/Content/ContentFactoryInterface.php
@@ -20,26 +20,27 @@
namespace ILIAS\MetaData\OERHarvester\ControlCenter\Content;
-use ILIAS\UI\Component\Modal\RoundTrip as RoundTripModal;
use ILIAS\MetaData\OERHarvester\ControlCenter\State\StateInfoInterface;
use ILIAS\MetaData\OERHarvester\ControlCenter\State\Action;
+use ILIAS\UI\Component\Prompt\State\State as PromptState;
+use ILIAS\UI\Implementation\Component\Chart\ScaleBar;
interface ContentFactoryInterface
{
- public function getInfoContent(
+ public function getInfoShowState(
int $ref_id,
int $obj_id,
string $type,
StateInfoInterface $state_info
- ): RoundTripModal;
+ ): PromptState;
- public function getConfirmationContent(
+ public function getConfirmationShowState(
int $ref_id,
int $obj_id,
string $type,
Action $action,
bool $is_last_reference
- ): RoundTripModal;
+ ): PromptState;
public function getSuccessMessage(Action $action): string;
}
diff --git a/components/ILIAS/MetaData/classes/OERHarvester/ControlCenter/ControlCenterGUI.php b/components/ILIAS/MetaData/classes/OERHarvester/ControlCenter/ControlCenterGUI.php
index 7b2f5a523a60..f99be28410b2 100755
--- a/components/ILIAS/MetaData/classes/OERHarvester/ControlCenter/ControlCenterGUI.php
+++ b/components/ILIAS/MetaData/classes/OERHarvester/ControlCenter/ControlCenterGUI.php
@@ -113,8 +113,8 @@ protected function isCommandAvailable(Command $cmd): bool
protected function view(): void
{
- $content = $this->content_factory->getInfoContent($this->ref_id, $this->obj_id, $this->type, $this->state_info);
- echo $this->ui_renderer->renderAsync($this->ui_factory->prompt()->state()->show($content));
+ $show_state = $this->content_factory->getInfoShowState($this->ref_id, $this->obj_id, $this->type, $this->state_info);
+ echo $this->ui_renderer->renderAsync($show_state);
exit;
}
@@ -144,14 +144,14 @@ protected function publish(): void
protected function withdraw(): void
{
- $content = $this->content_factory->getConfirmationContent(
+ $show_state = $this->content_factory->getConfirmationShowState(
$this->ref_id,
$this->obj_id,
$this->type,
Action::WITHDRAW,
$this->object_handler->isOnlyReference($this->ref_id)
);
- echo $this->ui_renderer->renderAsync($this->ui_factory->prompt()->state()->show($content));
+ echo $this->ui_renderer->renderAsync($show_state);
exit;
}
@@ -175,14 +175,14 @@ protected function submit(): void
protected function accept(): void
{
- $content = $this->content_factory->getConfirmationContent(
+ $show_state = $this->content_factory->getConfirmationShowState(
$this->ref_id,
$this->obj_id,
$this->type,
Action::ACCEPT,
$this->object_handler->isOnlyReference($this->ref_id)
);
- echo $this->ui_renderer->renderAsync($this->ui_factory->prompt()->state()->show($content));
+ echo $this->ui_renderer->renderAsync($show_state);
exit;
}
@@ -198,14 +198,14 @@ protected function confirmAccept(): void
protected function reject(): void
{
- $content = $this->content_factory->getConfirmationContent(
+ $show_state = $this->content_factory->getConfirmationShowState(
$this->ref_id,
$this->obj_id,
$this->type,
Action::REJECT,
$this->object_handler->isOnlyReference($this->ref_id)
);
- echo $this->ui_renderer->renderAsync($this->ui_factory->prompt()->state()->show($content));
+ echo $this->ui_renderer->renderAsync($show_state);
exit;
}
diff --git a/components/ILIAS/UI/resources/js/Prompt/dist/prompt.min.js b/components/ILIAS/UI/resources/js/Prompt/dist/prompt.min.js
index 788838ffbdba..bfbceaa00056 100644
--- a/components/ILIAS/UI/resources/js/Prompt/dist/prompt.min.js
+++ b/components/ILIAS/UI/resources/js/Prompt/dist/prompt.min.js
@@ -12,4 +12,4 @@
* https://www.ilias.de
* https://github.com/ILIAS-eLearning
*/
-!function(t,e){"use strict";class r{#t;#e;#r;constructor(t,e){if(this.#t=t,this.#e=document.getElementById(e),null===this.#e)throw new Error(`Could not find a Prompt for id '${e}'.`);this.#r=this.#e.getElementsByTagName("dialog").item(0)}show(t){this.load(t),this.#r.showModal()}close(){this.#r.close()}async load(t,e={}){await fetch(t,e).then((t=>t.text())).then((t=>{const e=(new this.#t).parseFromString(t,"text/html"),r=e.querySelector('section[data-section="il-prompt-state__title"]'),n=e.querySelector('section[data-section="il-prompt-state__contents"]'),o=e.querySelector('section[data-section="il-prompt-state__buttons"]'),i=e.querySelector('section[data-section="il-prompt-state__command"]'),s=e.querySelector('section[data-section="il-prompt-state__parameters"]'),a=e.querySelector("script"),c=this.#r.querySelector("span.il-prompt__title"),p=this.#r.querySelector("div.il-prompt__contents"),l=this.#r.querySelector("div.il-prompt__buttons");c.innerHTML=r.innerHTML,p.innerHTML=n.innerHTML,l.innerHTML=o.innerHTML,this.#n(p),this.#o(p),a&&this.#i(a.text);const m=[];return s.querySelectorAll("data").forEach((t=>{m[t.innerHTML.trim()]=t.getAttribute("value")})),{cmd:i.innerHTML.trim(),params:m}})).then((t=>{const e=t.cmd,{params:r}=t;"close"===e&&this.close(),"redirect"===e&&window.location.replace(r.redirect)}))}#i(t){const e=this.#e.querySelector("section.il-prompt__scripts"),r=document.createElement("script");r.text=t,e.innerHTML="",e.appendChild(r)}#n(t){t.getElementsByTagName("form").forEach((t=>{t.addEventListener("submit",(e=>{e.preventDefault(),this.load(t.action,{method:t.method,body:new FormData(t)})}))}))}#o(t){t.getElementsByTagName("a").forEach((t=>{const{target:e}=t;if("_blank"!==e){const e=t.href;t.addEventListener("click",(()=>this.load(e))),t.removeAttribute("href")}}))}}t.UI=t.UI||{},t.UI.prompt=new class{#t;#s=[];constructor(t){this.#t=t}init(t){if(void 0!==this.#s[t])throw new Error(`Prompt with id '${t}' has already been initialized.`);this.#s[t]=new r(this.#t,t)}get(t){return this.#s[t]??null}}(e)}(il,DOMParser);
+!function(t,e){"use strict";class r{#t;#e;#r;constructor(t,e){if(this.#t=t,this.#e=document.getElementById(e),null===this.#e)throw new Error(`Could not find a Prompt for id '${e}'.`);this.#r=this.#e.getElementsByTagName("dialog").item(0)}show(t){this.load(t),this.#r.showModal()}close(){this.#r.close()}async load(t,e={}){await fetch(t,e).then(t=>t.text()).then(t=>{const e=(new this.#t).parseFromString(t,"text/html"),r=e.querySelector('section[data-section="il-prompt-state__title"]'),o=e.querySelector('section[data-section="il-prompt-state__contents"]'),n=e.querySelector('section[data-section="il-prompt-state__buttons"]'),i=e.querySelector('section[data-section="il-prompt-state__command"]'),s=e.querySelector('section[data-section="il-prompt-state__parameters"]'),c=e.querySelector("script"),a=this.#r.querySelector("span.il-prompt__title"),p=this.#r.querySelector("div.il-prompt__contents"),l=this.#r.querySelector("div.il-prompt__buttons");a.innerHTML=r.innerHTML,p.innerHTML=o.innerHTML,l.innerHTML=n.innerHTML,this.#o(p),this.#n(p),c&&this.#i(c.text);const m=[];return s.querySelectorAll("data").forEach(t=>{m[t.innerHTML.trim()]=t.getAttribute("value")}),{cmd:i.innerHTML.trim(),params:m}}).then(t=>{const e=t.cmd,{params:r}=t;"close"===e&&this.close(),"redirect"===e&&window.location.replace(r.redirect)})}#i(t){const e=this.#e.querySelector("section.il-prompt__scripts"),r=document.createElement("script");r.text=t,e.innerHTML="",e.appendChild(r)}#o(t){t.querySelectorAll("form").forEach(t=>{t.addEventListener("submit",e=>{e.preventDefault(),this.load(t.action,{method:t.method,body:new FormData(t)})})})}#n(t){t.querySelectorAll("a").forEach(t=>{const{target:e}=t;if("_blank"!==e){const e=t.href;t.addEventListener("click",()=>this.load(e)),t.removeAttribute("href")}})}}t.UI=t.UI||{},t.UI.prompt=new class{#t;#s=[];constructor(t){this.#t=t}init(t){if(void 0!==this.#s[t])throw new Error(`Prompt with id '${t}' has already been initialized.`);this.#s[t]=new r(this.#t,t)}get(t){return this.#s[t]??null}}(e)}(il,DOMParser);
diff --git a/components/ILIAS/UI/resources/js/Prompt/rollup.config.js b/components/ILIAS/UI/resources/js/Prompt/rollup.config.js
index f815677b5a1a..b2bbcc13ce48 100644
--- a/components/ILIAS/UI/resources/js/Prompt/rollup.config.js
+++ b/components/ILIAS/UI/resources/js/Prompt/rollup.config.js
@@ -15,8 +15,8 @@
******************************************************************** */
import terser from '@rollup/plugin-terser';
-import copyright from '../../../../../../scripts/Copyright-Checker/copyright';
-import preserveCopyright from '../../../../../../scripts/Copyright-Checker/preserveCopyright';
+import copyright from '../../../../../../scripts/Copyright-Checker/copyright.js';
+import preserveCopyright from '../../../../../../scripts/Copyright-Checker/preserveCopyright.js';
export default {
input: './src/prompt.js',
diff --git a/components/ILIAS/UI/resources/js/Prompt/src/prompt.class.js b/components/ILIAS/UI/resources/js/Prompt/src/prompt.class.js
index e34ae4065d9a..11d345223ec8 100644
--- a/components/ILIAS/UI/resources/js/Prompt/src/prompt.class.js
+++ b/components/ILIAS/UI/resources/js/Prompt/src/prompt.class.js
@@ -127,7 +127,7 @@ export default class Prompt {
* @return {void}
*/
#captureForms(doc) {
- const forms = doc.getElementsByTagName('form');
+ const forms = doc.querySelectorAll('form');
forms.forEach(
(form) => {
form.addEventListener('submit', (e) => {
@@ -146,7 +146,7 @@ export default class Prompt {
* @return {void}
*/
#captureLinks(doc) {
- const links = doc.getElementsByTagName('a');
+ const links = doc.querySelectorAll('a');
links.forEach(
(lnk) => {
const { target } = lnk;
diff --git a/components/ILIAS/UI/src/Component/Prompt/State/Factory.php b/components/ILIAS/UI/src/Component/Prompt/State/Factory.php
index 8d2aacd0553e..970ff4856a66 100644
--- a/components/ILIAS/UI/src/Component/Prompt/State/Factory.php
+++ b/components/ILIAS/UI/src/Component/Prompt/State/Factory.php
@@ -48,7 +48,8 @@ interface Factory
* @return \ILIAS\UI\Component\Prompt\State\State
*/
public function show(
- \ILIAS\UI\Component\Prompt\IsPromptContent $content
+ \ILIAS\UI\Component\Prompt\IsPromptContent $primary_content,
+ \ILIAS\UI\Component\Prompt\IsPromptContent ...$secondary_content
): State;
/**
diff --git a/components/ILIAS/UI/src/Component/Prompt/State/State.php b/components/ILIAS/UI/src/Component/Prompt/State/State.php
index f6f440041f7f..9da0d772fd42 100644
--- a/components/ILIAS/UI/src/Component/Prompt/State/State.php
+++ b/components/ILIAS/UI/src/Component/Prompt/State/State.php
@@ -24,4 +24,5 @@
interface State extends Component
{
+ public function withTitle(string $title): self;
}
diff --git a/components/ILIAS/UI/src/Implementation/Component/Chart/ScaleBar.php b/components/ILIAS/UI/src/Implementation/Component/Chart/ScaleBar.php
index 9c1f2808d702..926c5f2c31fc 100755
--- a/components/ILIAS/UI/src/Implementation/Component/Chart/ScaleBar.php
+++ b/components/ILIAS/UI/src/Implementation/Component/Chart/ScaleBar.php
@@ -22,12 +22,13 @@
use ILIAS\UI\Component as C;
use ILIAS\UI\Implementation\Component\ComponentHelper;
+use ILIAS\UI\Component\Prompt\IsPromptContent;
/**
* Class ScaleBar
* @package ILIAS\UI\Implementation\Component\Listing\Descriptive
*/
-class ScaleBar implements C\Chart\ScaleBar
+class ScaleBar implements C\Chart\ScaleBar, IsPromptContent
{
use ComponentHelper;
diff --git a/components/ILIAS/UI/src/Implementation/Component/Dropzone/File/File.php b/components/ILIAS/UI/src/Implementation/Component/Dropzone/File/File.php
index c2c725a6a8b5..c0fbf229129d 100755
--- a/components/ILIAS/UI/src/Implementation/Component/Dropzone/File/File.php
+++ b/components/ILIAS/UI/src/Implementation/Component/Dropzone/File/File.php
@@ -281,20 +281,4 @@ public function withDedicatedName(string $dedicated_name): self
{
return $this;
}
-
- /**
- * @inheritdoc
- */
- public function getPromptButtons(): array
- {
- return $this->buttons;
- }
-
- /**
- * @inheritdoc
- */
- public function getPromptTitle(): string
- {
- return $this->type;
- }
}
diff --git a/components/ILIAS/UI/src/Implementation/Component/Input/Container/Form/Standard.php b/components/ILIAS/UI/src/Implementation/Component/Input/Container/Form/Standard.php
index 890fc4c5f663..dc98f9d6838b 100755
--- a/components/ILIAS/UI/src/Implementation/Component/Input/Container/Form/Standard.php
+++ b/components/ILIAS/UI/src/Implementation/Component/Input/Container/Form/Standard.php
@@ -33,7 +33,7 @@
/**
* This implements a standard form.
*/
-class Standard extends Form implements C\Input\Container\Form\Standard, IsPromptContentInternal, JavaScriptBindable
+class Standard extends Form implements C\Input\Container\Form\Standard, JavaScriptBindable
{
use HasPostURL;
use JavaScriptBindableTrait;
@@ -71,16 +71,6 @@ public function getSubmitLabel(): ?string
return $this->submit_caption;
}
- public function getPromptButtons(): array
- {
- return [];
- }
-
- public function getPromptTitle(): string
- {
- return '';
- }
-
public function getSubmitSignal(): Signal
{
return $this->submit_signal;
diff --git a/components/ILIAS/UI/src/Implementation/Component/MessageBox/MessageBox.php b/components/ILIAS/UI/src/Implementation/Component/MessageBox/MessageBox.php
index 4edd6e01fb35..c679a73966a4 100755
--- a/components/ILIAS/UI/src/Implementation/Component/MessageBox/MessageBox.php
+++ b/components/ILIAS/UI/src/Implementation/Component/MessageBox/MessageBox.php
@@ -24,7 +24,7 @@
use ILIAS\UI\Implementation\Component\ComponentHelper;
use ILIAS\UI\Implementation\Component\Prompt\IsPromptContentInternal;
-class MessageBox implements C\MessageBox\MessageBox, IsPromptContentInternal
+class MessageBox implements C\MessageBox\MessageBox
{
use ComponentHelper;
@@ -107,22 +107,4 @@ public function withLinks(array $links): C\MessageBox\MessageBox
$clone->links = $links;
return $clone;
}
-
- /**
- * @inheritdoc
- */
- public function getPromptButtons(): array
- {
- return $this->buttons;
- }
-
- /**
- * @inheritdoc
- */
- public function getPromptTitle(): string
- {
- return $this->type;
- }
-
-
}
diff --git a/components/ILIAS/UI/src/Implementation/Component/Modal/RoundTrip.php b/components/ILIAS/UI/src/Implementation/Component/Modal/RoundTrip.php
index a6125e631c31..235a0e27d266 100755
--- a/components/ILIAS/UI/src/Implementation/Component/Modal/RoundTrip.php
+++ b/components/ILIAS/UI/src/Implementation/Component/Modal/RoundTrip.php
@@ -261,20 +261,4 @@ public function withDedicatedName(string $dedicated_name): self
{
return $this;
}
-
- /**
- * @inheritdoc
- */
- public function getPromptButtons(): array
- {
- return $this->buttons;
- }
-
- /**
- * @inheritdoc
- */
- public function getPromptTitle(): string
- {
- return $this->type;
- }
}
diff --git a/components/ILIAS/UI/src/Implementation/Component/Prompt/IsPromptContentInternal.php b/components/ILIAS/UI/src/Implementation/Component/Prompt/IsPromptContentInternal.php
deleted file mode 100644
index c6f0c248003c..000000000000
--- a/components/ILIAS/UI/src/Implementation/Component/Prompt/IsPromptContentInternal.php
+++ /dev/null
@@ -1,39 +0,0 @@
-withCloseModal(true);
+ return new State(null)->withCloseModal(true);
}
public function redirect(URI $redirect): State
{
- return (new State(null))
- ->withRedirect($redirect);
+ return new State(null)->withRedirect($redirect);
}
}
diff --git a/components/ILIAS/UI/src/Implementation/Component/Prompt/State/Renderer.php b/components/ILIAS/UI/src/Implementation/Component/Prompt/State/Renderer.php
index d7c22257d2b5..ecd7a847a2c6 100644
--- a/components/ILIAS/UI/src/Implementation/Component/Prompt/State/Renderer.php
+++ b/components/ILIAS/UI/src/Implementation/Component/Prompt/State/Renderer.php
@@ -25,6 +25,7 @@
use ILIAS\UI\Implementation\Component\Prompt\State\State;
use ILIAS\UI\Renderer as RendererInterface;
use ILIAS\UI\Component;
+use ILIAS\UI\Component\Prompt\IsPromptContent;
class Renderer extends AbstractComponentRenderer
{
@@ -53,22 +54,28 @@ protected function renderState(State $component, RendererInterface $default_rend
$tpl->parseCurrentBlock();
}
- $content_component = $component->getContent();
- if ($content_component === null) {
+ $secondary_content_components = $component->getSecondaryContent();
+ foreach ($secondary_content_components as $secondary_content_component) {
+ if ($secondary_content_component instanceof Component\MessageBox\MessageBox) {
+ $tpl->setCurrentBlock('top_secondary');
+ $tpl->setVariable('TOP_SECONDARY_CONTENT', $default_renderer->render($secondary_content_component));
+ $tpl->parseCurrentBlock();
+ continue;
+ }
+ $tpl->setCurrentBlock('bottom_secondary');
+ $tpl->setVariable('BOTTOM_SECONDARY_CONTENT', $default_renderer->render($secondary_content_component));
+ $tpl->parseCurrentBlock();
+ }
+
+ $primary_content_component = $component->getPrimaryContent();
+ if ($primary_content_component === null) {
return $tpl->get();
}
- $tpl->setVariable('CONTENT', $default_renderer->render($content_component));
+ $tpl->setVariable('PRIMARY_CONTENT', $default_renderer->render($primary_content_component));
$tpl->setVariable('TITLE', $component->getTitle());
- $buttons = $component->getButtons();
- if ($content_component instanceof \ILIAS\UI\Component\Input\Container\Form\Form) {
- $submit_button = $this->getUIFactory()->button()->standard(
- $content_component->getSubmitLabel() ?? $this->txt("save"),
- $content_component->getSubmitSignal()
- );
- $buttons[] = $submit_button;
- }
+ $buttons = $this->deriveButtonsFromPrimaryContent($primary_content_component);
$buttons[] = $this->getUIFactory()->button()
->standard($this->txt('close'), '')
@@ -83,4 +90,22 @@ protected function renderState(State $component, RendererInterface $default_rend
return $tpl->get();
}
+ /**
+ * @return Component\Button\Button[]
+ */
+ protected function deriveButtonsFromPrimaryContent(IsPromptContent $content): array
+ {
+ $buttons = [];
+ if ($content instanceof Component\MessageBox\MessageBox) {
+ $buttons = $content->getButtons();
+ }
+ if ($content instanceof Component\Input\Container\Form\Form) {
+ $submit_button = $this->getUIFactory()->button()->standard(
+ $content->getSubmitLabel() ?? $this->txt("save"),
+ $content->getSubmitSignal()
+ );
+ $buttons[] = $submit_button;
+ }
+ return $buttons;
+ }
}
diff --git a/components/ILIAS/UI/src/Implementation/Component/Prompt/State/State.php b/components/ILIAS/UI/src/Implementation/Component/Prompt/State/State.php
index 36e85c616040..02bc2338569c 100644
--- a/components/ILIAS/UI/src/Implementation/Component/Prompt/State/State.php
+++ b/components/ILIAS/UI/src/Implementation/Component/Prompt/State/State.php
@@ -33,22 +33,26 @@ class State implements I\State\State
{
use ComponentHelper;
- public const CMD_CLOSE = 'close';
- public const CMD_REDIRECT = 'redirect';
+ public const string CMD_CLOSE = 'close';
+ public const string CMD_REDIRECT = 'redirect';
protected array $buttons = [];
protected string $cmd = 'show';
protected array $params = [];
protected string $title = '';
+ /** @var I\IsPromptContent[] */
+ protected array $secondary_content = [];
public function __construct(
- protected ?I\IsPromptContent $content
+ protected ?I\IsPromptContent $primary_content,
+ I\IsPromptContent ...$secondary_content
) {
+ $this->secondary_content = $secondary_content;
}
public function getTitle(): string
{
- return $this->title ? $this->title : $this->content->getPromptTitle();
+ return $this->title;
}
public function withTitle(string $title): self
@@ -58,27 +62,34 @@ public function withTitle(string $title): self
return $clone;
}
- public function withContent(I\IsPromptContent $content): self
+ public function withPrimaryContent(I\IsPromptContent $content): self
{
$clone = clone $this;
- $clone->content = $content;
+ $clone->primary_content = $content;
+ return $clone;
+ }
+
+ public function withAdditionalSecondaryContent(I\IsPromptContent ...$content): self
+ {
+ $clone = clone $this;
+ $clone->secondary_content = array_merge($clone->secondary_content, $content);
return $clone;
}
/**
* @return Component[]
*/
- public function getContent(): ?I\IsPromptContent
+ public function getPrimaryContent(): ?I\IsPromptContent
{
- return $this->content;
+ return $this->primary_content;
}
/**
- * @return Button[]
+ * @return I\IsPromptContent[]
*/
- public function getButtons(): array
+ public function getSecondaryContent(): array
{
- return $this->content->getPromptButtons();
+ return $this->secondary_content;
}
public function withCloseModal(bool $flag): self
diff --git a/components/ILIAS/UI/src/templates/default/Prompt/tpl.promptstate.html b/components/ILIAS/UI/src/templates/default/Prompt/tpl.promptstate.html
index 47459ef5831f..93bb1029be4b 100644
--- a/components/ILIAS/UI/src/templates/default/Prompt/tpl.promptstate.html
+++ b/components/ILIAS/UI/src/templates/default/Prompt/tpl.promptstate.html
@@ -3,7 +3,13 @@
{TITLE}
- {CONTENT}
+
+ {TOP_SECONDARY_CONTENT}
+
+ {PRIMARY_CONTENT}
+
+ {BOTTOM_SECONDARY_CONTENT}
+
{BUTTONS}
@@ -16,4 +22,4 @@
{KEY}
-
\ No newline at end of file
+
diff --git a/components/ILIAS/UI/tests/Component/Prompt/State/StateTest.php b/components/ILIAS/UI/tests/Component/Prompt/State/StateTest.php
new file mode 100644
index 000000000000..f1aa444462ca
--- /dev/null
+++ b/components/ILIAS/UI/tests/Component/Prompt/State/StateTest.php
@@ -0,0 +1,147 @@
+close_button = $this->createStub(I\Button\Standard::class);
+ $this->close_button_html = sha1(I\Button\Standard::class);
+ $this->close_button->method('getCanonicalName')->willReturn($this->close_button_html);
+ $this->close_button->method('withOnLoadCode')->willReturn($this->close_button);
+
+ $this->button_factory = $this->createStub(I\Button\Factory::class);
+ $this->button_factory->method('standard')->willReturn($this->close_button);
+
+ parent::setUp();
+ }
+
+ public function getUIFactory(): NoUIFactory
+ {
+ return new class ($this->button_factory) extends NoUIFactory {
+ public function __construct(
+ protected I\Button\Factory $button_factory
+ ) {
+ }
+
+ public function button(): I\Button\Factory
+ {
+ return $this->button_factory;
+ }
+ };
+ }
+
+ public function testWithAdditionalSecondaryContent(): void
+ {
+ $content_1 = $this->createStub(C\Prompt\IsPromptContent::class);
+ $content_2 = $this->createStub(C\Prompt\IsPromptContent::class);
+
+ $state = new I\Prompt\State\State(null, $content_1);
+ $state = $state->withAdditionalSecondaryContent($content_2);
+
+ $this->assertSame($state->getSecondaryContent(), [$content_1, $content_2]);
+ }
+
+ public function testRenderGenericSecondaryContentBelowPrimaryContent(): void
+ {
+ $primary = $this->createStub(C\Prompt\IsPromptContent::class);
+ $primary_html = sha1(C\Prompt\IsPromptContent::class);
+ $primary->method('getCanonicalName')->willReturn($primary_html);
+ $secondary = $this->createStub(C\Prompt\IsPromptContent::class);
+ $secondary_html = sha1(C\MessageBox\MessageBox::class);
+ $secondary->method('getCanonicalName')->willReturn($secondary_html);
+
+ $r = $this->getDefaultRenderer(null, [$primary, $secondary, $this->close_button]);
+
+ $state = new I\Prompt\State\State($primary, $secondary);
+ $actual_html = $r->render($state);
+
+ $expected_html = <<
+
+
+ $primary_html
+ $secondary_html
+
+
+ $this->close_button_html
+
+
+
+
+EOT;
+
+ $this->assertEquals(
+ $this->brutallyTrimHTML($expected_html),
+ $this->brutallyTrimHTML($actual_html),
+ );
+ }
+
+ public function testRenderSecondaryMessageBoxAbovePrimaryContent(): void
+ {
+ $primary = $this->createStub(C\Prompt\IsPromptContent::class);
+ $primary_html = sha1(C\Prompt\IsPromptContent::class);
+ $primary->method('getCanonicalName')->willReturn($primary_html);
+ $message_box = $this->createStub(C\MessageBox\MessageBox::class);
+ $message_box_html = sha1(C\MessageBox\MessageBox::class);
+ $message_box->method('getCanonicalName')->willReturn($message_box_html);
+
+ $r = $this->getDefaultRenderer(null, [$primary, $message_box, $this->close_button]);
+
+ $state = new I\Prompt\State\State($primary, $message_box);
+ $actual_html = $r->render($state);
+
+ $expected_html = <<
+
+
+ $message_box_html
+ $primary_html
+
+
+ $this->close_button_html
+
+
+
+
+EOT;
+
+ $this->assertEquals(
+ $this->brutallyTrimHTML($expected_html),
+ $this->brutallyTrimHTML($actual_html),
+ );
+ }
+}