Skip to content

fix(apollo-react): replace ICU plurals in canvas counts with count-neutral labels - #1451

Merged
roxana-mocanu merged 2 commits into
mainfrom
fix/apollo-react-icu-plural-counts
Oct 29, 2026
Merged

roxana-mocanu merged 2 commits into
mainfrom
fix/apollo-react-icu-plural-counts

Conversation

@roxana-mocanu

@roxana-mocanu roxana-mocanu commented Oct 22, 2026 •

Copy link
Copy Markdown
Collaborator

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:

image

The damage already reaches users. Both translators and our translation agents have
translated the ICU keywords themselves (other became weitere, autre, otro,
기타, 其他, diğer), often while leaving the English text inside untouched. Lingui
rejects these strings, so users see English instead:

image image
Key Broken today in
stage-node.task-badge.ran-n-times de, es, es-MX, fr, ko, tr, zh-CN, zh-TW
canvas.json_value_panel.item_count de, es, es-MX, fr, ko, tr, zh-CN, zh-TW
canvas.json_value_panel.key_count de, es, es-MX, fr, ko, tr, zh-CN, zh-TW
canvas.diff_view.{added,removed,changed}_{nodes,edges} (6 keys) de, es-MX, fr

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}.

Where it shows Before After
Node variables panel (section and node counts) 3 outputs Outputs: 3
JSON tree 3 items · 3 keys Items: 3 · Keys: 3
Diff view summary 2 nodes added Nodes added: 2
Task runs tooltip Ran 3 times Runs: 3
  • Key IDs are unchanged, so the Smartling connector replaces the broken translations
    on the next sync. Only en.json is edited. Other locale files are left to the TMS.
  • The English default in each _({ id, message }) call matches en.json, so the
    English fallback (no provider, or a key missing from a locale) shows the new text.
  • Tests asserting the old wording are updated.

Why this rewrite

We considered two options:

  1. Count-neutral label (chosen): one string per meaning, Outputs: {count}.
  2. Two keys per string ({count} output / {count} outputs), chosen in code.

Option 1 gives the better result here:

  • It fits where the strings appear. All 15 are short counts on their own (tooltips,
    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.
  • It is correct in every language and for every number. No plural rules are needed,
    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.
  • It keeps the change small. It adds no new keys and no branching in code, and
    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-files has two different English texts in code, which
    blocks lingui extract on main. Separate PR.

Checks

  • Affected test suites: 546 passed. 2 failures also occur on main (a slow import test
    timeout and an Intl duration format that depends on the Node version).
  • Biome: clean.

🤖 Generated with Claude Code

Copilot AI balanced review requested due to automatic review settings October 22, 2026 18:18
@github-actions
github-actions Bot temporarily deployed to preview/apollo-vertex October 22, 2026 18:18 Destroyed
@github-actions
github-actions Bot temporarily deployed to preview/apollo-design October 22, 2026 18:18 Destroyed
@github-actions
github-actions Bot temporarily deployed to preview/apollo-landing October 22, 2026 18:18 Destroyed
@github-actions
github-actions Bot temporarily deployed to preview/apollo-docs October 22, 2026 18:18 Destroyed
@github-actions github-actions Bot added the size:L 100-499 changed lines. label Oct 22, 2026

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟢 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

@github-actions

Copy link
Copy Markdown
Contributor

Dependency License Review

  • ✅ 1957 package(s) scanned
  • ✅ No license issues found
  • ⚠️ 2 package(s) excluded (see details below)
License distribution
License Packages
MIT 1721
ISC 91
Apache-2.0 57
BSD-3-Clause 28
BSD-2-Clause 23
BlueOak-1.0.0 8
MPL-2.0 4
CC0-1.0 4
MIT-0 3
MIT OR Apache-2.0 2
(MIT OR Apache-2.0) 2
Unlicense 2
LGPL-3.0-or-later 1
Python-2.0 1
CC-BY-4.0 1
(MPL-2.0 OR Apache-2.0) 1
Unknown 1
Artistic-2.0 1
(WTFPL OR MIT) 1
(BSD-2-Clause OR MIT OR Apache-2.0) 1
CC-BY-3.0 1
0BSD 1
(MIT OR CC0-1.0) 1
MIT AND ISC 1
Excluded packages
Package Version License Reason
@img/sharp-libvips-linux-x64 1.3.4 LGPL-3.0-or-later LGPL pre-built binary, not linked
khroma 2.1.0 Unknown MIT per GitHub repo, missing license field in package.json

@github-actions

github-actions Bot commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

📊 Coverage + size by package

Per-package coverage and bundle size on this PR. New-line coverage = of the source lines this PR adds or changes, the % hit by tests.

Package Coverage New-line coverage Packed (gzip) Unpacked vs main
@uipath/apollo-core — — 42.02 MB 50.17 MB ±0
@uipath/apollo-react 58.4% — (19 untracked) 8.29 MB 32.95 MB −1.3 KB
@uipath/apollo-ui-icons — — 2.86 MB 6.97 MB ±0
@uipath/apollo-vertex — — — — —
@uipath/apollo-wind — — 834.6 KB 4.78 MB +9 B
@uipath/ap-chat 85.8% — 40.48 MB 46.09 MB −115 B

"Coverage" is each package's own coverage.include scope (e.g. apollo-core instruments only scripts/). "Packed"/"Unpacked" come from npm pack --dry-run and only cover built packages — "—" means not measured this run (package not affected / not built). "vs main" is the packed (gzipped) delta against the last successful main build (the package-sizes artifact from the Release workflow); "—" there means no main baseline was available this run. The baseline is main's latest build, not this PR's exact merge-base, so it includes any drift since the branch diverged. Packages with no vitest config are omitted.

@github-actions

github-actions Bot commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

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

Copilot AI balanced review requested due to automatic review settings October 22, 2026 19:10
@roxana-mocanu

Copy link
Copy Markdown
Collaborator Author

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):

