Skip to content

fix(i18n): replace manual pluralize() with i18next count-based plurals#17760

Merged
max-datahub merged 2 commits into
masterfrom
i18n-replace-manual-pluralize
Jun 5, 2026
Merged

fix(i18n): replace manual pluralize() with i18next count-based plurals#17760
max-datahub merged 2 commits into
masterfrom
i18n-replace-manual-pluralize

Conversation

@max-datahub
Copy link
Copy Markdown
Collaborator

@max-datahub max-datahub commented Jun 5, 2026

Summary

Several files that are already in the i18n allowlist still call the manual
pluralization helpers (pluralize / forcePluralize / pluralizeIfIrregular)
from @app/shared/textUtil. Those helpers hardcode English plural rules (a
naive +s suffix plus a small English-only irregular map), so the text they
produce can never be localized correctly — other locales have different plural
categories and word forms.

This PR:

  1. Migrates each call site to i18next's native count-based plural keys
    (_one / _other) or simple interpolation, so each locale owns its own
    plural forms, and removes the now-unused textUtil imports.
  2. Adds an ESLint rule, no-manual-pluralize-in-i18n (scoped via
    .eslintrc.js to the i18n allowlist), so these helpers can't be
    reintroduced into translated files going forward.

EN-only (no DE) per the i18n extraction convention.

Keys added

  • entity.types: shared.assetTypeNameCount
  • entity.shared.containers: sidebar.entityTypeCount, sidebar.ownership.type.pluralName
  • ingestion: source.entityTypeNameCount
  • search: matches.matchedField.fieldLabelCount, filters.pluralizedTypeLabel

Files migrated

  • entityV2/application/AssetsSections.tsx, entityV2/dataProduct/AssetsSections.tsx,
    entityV2/domain/summary/ContentsSection.tsx — entity-count card tooltips
  • entityV2/shared/containers/profile/sidebar/{Container,Domain,Lineage}/utils.tsx
    "{count} {type}" sidebar summaries
  • entityV2/shared/containers/profile/sidebar/Ownership/ownershipUtils.ts
    ownership-type fallback label
  • ingestV2/source/utils.ts — ingestion source facet display name
  • searchV2/matches/MatchedFieldList.tsx — matched-field label
  • searchV2/filters/utils.tsx — filter option labels (entity type / subtype)

Pages to verify

  • An Application profile → Assets section (hover an entity-count card; tooltip shows the type name)
  • A Data Product profile → Assets section (entity-count card tooltips)
  • A Domain profile → Contents section (entity-count card tooltips)
  • Any entity profile right sidebar → Contents (container), Lineage summary, and Owners (ownership type label)
  • Ingestion → Sources list (entity-type facet counts)
  • Search → search filters (entity type / subtype filter option labels) and matched-field result rows

Checklist

  • The PR conforms to DataHub's Contributing Guideline (particularly the Commit Message Format)
  • Verified locally: ESLint (incl. the new rule), tsc --noEmit, and Prettier pass
  • Links to related issues (N/A)
  • Docs added/updated (N/A — internal refactor, no user-facing doc change)

🤖 Generated with Claude Code

Several files in the i18n allowlist still call the manual pluralization helpers
(`pluralize` / `forcePluralize`) from `@app/shared/textUtil`. Those helpers
hardcode English plural rules (a naive `+s` plus a small irregular map), so the
text they produce can never be localized correctly — other locales have
different plural categories and word forms.

Migrate these call sites to i18next's native count-based plural keys
(`_one` / `_other`), letting each locale own its plural forms, and drop the
now-unused textUtil imports:

- entity.types: shared.assetTypeNameCount — entity-count card tooltips in the
  application / data product Assets sections and the domain Contents section
- entity.shared.containers: sidebar.entityTypeCount — Container, Domain, and
  Lineage sidebar summaries ("{count} {type}"); sidebar.ownership.type.pluralName
  — ownership type fallback label
- ingestion: source.entityTypeNameCount — ingestion source facet display name

