You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 9a63ecb
Browse filesBrowse the repository at this point in the historyBrowse files
fix(console): the shared-record page shows a lookup as "Linked record", never its stored id (#31346)
<!-- claude-projects-attribution: {"github_login":"os-project-manager"}
-->
_Requested by **Leehom** · [project
thread](https://claude.ai/code/project/chan_01TenzsRopZj4jMbvjX8uz1X?thread=cmsg_01TenzsRopZj4jMbvjX8uz1XLP7yPUeEpHsHyGhzfziP4q)_Fixes#31326
Clause-②: yes (widening)
Metadata-protocol: none
## 维护者速读
- 改了什么:分享链接页 `/s/TOKEN` 上,有值的查找字段与主从字段不再显示被关联记录的存储
ID,改为显示本地化的中性占位「已关联记录」/ "Linked record";空值仍显示为空。是否为查找字段,按 resolve 应答
`fields` 投影里已下发的 `type` 判断,不看值的形状。
- 为什么改:匿名访客看到一串内部 ID,读起来像页面坏了(#27200 字母 C 裁决)。显示目标记录名称是选项 B,仍挂在 #27200,本
PR 不碰。
- 风险与回滚:只改 console 一页的展示层,外加 `@object-ui/i18n` 每个语言包一个新键
`sharedRecord.linkedRecord`;不改 resolve 接口、不改服务端、不多发请求、不读目标记录。旧服务端不返回
`fields` 时没有类型可读,页面与之前一样。回滚即 revert。
-
先看:`ui/apps/console/src/pages/SharedRecordFields.tsx`(`RECORD_REFERENCE_TYPES`
与行渲染的分支)、`SharedRecordPage-27121.test.tsx` 末尾新增的 `objectstack#31326`
describe。
- 两分钟验证:`pnpm --dir ui exec vitest run
apps/console/src/pages/SharedRecordPage-27121.test.tsx`,预期 13
个用例全绿,其中查找、主从、多值查找三例断言整个 DOM 里找不到存储 ID。
- 需要你做的:无,席位落地。
## What changes
- **`SharedRecordFields.tsx`** (`@object-ui/console`): a row whose
projected field `type` is `lookup` or `master_detail`
(`RECORD_REFERENCE_TYPES`) no longer renders its value. A filled one (an
id, or a non-empty array of ids for a multiple lookup) renders
`t('sharedRecord.linkedRecord')` in the muted foreground; an empty one
(null, undefined, empty string, empty array) renders the page's existing
empty face. The decision reads the `type` the resolve answer's `fields`
projection already serves, never the value's shape. The branch sits
before the no-fetch cell renderers, so nothing for these rows reads the
target record, the data source or the meta door. The module header now
states this rule in place of "the id is what shows".
- **`@object-ui/i18n`**: every built-in pack gains
`sharedRecord.linkedRecord` (en "Linked record", zh-Hans 「已关联记录」, the
other nine translated). `zh-Hant.ts` was produced by `pnpm --filter
@object-ui/i18n gen:zh-hant`, and a rerun reproduces the committed file
byte for byte.
- **Changeset** `.changeset/31326-shared-lookup-placeholder.md`:
`@object-ui/console` and `@object-ui/i18n` patch, with both declaration
lines.
- Not changed: `GET /api/v1/share-links/TOKEN/resolve`,
`packages/types/src/share-link-resolve-answer.ts`, and any server code.
## Tests
- `SharedRecordPage-27121.test.tsx`, the page's existing harness,
rendered through the real route with the resolve answer stubbed the way
both producers send it.
- New top-level describe for objectstack#31326 (6 cases), fed an
`opportunity` answer: a filled lookup (and the registry-injected
`created_by` lookup) shows the placeholder and its id is absent from
`document.body.innerHTML`, and only the resolve request is made; a
filled master-detail likewise; a multiple lookup shows one placeholder
and none of its ids; an empty lookup renders the empty face; under a zh
`I18nProvider` the placeholder is the zh-Hans pack's value (guarded as a
real zh row); CONTROL: text fields render their values as before.
- Two #27121 cases that pinned the old behaviour now pin the new one:
the lookup row reads "Linked record", and under a host data source the
id and the target's name are absent from the DOM while `find`, `findOne`
and `getObjectSchema` are never called.
- Unchanged and green: an answer without `fields` (an older server)
still shows the id, because no type is served to read.
- Ablation on head `d33a03b2` through `scripts/ablation-replace.mjs`:
the reference-type branch was replaced with a constant false, so the raw
value renders again (anchor 1 to 0, blob `7bf595db` to `52d8493a`).
Result: 6 of 13 red (the six cases that assert the placeholder or the
id's absence); the empty-lookup preservation case and the control stay
green. Restored: blob equal to HEAD (`7bf595db`) and `git diff HEAD`
empty. The console tests read `SharedRecordFields.tsx` from source by
relative import, so no build sat between the mutation and the run.
## Acceptance notes
- **Which types.** The card names lookup and master-detail, and this PR
covers exactly those two `type` values. A `user` field is stored the
same way (a `sys_user` id) and, by reading the code path, still renders
its id on this page; a `tree` field may too. Not measured on a live
page; noted for the seat, not filed.
- **An older server.** An answer without `fields` carries no `type`, so
a lookup there still shows its id, as before #27121. Guessing from the
value's shape was ruled out by the order.
- **Option B** (the target's name) stays on #27200; nothing here reads
or serves it.
- **Declaration lines.** The claim opened at `Clause-②: no`; adding an
`@object-ui/i18n` key is published surface, so this PR and its changeset
declare `yes (widening)`. `Metadata-protocol: none`: nothing a metadata
author writes changes.
## Verification
Run on head `d33a03b2` (base `f5e23e2f`):
<details><summary>Build, tests and type-check</summary>
- `pnpm --workspace-concurrency=2 --filter '@object-ui/console^...'
build` under the verify lock: VERDICT command-exit 0.
- `pnpm --dir ui exec vitest run
apps/console/src/pages/SharedRecordPage-27121.test.tsx
apps/console/src/pages/SharedRecordPage-26767.test.tsx
apps/console/src/pages/consolePagesLocale-secondPass-13460.test.tsx`:
Test Files 3 passed (3), Tests 29 passed (29).
- `pnpm --dir ui exec vitest run packages/i18n/
apps/console/src/pages/`: Test Files 250 passed, 1 failed (251); the one
failure was `SettingsField.labelBinding-11690.test.tsx` timing out at 15
s while the gate loop ran beside it. That file is untouched by this
diff, and rerun alone it passed 15 of 15.
- `pnpm --filter @object-ui/console run type-check`: exit 0. `pnpm
--filter @object-ui/i18n run type-check`: exit 0.
- eslint on the two changed console files: exit 0. `pnpm --dir ui run
check:new-line-citations`: 0 new citations, exit 0.
</details>
<details><summary>Derived gates (38)</summary>
`node scripts/pm/dispatch-gates.mjs --commands --repo
objectstack-ai/objectstack` derived 38 families on this diff, and all 38
exited 0. `pnpm --dir ui exec vitest run scripts/` was SIGKILLed on its
first run while the console suite ran beside it; rerun alone under the
lock, it exited 0 (Test Files 170 passed, 2 skipped; Tests 4996 passed).
`--ran` reconciliation with exit codes recorded: 38 derived, 38 run, 0
NOT-MEASURED, 0 UNRUN. Changed lines: 185, under the 3,000 threshold.
</details>
---
_Generated by [Claude
Code](https://claude.ai/code/session_01FEkQ5nVH4357CHXi47gYLr)_
---------
Co-authored-by: Claude <noreply@anthropic.com>
fix(console): the shared-record page shows a lookup as "Linked record", never its stored id
7
+
8
+
Clause-②: yes (widening)
9
+
Metadata-protocol: none
10
+
11
+
-**`@object-ui/console`**: on a share link (`/s/TOKEN`), a lookup or master-detail field with a value now reads "Linked record" instead of the referenced record's stored id, which an anonymous visitor could not use and which read as a broken page. An empty one still reads as empty. Which field is a lookup comes from the `type` the resolve answer's `fields` projection already serves; the page sends no extra request and reads nothing about the referenced record. An answer from a server that predates the projection carries no type, so its rows render as before.
12
+
-**`@object-ui/i18n`**: every pack gains `sharedRecord.linkedRecord` (en "Linked record", zh-Hans 「已关联记录」).
0 commit comments