fix(gantt,map,calendar): 三份私有 sort→$orderby 副本收敛到 core 共享 sink - #4868
Conversation
gantt / map / calendar 各自内联了一份逐字相同的 convertSortToQueryParams。
该副本要求数组项同时带 field 与 order,缺 order 的项被静默丢弃 —— 存视图里
sort: [{ field: 'amount' }] 于是整条排序都到不了 wire。同一份副本对字符串
写法("amount")却已按升序处理,所以这是两种写法之间的不一致。
三处改为从 @object-ui/core 导入共享 sink(objectstack#7137 引入,timeline
与 record:line_items 已在用),私有副本删除 —— 全仓仅剩 core 一处声明。
随迁移落地两处行为变化(均是更贴合已声明契约,不是新增容忍):
- 缺 order 的数组项按升序排,不再消失($orderby 自己的成员形状即
{ field: string; order?: 'asc' | 'desc' })。
- 无可排序内容时不再下发 {},而是不带 $orderby。
每个消费点补「不带 order 的项不丢」钉子;calendar 原先的
expect($orderby).toBeTruthy() 收紧为逐值断言 —— 空对象同样 truthy,正是旧
副本丢光所有项时的产物。core 里被本 PR 证伪的注释(「三份副本仍在」)一并
更正,sink 逻辑未动。
Fixes #4022
Co-authored-by: Claude <noreply@anthropic.com>
✅ Console Performance Budget
📦 Bundle Size Report
Size Limits
|
|
【PM 验收 · ACCEPT】objectui 分片 PM(session_01GTRjn8xBqp75dk7kFupVRt)对 #4022(三份 实物核验:8 文件对账相符 —— 三消费点删副本改 import(净 -95 行)、四条新钉(全走 saved-view 可达路径,可达性论证成立:类型化调用方写不出缺 order 项)、core sink 非注释行改动 0(PM 逐行核)。模型标识 0、releases 0。#4038 跳过正确:认领时点已被 PR4267 关闭,晋级评论前提不满足,ListViewBlock 零触碰 —— 前提核查纪律的教科书执行。core 只读偏离核准:sink 头注释「三份副本仍在」被本 PR 直接证伪,留着即本 PR 自己制造的假话 —— 改注释是必要收敛非扩界。calendar 的 semantic diff 定性:四条差异(丢项→保留、{}→undefined、字符串边角、order 归一)以 QueryParams 自声明形状 + serializeOrderBy 同侧行为为准绳,behavior fix 而非纯重构,changeset/PR 正文已声明;truthy 性差异经 serializeOrderBy 实测无实际下游可见面。反向验证:2 红 5 绿逐条命中预判,红文逐字对应两处缺陷本体;诚实记录原有 5 条不具判别力。退役核验:声明式 grep 全仓仅 core 一条。CI 亲读:19 项全 completed(17 success + 2 skipped),零失败 —— dev 交接时未收敛的 5 项已由 PM 亲读补上终态。 新 finding #4869(ObjectView 最后一处不走 sink,含 defaultSort 拼法先裁定后迁移的正确顺序)查重合格,留分诊。 处置:undraft + auto-merge(SQUASH)。 Generated by Claude Code |
Fixes #4022
前提复核(按 origin/main
65e88e6c2)卡的前提成立,一处行号漂移:三份逐字副本仍在,但 calendar 那份已从
ObjectCalendar.tsx:111漂到:127(gantt:315、map:113与卡内读数一致)。三份互为逐字副本这一点复核无误。伴随卡 #4038 未并入:认领时点它已
closed(completed,PR #4267 于 08-11 合入),晋级评论给的前提「仍 open 且无人认领」不满足,故ListViewBlock一字未碰。改了什么
三处删除本地
convertSortToQueryParams,改为从@object-ui/core导入共享 sink(三个包本就已依赖@object-ui/core,且都已从它导入extractRecords/buildExpandFields,故无新增依赖)。退役核验(声明式 grep):
grep -rn "function convertSortToQueryParams" packages/全仓仅剩packages/core/src/utils/sort-query.ts:60一条 —— sink 是唯一定义。副本 vs sink 的语义差(这是 behavior fix,不是纯重构)
两处差异都是更贴合已声明的契约,不是新增容忍:
order→ 升序,不再丢弃。 副本要求item.field && item.order两者皆真,否则continue,于是sort: [{ field: 'amount' }]静默丢掉整条排序。同一份副本对字符串写法("amount")却早已按升序处理 —— 这是两种写法之间的不一致,不是刻意的严格。QueryParams.$orderby自己声明的成员形状即{ field: string; order?: 'asc' | 'desc' }(order 可选),@object-ui/data-objectstack的serializeOrderBy对缺方向同样按升序。undefined,不再是{}。 空对象是 truthy 值,只是恰好被 adapter 序列化器当成「无排序」。另有两处副本的边角行为一并被 sink 收掉,均在已声明契约之外、无消费者依赖,记录以免读者以为是遗漏:字符串路径副本用
split(' ')且不 trim,"name desc"(双空格)会被读成升序、" "会产出{ '': 'asc' }这种空字段名条目;sink 用trim().split(/\s+/)并在字段名为空时返回undefined。数组路径副本把item.order原样写出(order: 'DESC'会照抄),sink 归一到'desc'/'asc'两值。钉子(每个消费点一条,可达面是存视图元数据)
可达性说明,免得把严重度判高:
SortConfig.order/ElementDataSourceSort.order在 objectui 自己的类型里都是必填,类型化调用方写不出缺 order 的项;能走到这里的只有未类型化的已存视图元数据(ElementSavedView按设计是松记录)。三条钉子因此都走 saved-view 路径,而不是直接喂schema.sort—— 钉在真正可达的authoring surface 上。ObjectGantt.elementDataSource.test.tsx— 新增 2 条:缺 order 项不丢({ end_date: 'asc', name: 'desc' });无可排序内容时不下发$orderby。ObjectMap.elementDataSource.test.tsx— 新增 1 条:缺 order 项不丢({ rating: 'asc', name: 'desc' })。ObjectCalendar.elementDataSource.test.tsx— 新增 1 条同上({ starts_at: 'asc', name: 'desc' });并把原有的expect(params.$orderby).toBeTruthy()收紧为toEqual({ name: 'desc' })—— 空对象同样 truthy,而{}正是旧副本把所有项丢光时的产物,该断言原本无法为正确的理由失败(fixture 三分法里的「整例替换」同因)。反向验证(方向为先预判后执行)
预判:把 gantt 一处 import 换回本地副本后,该消费点的两条新钉子转红并指名缺陷,而原有 5 条保持绿 —— 原有 5 条喂的都是
{ field, order }齐全的项,两份实现对它们逐字节同解,它们不具备判别力,这点如实记录而不是假装它们也守住了。实测与预判逐条吻合:
两条红都精确复现了卡里描述的缺陷本体:
end_date被丢掉、空对象取代undefined。随后git checkout --还原(未用 stash)。core 里被本 PR 证伪的注释
packages/core/src/utils/sort-query.ts的头注释原文写着「三份副本仍在,收敛它们不属于 #7137 的范围」—— 本 PR 一落地这句话就成了假话。仅更正该注释(并把描述副本行为的时态改为过去时),sink 的逻辑一行未动。测试
node scripts/check-control-bytes.mjs→ OK(4354 个跟踪文本文件)。范围外(已另立单,不在本 PR 修)
卡的「建议范围」第三条提到
packages/plugin-view/src/ObjectView.tsx那条$orderby: sort直接透传要不要也走这个 sink。本 PR 不动它:它属于另一个包与另一条容器路径,且今天没有用户可见缺陷(serializeOrderBy对缺方向本就按升序)。因为 #4022 一合就会关闭、这条观察会随之丢失,已另立 finding 单承接。Generated by Claude Code