… (objectstack#7121)
objectstack#6953(objectui PR #3969)把 spec 的 per-element 数据绑定接到了它点名的
8 个 block,同一条声明在其余 7 个 object-bound public block 上依旧无人消费:
object-gantt / object-timeline / object-map / object-pivot /
object-master-detail-form / embeddable-form / record:line_items。
每一块都把取数挂在自己的对象键上,而没有任何地方把 `dataSource.object` 映射过去
—— 按 spec 写、不额外写 `objectName` 的页面渲染出空甘特 / 空时间轴 / 无标记的地图 /
空交叉表 / 无字段的表单,不发请求、也没有任何诊断。spec-valid 的 metadata 渲染出空,
即 objectstack#4413 的形状。
复用 #6953 落地的共享层(`useElementDataSourceSchema` / `ElementDataSourceGate`),
一行未改;合成语义完全沿用 #5576(view 作基线、组件显式键覆盖 view、绑定显式键覆盖
两者、`filter` 三方 `and` 合成、view 解析不到报错不回退全量)。
映射只写该 block 真读的键(逐块查过读点):
- object-gantt (plugin-gantt/src/index.tsx) object + filter + sort
`$filter: schema.filter` / `$orderby: convertSortToQueryParams(schema.sort)`;
reload 不发 `$top`、字段由 `gantt` 配置点名 → limit/columns 不映射。
- object-map (plugin-map/src/index.tsx) object + filter + sort(同上读点)
- object-pivot (plugin-dashboard/src/index.tsx) object + filter
交叉表由 rowField/columnField 自己定序、总计不能在截断页上算 → sort/limit 不映射。
- object-timeline (plugin-timeline/src/index.tsx) object only
取数就是 `find(objectName, { options: { $top: 100 } })` —— 无 filter/orderby 读点、
窗口硬编码 → filter/sort/limit 刻意不映射。
- embeddable-form / object-master-detail-form (plugin-form/src/index.tsx) object only
写一条记录,没有集合查询给 filter/sort/limit 收窄;master-detail 的 object 是**父**
对象,子集合按 `details[]` 的 FK 取、固定 `$top: 500`。
- record:line_items (plugin-form/src/index.tsx) object → **childObject**
它列的/取的/写的集合是 `childObject`(与 record:related_list 的 `objectName` 同义:
都是该面板绑定的子对象);`relationshipField` 不属于绑定,仍归作者;查询只有父 FK +
固定 `$top: 500`;`columns` 是可编辑网格的 `GridColumn[]`,不是字段名投影 —— view 的
列表在这里是**形状不对**,不只是更宽。
把合成值写到 block 不读的键上,等于把本单要消除的缺陷往下挪一层、看起来像接好了,
所以上面每一个「不映射」都各钉了一条诚实断言(查询里确实没有那个键)。逐块覆盖表与
两处残缺口(timeline / line_items 的 view 贡献为零)补进了
`content/docs/guide/data-source.md`。
钉子:7 个新测试文件 31 例,每块两方向(带 `dataSource`(含 `view`)/ 不带),外加
「未映射的键一定不进查询」。
反向验证(先预判方向再跑,变异不提交):
- 撤掉 object-map 的 gate(恢复 pre-fix 渲染器):预判 4 条带绑定的钉子翻红(dataConfig
为 null → 压根不发 find、也不渲染错误面板)、无绑定基线保持绿。实测
`4 failed | 1 passed`,红的正是那 4 条(全部卡在 `waitFor(find 被调用)` / 错误面板),
绿的是「不带 dataSource 时行为逐字一致」。
- 把 record:line_items 的映射键从 `childObject` 改回默认 `objectName`:预判两条对象身份
断言翻红(合成值落到没人读的键上 → 查询对象变 `undefined`)、错误面板与无绑定基线保持
绿。实测 `2 failed | 2 passed`,报文正是 `expected undefined to be 'invoice_line'` ——
「写到没有读点的键上」这一失败模式被直接观测到。
顺手记录、未在本 PR 修:objectstack#7137(timeline / line_items 无 filter/sort 读点,
命名的 view 贡献为零)、objectstack#7138(ObjectMap 从 `schema.filter.map` 读地图配置)、
objectstack#7139(plugin-map 模块作用域的 console.log)。
Claude-Session: https://claude.ai/code/session_01GTRjn8xBqp75dk7kFupVRt
Co-Authored-By: Claude <noreply@anthropic.com>
Fixes objectstack-ai/objectstack#7121
这个 PR 修什么
objectstack#6953(PR #3969)把 spec 的 per-element 数据绑定(
PageComponentSchema.dataSource={ object, view?, filter?, sort?, limit? })接到了它正文点名的 8 个 block,同一条声明在其余 7 个 object-bound public block 上依旧无人消费:object-gantt/object-timeline/object-map/object-pivot/object-master-detail-form/embeddable-form/record:line_items。每一块都把取数挂在自己的对象键上,而没有任何地方把
dataSource.object映射过去 —— 按 spec 写、不额外写objectName的页面渲染出空甘特 / 空时间轴 / 无标记的地图 / 空交叉表 / 无字段的表单,不发请求、也没有任何诊断。spec-valid 的 metadata 渲染出空,就是 objectstack#4413 的形状。本 PR 复用 #6953 落地的共享层(
useElementDataSourceSchema/ElementDataSourceGate),共享层与 #5576 的解析层一行未改;合成语义完全沿用 #5576(view 提供基线 → 组件显式键覆盖 view → 绑定显式键覆盖两者;filter三方and合成,绑定只能收窄 view;view解析不到报错、不回退全量)。接线清单(block → 文件 → 映射了哪些键)
objectview贡献filtersortlimitobject-gantt(+view:gantt)packages/plugin-gantt/src/index.tsxobjectName$topobject-map(+view:map)packages/plugin-map/src/index.tsxobjectName$topobject-pivotpackages/plugin-dashboard/src/index.tsxobjectNameobject-timeline(+view:timeline)packages/plugin-timeline/src/index.tsxobjectNameembeddable-formpackages/plugin-form/src/index.tsxobjectNameobject-master-detail-formpackages/plugin-form/src/index.tsxobjectName(父对象)record:line_itemspackages/plugin-form/src/index.tsxchildObject$top: 500⛔ 的含义是「该 block 没有这个键的读点,所以故意不映射」,不是遗漏。 把合成值写到 block 不读的键上,等于把本单要消除的缺陷(声明了却被丢弃)往下挪一层、看起来像接好了 —— 所以每一个 ⛔ 都各钉了一条诚实断言:确认那个键确实没有进到查询里。逐块读点(给行号)在各处代码注释里;逐块覆盖表连同残缺口写进了
content/docs/guide/data-source.md。view那一列写的是「命名的 saved view 在该 block 上实际贡献了什么」。解析不到的 view 名在这 7 块上全部渲染配置错误 —— 包括那些从 view 里什么都不取的块,所以写错名字在任何一块上都不会静默通过。一处需要单独说明:
record:line_items的object落在childObject这是本批唯一一个对象键不叫
objectName的块。它列的、取的、写的集合都是schema.childObject(LineItemsPanel.tsx:dataSource.find(schema.childObject, …)、getObjectSchema(schema.childObject)、保存批次的子腿),所以dataSource.object映射到那里 —— 与record:related_list的objectName同义:两处那个键都是该面板绑定的子对象,正是dataSource.object的含义。relationshipField不属于绑定、仍归作者(它必须是绑定子对象上的字段);columns在这里是可编辑网格的GridColumn[]({ field, type, options, computed, expr, … }),不是字段名投影 —— view 的列表在这里是形状不对,不只是「答案更宽」,因此不映射。每块两方向钉子
7 个新测试文件 31 例。每一块都同时钉住「带
dataSource(含view)时正确映射」与「不带时行为与现状逐字一致」,并各带一条「未映射的键一定不进查询」。反向验证(先预判方向,再跑;变异不提交)
object-map的 gate(恢复 pre-fix 渲染器)。预判:4 条带绑定的钉子翻红(无objectName→getDataConfig()返回 null → 压根不发find、也不渲染错误面板),无绑定基线保持绿。实测4 failed | 1 passed,红的正是那 4 条(全部卡在waitFor(find 被调用)或错误面板断言),绿的是「不带 dataSource 时行为逐字一致」。record:line_items的映射键从childObject改回默认objectName。预判:两条对象身份断言翻红(合成值落到没人读的键上 → 查询对象变undefined),错误面板那条与无绑定基线保持绿。实测2 failed | 2 passed,报文正是expected undefined to be 'invoice_line'—— 「写到没有读点的键上」这一失败模式被直接观测到,也是这个映射键选择的证据。顺手记录、未在本 PR 修的发现
object-timeline/record:line_items的取数没有 filter/sort 读点(timeline 是find(objectName, { options: { $top: 100 } }),line_items 只按父 FK + 固定$top: 500),所以命名的 view 解析成功却贡献为零、列表可能比它引用的 view 更宽。与 objectstack#7118 同形。本 PR 刻意不映射这些键,并各钉了一条确认查询里确实没有它们的断言 —— 缺口一旦补上,那两条钉子会翻红,提醒同步更新映射与文档。ObjectMap.getMapConfig()从schema.filter.map/schema.filter.map.style读地图配置(把 filter 键当配置容器;声明过的输入是map)。注意其相互作用:绑定/view 带来的 filter 一旦合成成and节点,legacy 那条 stash 就找不到了 —— 已在映射旁注释写清,本 PR 不依赖该 legacy 形状。plugin-map/src/index.tsx模块作用域遗留console.log('Registering object-map...')(观察类)。边界(按派发约定)
⛔ 未碰
RelatedList.tsx/record-related-list.tsx(在飞的 os#7118 + #3895 结对面);⛔ 未碰共享层本体、SchemaRenderer、ChartContainerImpl;⛔ 未碰content/docs/releases/。验证输出
changeset:
@object-ui/plugin-gantt/plugin-timeline/plugin-map/plugin-dashboard/plugin-form各patch—— 用户可见的行为修复,无新增公共 API(共享层未改),按仓约定不声明major。Generated by Claude Code