EN-only (no DE) per the i18n extraction convention.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@alwaysmeticulous
Copy link
Copy Markdown

alwaysmeticulous Bot commented Jun 5, 2026

🔴 Meticulous spotted visual differences in 16 of 1423 screens tested: view and approve differences detected.

Meticulous evaluated ~10 hours of user flows against your PR.

Last updated for commit e19964a chore(i18n): enforce no-manual-pluralize-in-i18n and migrate remaining c.... This comment will update as new commits are pushed.

@codecov
Copy link
Copy Markdown

codecov Bot commented Jun 5, 2026

Bundle Report

Changes will increase total bundle size by 1.0kB (0.0%) ⬆️. This is within the configured threshold ✅

Detailed changes
Bundle name Size Change
datahub-react-web-esm 23.54MB 1.0kB (0.0%) ⬆️

Affected Assets, Files, and Routes:

view changes for bundle: datahub-react-web-esm

Assets Changed:

Asset Name Size Change Total Size Change (%)
assets/index-*.js 513 bytes 8.86MB 0.01%
assets/en-*.js 488 bytes 225.1kB 0.22%

Files in assets/index-*.js:

  • ./src/app/entityV2/application/AssetsSections.tsx → Total Size: 2.54kB

  • ./src/app/entityV2/dataProduct/AssetsSections.tsx → Total Size: 2.38kB

  • ./src/app/entityV2/domain/summary/ContentsSection.tsx → Total Size: 2.67kB

  • ./src/app/searchV2/matches/MatchedFieldList.tsx → Total Size: 3.33kB

  • ./src/app/entityV2/shared/containers/profile/sidebar/Ownership/ownershipUtils.ts → Total Size: 1.68kB

  • ./src/app/entityV2/shared/containers/profile/sidebar/Domain/utils.tsx → Total Size: 3.74kB

  • ./src/app/entityV2/shared/containers/profile/sidebar/Lineage/utils.tsx → Total Size: 3.05kB

  • ./src/app/entityV2/shared/containers/profile/sidebar/Container/utils.tsx → Total Size: 3.02kB

  • ./src/app/searchV2/filters/utils.tsx → Total Size: 16.79kB

  • ./src/app/ingestV2/source/utils.ts → Total Size: 15.7kB

Files in assets/en-*.js:

  • ./src/i18n/locales/en/entity.shared.containers.json → Total Size: 14.15kB

  • ./src/i18n/locales/en/ingestion.json → Total Size: 9.52kB

  • ./src/i18n/locales/en/entity.types.json → Total Size: 16.22kB

  • ./src/i18n/locales/en/search.json → Total Size: 8.22kB

@codecov
Copy link
Copy Markdown

codecov Bot commented Jun 5, 2026

Codecov Report

❌ Patch coverage is 22.22222% with 7 lines in your changes missing coverage. Please review.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
datahub-web-react/src/app/ingestV2/source/utils.ts 20.00% 4 Missing ⚠️
...ainers/profile/sidebar/Ownership/ownershipUtils.ts 25.00% 3 Missing ⚠️

📢 Thoughts on this report? Let us know!

…g call sites

Add the `no-manual-pluralize-in-i18n` ESLint rule (scoped via .eslintrc.js to
the i18n allowlist) so the manual pluralization helpers
(`pluralize` / `forcePluralize` / `pluralizeIfIrregular`) can't be reintroduced
into already-translated files — they hardcode English plural rules and can't be
localized.

Enabling the rule surfaced two more allowlisted files still using the helpers;
migrate them to i18next keys in the `search` namespace:

- searchV2/matches/MatchedFieldList.tsx → matches.matchedField.fieldLabelCount
  (count-based `_one`/`_other`)
- searchV2/filters/utils.tsx → filters.pluralizedTypeLabel (always-plural label)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@max-datahub max-datahub merged commit 68ece80 into master Jun 5, 2026
53 of 55 checks passed
@max-datahub max-datahub deleted the i18n-replace-manual-pluralize branch June 5, 2026 07:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

product PR or Issue related to the DataHub UI/UX

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants