Skip to content

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

Closed as not planned

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

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

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

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

  1. 不带 order 的数组项按升序处理,而不是丢弃。 私有副本要求 item.field 与 item.order 两个键都在,否则跳过该项 —— 于是 sort: [{ field: 'amount' }] 会静默丢掉整个排序(全部项都缺 order 时 reduce 出 {})。同一份副本在字符串写法上却已经把「只有字段名」当升序("amount" → { amount: 'asc' }),所以这是两种写法之间的不一致,不是刻意的严格。QueryParams.$orderby 自己声明的数组成员也是 { field: string; order?: 'asc' | 'desc' }(order 可选),@object-ui/data-objectstack 的 serializeOrderBy 同样按升序处理缺失的方向。
  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 的引入者)。

Activity

  1. added
    repo:objectuiSeam card: cross-repo ordering with objectui is the substance (pure objectui fixes live in objectui)
    findingRecorded observation — held, not dispatchable until the findings triage round grades it
    on Aug 9, 2026
  2. os-zhuang commented on Aug 10, 2026

    @os-zhuang
    Contributor

    Finding-triage ruling: Hold (why still held): the shared sink this card migrates to is not on main — it ships with open PR objectui#4009; the three inline copies are semantically equal today. Restart: objectui#4009 merges, then promote as a mechanical migration (sweep-candidate: shared-sink-consolidation, together with #7120).

    Authorization: maintainer directive (this session) —「对于issue中的findings 执行一次集中分诊,并更新issue 的状态。」Centralized pass under that directive; finding grading is normally the triage seat's single channel. Round: objectstack#4949 finding-triage, 2026-08-10.
    Session: 01JaVVMrSxt7Tgi1uwEuDtH7


    Generated by Claude Code

  3. os-zhuang commented on Aug 10, 2026

    @os-zhuang
    Contributor

    Migrated to objectstack-ai/objectui#4022 under #7167 (file-at-destination ruling, maintainer 2026-08-10). Native GitHub issue transfer is not available to this session's credential, so the card was recreated at the destination; this thread stays as the authoritative history and is linked from the new card. Closing as not planned here — moved, not rejected.


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    findingRecorded observation — held, not dispatchable until the findings triage round grades itrepo:objectuiSeam card: cross-repo ordering with objectui is the substance (pure objectui fixes live in objectui)

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions