Skip to content

Fix error state is not visible when translation is missing#16157

Merged
andreslucena merged 13 commits intodecidim:developfrom
i-need-another-coffee:fix/error-on-i18n-field
Feb 26, 2026
Merged

Fix error state is not visible when translation is missing#16157
andreslucena merged 13 commits intodecidim:developfrom
i-need-another-coffee:fix/error-on-i18n-field

Conversation

@alecslupu
Copy link
Copy Markdown
Contributor

@alecslupu alecslupu commented Feb 20, 2026

🎩 What? Why?

In this PR i am fixing the an issue when there is an error on a i18n field and not visible if the user has other locale.

📌 Related Issues

Link your PR to an issue

Testing

  1. Login as admin & visit the admin panel
  2. Visit a Process , choose a blog component
  3. Choose Spanish or Catalan as display language
  4. Click on "Nova publicació"
  5. Fill in "Titol" with some random text
  6. Click on Crear
  7. See the error text in the select box
  8. Apply patch, restart the server (needed for reading the formBulder )
  9. Repeat steps 1 - 6
  10. See the Select is automatically selected to english
  11. The text field is changed to english

📷 Screenshots

image

♥️ Thank you!

Summary by CodeRabbit

  • Improvements

    • Language selection now synchronizes immediately on load, improves per‑locale tab/selector behavior, highlights locales with validation errors, and enhances accessibility states.
  • Tests

    • Added system and controller tests for initial language activation and multi‑locale form validation when required names are missing.
  • Chores

    • Updated spelling dictionary with two additional entries.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Feb 20, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Dispatches an initial "change" event from the language-change controller on connect, marks the first locale with errors as the active/selected locale in language selectors, adds tests for the controller and admin organization form validation, and updates the spelling exceptions list.

Changes

Cohort / File(s) Summary
Spelling exceptions
.github/actions/spelling/expect.txt
Added two words (actualitzar, estar) to the spelling exceptions list.
Language change controller
decidim-core/app/packs/src/decidim/controllers/language_change/controller.js, decidim-core/app/packs/src/decidim/controllers/language_change/language_change.test.js
Controller now dispatches a change event on connect to initialize panels; test added to assert the panel matching the selected option is activated on connect.
Form builder / validation
decidim-core/lib/decidim/form_builder.rb
Refactored language rendering: compute error_on_locale and propagate it through new helpers (translated_labels, translated_tabs, create_language_selector, language_selector_select, language_tabs); updated tab ARIA handling and per-locale active/error rendering.
System tests
decidim-admin/spec/system/admin_manages_organization_spec.rb
Added system specs verifying official-language validation and visibility when translations are missing across different locale counts.
Package manifest
package.json
Single-line manifest update recorded in package.json.

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant Select as "Locale Select"
  participant Controller as "LanguageChangeController"
  participant Panels as "Locale Panels"

  User->>Select: has current locale selected
  Select->>Controller: controller connects
  Controller->>Select: add "change" listener
  Controller->>Select: dispatch "change" event
  Controller->>Panels: activate panel for selected locale
  Panels-->>User: render active panel, set aria-hidden accordingly
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • andreslucena
  • github-actions

Poem

🐇
I nudged the select with gentle care,
so hidden faults are found somewhere.
Tabs unfurl, the panels gleam,
admins spot the missing seam. 🥕

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Fix error state is not visible when translation is missing' accurately describes the main objective of the PR, which is to make validation error states visible on multilingual fields.
Linked Issues check ✅ Passed The PR implements fixes for both linked issues: #16079 (error visibility on missing translations) and #16195 (all mandatory fields should be highlighted), with form builder changes, controller updates, and comprehensive test coverage.
Out of Scope Changes check ✅ Passed All changes are scoped to the objectives: form builder refactoring for error visibility, JavaScript controller enhancement for locale switching, test coverage, and spelling additions. No extraneous modifications detected.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions bot added module: core module: admin type: fix PRs that implement a fix for a bug labels Feb 20, 2026
github-actions[bot]
github-actions bot previously approved these changes Feb 20, 2026
github-actions[bot]
github-actions bot previously approved these changes Feb 20, 2026
@alecslupu alecslupu marked this pull request as ready for review February 20, 2026 12:44
Copilot AI review requested due to automatic review settings February 20, 2026 12:44
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes a UX issue where validation errors on multilingual form fields are not visible when the user is viewing the form in a locale different from the one with the error. The solution automatically switches the language selector dropdown to the first locale with an error, making the error immediately visible to the user.

