Support multi-select answers for Duo question
What does this MR do and why?
Renders a Duo question that accepts several answers as checkboxes rather than one-click options, so picking one no longer settles a question that wanted a set. This is a follow-up to !249919 (merged) and !250539 (merged).
Every ticked option and a typed answer, if there is one, go together as a single reply that names each choice as a bullet and records the chosen ids in one marker. Answering in your own words works here too, as a checkbox row that ticks itself as soon as you type.
The answered state lists one row per answer. It is read back from the reply's bullets rather than by mapping ids to options, because an answer written in the reader's own words exists nowhere else.
References
Screenshots or screen recordings
| Default State | Typing custom answer | Submitted Multiple Options | Submitted Single Option |
|---|---|---|---|
![]() |
![]() |
![]() |
![]() |
| Multi-line Option | Focus State | Check on row click |
|---|---|---|
![]() |
How to set up and validate locally
Setting up mock data
The backend that posts these questions is still not merged, so post the question yourself. Any comment carrying a json:duo-question fenced block is treated as a Duo question, and "multiple": true is what makes it a multi-select one.
- Enable the feature flag in the Rails console:
Feature.enable(:duo_workplan_async_flow) - Open any work item you can comment on.
- Post a comment with the contents below, using your own user account.
Which SAML 2.0 capabilities are in scope for the first release?
```json:duo-question
{"type": "closed", "question": "Which SAML 2.0 capabilities are in scope for the first release?", "multiple": true, "options": [{"id": "sp_sso", "label": "SP-initiated SSO", "recommended": true}, {"id": "jit", "label": "Just-in-time provisioning", "recommended": true}, {"id": "idp_sso", "label": "IdP-initiated SSO"}, {"id": "scim", "label": "SCIM provisioning and group mapping"}]}
```The comment starts out as an individual note, and GitLab promotes it to a resolvable thread on the first reply, since Notes::BuildService calls convert_to_discussion!. That is what lets answering resolve the thread.
Answering resolves the thread, so each question can only be answered once. Post the comment again whenever you want a fresh one.
Testing the UI
- Reload the work item. The question should render with a checkbox per option, a
Recommendedbadge on each option the agent recommends (more than one is expected here), a text input below them, and aSubmitbutton. - Leave everything unticked.
Submitshould stay disabled, since there is no answer to send. - Tick two options and submit. One reply should post, naming each choice as a bullet and carrying both ids in a single marker, and the thread should resolve:
- SP-initiated SSO - Just-in-time provisioning <!-- duo-answer: sp_sso,jit --> - Post the question again, then type an answer of your own without ticking anything. The checkbox on that row should tick itself, and submitting should post it as a bullet marked
rejected, alongside any options you also ticked. - Clear the typed answer. The row should untick and its checkbox should go back to being unusable, rather than staying ticked, and
Submitshould disable again if nothing else is ticked. - Reload the page. The card should list one row per answer, including the typed one, read back from the reply.
- Type a partial answer and reload without submitting. It should come back in the input, already counted towards the answer.
- Check that a single-select question still behaves as before: options answer on click, with no checkboxes and no
Submit. - Check both light and dark mode.
MR acceptance checklist
Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.
Related to #608852 (closed)




