Uh oh!
There was an error while loading. Please reload this page.
test(plugin-form): pin form section headings to the _sections convention (objectstack#5408) - #3373
Merged
Merged
Conversation
…ntion (objectstack#5408) objectstack#5408 reported that the create/edit form's section tab strip ignores the `_sections` translations the detail page applies. Verified against origin/main: it does not — `ObjectForm.tsx` (`tSec`), `ModalForm.tsx` (`sectionTitle`) and `SimpleObjectForm`'s stacked path all resolve `objects.<object>._sections.<section>.label` through the same `useObjectLabel().sectionLabel` the detail page calls, falling back to the authored label. What was genuinely missing is coverage: not one test on the form side pinned that behaviour, so nothing stopped the two halves from drifting apart again — which is what the issue believed had already happened. Adds six pins: page-mode tabbed, modal-hosted tabbed, stacked sectioned, the no-bundle fallback, a parity assertion against the resolver the detail page uses, and a contract pin that the lookup key is the section's stable `name` and never a guess derived from its authored label. No production code changed. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GTRjn8xBqp75dk7kFupVRt
The latest updates on your projects. Learn more about Vercel for GitHub. |
Contributor
✅ Console Performance Budget
📦 Bundle Size Report
Size Limits
|
yinlianghui
marked this pull request as ready for review
August 5, 2026 10:34
Uh oh!
There was an error while loading. Please reload this page.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Refs objectstack-ai/objectstack#5408(前提证伪,issue 由 PM 按证伪结论另行关闭 —— 见该单评论;本 PR 交付的是缺失的护栏测试,不是症状修复)
结论先行:issue 的前提在
origin/main上不成立objectstack#5408 断言「表单的 section tab strip 从不查
_sections,而 detail 页会查」。对着
origin/main@68b6a28核验:表单这一半早就接上了,而且是和 detail 页同一个解析器、同一个 key 约定
objects.{objectName}._sections.{sectionName}.label,miss 时回退 authored label。三处独立调用点:
packages/plugin-form/src/ObjectForm.tsx:165-167(tSec),5 个分支映射各调一次packages/plugin-form/src/ModalForm.tsx:588(sectionTitle)、:684packages/plugin-form/src/ObjectForm.tsx:966-968detail 页那一半在
packages/plugin-detail/src/renderers/record-details.tsx:199,调的是同一个
useObjectLabel().sectionLabel(objectName, section.name, authoredLabel)。两半没有分岔。PM 补充里「plugin-form 全包零
_sections命中」是 grep 了字面量_sections的结果 —— 解析发生在@object-ui/i18n的sectionLabel()内部,包里自然搜不到这个字符串。
实测(见下方证据)zh-CN bundle 带
_sections时,tab strip 渲染的就是译文。现场那条 English tab strip 的真正成因:元数据缺
name_sections是按 section 的name建索引的。HotCRM 的src/views/case.view.ts里,crm_case默认 form view 的三个 section 只写了label,没有name:—— 正是 issue 里报的那条
Case / SLA / Resolution。而同一个 object 的src/translations/zh-CN.ts的crm_case._sections键是info/status/description(detail 页case_detail.page.ts的 section name,所以 detail 页正常出译文)加
basic/origin/sla/resolution(
case.object.ts的fieldGroups键)。form view 那三个 section 一个name都没有,渲染器根本拿不到 key,只能回退 authored label。
这是 producer 侧的元数据缺口,不是 renderer 缺口。按 AGENTS.md #0.1(contract-first),
不能在渲染器里把 label slug 化去猜第二套 key —— 那会把一个错误约定固化成第二份
事实契约。正确修法在下游元数据(给 form view 的 section 补
name)+ 平台侧加一道门(objectstack#5417)。
那这个 PR 交付什么
真正缺的东西:这套行为在 form 侧一条测试都没有(plugin-form 全包搜不到一处
sectionLabel的断言)。也就是说,让 issue 作者担心的「两半分岔」在今天是完全没有护栏的 —— 谁把
tSec改回s.label都不会红。本 PR 补的就是这道护栏,不改一行生产代码。
六条钉子(
packages/plugin-form/src/__tests__/sectionLabelI18n.test.tsx):工单信息),同一次渲染里未翻译的sla回退authored
SLA—— 译文路径和回退路径一次覆盖。formType: 'modal'+contentLayout: 'tabbed'):同上。(PM 点名的「FormSection 标题」那一半)。
_sections时,回退 authored label。useObjectLabel().sectionLabel、按record-details.tsx的同款入参形状算出期望值,断言 tab strip 文本与之逐项相等。form 侧一旦绕开这个解析器就红。
label没有name时,即使 bundle 里存在长得很像的键,渲染出来的就是 authored label —— 钉住「key 只认
name,渲染器不猜」,也就是上面HotCRM 那个 case 的最小复现。
验证
pnpm --filter @object-ui/plugin-form test(容器级 flock +--maxWorkers=2):33 = 原有 32 + 本 PR 新增 1,新文件确实进了这一轮(objectui#3288 的路径过滤坑,靠文件
计数而不是
-- --run path确认)。单跑新文件6 passed (6)。type-check退出 0;lint0 errors(500 条既有no-explicit-anywarning,与本 PR 无关)。反向验证(先定方向再跑):把生产代码改坏,看测试往哪边走。
ObjectForm.tsx的tSec改成s?.label—— 预测只红 2 条(用例 1 和 5),用例 2、3 应当仍绿,因为模态与 stacked 两条路各自还有独立的解析调用
(
ModalForm.sectionTitle/SimpleObjectForm)会把name再解析一次。实测:2 failed | 4 passed,失败正是用例 1、5(expected [ 'Case Info', 'SLA' ] to deeply equal [ '工单信息', 'SLA' ])。方向与预测一致。ModalForm.tsx:588与ObjectForm.tsx:966-968两处一并改坏 —— 预测用例2、3 补红,用例 4、6 恒绿(它们不依赖解析器)。实测:
4 failed | 2 passed,红的就是 1/2/3/5。
四条依赖解析器的用例全部可红,两条回退/契约钉在两次突变下都稳绿 —— 覆盖是活的,
不是「因为什么都没产出所以恰好通过」。改坏的文件已按原样还原,
git diff对生产代码为空。无 changeset:纯测试,无用户可见变更。
Generated by Claude Code