Symfony's required default forced an answer to every question no matter
what the mandatory checkbox said. Optional choice questions now offer a
dedicated 'Keine Antwort' option, optional range and text questions a
'Keine Angaben machen' checkbox (preselected for ranges, because a slider
always submits a value); the side that is not chosen gets dimmed but stays
clickable. Mandatory ranges start their value display at '?' and reject
the submit until the slider was actually used, so the browser's midpoint
default no longer leaks into the results.
Empty answers are stored as a deliberate 'no answer', kept out of counts,
averages and charts, and reported separately on the results page and in
the PDF export. Also gives the reader textarea its full width and field
styling, adds grid overflow guards for unbreakable content and styles the
form error box.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Quill 2's getSemanticHTML() serializes every space as U+00A0, turning a
whole paragraph into one unbreakable word that stretched the survey cards
far past the viewport. Normalize to plain spaces when sanitizing (which
also heals existing records on every output) and when the editor writes
the serialized HTML back into the textarea.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Add a template override for Contao's changePassword module with the
same card, explanatory copy and corporate design as the lost password
module.
The card rules keyed off .mod_lostPassword.block, which does not scale
to a third auth module. Move them to a .survey-auth-module class that
the overrides put on the wrapper themselves, so another auth module
needs one line and no new CSS.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Give the lost password module the same centred card as the login,
right-align the reset link, add explanatory copy and a way back to
the login from every dead end Contao routes through mod_message.
Contao only sets a text body on the opt-in mail, so a MessageEvent
listener adds an HTML alternative in the corporate design. It reads
the locale from the fallback root page because mails can go out from
a CLI worker, where kernel.default_locale is "en".
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Questions, editor assignments and conditions were inserted without tstamp,
so Contao rendered them with tstamp=0 -> the backend "draft" styling
(opacity .5), making question rows look greyed out despite being published.
- SurveyQuestionRepository::insert()/update() (covers create, edit, duplicate)
- SurveyEditorRepository::insert()
- SurveyConditionRepository::insert()
SurveyRepository already set tstamp. Also widened the assigned-members
checkbox-wizard columns at smaller breakpoints.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
CSRF / actions:
- List action forms now send both REQUEST_TOKEN (Contao gate) and _token
(Symfony, validated via isCsrfTokenValid) — mirrors the editor; fixes
the 400/500 "Ungültiger CSRF-Token" on publish/toggle/duplicate/delete
Public reader / URLs:
- Reader & results read auto_item via Input::get (marks the route param used)
so clean path URLs /<page>/<alias> no longer 404
- List controller generates path URLs via ['parameters' => '/'.$alias]
- Allow re-participation in the same session after a 60s cooldown
Review fixes:
- Results: merge answer snapshots by questionId+type (no more split cards on
label edits); seed "Vielleicht" when allowMaybe so screen matches Excel
- Reader: replace generic answer hint with per-option "weiter zu Frage X"
only when a jump is configured; strip HTML tags from survey description
- PDF: render free-text frequency summary; drop duplicate "Minimum" label
- Drag-sort: bundle SortableJS locally, drop the duplicated inline sort CSS/JS
from _survey_assets, throttle the backend MutationObserver
- Backend: move hardcoded tl_survey operation labels to TL_LANG (de+en)
- Remove dead code: SurveyEditorVoter, SurveyPermissionService,
categoryFilter/categorySummary + helpers, orphaned publishSurvey lang key
Reader layout:
- max-width 1000px (other views keep 1400px); back/next buttons fill the
width as equal, card-sized halves; sort handle icon offset tweak
Docs: update AI_HANDOVER (dual-token CSRF, clean URLs) and README
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Frontend editor: drag-to-sort questions with dedicated sort assets/JS
- Backend list/search refinements for tl_survey and tl_survey_content
- Repository helpers for survey/question/editor queries
- Translations and AI handover notes update