Key Where it shows Before After
autopilot-chat.tool-call.json.item-count Wind chat, tool-call JSON tree 3 items Items: 3
autopilot-chat.tool-call.json.key-count Wind chat, tool-call JSON tree 3 keys Keys: 3
  • They feed the same JSON tree component as the canvas item_count / key_count, so they now use the same wording.
  • Both keys are new and have not reached Smartling yet, so no translation has been affected. Fixing them now keeps them from breaking on the first sync.
  • Only en.json and the code default change. The chat catalog uses macros, so plural() was removed from the call.
  • Chat tests: 394 passed. Biome clean.

With this, no ICU plural, select or selectordinal strings remain in any apollo-react catalog.

@github-actions
github-actions Bot temporarily deployed to preview/apollo-docs October 22, 2026 19:11 Destroyed
@github-actions
github-actions Bot temporarily deployed to preview/apollo-vertex October 22, 2026 19:11 Destroyed
@github-actions
github-actions Bot temporarily deployed to preview/apollo-landing October 22, 2026 19:11 Destroyed
@github-actions
github-actions Bot temporarily deployed to preview/apollo-design October 22, 2026 19:11 Destroyed

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟢 Approval recommended

The scoped text changes preserve translation IDs and count bindings, with consistent catalogs, defaults, and updated assertions.

No open issues 🎉

Review effort: Balanced

Copilot AI balanced review requested due to automatic review settings October 22, 2026 19:23
@github-actions
github-actions Bot temporarily deployed to preview/apollo-landing October 22, 2026 19:24 Destroyed
@github-actions
github-actions Bot temporarily deployed to preview/apollo-vertex October 22, 2026 19:24 Destroyed
@github-actions
github-actions Bot temporarily deployed to preview/apollo-design October 22, 2026 19:24 Destroyed
@github-actions
github-actions Bot temporarily deployed to preview/apollo-docs October 22, 2026 19:24 Destroyed

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟢 Approval recommended

The scoped wording changes preserve IDs and interpolation values, align catalogs with component messages and assertions, and have no identified blocking issues.

No open issues 🎉

Review effort: Balanced

Copilot AI balanced review requested due to automatic review settings October 23, 2026 07:41
@roxana-mocanu
roxana-mocanu force-pushed the fix/apollo-react-icu-plural-counts branch from 671e555 to eb395e9 Compare October 23, 2026 07:41
@github-actions
github-actions Bot temporarily deployed to preview/apollo-docs October 23, 2026 07:41 Destroyed
@github-actions
github-actions Bot temporarily deployed to preview/apollo-vertex October 23, 2026 07:41 Destroyed
@github-actions
github-actions Bot temporarily deployed to preview/apollo-design October 23, 2026 07:41 Destroyed
@github-actions
github-actions Bot temporarily deployed to preview/apollo-landing October 23, 2026 07:41 Destroyed

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟢 Approval recommended

The narrow wording changes preserve IDs and interpolation values, with consistent catalogs, defaults, and assertions; tests were not rerun.

No open issues 🎉

Review effort: Balanced

@github-actions
github-actions Bot temporarily deployed to preview/apollo-design October 23, 2026 07:58 Destroyed
@github-actions
github-actions Bot temporarily deployed to preview/apollo-landing October 23, 2026 07:58 Destroyed
@roxana-mocanu
roxana-mocanu marked this pull request as ready for review October 23, 2026 09:11
@roxana-mocanu
roxana-mocanu enabled auto-merge (rebase) October 23, 2026 09:14
roxana-mocanu and others added 2 commits October 29, 2026 11:07
…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>
@roxana-mocanu
roxana-mocanu force-pushed the fix/apollo-react-icu-plural-counts branch from eb395e9 to 59784a0 Compare October 29, 2026 09:30
Copilot AI balanced review requested due to automatic review settings October 29, 2026 09:31
@github-actions
github-actions Bot temporarily deployed to preview/apollo-design October 29, 2026 09:31 Destroyed
@github-actions
github-actions Bot temporarily deployed to preview/apollo-landing October 29, 2026 09:31 Destroyed
@github-actions
github-actions Bot temporarily deployed to preview/apollo-vertex October 29, 2026 09:31 Destroyed
@github-actions
github-actions Bot temporarily deployed to preview/apollo-docs October 29, 2026 09:31 Destroyed

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟢 Approval recommended

The review identifies no active issues with the canvas and chat count-label changes.

No open issues 🎉

Review effort: Balanced

@roxana-mocanu

Copy link
Copy Markdown
Collaborator Author

Rebased and resolved conflicts. Re-requesting approval. Sorry for the hassle!

@roxana-mocanu
roxana-mocanu merged commit c00c799 into main Oct 29, 2026
43 checks passed
@roxana-mocanu
roxana-mocanu deleted the fix/apollo-react-icu-plural-counts branch October 29, 2026 15:43

This branch was successfully deployed

No deployments
preview/apollo-docs — 59784a01 Deployed Oct 29, 2026 by github-actions[bot]
preview/apollo-vertex — 59784a01 Deployed Oct 29, 2026 by github-actions[bot]
preview/apollo-landing — 59784a01 Deployed Oct 29, 2026 by github-actions[bot]
preview/apollo-design — 59784a01 Deployed Oct 29, 2026 by github-actions[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pkg:apollo-react size:L 100-499 changed lines.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants