Skip to content

fix(setup-wizard): translate the body and the tab labels, not just the heading - #871

Merged
rubenvdlinde merged 1 commit into
developmentfrom
fix/setup-wizard-translates-body-and-tabs
Aug 31, 2026
Merged

fix(setup-wizard): translate the body and the tab labels, not just the heading#871
rubenvdlinde merged 1 commit into
developmentfrom
fix/setup-wizard-translates-body-and-tabs

Conversation

@rubenvdlinde

Copy link
Copy Markdown
Contributor

A setup wizard on a Dutch instance rendered "Welkom" over an English paragraph, between a translated Annuleren and Volgende. That reads as a bug rather than as a missing string, and the consuming app could not fix it from its side.

stepTitle() was routed through cnTranslate and everything else was not:

  • step.body was interpolated verbatim in four places (info, choice, config-fields, run-action)
  • wizardSteps() used s.title raw for the tab strip, so the same string was translated inside the step and untranslated in the tab above it
  • optionsFor() returned option labels raw, so a choice step listed its options in English

How it was found

Measured on decidiq (2026-08-30), which stopped planting 334 unchosen objects on install and now asks which example set to load (decidiq#1024). It shipped correct Dutch for every one of those strings in l10n/nl.json. The heading picked it up; the question, the options and the explanation did not, because this component never asked for them.

This is the same shape as #863 ("widget titles never asked the host catalogue"): translation here is per-field, and a field nobody routed is a field that can never be localised.

What changes

  • stepBody() mirrors stepTitle(), and the four raw interpolations use it
  • the tab strip uses stepTitle()
  • option labels are translated; option values are not

That last split is deliberate: scalarChoice() reads .value, and that is what reaches POST /api/setup/config, so translating a label cannot change what gets stored. Translating the value would.

Verification

CnSetupWizard.spec.js   21 passed  (17 existing + 4 new)
full suite             594 suites, 6997 tests, all passing

Each new test fails without the change:

  • resolves a step body through the injected cnTranslate
  • returns an empty body rather than undefined, so a bodyless step renders nothing
  • translates the tab-strip labels, not just the heading inside the step
  • translates a choice option LABEL and leaves its VALUE alone

🤖 Generated with Claude Code

…e heading

A setup wizard on a Dutch instance rendered "Welkom" over an English paragraph,
between a translated Annuleren and Volgende. That reads as a bug rather than as
a missing string, and the app could not fix it from its side.

`stepTitle()` was routed through `cnTranslate` and everything else was not:

- `step.body` was interpolated verbatim in FOUR places (info, choice,
  config-fields, run-action)
- `wizardSteps()` used `s.title` raw for the tab strip, so the same string was
  translated inside the step and untranslated in the tab above it
- `optionsFor()` returned option labels raw, so a `choice` step listed its
  options in English

Measured on decidiq (2026-08-30), which stopped planting 334 unchosen objects
on install and now asks which example set to load. It shipped correct Dutch for
every one of those strings in l10n/nl.json. The heading picked it up; the
question, the options and the explanation did not, because this component never
asked.

So `stepBody()` mirrors `stepTitle()`, the tab strip uses `stepTitle()`, and
option LABELS are translated while option VALUES are not: `scalarChoice()` reads
`.value` and that is what reaches `POST /api/setup/config`, so translating a
label cannot change what gets stored.

Verified: 21 CnSetupWizard tests pass, four of them new and each failing before
this change. Full suite 6997/6997.
@github-actions

Copy link
Copy Markdown
Contributor

Quality Report — ConductionNL/nextcloud-vue @ 93be27c

Check PHP Vue Security License Tests
lint ⏭️
phpcs ⏭️
phpmd ⏭️
psalm ⏭️
phpstan ⏭️
phpmetrics ⏭️
eslint
stylelint
build
test
check-build
check-public-safe
check-docs
check-jsdoc
check-integration-parity
check-peers
check-docs-fresh
check-a11y
check-smoke
check-vue3-compile
composer
npm ✅ 556/556
app:check-code ⏭️
info.xml ⏭️
REUSE
PHPUnit ⏭️
Newman ⏭️
Playwright ⏭️
Hydra gates ⏭️

Quality workflow — 2026-08-30 23:12 UTC

Download the full PDF report from the workflow artifacts.

@rubenvdlinde
rubenvdlinde merged commit b176eb5 into development Aug 31, 2026
37 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant