Repository navigation
fix(apollo-react): replace ICU plurals in canvas counts with count-neutral labels - #1451
Conversation
There was a problem hiding this comment.
🟢 Approval recommended
The scoped wording changes consistently align all 15 catalog entries, component defaults, and affected assertions, with no blocking issues identified.
No open issues 🎉
What changed in this PR
Replaces 15 ICU plural messages in Apollo React’s canvas UI with count-neutral labels that Smartling can translate reliably, while preserving translation keys and count interpolation.
Changes:
- Updates English catalog entries to the
Label: {count}pattern. - Aligns component fallback messages with the catalog.
- Updates existing test assertions for the new wording.
| File | Description |
|---|---|
packages/apollo-react/src/canvas/locales/en.json |
Rewrites 15 count messages without plural syntax. |
packages/apollo-react/src/canvas/components/StageNode/tasks/TaskContent.tsx |
Updates the task-run tooltip fallback. |
packages/apollo-react/src/canvas/components/StageNode/tasks/TaskContent.test.tsx |
Updates task-run tooltip assertions. |
packages/apollo-react/src/canvas/components/NodeVariablesPanel/NodeVariablesPanel.tsx |
Updates section and node count fallbacks. |
packages/apollo-react/src/canvas/components/NodeVariablesPanel/NodeVariablesPanel.test.tsx |
Updates accessible count-label assertions. |
packages/apollo-react/src/canvas/components/NodeIOView/NodeIOView.test.tsx |
Updates JSON item and key count assertions. |
packages/apollo-react/src/canvas/components/JsonTree/JsonTree.tsx |
Updates item and key count fallbacks. |
packages/apollo-react/src/canvas/components/CanvasDiffView/CanvasDiffView.tsx |
Updates diff summary fallbacks and the documentation example. |
packages/apollo-react/src/canvas/components/CanvasDiffView/CanvasDiffView.test.tsx |
Updates summary and status-label assertions. |
Review effort: Balanced
Dependency License Review
License distribution
Excluded packages
|
📊 Coverage + size by packagePer-package coverage and bundle size on this PR. New-line coverage = of the source lines this PR adds or changes, the % hit by tests.
"Coverage" is each package's own |
Storybook visual diff✅ No visual changes. 0 stories affected by this PR were compared against the deployed main Storybook. Logs Updated (PT): Oct 29, 2026, 02:39:45 AM |
|
While fixing these, a sweep of the other apollo-react catalogs turned up two more ICU plurals of the same kind, so they are folded into this PR (second commit):
With this, no ICU plural, select or selectordinal strings remain in any apollo-react catalog. |
671e555 to
eb395e9
Compare
…utral labels
Smartling cannot parse ICU plural syntax: it locks the branch text and leaves
the syntax editable, and translations come back with the ICU keywords
translated, which Lingui rejects and renders as raw markup. Rewrite the 15
canvas count strings (node variables panel, JSON tree, diff view summary,
task runs tooltip) as "Label: {count}". Key IDs are unchanged, so the
connector replaces the existing translations on the next sync. Only en.json
is edited.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…count-neutral labels
The Wind tool-call JSON tree counts used Lingui plural(), which emits ICU
plural syntax the TMS cannot parse. Use the same "Label: {count}" pattern
as the canvas JSON tree: "Items: {count}" and "Keys: {count}". The keys
have not reached other locales yet, so only en.json changes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
eb395e9 to
59784a0
Compare
|
Rebased and resolved conflicts. Re-requesting approval. Sorry for the hassle! |
Why
Smartling cannot parse ICU plural syntax. It locks the branch text and leaves the
syntax editable, so neither our translators nor our translation agents can translate
these strings reliably:
The damage already reaches users. Both translators and our translation agents have
translated the ICU keywords themselves (
otherbecameweitere,autre,otro,기타,其他,diğer), often while leaving the English text inside untouched. Linguirejects these strings, so users see English instead:
stage-node.task-badge.ran-n-timescanvas.json_value_panel.item_countcanvas.json_value_panel.key_countcanvas.diff_view.{added,removed,changed}_{nodes,edges}(6 keys)The same strings came back correct in other locales, so the result depends on who
or what handled each one. A source format that only works when every translator and
every agent avoids touching its syntax as plaintext is not one we can rely on.
We rely on the TMS to be able to correctly add the placeholder mark-up so neither
translators nor automated systems break it.
What changed
15 strings in the canvas catalog now use one count-neutral pattern,
Label: {count}.on the next sync. Only
en.jsonis edited. Other locale files are left to the TMS._({ id, message })call matchesen.json, so theEnglish fallback (no provider, or a key missing from a locale) shows the new text.
Why this rewrite
We considered two options:
Outputs: {count}.{count} output/{count} outputs), chosen in code.Option 1 gives the better result here:
screen-reader labels, summary chips), never part of a sentence. "Label: number" is a
familiar, scannable UI pattern and reads naturally aloud in a screen reader.
so 0, 1 and 21 read correctly even in languages with three or more plural forms
(Polish, Russian, Arabic), where option 2 would still be wrong.
translators and translation agents get one plain string per meaning with a single
placeholder.
Option 2 would only be worth it for counts inside a running sentence. None of these is.
Out of scope (follow-ups)
autopilot-chat.error.multiple-fileshas two different English texts in code, whichblocks
lingui extracton main. Separate PR.Checks
timeout and an Intl duration format that depends on the Node version).
🤖 Generated with Claude Code