feat(assistant-wizard): reorder step 2 and add rich-radio sensitivity - #207
Merged
Merged
Conversation
Step 2 of the assistant create/edit wizard groups its fields in an
order that no longer matches how curators think about the
assistant, and the data-sensitivity choice hides behind a plain
<select> whose default is whichever case sits first in the enum.
- Reorder fields (declaration + template):
1. Title
2. Short description (tagline) — now REQUIRED
3. Description
4. Knowledge description
5. Language model + Organisation (paired on `md:` and up,
stacked on narrower viewports via `md:grid-cols-2`)
6. Tags
7. Data sensitivity
- `tagline`: `required => true`, add `NotBlank` under the
`metadata` validation group with a new `tagline_required`
translation key. Curators must now write the short one-line
summary the catalog surfaces on cards; the wizard cannot ship
an assistant without it.
- `dataSensitivity`: switch `EnumType` to `expanded => true` and
drop the `placeholder`. In the template, iterate the field's
children and render each as a rich radio card that pairs the
enum's short label with its longer descriptive copy on
`<label>` + `has-[input:checked]:` states. `choice_attr`
surfaces the description translation key on each child's
`vars.attr` so the template can reach it without dragging the
whole enum case through the view. Empty case remains
guarded by the existing `NotNull` constraint.
- Two knock-on test edits in the create-flow controller test
(set tagline before submit) plus two in the edit-flow test
(radio ChoiceFormField requires disableValidation() to force
"no radio selected"; badge selector narrows to `label
span.uppercase` so the rich-radio card spans no longer match).
- Minor whitespace normalisation in
`templates/assistant/show.html.twig` (twig-cs-fixer:
single-space rule before `#}`).
Fixes #202
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Two visual polish fixes on the reordered step 2:
- Language-model column rendered its help text through a raw
`<small>` tag, which the browser shrinks to ~80% of the parent's
font size. Every other field on the step routes its help
through Symfony's default `form_help` block (renders as a `<div>`
inheriting the row's `text-sm` size). Swap the manual `<small>`
for `form_help(language_model)` so all step-2 help texts sit at
the same size.
- Choices.js's default CSS pins `.choices__inner` at `min-height:
44px` with asymmetric `7.5px 7.5px 3.75px` padding and
`.choices { margin-bottom: 24px }`, so the enhanced language-
model widget rendered taller than the plain organisation
`<select>` sharing its row — reading as an inflated gap between
the label and the visible input. Add scoped overrides that pin
`.choices__inner` to the shared form-input shape (`py-2 px-3`,
`rounded-lg`, `border-line`, `bg-surface`) and zero out the
vendor bottom margin so the two columns align at both the
label→input baseline and the input→help baseline.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The outer `md:grid-cols-2` on step 2's language-model + organisation row stretches each column to the tallest cell's height (grid's default `align-items: stretch`). Without an explicit `align-content: start` on each column's inner grid, the shorter column distributes the extra vertical space across its tracks and inflates the gap between the label, the input, and the help line — enough that a curator reads it as a mis-alignment between the two columns. Add `content-start` (align-content: flex-start) to both column grids so their tracks stay compact at the top and any extra space falls below the last track. Applies to the language- model column's manual `<div>` and to the organisation field via a `row_attr` override on `form_row`. Same treatment for the sensitivity fieldset's help line — swap the manual `<small>` render for `form_help(sensitivity_field)` so every step-2 help text ships through Symfony's default `form_help` block at the row's `text-sm` size. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Links to issues
Fixes #202
Description
Step 2 of the assistant create/edit wizard groups its fields in an
order that no longer matches how curators think about the
assistant. The tagline sits below the long description, knowledge
sits below the language model, and language model + organisation
each occupy a full-width row when they should read as a matched
pair. The data-sensitivity choice hides behind a plain
<select>whose default is whichever case happens to sit first in the enum.
src/Form/AssistantMetadataStepType.phpandtemplates/assistant/_step_metadata.html.twig):grid gap-4 md:grid-cols-2, stacked belowmd:)required => true+NotBlankunderthe
metadatavalidation group. A newassistant.new.step_metadata.tagline_requiredtranslation key("Angiv en kort beskrivelse.") wires the message. Curators can
no longer ship an assistant without the short one-line summary
the catalog surfaces on card lists.
EnumTypegetsexpanded => true, the emptyplaceholderis dropped, and thetemplate iterates the field's children directly. Each card
pairs the enum's short label (
DataSensitivity::label()) withits longer description (
DataSensitivity::description());choice_attrsurfaces the description key on each child'svars.attrso the template can reach it without dragging thewhole enum case through the view. Card hover darkens the
border; the selected card gets
primaryborder +surface-2background viahas-[input:checked]:selectors.unchanged — just relocated into the paired column.
have
jsonBaselineentries today (title, description,languageModel, tags). Tagline isn't in the baseline, so it
never got a badge before and doesn't get one now — that
matches the current
AssistantDraftPrefiller::prefillForCreatebehaviour.
Screenshot of the result
To be added — please walk both the create and edit paths
(
POST /assistant/new→ step 2,GET /assistant/{id}/edit→ step 2) before merging. Confirm the paired columns collapse
correctly on narrow viewports and the three sensitivity cards
render distinct hover / checked states.
Checklist
Test edits (approved on the issue thread):
AssistantCreateControllerTest.php— set tagline beforesubmitting step 2 in two happy-path tests (the wizard no
longer accepts a blank tagline).
AssistantEditControllerTest.php— the radioChoiceFormFieldrejects an empty-string assignment(
"" not in choices), so the "unset dataSensitivity"negative case now calls
disableValidation()on the fieldbefore setting it. The badge assertion's selector narrows
from
label spantolabel span.uppercaseso the newrich-radio card spans no longer match.
Minor:
templates/assistant/show.html.twiggets atwig-cs-fixer whitespace normalisation on the
#}alignment inthe sensitivity-pill comment block. Zero behaviour change.
Details - AI specificities
Goal
Two things at once:
assistant: identity (title, tagline) → what it does
(description) → what it draws on (knowledge, language model +
organisation) → how it's classified (tags, data sensitivity).
it deserves — a hidden
<select>lets a curator ship anassistant without ever consciously picking, and the persisted
default is whichever case happens to be first in the enum.
Rich radios force the pick and communicate the weight of the
three options inline.
On top: tagline is now required so the catalog surface (cards)
never falls back to the long description silently.
Scope
src/Form/AssistantMetadataStepType.php— reorder->add()calls, promote
taglineto required, promotedataSensitivitytoexpanded: true+choice_attr.templates/assistant/_step_metadata.html.twig— reorder rows,add two-column wrapper for language-model + organisation,
render the rich-radio card list.
translations/validators.da.yaml— addtagline_required.Non-goals
AssistantDraft/Assistant.DataSensitivityenum values, labels, ordescriptions.
wizard's navigation.
— it keeps working exactly as today, just relocated into the
paired column.
@theme. Card sizinguses Tailwind utilities directly, matching the rest of the
codebase.
Decisions
form-theme override. The codebase has no existing form
theme, so introducing one for a single field is heavier than
looping the field's children directly.
EnumType+expanded: true+choice_attrgives us the raw material;the template's
<fieldset>/<legend>/<label>/<span>markup does the presentation.
choice_attrrather thanpassed as a separate view variable. Keeps the mapping on the
field, so the template doesn't need to know the enum exists —
it just reads
child.vars.attr['data-description-key']andtranslates it.
The DB column stays nullable so existing rows with a null
tagline continue to load; editing one of those forces the
curator to fill in the tagline on step 2 (which is the point).
Verification
task coding-standards-check→ clean.task test→ 690 tests, 2044 assertions, all green.Links
page). feat(assistant-wizard): reorder step 2 fields and turn data sensitivity into radio cards #202 handles the input side; feat(catalog): colour-code the data-sensitivity pill using the alert palette #201 handled the
output side.