Repository navigation
Commit fd97351
fix(console): the standalone /forms route shows select option labels in the language the user chose (#26584)
Fixes #26452
Clause-②: no
Metadata-protocol: none
## 维护者速读
- 改了什么:独立表单路由 `/forms/:name`(及 `/apps/:appName/forms/:name`)改走控制台已认证的
fetch 读写 API,下拉选项标签随用户所选语言显示。
- 为什么改:该路由用裸 `fetch` 读对象 schema,服务端按浏览器的 `Accept-Language`
本地化选项;应用内弹窗表单走的通道带会话语言,所以同一会话两处语言不一致(p1,发版扫描 FAIL)。
- 风险与代价(含回滚):内部路由的请求从此带上
Bearer、`X-Tenant-ID`、`Accept-Language`,与弹窗表单一致;公开表单 `/f/:slug` 不变。回滚即
revert 本 PR。
- 席位意见:
- 你要做的:无需操作;席位复核后按常规入队。
## Summary
On the standalone internal form route, a user whose chosen language
differs from the browser's saw field labels in their language and every
select option in the browser's. The in-app overlay form (`?form=ID`) in
the same session showed the options translated.
## Root cause
The overlay (`ModalForm` → `ObjectForm`) does not translate option
labels on the client. Its field builder (`fromObjectSchema` in
`@object-ui/plugin-form`) hands `field.options` to the widget as served.
The translation happens on the server: the object schema is read over
the console's authenticated fetch (`createAuthenticatedFetch`, published
to the renderers as `SchemaRendererContext.apiFetch`). That fetch stamps
`Accept-Language` with the session's UI language (the `lang` attribute
of the html element), and the server localizes `/meta/object`, option
labels included, in that language.
`FormPage` read `/meta/view`, `/meta/object` and the record with a bare
`fetch`, so the request carried the browser's language. Field labels
still came out translated because they resolve on the client through the
bundle (`fieldLabel`); options have no client lookup on either form
surface, so they followed the browser. This matches the card's Control
2: a zh-CN browser already got Chinese options on this route.
## Fix
`ui/apps/console/src/components/FormPage.tsx`: in internal mode, every
API request (the form view, object schema and record reads, and the
create/update submit) goes through `SchemaRendererContext.apiFetch`, the
host's authenticated fetch the console shell publishes. With no provider
above the route it falls back to the bare `fetch`, as before. The public
anonymous route `/f/:slug` keeps the bare `fetch`.
No option-label translator is added. The route now takes the channel the
overlay takes, so the server's one resolver answers both surfaces. An
option the bundle does not translate keeps its authored label, because
that is the server's fallback.
`InternalFormRoute.tsx` is unchanged: both internal mounts
(`InternalFormRoute` and `InAppFormRoute`) render `FormPage
mode="internal"` inside the console shell's `SchemaRendererProvider`.
## Tests
New pin
`ui/apps/console/src/components/FormPage.optionLabelLocale-26452.test.tsx`.
It mounts `/forms/:name` in edit mode inside a `SchemaRendererProvider`
whose `apiFetch` is the real `createAuthenticatedFetch({ sameOriginOnly:
true })`, with the html element's `lang` set to `zh-CN` and a stub
server that localizes `/meta/object` by the request's `Accept-Language`.
- Leg 1: the status and priority comboboxes read the zh option labels
(`评审中`, `高`), and the schema read carried `zh-CN`.
- Leg 2: an option with no zh translation (`urgent`) keeps its authored
label `Urgent`.
Red first, at `1768fd79` (pin only, no fix): 2 of 2 failed,
`AssertionError: expected 'In Review' to contain '评审中'` and `expected
'Done' to contain '已完成'`. Green at `ff64ab6a` (fix): 2 of 2 passed.
At head `f0294fa8` (after merging `origin/main`), under the shared
verify lock (`VERDICT command-exit 0`):
- closure build `pnpm --filter "@object-ui/console^..." build`: ok;
- every console test file that imports `FormPage` or `InternalFormRoute`
(`FormPage.*`, `formPageRequiredMarker`, `internalFormShell`,
`formViewFeaturesRootRefused`, `App.homePermissions`,
`App.docsPortalLazy`, `App.uploadAltitude`, `createdRecordPath`,
`submitRedirect`, `OAuthConsentPage.agent-scopes`): Test Files 42 passed
(42), Tests 415 passed (415);
- `pnpm --filter @object-ui/console type-check`: exit 0. The console
tsconfig includes `src`, so the new test is type-checked.
Live showcase reproduction: NOT MEASURED. Booting the showcase plus a
console build and a browser on the shared box was not cheap under the
verify-lock queue. The pin models the server's measured behaviour (the
card's Control 2) with the real host fetch.
## Gates
Local, at `f0294fa8`: `node scripts/pm/dispatch-gates.mjs --repo
objectstack-ai/objectstack --ran` reports 33 derived, 33 run, 0
NOT-MEASURED, and every one exited 0. That includes `node
scripts/check-sdui-manifest.mjs` (intact, 106 components; no registry
contract changed, so it was not regenerated) and `pnpm --dir ui exec
vitest run scripts/` (178 passed, 2 skipped). CI runs the rest.
## Acceptance notes
- The public route `/f/:slug` still reads over the bare `fetch`. For an
anonymous visitor the UI language is the detected browser language, so
nothing diverges. A signed-in visitor who chose another language would
still see options in the browser's language there. Moving that route
onto a session-carrying channel changes what the anonymous resolver and
submit see, so it is left out of this change.
- The card's two related notes (the route's English-only refusal and
missing-recordId messages, and `?form=UNKNOWN_ID` opening a blank edit
form) are not addressed here.
---
_Generated by [Claude
Code](https://claude.ai/code/session_01SMps7wq7rBTk53e8KTSEup)_
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent e443a60 commit fd97351
3 files changed
Lines changed: 238 additions & 14 deletions
File tree
- .changeset
- ui/apps/console/src/components
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 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 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
116 | 116 | | |
117 | 117 | | |
118 | 118 | | |
119 | | - | |
| 119 | + | |
120 | 120 | | |
121 | 121 | | |
122 | 122 | | |
| |||
148 | 148 | | |
149 | 149 | | |
150 | 150 | | |
151 | | - | |
| 151 | + | |
152 | 152 | | |
153 | 153 | | |
154 | 154 | | |
| |||
1449 | 1449 | | |
1450 | 1450 | | |
1451 | 1451 | | |
1452 | | - | |
1453 | | - | |
| 1452 | + | |
| 1453 | + | |
| 1454 | + | |
| 1455 | + | |
| 1456 | + | |
| 1457 | + | |
| 1458 | + | |
| 1459 | + | |
| 1460 | + | |
| 1461 | + | |
| 1462 | + | |
1454 | 1463 | | |
1455 | 1464 | | |
1456 | 1465 | | |
| |||
1629 | 1638 | | |
1630 | 1639 | | |
1631 | 1640 | | |
| 1641 | + | |
1632 | 1642 | | |
1633 | | - | |
| 1643 | + | |
1634 | 1644 | | |
1635 | 1645 | | |
1636 | 1646 | | |
| |||
1658 | 1668 | | |
1659 | 1669 | | |
1660 | 1670 | | |
1661 | | - | |
| 1671 | + | |
1662 | 1672 | | |
1663 | 1673 | | |
1664 | 1674 | | |
| |||
1691 | 1701 | | |
1692 | 1702 | | |
1693 | 1703 | | |
| 1704 | + | |
| 1705 | + | |
1694 | 1706 | | |
1695 | 1707 | | |
1696 | 1708 | | |
| |||
1725 | 1737 | | |
1726 | 1738 | | |
1727 | 1739 | | |
1728 | | - | |
| 1740 | + | |
| 1741 | + | |
1729 | 1742 | | |
1730 | 1743 | | |
1731 | 1744 | | |
| |||
1746 | 1759 | | |
1747 | 1760 | | |
1748 | 1761 | | |
| 1762 | + | |
1749 | 1763 | | |
1750 | 1764 | | |
1751 | 1765 | | |
1752 | 1766 | | |
1753 | | - | |
1754 | | - | |
1755 | | - | |
1756 | | - | |
| 1767 | + | |
| 1768 | + | |
| 1769 | + | |
| 1770 | + | |
| 1771 | + | |
1757 | 1772 | | |
1758 | 1773 | | |
1759 | 1774 | | |
| |||
2146 | 2161 | | |
2147 | 2162 | | |
2148 | 2163 | | |
| 2164 | + | |
| 2165 | + | |
| 2166 | + | |
| 2167 | + | |
| 2168 | + | |
| 2169 | + | |
| 2170 | + | |
| 2171 | + | |
| 2172 | + | |
| 2173 | + | |
| 2174 | + | |
| 2175 | + | |
| 2176 | + | |
| 2177 | + | |
| 2178 | + | |
| 2179 | + | |
| 2180 | + | |
| 2181 | + | |
| 2182 | + | |
| 2183 | + | |
| 2184 | + | |
| 2185 | + | |
| 2186 | + | |
| 2187 | + | |
2149 | 2188 | | |
2150 | 2189 | | |
2151 | 2190 | | |
| |||
2213 | 2252 | | |
2214 | 2253 | | |
2215 | 2254 | | |
2216 | | - | |
| 2255 | + | |
2217 | 2256 | | |
2218 | 2257 | | |
2219 | 2258 | | |
| |||
2238 | 2277 | | |
2239 | 2278 | | |
2240 | 2279 | | |
2241 | | - | |
| 2280 | + | |
2242 | 2281 | | |
2243 | 2282 | | |
2244 | 2283 | | |
| |||
2347 | 2386 | | |
2348 | 2387 | | |
2349 | 2388 | | |
2350 | | - | |
| 2389 | + | |
2351 | 2390 | | |
2352 | 2391 | | |
2353 | 2392 | | |
| |||
0 commit comments