UI: Confirmation Prompts - #10031
Conversation
6975f6e to
ebb6b9c
Compare
03c9733 to
0949c7c
Compare
5f51546 to
a95be6f
Compare
|
@fhelfer is this ready for a technical review, or are you still rounding some corners here? |
Im still need to work on some things. I will notify if this is ready |
|
@fhelfer sure, assign this back to me once you're ready. I quickly looked over the changes and have two remarks which you could already address:
Kind regards, |
oliversamoila
left a comment
There was a problem hiding this comment.
Hello everyone.
Many thanks to @fhelfer for this PR. Many thanks also to @mjansen and @thisby, who have already discussed this topic at length beforehand.
This new UI component is already looking good in the UI Service documentation. Having reviewed the various new features and changes, I, as UI Coordinator, would like to give it the green light. Conditional on feedback from @thibsy's code review and an assessment of accessibility by @Annett7811.
From the perspective of the project manager for our major project ‘Removing of Legacy-UIComponents-Service and Table’, I would like to emphasise its relevance once again and hope that we can move forward with this.
Best regards,
@oliversamoila
There was a problem hiding this comment.
Hello together!
From an accessibility perspective, the result looks good. One small note:
- Accessibility / Follow-up: After the transition to the “Confirmation result” state, there is no reliable, visible focus. Even though the MessageBox used is an existing component, the new confirmation prompt should be able to set a clear focus target when the state changes. It would be helpful to check whether this can be fixed as part of this PR or if a linked follow-up issue can be created.
Thank you very much for your work.
Best regards,
@Annett7811
425dd0a to
7f7fcd5
Compare
|
Hi all, we (UI coordinators) decided to label this for the next JF already, since the one after that will otherwise cause some larger delay. The review will likely not be done until then, so there might still be some minor interface changes that occur during the final iteration. We would communicate them after the integration of this PR at JF again. |
…nfirmationRedirect Example + BriefEntitiy
|
Jour Fixe, 24 AUG 2026: @fhelfer gave a presentation of the intention and implementation of this PR. We highly appreciate this suggestion and accept it for trunk after the requested changes that @thibsy has requested. To prevent misunderstanding: the confirmation message shown on the mock-up is only an example. In the real implementation the existing confirmation will be used, instead. |
7f7fcd5 to
70dfa8e
Compare
thibsy
left a comment
There was a problem hiding this comment.
Hi @fhelfer,
Thx a lot for working on this complex workflow and its UI components!
I think its important that we get this composition right, before any usages of the legacy confirmation GUI are migrated towards the UI framework. I will therefore summarise the dilemma we are facing and why the pivot below is still necessary (as discussed with you today on Discord).
Read namespaces ILIAS\UI\Component as C and ILIAS\UI\Implementation\Component as I throughout this review.
The dilemma: in theory, we could already implement the confirmation workflow with some minor adjustments to the C\Prompt\State\Factory::show() method, so it supports more than 1 C\Prompt\IsPromptContent. This way, consumers of the framework could simply provide a form that consists of C\Input\Field\Hidden inputs for each technical identifier, along with a C\Listing\Entity\Entity to show what identifiers are operated on and a C\MessageBox\MessageBox for the question. This does however create an implicit coupling between the listing and the form, since they essentially need to show the same information of the same set of technical identifiers. To shift this towards the UI framework and prevent divergence, we wanted to encapsulate this in a convenient way.
The pivot: we already went into the right direction by trying to encapsulate this behind a dedicated component, concretely a C\Prompt\State\Factory::confirm() state, but we noticed during development that we would have expose the data processing functionality to the form we used internally on the C\Prompt\State\State public interface. This would be very unnatural, since a state serves another purpose. The pivot @fhelfer and I already discussed is: the problem we currently face is already solved by the prompt infrastructure, because it allows to provide a form as state content while the form remains its own entity. If we hide this behind a higher order component, we loose the ability to use its data processing functionality. So to avoid this and reuse most of the data processing infrastructure, we should implement this confirmation as an C\Input\Field instead. Although this will be an unusual kind of input, since it should not be operated and only visualise provided data, we feel like it is still the most natural place at the moment. A precondition for this is currently being worked on by @schmitz-ilias, as he and I discussed in #11105.
This leads to the following change requests for the current proposal:
- Add
C\Input\Field\Factory::entity(): introduce a new factory method for an entity input. It should only accept aC\Entity\EntityRetrievalas argument, which will be used later to factor entities for the listing. The method description should explain that this input exists primarily to carry along entities during form roundtrips. Explain the context around confirmation prompts briefly. - Add
I\Input\Field\Entity: implement the new input very similar to theI\Input\Field\TreeSelectinput. It should extend fromI\Input\Field\HasDynamicInputs, sowithValue()calls generate new hidden inputs. This is how we define the payload for confirmation prompts. - Add
I\Input\Field\Renderer::renderEntityField(): implement the rendering of theI\Input\Field\Entityinput also similar to theI\Input\Field\TreeSelect(seeI\Input\Field\Renderer::prepareTreeSelectTemplate()). The crucial part is how theI\Input\Field\Entity::getGeneratedDynamicInputs()and theC\Entity\EntityRetrieval::getEntitiesByIds()are iterated in lockstep to ensure there is no divergence. Inside this loop you need to check that the generated entity is of the correct instance and render it using the rendering chain. We probably want to add a new template for this input that wraps this up in an unordered list as well. - Update
I\Entity\EntityRendererFactory: the context now changes from'StateStatePrompt'to'EntityFieldInput'(or similar). - Rename
I\Entity\BriefEntityRenderer: please name thisEntityFieldContextRenderer, so its clear when this rendering will be applied. - Move
I\Entity\Entity::isCompactListItem(): this implements a design decision which should not take place on the composable DTO. We should always delegate to the context renderer insideI\Entity\EntityRendererFactoryand decide whether to run the default rendering or not there. You can achieve this by makingI\Entity\BriefEntityRendererextendI\Entity\Rendererand callparentif the condition isn't met. You can also drop theinstanceofcheck inI\Entity\EntityRendererFactory. - Revert changes to
C\Prompt\andI\Promptnamespace: we will encapsulate this all inside a newC\Input\Field\Entity, which can be provided to aC\Input\Container\Form\Standardand later onC\Prompt\State\Factory::show(). This will be possible once @tschmitz-ilias completed his work. - Verify JS changes: I am not sure if we still need the JS changes you propose. Could you explain or verify if we really need this?
I think this should already be the larger part of the pivot. If there are some unanswered questions or details, please ping me on Discord.
Kind regards,
@thibsy (as UI coordinator)