Changes:

  • Modified language selector dropdown to mark error locales as selected
  • Added automatic tab switching on page load by dispatching a change event when the controller connects
  • Added system test to verify error locale is automatically displayed

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
decidim-core/lib/decidim/form_builder.rb Sets selected attribute on dropdown options for locales with errors
decidim-core/app/packs/src/decidim/controllers/language_change/controller.js Dispatches change event on connect to activate the selected tab
decidim-admin/spec/system/admin_manages_organization_spec.rb Adds system test verifying automatic error locale selection
.github/actions/spelling/expect.txt Adds Catalan words used in the test

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (2)
decidim-admin/spec/system/admin_manages_organization_spec.rb (2)

108-111: Consider adding an assertion for the (error!) suffix in the dropdown option.

The is_error branch in language_selector_select changes the option title to "name_with_error" (e.g., "English (error!)"). The test confirms the panel is visible and the field shows the blank-error message, but doesn't verify that the dropdown option itself is re-labeled. Adding have_select("organization-name-tabs", with_options: [/English.*error/i]) (or the exact translated string) would fully exercise the title-change logic.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@decidim-admin/spec/system/admin_manages_organization_spec.rb` around lines
108 - 111, Test currently checks panel visibility and blank-error message but
omits asserting the dropdown option label change from the
language_selector_select is_error branch; update the spec in
admin_manages_organization_spec.rb to also assert the language tab select (e.g.,
"organization-name-tabs") contains the error-marked option by adding an
expectation like have_select("organization-name-tabs", with_options:
[/English.*error/i] or the exact translated "English (error!)") so the
name_with_error path in language_selector_select is exercised and verified.

96-96: Test description doesn't reflect what's actually being tested.

"displays the form for official language" is ambiguous. The test is specifically validating that after submitting with a missing English translation while in the Catalan locale, the error is surfaced by auto-selecting the English panel.

📝 Suggested rename
-      it "displays the form for official language" do
+      it "auto-selects the errored locale's panel after submitting with a missing primary-locale translation" do
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@decidim-admin/spec/system/admin_manages_organization_spec.rb` at line 96, The
example description for the spec example in the it block currently reads
"displays the form for official language" but is ambiguous; rename the it
description to clearly state the behavior being validated (e.g., "selects the
English translation panel when English translation is missing after submitting
in Catalan locale") so readers know the test checks that submitting with a
missing English translation in the Catalan locale auto-selects the English
panel; update only the example string in the it block in
admin_manages_organization_spec.rb to the new clearer description.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@decidim-core/lib/decidim/form_builder.rb`:
- Around line 805-816: Precompute the first locale that has an error before
generating options so only that option gets selected: call
error?(name_with_locale(name, locale)) or similar to find the first errored
locale, store it (e.g., first_error_locale), then in the loop that builds option
tags (the block using locales.each_with_index and content_tag(:option, ...)) set
selected: true only when locale == first_error_locale; keep using
name_with_locale, error?, sanitize_tabs_selector and tabs_id as in the current
code to build values and ids.
- Around line 807-810: The form builder
(decidim-core/lib/decidim/form_builder.rb) calls I18n.t("name_with_error",
scope: "locale") when rendering a language selector with errors, but 37 locale
YAMLs are missing that key; add a name_with_error entry under the same "locale"
scope in each of the listed locale files (match the structure and style of the
existing "name" key in those files) so that I18n.t("name_with_error", scope:
"locale") returns a proper translated string instead of "translation missing".

---

