Repository navigation
Commit a5d7098
fix(app-shell): an approver chip that stands for several slots says so in words (#27699)
domain:ui#4 · os-bill · session_01Utp6CbDAucNyQ4UtzCJKyh
<!-- claude-projects-attribution: {"github_login":"os-bill"} -->
_Requested by **Bill** · [project
thread](https://claude.ai/code/project/chan_016iMXWSZDzqWRWvWzdNo8wg?thread=cmsg_016iMXWSZDzqWRWvWzdNo8wgDFH4S5pR1C8YvYCWWsZfXx)_
Fixes #27615
Clause-②: yes (widening) — a new key: the `approvalsInbox.approverSlots`
count family, added to all ten published `@object-ui/i18n` packs. No
existing value is edited.
Metadata-protocol: none
## 维护者速读
- **改了什么**:审批「等待以下审批人」里,一个人占多个审批席位时,人名旁原来只画一个光秃秃的 `×3`;现在写成「Dev Admin ·
holds 3 approver slots」(中文「兼任 3 个审批席位」)。业务记录的审批面板和审批请求页两处一致。
- **为什么改**:同一行旁边是「1 位可审批人」,两个数字都对,但并排看像是矛盾,读者分不清是一个人还是三个人要审批。按 triage
裁定:只改文案,两个计数都不动。
- **风险与回滚**:风险低,只改一个徽标里的文字,加一个新的语言包键(十个语言包);回滚即 revert 本 PR。
- **先看**:`ui/packages/app-shell/src/views/RecordApprovalsPanel.tsx` 的
chip 渲染;`approval-decision/ApprovalDecisionPanel.tsx` 的
`PendingApprovers`;`ui/packages/i18n/src/locales/en.ts` / `zh.ts` 的
`approverSlots` 一族。
- **两分钟验证**:showcase 里以种子管理员打开 `EXP-DEMO`(High-Value Expense — Committee
Quorum)的审批请求页;预期「等待以下审批人」显示「Dev Admin · holds 3 approver slots」,旁边仍是「1
eligible approver」。
- **需要你做的**:无,席位落地。
## What changes
When one person holds several of a pending step's approver slots, the
"Waiting on" chip collapses those slots into one chip. It used to draw
the number as a bare `×3`, beside the tally line's "1 eligible approver"
(objectui#12781 counts distinct principals). Both numbers are right, but
side by side they read as a contradiction.
- **The chip says what its number counts.** Where the chip drew `×N` (N
above one), it now draws the pack's words: "Dev Admin · holds 3 approver
slots". It is the same copy, read by literal key, on the business
record's approvals panel (`RecordApprovalsPanel`) and on the approval
request page (`ApprovalDecisionPanel`'s `PendingApprovers`).
- **Neither count changes.** `approverChips` still collapses the same
slots into the same chip with the same `count`, and
`eligibleApproverCount` still counts that person once. No widget, dialog
or hook is added.
- **`@object-ui/i18n`: one new count family,
`approvalsInbox.approverSlots`, in all ten packs.** Each pack carries
every plural category its language selects, the same set as
`progressEligible` beside it (`en` / `de` one and other; `fr` / `es` /
`pt` add many; `ru` one, few, many and other; `ar` all six; `zh` / `ja`
/ `ko` count-invariant), plus the count-invariant base row. Real wording
in every pack, not English placeholders: `en` "holds 3 approver slots",
`zh` "兼任 3 个审批席位", `ja` "承認枠 3 件を兼任", `ko` "승인 자리 3개 겸임", `de` "belegt 3
Genehmigerplätze", `fr` "occupe 3 sièges d'approbateur", `es` "ocupa 3
puestos de aprobador", `pt` "ocupa 3 postos de aprovador", `ru`
"занимает 3 места согласующего", `ar` "يشغل 3 من مقاعد الاعتماد".
- `ApproverChip.count` gains a doc comment saying how it is drawn and
why.
Changeset: `.changeset/27615-approver-slots-chip.md`, patch for
`@object-ui/app-shell` and `@object-ui/i18n`, carrying the same
`Clause-②:` and `Metadata-protocol:` lines.
## Tests
- **Record approvals panel**, a new `describe` in
`RecordApprovalsPanel.eligibleApprovers-12781.test.tsx` (same fixtures
as the objectui#12781 pins: user-id slots, a name per id, the server's
quorum tally):
- the stock committee quorum (one user in all three slots): exactly one
chip, whose text is `Dev Admin· ` plus the pack row `approverSlots` at
count 3, no `×` anywhere in the panel, and the eligible line is the pack
row `progressEligible` at count 1;
- one user in two slots among two others: three chips, only the doubled
one carries the slot words at count 2, and the eligible line reads 3.
- **Approval request page**, the same two cases in
`ApprovalDecisionPanel.eligibleApprovers-12781.test.tsx`, plus a `zh`
case: under a `zh` provider the chip draws the `zh` pack's row (asserted
different from `en`'s) beside the `zh` eligible line.
- Labels are asserted as the pack rows the components read, rendered by
the same i18next instance, never as restated English prose.
- Two existing assertions moved from the bare `×2` / `×3` to the
family's count-invariant row, which is what a provider-less render
draws: `RecordApprovalsPanel.test.tsx` (the per-group chip test) and
`ApprovalDecisionPanel.test.tsx` (the objectui#12077 three-slot chip
test).
- The existing objectui#12781 tests are unchanged and green.
<details><summary>Targeted run on the merged head 0f72297: approvals
views + i18n pack tests</summary>
`pnpm --dir ui exec vitest run --maxWorkers=2
packages/app-shell/src/views/RecordApprovalsPanel
packages/app-shell/src/views/approval-decision/
packages/app-shell/src/views/approval-progress/ packages/i18n/`
```text
Test Files 106 passed (106)
Tests 1499 passed | 13 skipped (1512)
os-verify-lock: VERDICT command-exit 0
```
The i18n pack tests in that run include `all-locales-key-parity`,
`count-families-11445`, `plural-categories-11432` and
`untranslated-identity-4376`.
</details>
<details><summary>Ablation, one per panel: the old bare count restored,
the new pins go red</summary>
Each leg is `node scripts/ablation-replace.mjs`, which mutates the
committed panel back to drawing `×{chip.count}`, runs the panel's test
file, and restores with the restore proven by blob hash and an empty
`git diff HEAD`. The tests import the panels from source, so no build
sits between the mutation and the run.
```text
RecordApprovalsPanel.tsx ok mutation landed: anchor 1 -> 0, blob 9ad41c4 -> d497647b1758
× the stock committee quorum: one chip that says its person holds three slots, beside one eligible approver
× one person in two slots among others: only that chip carries the slot words
Tests 2 failed | 4 passed (6)
ok restored: blob == HEAD (9ad41c4) and `git diff HEAD` is empty
ApprovalDecisionPanel.tsx ok mutation landed: anchor 1 -> 0, blob 80c0bda -> 2e767972b457
× the stock committee quorum: one chip that says its person holds three slots, beside one eligible approver
× one person in two slots among others: only that chip carries the slot words
× the zh pack draws its own words for the chip, beside its own eligible count
Tests 3 failed | 4 passed (7)
ok restored: blob == HEAD (80c0bda) and `git diff HEAD` is empty
```
</details>
## Acceptance notes
- **Chip count above one from two different people.** `approverChips`
keys a chip by label, detail and group, so two distinct addresses that
resolve to an identical name with no group (two users who share a full
name, say) also collapse into one chip with a count, and the eligible
count says 2 beside it. That is a property of the chip's key and was
there before this change. The chip's `title` already lists both raw ids.
This change gives the number words; it does not change what the chip
groups.
- **Provider-less hosts** draw the count-invariant base row ("holds 3
approver slot(s)"), the same way the existing `progressEligible` line
does there. With an `I18nProvider` the plural slot is selected.
- **The only other "Waiting on" line**, the approval status beside
`DeclaredActionsBar`, lists each name once and draws no count, so there
is nothing to reconcile there. The `×{group.items.length}` in
`InboxPopover` counts notifications in a group and is out of scope.
- No new widget, dialog or hook.
## Verification
- Local gates: the full `dispatch-gates --commands` list for this diff,
run on the merged head and reconciled with `--ran`. That includes `node
scripts/check-sdui-manifest.mjs` (exit 0) and `pnpm --dir ui exec vitest
run scripts/`. The ui i18n checks were also run: `check:i18n-keys`,
`check:i18n-drift`, `check:i18n-dead-keys` and
`check:new-line-citations`, all exit 0.
- Type-check: `pnpm turbo run type-check --filter=@object-ui/app-shell
--filter=@object-ui/i18n`, both packages, both `tsc` programs (source
and tests).
- Scope: the full `@object-ui/app-shell` vitest suite was not run
locally. CI's Test UI runs it.
---
_Generated by [Claude
Code](https://claude.ai/code/session_01Utp6CbDAucNyQ4UtzCJKyh)_
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent c47f5eb commit a5d7098
18 files changed
Lines changed: 194 additions & 6 deletions
File tree
- .changeset
- ui
- apps/console/src/services
- packages
- app-shell/src/views
- approval-decision
- i18n/src/locales
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
50 | 50 | | |
51 | 51 | | |
52 | 52 | | |
| 53 | + | |
53 | 54 | | |
54 | 55 | | |
55 | 56 | | |
| |||
353 | 354 | | |
354 | 355 | | |
355 | 356 | | |
356 | | - | |
| 357 | + | |
| 358 | + | |
| 359 | + | |
| 360 | + | |
| 361 | + | |
357 | 362 | | |
358 | 363 | | |
359 | 364 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
128 | 128 | | |
129 | 129 | | |
130 | 130 | | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
26 | 26 | | |
27 | 27 | | |
28 | 28 | | |
| 29 | + | |
29 | 30 | | |
30 | 31 | | |
31 | 32 | | |
| |||
160 | 161 | | |
161 | 162 | | |
162 | 163 | | |
163 | | - | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
164 | 167 | | |
165 | | - | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
166 | 172 | | |
167 | 173 | | |
168 | 174 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
132 | 132 | | |
133 | 133 | | |
134 | 134 | | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
135 | 141 | | |
136 | 142 | | |
137 | 143 | | |
| |||
460 | 466 | | |
461 | 467 | | |
462 | 468 | | |
463 | | - | |
| 469 | + | |
| 470 | + | |
| 471 | + | |
| 472 | + | |
| 473 | + | |
| 474 | + | |
| 475 | + | |
| 476 | + | |
464 | 477 | | |
465 | 478 | | |
466 | 479 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
33 | 33 | | |
34 | 34 | | |
35 | 35 | | |
| 36 | + | |
36 | 37 | | |
37 | 38 | | |
38 | 39 | | |
| |||
109 | 110 | | |
110 | 111 | | |
111 | 112 | | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
274 | 274 | | |
275 | 275 | | |
276 | 276 | | |
277 | | - | |
| 277 | + | |
| 278 | + | |
| 279 | + | |
| 280 | + | |
| 281 | + | |
| 282 | + | |
278 | 283 | | |
279 | 284 | | |
280 | 285 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
213 | 213 | | |
214 | 214 | | |
215 | 215 | | |
216 | | - | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
| 221 | + | |
| 222 | + | |
| 223 | + | |
217 | 224 | | |
218 | 225 | | |
219 | 226 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
4503 | 4503 | | |
4504 | 4504 | | |
4505 | 4505 | | |
| 4506 | + | |
| 4507 | + | |
| 4508 | + | |
| 4509 | + | |
| 4510 | + | |
| 4511 | + | |
| 4512 | + | |
4506 | 4513 | | |
4507 | 4514 | | |
4508 | 4515 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
4166 | 4166 | | |
4167 | 4167 | | |
4168 | 4168 | | |
| 4169 | + | |
| 4170 | + | |
| 4171 | + | |
4169 | 4172 | | |
4170 | 4173 | | |
4171 | 4174 | | |
| |||
0 commit comments