Dear colleagues,
After some finishing of the
Promptcomponent with #9183, this PR introduces a new approach to implement "Confirmation Modals" by composing different UI components with the goal of eventually replacing the legacyilConfirmationGUI. The solution centers around an enhancedMessageBoxcomponent that can now render either action links/buttons or anEntityListingto display affected items requiring user interaction.After in-depth discussions with the "UI Clinic", we concluded that reusing the existing
EntityListingcomponent is preferable to introducing a new derivative (such as aBriefEntity). We also addressed the potential conflict between rendering links/buttons and entities within the same component (MessageBox), and considered how to handle this in a way that avoids parameterization issues for consumers (semantic documentation and exceptions). Additionally, we reviewed the current properties of the Entity interface and agreed that only the consumers have the necessary context to determine the appropriate values for primary/secondary identifiers and other slots, such as featured properties.Current Implementation
MessageBoxcomponent to support:EntityListingfor itemized confirmationsLinksAndEntitiesMustBeExclusiveException, that throws if a consumer tries to use bothMessageBoxRendererfor compact listing presentation that replaces the standard design for anEntityListingwhen using them in the context of "Confirmation Modals"Key challenges
We are facing challenges regarding the design of the final piece of these composed components: rendering and transporting technical identifiers for the entities listed in the "Confirmation Modal".
We have discussed several possible approaches (acknowledging there may be others), but we believe it would not be wise to proceed further without broader discussion and clear decisions, especially given the potential cost of moving in the wrong direction. We are very interested in any kind of feedback, particularly concrete suggestions.
In our opinion, three key decisions need to be made:
MessageBoxare already propagated to the parentPromptcomponent and itsPrompt\State.<form>, or as a URL for a button target or dynamic request) to enable easy transport to the server while respecting specifications, standards, and security considerations?To reliably transport the technical identifiers of the listed entities from the client to the server, at least one component in this composite must be enhanced to accept and render technical identifiers as input.
Advantages of embedding identifiers in a form:
Drawbacks of other approaches:
Table > Data, this approach violates HTTP method conventions for destructive or sensitive operations, can easily exceed practical URL length limits, and exposes identifiers to logs and caches.Given these trade-offs, embedding hidden fields in a POST-capable form strikes the best balance between usability, maintainability, and security.
While the
EntityListingalready receives the full set of entities (and their associated data for presentation), we propose that the technical identifiers relevant for server communication should be passed explicitly to theMessageBox. TheEntityListing’s responsibility is purely presentational, to render a list of entities with their display properties. It should remain agnostic to how these entities are used in subsequent user actions.The
MessageBox’s responsibility is to present a message (including optional actions) in a decision-making context. In confirmation scenarios, it is the logical owner of the data required to execute the chosen action, including technical IDs.MessageBoxitself accepts and renders the entity IDs as hidden input elements in a minimal form. This form would be submitted via HTTP POST when the user confirms the action. The IDs could be passed via an explicit interface method such aswithUniqueIds()or as a second (optional) parameter when passing theEntityListinginwithEntityListing(). If this is the case, theMessageBoxshould, in our opinion, not pass its buttons up to thePromptand itsPrompt\State, but instead be responsible itself for rendering a minimal form, the buttons, and connecting both.MessageBoxalready exposes its buttons by implementing\ILIAS\UI\Implementation\Component\Prompt\IsPromptContentInternal, the same mechanism could be used for the entity IDs. In this case, thePrompt(more specifically, thePrompt\Statecomponent) would be responsible for rendering the form with the input elements and for connecting the buttons to the form.Finally: We do not believe that we need an elaborated data type for the IDs, a simple
stringwould be sufficient.We are proposing a basic layout and style for rendering entities within the "Confirmation Modal", which intentionally differs from how entities are rendered in a global context. If you have any ideas, requirements, or suggestions regarding this (especially for the properties of the entities), we would be happy to hear them.
Discussion Welcome
Best regards,
Fabian