Nitpick comments:
In `@decidim-admin/spec/system/admin_manages_organization_spec.rb`:
- Around line 108-111: Test currently checks panel visibility and blank-error
message but omits asserting the dropdown option label change from the
language_selector_select is_error branch; update the spec in
admin_manages_organization_spec.rb to also assert the language tab select (e.g.,
"organization-name-tabs") contains the error-marked option by adding an
expectation like have_select("organization-name-tabs", with_options:
[/English.*error/i] or the exact translated "English (error!)") so the
name_with_error path in language_selector_select is exercised and verified.
- Line 96: The example description for the spec example in the it block
currently reads "displays the form for official language" but is ambiguous;
rename the it description to clearly state the behavior being validated (e.g.,
"selects the English translation panel when English translation is missing after
submitting in Catalan locale") so readers know the test checks that submitting
with a missing English translation in the Catalan locale auto-selects the
English panel; update only the example string in the it block in
admin_manages_organization_spec.rb to the new clearer description.

github-actions[bot]
github-actions bot previously approved these changes Feb 20, 2026
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
decidim-core/app/packs/src/decidim/controllers/language_change/language_change.test.js (1)

76-87: LGTM — test correctly covers the new connect() dispatch-change behavior.

One optional consistency note: the sibling handleChange test at line 92 uses selectElement.value = "#update_organization-name-tabs-name-panel-1" to set the selection. Using the same idiom here would make the two tests easier to compare at a glance.

♻️ Optional style alignment
-      const options = selectElement.querySelectorAll("option");
-      options[1].selected = true;
+      selectElement.value = "#update_organization-name-tabs-name-panel-1";
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@decidim-core/app/packs/src/decidim/controllers/language_change/language_change.test.js`
around lines 76 - 87, The test sets selection by toggling options[1].selected,
which is inconsistent with the sibling test that uses selectElement.value;
update this test to set selectElement.value =
"#update_organization-name-tabs-name-panel-1" before calling
controller.disconnect() and controller.connect() so it matches the idiom used in
the handleChange test and still triggers controller.connect() behavior affecting
panel0/panel1 and their ariaHidden/is-active assertions.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In
`@decidim-core/app/packs/src/decidim/controllers/language_change/language_change.test.js`:
- Around line 76-87: The test sets selection by toggling options[1].selected,
which is inconsistent with the sibling test that uses selectElement.value;
update this test to set selectElement.value =
"#update_organization-name-tabs-name-panel-1" before calling
controller.disconnect() and controller.connect() so it matches the idiom used in
the handleChange test and still triggers controller.connect() behavior affecting
panel0/panel1 and their ariaHidden/is-active assertions.

coderabbitai[bot]
coderabbitai bot previously approved these changes Feb 20, 2026
@alecslupu alecslupu requested a review from a team February 20, 2026 13:19
@andreslucena
Copy link
Copy Markdown
Member

@alecslupu I'd expect that the behavior is the same for the organizations that have less than 4 locales:

image

Can you fix that please? Thanks

@andreslucena andreslucena linked an issue Feb 24, 2026 that may be closed by this pull request
@andreslucena
Copy link
Copy Markdown
Member

This is also solving #16195

github-actions[bot]
github-actions bot previously approved these changes Feb 25, 2026
github-actions[bot]
github-actions bot previously approved these changes Feb 26, 2026
github-actions[bot]
github-actions bot previously approved these changes Feb 26, 2026
github-actions[bot]
github-actions bot previously approved these changes Feb 26, 2026
@alecslupu
Copy link
Copy Markdown
Contributor Author

@andreslucena this is ready for another round

@andreslucena andreslucena merged commit 69d7b19 into decidim:develop Feb 26, 2026
77 of 78 checks passed
@alecslupu alecslupu deleted the fix/error-on-i18n-field branch February 26, 2026 12:09
@alecslupu alecslupu added release: v0.30 Issues or PRs that need to be tackled for v0.30 release: v0.31 Issues or PRs that need to be tackled for v0.31 labels Feb 26, 2026
@andreslucena andreslucena removed the release: v0.30 Issues or PRs that need to be tackled for v0.30 label Mar 19, 2026
@andreslucena
Copy link
Copy Markdown
Member

Removing the v0.30 release label, as we would need the Stimulus controller decidim-core/app/packs/src/decidim/controllers/language_change/controller.js and in v0.30:

a. we don't have Stimulus
b. we don't have this file as it was introduced with #16122 - a fix for Taxonomies, that isn't in v0.30

So, too much time to invest for fixing this for v0.30. We will skip this.

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

Labels

configuration module: admin module: core no-backport Pull Requests that should not be backported release: v0.31 Issues or PRs that need to be tackled for v0.31 type: fix PRs that implement a fix for a bug

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Mandatory fields on new process creation Error state is not visible when translation is missing

3 participants