Skip to content

gantt / map / calendar 各自内联一份 convertSortToQueryParams(三份逐字副本),已有 @object-ui/core 的共享 sink 可迁移;副本会丢掉不带 order 的 sort 项 #7148

Description

@yinlianghui

发现于 objectstack#7137 的实施过程(objectui 分支 claude/issue-7137-timeline-lineitems-filter-sort,基线 f3b2874e1)。观察类 —— 今天没有用户能踩到它,记录以免下次有人再复制第五、第六份。

事实

sort → $orderby 的下降逻辑在三个 object-bound block 里各内联了一份逐字相同的私有函数:

  • packages/plugin-gantt/src/ObjectGantt.tsx:315
  • packages/plugin-map/src/ObjectMap.tsx:113
  • packages/plugin-calendar/src/ObjectCalendar.tsx:111

objectstack#7137 给 object-timelinerecord:line_items 各补了 sort 读点,要是照抄就是第五、第六份,所以那个 PR 把这份逻辑提到了 @object-ui/core(packages/core/src/utils/sort-query.ts,导出 convertSortToQueryParams,带单测)。三份私有副本没有动 —— 迁移不在 #7137 的范围内,故立此单。

迁移本身是机械的:删掉本地函数、从 @object-ui/core 导入(三个包都已经依赖它)。

一处行为差异,迁移时会一并被修掉

共享版有两点与私有副本不同,都是更贴合已声明的契约,而不是新增容忍:

  1. 不带 order 的数组项按升序处理,而不是丢弃。 私有副本要求 item.fielditem.order 两个键都在,否则跳过该项 —— 于是 sort: [{ field: 'amount' }]静默丢掉整个排序(全部项都缺 order 时 reduce 出 {})。同一份副本在字符串写法上却已经把「只有字段名」当升序("amount"{ amount: 'asc' }),所以这是两种写法之间的不一致,不是刻意的严格。QueryParams.$orderby 自己声明的数组成员也是 { field: string; order?: 'asc' | 'desc' }(order 可选),@object-ui/data-objectstackserializeOrderBy 同样按升序处理缺失的方向。
  2. 无可排序内容返回 undefined,不返回 {} 空对象是个 truthy 值,只是恰好被 adapter 的序列化器当成「无排序」;undefined 是把这件事说出来。

可达性说明(免得把严重度判高):SortConfig.order / ElementDataSourceSort.order 在 objectui 自己的类型里都是必填,所以类型化的调用方写不出缺 order 的项;能走到这一步的只有未类型化的已存视图元数据(ElementSavedView 声明为 Record< string, unknown >,按设计是松的)。这也是本单标 finding 而不是缺陷单的原因。

(注:上一版正文里 Record< string, unknown > 的泛型参数被 GitHub 的正文清洗器当成 HTML 标签吃掉了 —— < 紧跟字母会被就地剥掉。此处按仓内约定在 < 后留空格重写。)

建议范围

去重

已搜过 open issues(convertSortToQueryParams / $orderby / 重复 + 文件路径),无同题单。相关:objectstack#7137(共享 sink 的引入者)。

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions