Skip to content

fix(i18n): add missing dynamic-key catalogs, fix plurals and admin sections#323

Open
cavidelizade wants to merge 1 commit into
Devlaner:mainfrom
cavidelizade:fix/i18n-catalog-gaps
Open

fix(i18n): add missing dynamic-key catalogs, fix plurals and admin sections#323
cavidelizade wants to merge 1 commit into
Devlaner:mainfrom
cavidelizade:fix/i18n-catalog-gaps

Conversation

@cavidelizade

Copy link
Copy Markdown
Contributor

Summary

Follow-up to the i18n work (#32 / #312). The en/az catalogs were key-for-key in sync, but several surfaces had been migrated by passing an inline English default to t() without ever adding the key to the catalog — so Azerbaijani silently fell back to English on those screens, and a few plural/section keys were wrong.

Linked issues

Closes #318

Type of change

  • Bug fix (fix:)

Surface

  • UI (apps/web/)

What changed

Missing dynamic-key families added to both catalogs and registered in src/i18n/dynamicKeys.ts (so the parser keeps them): home widgets, notifications tabs, pages tabs + sort, project sidebar nav, saved-view date presets, page-editor colour names, slash menu (title + subtitle), toolbar labels, notification-preference rows (label + desc), estimate type options. ~107 keys, fully translated to Azerbaijani.

Instance-admin sections. InstanceAdminLayout queries instanceAdmin.section.<x>.label and .desc, but the catalog only had the flat instanceAdmin.section.<x> keys — so the .label/.desc lookups always missed and the Azerbaijani section labels/descriptions never showed. Replaced the flat keys with .label + .desc (with descriptions) in both catalogs and dynamicKeys.ts.

Broken plurals fixed:

  • common.time.{days,hours,minutes}Ago_other were singular ("3 day ago") → now "3 days ago".
  • drafts.moduleCount_one was "{{count}} Modules" → "{{count}} Module"; settings.webhooks.retriesCount_one was "{{count}} retries" → "{{count}} retry".
  • (Azerbaijani keeps nouns singular after numbers, so its _one/_other were already correct — the bug was English-only.)

Work-item slash menu (the .ts gate gap). The description editor's slash menu (editorSlashCommands.ts) rendered its titles/descriptions and empty state as raw English via vanilla textContent. Routed them through i18n, reusing the page editor's editor.slash.* keys instead of adding a duplicate family. Note: extending the no-literal-string lint rule to .ts wouldn't have caught this — it runs in jsx-text-only mode and these are DOM strings, not JSX — so routing them through i18n is the actual fix.

Verification

  • npm run typecheck + npm run lint (with the i18n gate) pass
  • npm run i18n:extract reports no untracked strings; en/az stay at full parity (2211 keys each, none empty), and a second extract is a no-op (stable sort)

AI assistance

  • AI tools were used — tool(s): Claude Code (Opus 4.8) — commits carry a Co-Authored-By: trailer

…ctions

Several surfaces were migrated by passing an inline English default to t()
without adding the key to the catalog, so Azerbaijani silently fell back to
English. Add the missing key families (home widgets, notification/pages tabs,
project sidebar nav, saved-view date presets, page-editor colour names, slash
menu and toolbar, notification-preference rows, estimate types) to both
catalogs and register them in dynamicKeys.ts.

Also:
- InstanceAdminLayout queries instanceAdmin.section.<x>.label/.desc but the
  catalog only had the flat instanceAdmin.section.<x> keys, so the Azerbaijani
  section labels never showed. Replace the flat keys with .label/.desc (with
  descriptions) in both catalogs and dynamicKeys.ts.
- Fix broken English plurals: "{{count}} days/hours/minutes ago" (were
  singular in _other), "{{count}} Module"/"{{count}} retry" (_one were plural).
- The work-item description editor's slash menu rendered its titles/descriptions
  and empty state as raw English (vanilla DOM in a .ts file). Route them through
  i18n, reusing the page editor's editor.slash.* keys.

en/az stay at full parity (2211 keys each, none empty); the extractor reports no
untracked strings.

Closes Devlaner#318

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@cavidelizade cavidelizade requested a review from a team as a code owner July 16, 2026 10:45
@coderabbitai

coderabbitai Bot commented Jul 16, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@cavidelizade, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 9 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 9ae327bf-a5e3-4679-9fcf-808d3fcc26f2

📥 Commits

Reviewing files that changed from the base of the PR and between 61bc903 and fa1e171.

📒 Files selected for processing (4)
  • apps/web/src/components/work-item/editorSlashCommands.ts
  • apps/web/src/i18n/dynamicKeys.ts
  • apps/web/src/i18n/locales/az/translation.json
  • apps/web/src/i18n/locales/en/translation.json
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@cavidelizade

Copy link
Copy Markdown
Contributor Author

@martian56 follow-up to the i18n work (#318): a bunch of surfaces were passing English defaults to t() without the key ever landing in the catalog, so Azerbaijani quietly fell back to English (home widgets, tabs, sidebar nav, the editor slash/toolbar, notification prefs, instance-admin sections…). Added the missing keys + az translations, fixed the flat-vs-.label/.desc mismatch on admin sections, and corrected a few English plurals. en/az are at full parity (2211 each) and the extractor's clean. Green — good to merge?

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.

i18n: Azerbaijani falls back to English on several surfaces; broken plurals and admin section keys

1 participant