Repository navigation
Commit af6ca00
feat(console): the approvals inbox keeps a way back from a record, takes an optional Reject reason, and marks requests you submitted (#28415)
<!-- claude-projects-attribution: {"github_login":"os-sales"} -->
_Requested by **Sales** · [project
thread](https://claude.ai/code/project/chan_01D5bWFY3rFzgJcytD5gD4Uu?thread=cmsg_01D5bWFY3rFzgJcytD5gD4UuJC8PModNwfD1TdoWpgVib6)_
Part of #27520 (row 12 only: the approvals inbox; the card's other open
rows stay on it)
Clause-②: yes (widening: `@object-ui/i18n` gains
`approvalsInbox.submittedByYou` in all ten locales; no accept set moves)
Metadata-protocol: none
## 维护者速读
- **改了什么**:审批收件箱三处小改。点行里的记录链接打开记录后,记录页顶部多一个「‹ Approvals
Inbox」返回链接;驳回确认框(单条和批量)多一个选填的意见框;自己提交的申请在申请人旁标「You submitted this」。
- **为什么改**:RC 走查发现:从 Account 应用的收件箱点进记录,回不到收件箱;驳回不能写理由;管理员看不出哪条是自己提交的。
- **风险与回滚**:只动收件箱页面和一个新的翻译键,不改谁能审批、不改服务端。驳回意见走审批接口本来就收的 `comment`
字段;留空时请求与原来完全一样。回滚即 revert 本 PR。
-
**先看**:`ui/apps/console/src/pages/system/ApprovalsInboxPage.tsx`(`RecordCell`
的
`state`、两个驳回框、`SelfSubmittedBadge`);`ApprovalsInboxPage.recordBackLink-27520.test.tsx`。
- **两分钟验证**:`pnpm --dir ui exec vitest run
apps/console/src/pages/system/` → 35 个文件全绿;或在 showcase 里以管理员进 Account →
Approvals,点记录链接,记录页左上出现「‹ Approvals Inbox」。
- **需要你做的**:无,席位落地(新增 i18n 键属 Clause-② widening,席位先做 TIER_DEFAULT 复核)。
## What changes
Measured on `main` `75ecaf4a` before any code; all three observations of
row 12 still held:
| Observation (row 12) | On `main` | This PR |
|:--|:--|:--|
| The record link opens the record inside the Account app shell with no
way back | The link targets `/apps/INBOX_APP/OBJECT/record/ID` and
carries no origin, so `RecordDetailView`'s crumb row (which draws
`state.from` or a `?from=` trail) draws nothing | Target unchanged (the
existing record-link pin and the served-page ruling keep it in the
inbox's app). The link now hands the record page `state.from = {
pathname: INBOX_PATH_AND_SEARCH, label: INBOX_TITLE }`, the same origin
a list row hands it, so the page draws "‹ Approvals Inbox" |
| Reject asks for no reason | The row and bulk Reject confirmations send
`{ actor_id }` only | Both offer an optional comment box (the existing
`approvalsInbox.comment` label, "Comment (optional)"). A non-empty,
trimmed reason is sent as `comment`, which `POST
/approvals/requests/:id/reject` already accepts. Empty sends `{ actor_id
}` as before. Closing a dialog clears it |
| The admin may decide a request they submitted | No marker | A row
whose server-attached `viewer.is_submitter` is true shows "You submitted
this" beside the requester (desktop row and phone card). Not repeated on
the Submitted by me tab. It gates nothing: who may decide is unchanged |
No server, spec or permission change. The reject reason needed no new
field.
## Tests
- New `ApprovalsInboxPage.recordBackLink-27520.test.tsx` (2): mounts the
real inbox and, on the record route, the real `RecordDetailView`.
Clicking the record link keeps the inbox-app href, and the record page
draws a link named "Approvals Inbox" that returns to the inbox. Control:
a record page reached directly draws none.
- New `ApprovalsInboxPage.rejectReasonSelfSubmitted-27520.test.tsx` (7):
the typed reason reaches `approvalsApi.reject` trimmed as `comment`;
empty sends no `comment` and a reopened dialog starts empty; the bulk
reason goes on every selected request; the marker shows on the
self-submitted row and card only; the marked row stays decidable; the
Submitted by me tab does not repeat it; a row without
`viewer.is_submitter` is not marked (the server flag decides, not a
client id match).
- Red first on unfixed code: the back-link case failed ("Unable to find
role=link and name Approvals Inbox"); four of the queue cases failed (no
comment box, no marker).
- `pnpm --dir ui exec vitest run apps/console/src/pages/system/` at the
fix: 35 files, 225 tests passed (lock VERDICT command-exit 0).
<details><summary>Ablations (scripts/ablation-replace.mjs, each restored
to blob == HEAD 46056de)</summary>
| Leg | Mutation | Result |
|:--|:--|:--|
| 1 | delete `state={linkState}` | back-link case red (1 failed / 1
passed) |
| 2 | `decisionComment` returns `{}` | row and bulk reason cases red (2
failed / 5 passed) |
| 3 | drop the `tab !== 'submitted'` guard (desktop) | Submitted-tab
case red |
| 4 | marker keyed on `submitter_id === user.id` instead of
`viewer.is_submitter` | server-flag case red |
</details>
## Acceptance notes
- Opening a request (row click, card, Enter) goes to the request's
served page as before; it carries no origin here. That page is reached
by the row, so browser Back returns, and the app's own nav lists the
inbox. Only the record link was named in row 12.
- The approve confirmation still says "To add a comment or attachment,
open the request instead." It was not in row 12.
## Verification
Local subset, measured at `9a6804d1` (the fix commit); the later merge
of `origin/main` (`f7ef4650`) brought only two plugin-audit test files,
none of which these gates or tests read.
- `node scripts/pm/dispatch-gates.mjs --commands`: 34 derived, all 34
run with exit 0; `--ran` reconcile: "34 derived, 34 run, 0 NOT-MEASURED
(a DERIVED zero — all 34 recorded an exit code)". Includes `node
scripts/check-sdui-manifest.mjs` (exit 0) and `pnpm --dir ui exec vitest
run scripts/` (169 files passed, 2 skipped; 4901 tests passed).
- `pnpm --dir ui check:new-line-citations`: 0 new citations, exit 0.
- eslint on the three console files and `ui/packages/i18n/src/locales/`:
0 errors; the 13 warnings sit on unchanged lines of
`ApprovalsInboxPage.tsx`.
- `pnpm --dir ui exec vitest run packages/i18n/`: 94 files passed, 1438
tests passed, 13 skipped.
- `turbo run type-check --filter=@object-ui/console
--filter=@object-ui/i18n`: 72 of 72 tasks successful (lock VERDICT
command-exit 0).
- `git merge-tree --write-tree` against the two open PRs that touch the
same locale files (#28400, #28394): clean. No open PR touches
`ApprovalsInboxPage*`.
- No live browser run: the back-link case mounts the real
`RecordDetailView` on the real route instead.
---
_Generated by [Claude
Code](https://claude.ai/code/session_01L6bhgWckvpzUHJaGf595aP)_
🤖 Generated with [Claude Code](https://claude.com/claude-code)
https://claude.ai/code/session_01L6bhgWckvpzUHJaGf595aP
Co-authored-by: Claude <noreply@anthropic.com>1 parent a727ba2 commit af6ca00
14 files changed
Lines changed: 531 additions & 9 deletions
File tree
- .changeset
- ui
- apps/console/src/pages/system
- packages/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 | + | |
| 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 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 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 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
0 commit comments