Skip to content

UI: Confirmation Prompts - #10031

Open
fhelfer wants to merge 16 commits into
ILIAS-eLearning:trunkfrom
fhelfer:ui/confimration-modals
Open

UI: Confirmation Prompts#10031
fhelfer wants to merge 16 commits into
ILIAS-eLearning:trunkfrom
fhelfer:ui/confimration-modals

Conversation

@fhelfer

@fhelfer fhelfer commented Aug 27, 2025

Copy link
Copy Markdown
Contributor

Dear colleagues,

After some finishing of the Prompt component with #9183, this PR introduces a new approach to implement "Confirmation Modals" by composing different UI components with the goal of eventually replacing the legacy ilConfirmationGUI. The solution centers around an enhanced MessageBox component that can now render either action links/buttons or an EntityListing to display affected items requiring user interaction.
After in-depth discussions with the "UI Clinic", we concluded that reusing the existing EntityListing component is preferable to introducing a new derivative (such as a BriefEntity). 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

  • Enhancement of the MessageBox component to support:
    • Traditional action links/buttons (existing functionality)
    • Allowing an EntityListing for itemized confirmations
  • Adding documentation and validation via LinksAndEntitiesMustBeExclusiveException, that throws if a consumer tries to use both
  • Introducing a dedicated MessageBoxRenderer for compact listing presentation that replaces the standard design for an EntityListing when using them in the context of "Confirmation Modals"

Key challenges

  1. Transport of Technical Identifiers

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:

  1. Besides presentation topics, which are, in our opinion, already fully addressed, which component should be responsible for accepting the technical IDs, and how should a consumer pass them?
  2. Which component should be responsible for rendering the technical IDs? This may not necessarily be the same component, as the buttons of the MessageBox are already propagated to the parent Prompt component and its Prompt\State.
  3. How should the technical IDs be represented in the rendering process (as an HTML <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:

  • Specification compliance: Using POST for transmitting entity IDs adheres to HTTP semantics, where GET should not be used for state-changing operations.
  • Security and privacy: Entity IDs remain in the request body and are not exposed in the URL, reducing the risk of information leakage via server logs, browser history, analytics tools, or link sharing.

Drawbacks of other approaches:

  • Appending IDs as URL query parameters: While simple to implement and currently used in places like 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 EntityListing already 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 the MessageBox. The EntityListing’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.

  • Option 1: The MessageBox itself 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 as withUniqueIds() or as a second (optional) parameter when passing the EntityListing in withEntityListing(). If this is the case, the MessageBox should, in our opinion, not pass its buttons up to the Prompt and its Prompt\State, but instead be responsible itself for rendering a minimal form, the buttons, and connecting both.
  • Option 2: Since the MessageBox already exposes its buttons by implementing \ILIAS\UI\Implementation\Component\Prompt\IsPromptContentInternal, the same mechanism could be used for the entity IDs. In this case, the Prompt (more specifically, the Prompt\State component) 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 string would be sufficient.

  1. Layout/Style of the Entities

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

  • Additional approaches of sending the technical identifiers for the entities to the server endpoint
  • Layout/Style of the rendered entities
  • Other objections or error-corrections

Best regards,
Fabian

@fhelfer
fhelfer marked this pull request as draft August 27, 2025 08:49
@fhelfer fhelfer added kitchen sink improvement php Pull requests that update Php code labels Aug 27, 2025
@fhelfer
fhelfer force-pushed the ui/confimration-modals branch from 6975f6e to ebb6b9c Compare August 27, 2025 09:00
@fhelfer fhelfer changed the title UI/confimration modals UI: Confirmation Modals Aug 27, 2025
@fhelfer
fhelfer marked this pull request as ready for review August 27, 2025 09:41
@fhelfer
fhelfer force-pushed the ui/confimration-modals branch from 03c9733 to 0949c7c Compare August 28, 2025 07:48
@Amstutz Amstutz removed their assignment Aug 28, 2025
@dsstrassner dsstrassner assigned oliversamoila and unassigned klees and yvseiler Dec 1, 2025
@BettyFromHH BettyFromHH added the css/html Pull requests that propose changes to CSS/SCSS or HTML files. label Jan 21, 2026
@fhelfer
fhelfer force-pushed the ui/confimration-modals branch 2 times, most recently from 5f51546 to a95be6f Compare July 2, 2026 10:07
@thibsy

thibsy commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

@fhelfer is this ready for a technical review, or are you still rounding some corners here?

@fhelfer

fhelfer commented Jul 9, 2026

Copy link
Copy Markdown
Contributor Author

@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

@thibsy thibsy assigned fhelfer and unassigned thibsy and oliversamoila Jul 9, 2026
@thibsy

thibsy commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

@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:

  • please remove the coupling of the message box and the entity listing again. The listing should be displayed on its own below the message box, not within it. If this is required to transfer information, I might have overlooked something, but I think with the interface I proposed to you this should already be possible.
  • please rebase this onto latest trunk early, I have recently integrated the grid entity listing which brings some changes to the listing component family. Be careful during conflicts resolution.

Kind regards,
@thibsy

@fhelfer
fhelfer requested a review from oliversamoila July 16, 2026 11:47

@oliversamoila oliversamoila left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

@oliversamoila

Copy link
Copy Markdown
Contributor

Below you can see an Example for a Prompt within a 'message box' and an EntityListing – such as a BriefEntity.
However, the documentation also contains further examples of Prompts.


 
image

@Annett7811 Annett7811 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

@thibsy

thibsy commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

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.

@matthiaskunkel

Copy link
Copy Markdown
Member

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.

@fhelfer
fhelfer force-pushed the ui/confimration-modals branch from 7f7fcd5 to 70dfa8e Compare August 25, 2026 09:42

@thibsy thibsy left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 a C\Entity\EntityRetrieval as 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 the I\Input\Field\TreeSelect input. It should extend from I\Input\Field\HasDynamicInputs, so withValue() 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 the I\Input\Field\Entity input also similar to the I\Input\Field\TreeSelect (see I\Input\Field\Renderer::prepareTreeSelectTemplate()). The crucial part is how the I\Input\Field\Entity::getGeneratedDynamicInputs() and the C\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 this EntityFieldContextRenderer, 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 inside I\Entity\EntityRendererFactory and decide whether to run the default rendering or not there. You can achieve this by making I\Entity\BriefEntityRenderer extend I\Entity\Renderer and call parent if the condition isn't met. You can also drop the instanceof check in I\Entity\EntityRendererFactory.
  • Revert changes to C\Prompt\ and I\Prompt namespace: we will encapsulate this all inside a new C\Input\Field\Entity, which can be provided to a C\Input\Container\Form\Standard and later on C\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)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

css/html Pull requests that propose changes to CSS/SCSS or HTML files. improvement kitchen sink php Pull requests that update Php code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

10 participants