fix(i18n): ru/ar count labels on seven more === 1 two-key values (objectui#10425) - #10558
Conversation
…bjectui#10425) The count-not-one half of seven values behind the `count === 1` switch held one noun form, wrong at some of the counts it serves (ru 2-4 and 21; ar 2 and 11+). Each becomes a count label, the objectui#10024 / #10242 device: ru list.recordCount; ar list.recordCount, lookup.recordCount, detail.reactionCount, collaboration.presentUserCount / moreUserCount and search.itemsAvailable. Key sets and call sites are unchanged. The card's eighth value, ar detail.revisionFieldsChanged, left the tree with its only consumer (PointInTimeRestore) in #10453. Pins: a real-render pin beside the objectui#10242 one, the 9664 value pin flipped to the new ar value, and the pending 9664 changeset's last sentence reworded to the shape the ar value now has. Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KUxVUa7e39aNjhkKi1gsoy
Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KUxVUa7e39aNjhkKi1gsoy
Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KUxVUa7e39aNjhkKi1gsoy
✅ Console Performance Budget
The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it. 📦 Bundle Size Report
Size Limits
|
Contract reviewServed-tier: Isolated adversarial review of objectui#10558 (card objectui#10425). Read set: the card body and its three comments (the ① Derived judgments1. The seven value changes, each against the card table and the ruled device. The card's rulings bind: the objectui#10024 / #10240 / #10242 count label (「a label, a colon, then the number」) and 「⛔ No
2. Key set and accepted set: unchanged. The pack diff, filtered to key lines, is exactly seven removed and seven added lines with identical key names ( 3. The eighth row is dead, and leaving it out is right, not a missing ask. ar 4. Asked and done; done and not asked.
5. The one existing pin edited: load-bearing, not weakened. In 6. The new pin can fail.
7. Published surface. ② Semver level
③ Boundary flags
Implemented-by: VERDICT: PASS |
Fixes #10425
Clause-②: no
What this does
Seven locale values sit behind a
count === 1two-key switch. The count-not-one half of each held one noun form, which is wrong at some of the counts it serves:ruat 2-4 (few) and 21 (one),arat 2 (two) and from 11 up. Each becomes a count label (a label, a colon, then the number), the device ruled for this family on objectui#10024, objectui#10240 and objectui#10242. The singular halves, the key sets and the call sites are unchanged. There are no_few/_twokeys, becauseall-locales-key-parity.test.tsholds every pack to theenkey set.main)list.recordCountCOUNT записейЗаписей: COUNTtotalCount === 1(ListView)list.recordCountCOUNT سجلاتعدد السجلات: COUNTtotalCount === 1(ListView)lookup.recordCountCOUNT سجلعدد السجلات: COUNTtotalCount === 1(RecordPickerDialog)detail.reactionCountEMOJI COUNT تفاعلاتEMOJI عدد التفاعلات: COUNTreaction.count === 1(ReactionPicker)collaboration.presentUserCountCOUNT مستخدمين متواجدينعدد المستخدمين المتواجدين: COUNTusers.length === 1(PresenceAvatars)collaboration.moreUserCountCOUNT مستخدمين آخرينعدد المستخدمين الآخرين: COUNToverflowCount === 1(PresenceAvatars)search.itemsAvailableCOUNT عناصر متاحةعدد العناصر المتاحة: COUNTallItems.length === 1(SearchResultsPage)COUNT and EMOJI stand for the i18next double-brace placeholders.
ruvalue matchesrulookup.recordCount, which already readЗаписей: COUNT. Thearvalues use theعدد …: COUNTshape of objectui#10242.ardetail.revisionFieldsChanged, is no longer in the tree. The key and its only consumer,PointInTimeRestore, were deleted by objectui#10453 (0348bc9, an ancestor of this branch's base). So seven values change, not eight..changeset/9664-search-items-available-plural.md: its last sentence said thearvalue "uses the same noun pair thatar'scommon.itemCount/itemCountOnealready uses". After objectui#10242 and this change that is no longer true, so the sentence is reworded (triage execution note). Its front matter is unchanged.check-changeset-overwritereports this edit as intended: case 2, prose correction..changeset/10425-ru-ar-count-labels.md:@object-ui/i18n: patch.Pins
packages/app-shell/src/views/__tests__/countLabels.ruAr-10425.test.tsx, beside the objectui#10242 pin and in the same shape. It boots a real i18next fromcreateI18nin the session's language, withtnot mocked. Each consumer is rendered for real: theListViewrecord-count bar, theRecordPickerDialogcount line, theReactionPickerchip, thePresenceAvatarsgroup name and overflow tooltip, and theSearchResultsPagebrowse count. The representative counts areru2 / 5 / 21 andar2 / 3 / 11, and the file asserts theirIntl.PluralRulescategories. Controls areen, the singular halves, and theruvalues this change leaves alone (lookup.recordCount,presentUserCount,moreUserCount). Pack-level: each changed value ends in a colon and the count, and differs from its One half.packages/i18n/src/__tests__/searchItemsAvailable-plural-9664.test.ts. Thearrow of itsPLURALtable now holds the new value, so the pin still does work, and its two comments about thearnoun pair are updated to match. Nothing was deleted.Reverse verification (one-off, not kept as a test)
Run at fix commit
e9e5896, with the fix already committed. Both packs went back to base111fa4c(git checkout BASE -- ru.ts ar.ts), under atraprestore.grep -cfound the newarvalueعدد السجلات: COUNT0 times.rulist bar at 2 / 5 / 21, andarlist bar, picker, chip, presence name, overflow tooltip and browse count at 2 / 3 / 11. The rest of the 24 are the two named-defect tests and the count-invariance test.ar defines both halvesrow.git checkout HEAD -- .... Both files'git hash-objectmatched the HEAD blobs, andgit diff HEADwas empty.Local verification, at head
574169b(after mergingorigin/mainfee1da5, which contains objectui#10534)pnpm exec vitest run packages/i18n/plus the four app-shell pins (countLabels.ruAr-10425,countLabels.ruAr-10242,SearchResultsPage.itemsAvailablePlural-9664,SearchResultsPage.resultsCountPlural-10024):Test Files 75 passed (75),Tests 1282 passed (1282), exit 0.pnpm check:i18n-keys,check:i18n-drift,check:i18n-dead-keys,check:control-bytes,check:new-line-citations(VERDICT new-cross-file-line-citations: 0 new citation(s)),check:changeset-claims,check:pending-changeset-literals,changeset:check,node scripts/check-changeset-presence.mjs,check-vi-mock-specifiers,check-vi-mock-inheritandcheck-changeset-overwrite(report-only).eslint --no-inline-config --format jsonreports 4 files, 0 errors and 0 warnings. The config istypescript-eslintrecommended, with no type-aware parser options, so this diff cannot change the verdict on any file it does not touch. Repo-widepnpm lintis left to CI.pnpm --filter @object-ui/i18n type-check: exit 0. It was run after building its dependency closure (@object-ui/i18n^...).tsconfig.test.json --listFilesincludes the 9664 test and both packs.pnpm --filter @object-ui/app-shell type-check: exit 0 at35c233b, after a turbo build of the 29-package@object-ui/app-shell^...closure.--listFilesOnlyincludes the new pin (1 of 4635 files). It was not re-run after the secondorigin/mainmerge, which does not change this diff.Acceptance notes
rusearch.itemsAvailable(COUNT доступно) is unchanged. It states no noun, so there is no word to agree with the number. This is theNO_SINGULAR_FORMreasoning in the 9664 pin.ruandardetail.relatedRecordscarry the same one-noun-form value, but no call site reads that pair. The only hits are its defaults-map row and comments. It has no pull, so it is left alone.console.objectView.recordCountis a separate defect, reported to the seat and not changed here. It is one key with no One sibling and no switch, read by theObjectViewrecord-count footer. A real i18next inenreturns1 recordsat count 1.Implemented by
session_01KUxVUa7e39aNjhkKi1gsoy(https://claude.ai/code/session_01KUxVUa7e39aNjhkKi1gsoy), dispatched by thedomain:uiseat 5 PM.Generated by Claude Code