fix(app-shell): record:details 段落设计器补上 name 这个 i18n 锚点位 (#3819) - #3911
Merged
Conversation
The `record:details` sections editor offered label/columns/fields and omitted `name`, which is the section heading's i18n anchor: `record-details.tsx` resolves the heading through `objects.<object>._sections.<name>.label` and falls back to the authored string when `name` is absent. Every section built in Studio was therefore untranslatable by construction and carried an upstream `translation-section-name-missing` diagnostic no designer control could clear. Adds the `Name (i18n key)` text field, first in each section entry (matching page:tabs / page:accordion, where the identifier precedes the label). The snake_case convention lives in the placeholder because `BlockPropField` has no description/pattern affordance. Deliberately not derived from `label` (a localized label would freeze one locale's prose into a locale-independent key, invisibly — the renderer's fallback makes a wrong anchor render exactly like the bug) and existing label-only sections are not backfilled (the inspector is read-through; nothing is written until the author types). Section-entry coverage is now derived from the spec's `RecordDetailsProps` shape instead of hand-listed, so the next section key the spec grows fails loudly here rather than quietly never reaching the designer.
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
Contributor
✅ Console Performance Budget
📦 Bundle Size Report
Size Limits
|
Collaborator
Author
|
✅ 验收(PM,session 实物核验:头 裁定要点:
转 ready 并挂 auto-merge。越界 #3912(BlockPropField 无校验能力位,observation)与 #3913(块检查器 PROPERTIES 面 zh-CN 下英文,concrete,100+ label)归分诊席。 Generated by Claude Code |
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 free
to 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.
Fixes #3819
问题
record:details的 sections 编辑器只给了label/columns/fields,漏掉了name。而name不是可选的装饰位,它是段落标题的 i18n 锚点 ——plugin-detail的record-details.tsx用它去解析objects.{object}._sections.{name}.label,name缺失时直接退回作者当时敲进去的那串字:于是 Studio 里搭出来的每个 section 在结构上就不可翻译:所有 locale 下同一串英文,并且必然挂着上游
translation-section-name-missing这条作者在设计器里修不掉的诊断。这个键此前只能靠手改 source 才能写上 —— 而"不必手改 source"正是设计器存在的理由。前提复核(origin/main @
50fa3766ebb2ebf2ec78c5d13b1d627e6a91696f)三个锚点都还在,issue 前提成立:
previews/block-config.ts的record:detailssectionsitemFields确实只有 label/columns/fields;plugin-detail/src/renderers/record-details.tsx:199的sectionLabel(objectName, s.name, …)实读在;packages/i18n/src/useObjectLabel.ts:419的键约定({ns}.objects.{objectName}._sections.{sectionName}.label)在。改法
新增
Name (i18n key)文本位,放在每个 section 条目的第一个 —— 与page:tabs(key)、page:accordion(value)一致:标识符在人类标签之前。snake_case 约定写在 placeholder 里,因为BlockPropField没有 description/pattern 这类能力位(与本套件已有的"每个 json 位必须带形状 placeholder"同一条理由)。两个实现级子问题的判定
① 不做自动派生,也不新造校验。 实测
BlockPropField的text只支持placeholder,没有 pattern/validate 能力位;按分诊"没有就不为此单独造",不为一个字段单独造校验层,约定交给 placeholder 陈述、强制点仍在上游 lint 规则。派生能力其实存在(InspectorTextField有一个注释写明"e.g. to derive a dependent field"的onBlur钩子),这里刻意不接:label可能已经是译好的文案,甚至是内联{ en, 'zh-CN' }映射(record-details会走pickLocalized),从它派生等于把某一个 locale 的文案冻进那个本该与 locale 无关的键里。更糟的是这种损坏看不见 —— 译文缺失时渲染器回退到 authored label,派生错的锚点渲染出来和 bug 本身一模一样,要等有人加第二个 locale 才暴露。② 既有仅 label 的 section 不回填。 打开时锚点位留空、
label原样不动,作者不输入就什么都不写。这一条不需要代码:inspector 是纯读穿的,renderField只在 commit 回调里写;反过来做回填要在 render 期打补丁,还会让一个只是被点开过的页面变成 dirty。钉子
record:details的 section 条目覆盖率现在从 spec 自身的RecordDetailsProps形状推导,不再手列 —— 手写一句expect(name).toBeDefined()只能把今天这个洞钉住,spec 下次长出新的 section 键时它照样绿。另加三条:name是 text 位、placeholder 陈述 snake_case、label 说明是 i18n 键、且排在label之前。PageBlockInspector.sectionName.test.tsx,仿同目录visibleWhen先例):输入位真的渲染出来、输入落进properties.sections[i].name且合并而非覆盖同条目其它键、多 section 时写对那一个、既有 label-only section 打开留空、仅渲染不产生任何 patch、改邻位 label 不会派生出name。hidden条件框写的是 spec 不认识的键(canonical 是visibleWhen) #3229 的visibleWhen不同,这个面是宽松的 —— 实测 pin 版@objectstack/spec@17.0.0-rc.5:PageSchema.parse根本不拿RecordDetailsProps校验properties,RecordDetailsProps自己对 section 条目里的未知键也放行。所以无名 section 一直都能 parse,只是永远不可翻译。写一条"提交的 draft 能 parse"是绿得没有意义的断言,本单真正要钉的是这个键可达。测试文件头把这点写清了,免得下一个读者照抄错的判据。反向验证(方向先判后跑,结果与预判一致)
预判 Red:去掉新 itemField → 9 条红(配置面 3:spec 覆盖率 pin 报
missing: ['name']、形状 pin、顺序 pin;交互面 6:所有定位锚点输入位的用例),15 条绿。实跑:失败集合与预判逐条对上。如实说明:保持绿的 15 条里,子问题 ② 的两条(
rendering the inspector writes nothing by itself、keeps the section nameless until the author types one)在改动前也是绿的 —— 它们钉的是"不回填/不派生"这个无代码的决定,走labelBox而不是锚点位,因此按定义不可能因为删掉字段而变红。这不是缺陷,是那条决定的正确钉法。另有一条a freshly added section offers an empty name box初版只断言 Add 推入{},删掉字段后会空绿(断言通过是因为什么都没产生);已补上锚点位读数,现在会红。浏览器实证(preview gallery,无后端)
走真实授权路径:palette 加
record:details块 → 画布选中 → Add section → 输入锚点。探针直接读DesignerCard的 draft state(React fiber 的queue.lastRenderedState,memoizedState会慢一帧):STEP 4 是子问题 ② 在真实 UI 里的读数:写了 label,
name仍不存在、输入位仍空 —— 没有派生。STEP 5 是"落进 schema"的读数(输入位是受控的,值留得住就说明真的进了 state)。placeholder 量了一下没有被截断:文本 206px / 输入内宽 243px,完整可读。验证命令
pnpm --filter '@object-ui/app-shell^...' build→ 通过pnpm exec vitest run两个测试文件--maxWorkers=2→Test Files 2 passed | Tests 24 passedplugin-detail的recordDetailsInputs.spec-parity/record-details/buildDefaultPageSchema)→Test Files 12 passed | Tests 204 passedpnpm exec turbo run type-check --concurrency=2→78 successful, 78 totalnode scripts/check-control-bytes.mjs→ OK(3789 文件);改动文件另做grep -naP控制字节自查,零命中边界
只改
previews/block-config.ts的record:details一条 + 测试 + changeset。上游 lint 规则本体没动;#3831(plugin-detail/fields)、#3134(表单布局设计面)零相交;content/docs/releases/**未碰。Generated by Claude Code