Skip to content

[console] List sort: filterableFields doubles as the sort whitelist, and a header click discards the view's multi-level default with no way back #4243

Description

@baozhoutao

Two related gaps in the Console list view's sort experience, found while shipping a downstream app on @objectstack/*@17.0.0-rc.6. Both are capability requests, not defects — the platform behaves as currently designed.

1. filterableFields doubles as the sort-field whitelist; there is no way to open sorting without also opening filtering

Observed: a list view declares a two-level default sort (e.g. plan_start_date then name). Neither field appears in the Sort panel's field dropdown, and the sort rows render with blank field names. The dropdown's contents turn out to be exactly filterableFields minus relation-typed fields (lookup / master_detail / user / owner — consistent with the panel's own footnote about columns pointing at other records).

So the same array feeds both the Filter builder and the Sort builder. A field that should be sortable but not offered as a filter condition cannot be expressed: the only workaround is to add it to filterableFields, which also makes it appear in the filter condition builder.

Also note the asymmetry: a view can declare sort on a field the sort panel refuses to list. The declared default sort works on load, but the user cannot reproduce or modify it through the UI.

Request: either a dedicated sortableFields (spec has no such key today), or have the sort panel fall back to all non-relation fields rather than reusing filterableFields.

2. Clicking a column header replaces the entire multi-level sort, with no way back to the view's default

Observed: a view ships a two-level default sort. One click on any column header replaces the whole sort array with that single column. The view's declared sort acts only as an initial value — after that first click it is unreachable for the rest of the session; there is no "reset to default sort" affordance.

Combined with #1 this was worse: because the fields were not in filterableFields, the user could not even rebuild the original two-level sort by hand. Adding the fields to filterableFields restores the ability to rebuild it manually, but "restore the view's default" still requires a page reload.

Request: a way to restore the view-declared default sort (a reset control in the sort panel, or preserving the declared sort as a fallback tier under the ad-hoc header sort).

Environment

@objectstack/*@17.0.0-rc.6, Console list view. Verified against a clean database with no view overlay rows (sys_view_definition / sys_metadata type=view both empty), server restarted by port before capturing — i.e. the source-declared view is what rendered.

Downstream context

Reported from a private app repo, so screenshots are not linkable here. Happy to build a public minimal reproduction on a showcase app if that helps — just say the word.

Activity

  1. os-zhuang commented on Aug 11, 2026

    @os-zhuang
    Contributor

    Triage: needs-user-decision.

    • Classification: both halves are capability forks, not defects (the body says so itself). Part 1 offers two directions with different owners — a new spec sortableFields key (contract change in objectstack packages/spec; the key has zero hits across objectui @ f812de6, counter-probe: filterableFields greps fine) vs a console-side fallback to all non-relation fields. Part 2 (restore view-declared default sort after a header click) is console UX shape. Which direction part 1 takes decides whether an objectstack spec sub-card exists at all, so the ruling comes first.
    • Code face verified on origin/main @ f812de6: packages/plugin-list/src/ListView.tsx:1876-1883 applies the filterableFields whitelist to the field set, and packages/plugin-view/src/SortUI.tsx:166 builds the sort dropdown from that same filtered schema.fields — the "one array feeds both builders" claim holds.
    • Dedup: only adjacent open card is ui#3950 (sort headers offered on formula fields the server refuses) — different defect, different fix site; cross-repo search for a spec-side sortableFields card: zero hits. No duplicate.
    • If the ruling picks the spec-key direction, contract-first split applies: spec sub-card in objectstack first, console consumption blocked on it.

    本评论来自分诊座位 Routine(#5474 试点),不构成认领。


    Generated by Claude Code

  2. os-zhuang commented on Aug 11, 2026

    @os-zhuang
    Contributor

    Maintainer ruling recorded 2026-08-11 (PM session, executing the maintainer's direct instruction in chat — verbatim: 「接受你的全部建议,请更新 issue 的状态和标签」, accepting the four-lens decision-inbox review in full).

    Ruling: the narrow fix. (1) The Sort panel's field list falls back to all non-relation fields instead of reusing filterableFields — ⛔ no new sortableFields spec key (a new vocabulary entry with no measured pull, against startup-focus). (2) Add a "reset to view default sort" affordance so a header click no longer makes the declared multi-level sort unreachable for the session.

    Scheduling: normal queue, NOT v17.

    State: needs-user-decision → pm:queue (objectui whole-repo seat).


    Generated by Claude Code

  3. self-assigned this
    on Aug 11, 2026
  4. yinlianghui commented on Aug 11, 2026

    @yinlianghui
    Collaborator

    CLAIM — session session_017Qqyix2QcnpUC9XeYVDzx3(objectui whole-repo PM seat),dispatching now. Branch: claude/issue-4243-sort-fallback-reset. Worktree-first.

    按 2026-08-11 已记录的维护者裁决执行(窄修,两半):(1) Sort 面板字段列表回退到全部非关系字段,⛔ 不新增 sortableFields spec 键;(2) 新增"恢复视图默认排序"控件。派单附加一条测量令:#3950(formula 字段被 server 拒排)是相邻卡——若 formula 类型确属 server 不可排,回退集合应把它一并排除并在 PR 正文说明(裁决的 ⛔ 在新词汇键上,不在合理的可排性排除上),但不修 #3950 的表头路径本身。

    Surface: packages/plugin-list/src/ListView.tsx(白名单应用点 ~1876)+ packages/plugin-view/src/SortUI.tsx(下拉源 ~166)+ 测试;当前无在飞持有者(#4267 已落,#4040 排除 plugin-list)。


    Generated by Claude Code

  5. yinlianghui commented on Aug 11, 2026

    @yinlianghui
    Collaborator

    ACCEPT — PM review of record (session session_017Qqyix2QcnpUC9XeYVDzx3)。

    PR #4299 按维护者裁决(窄修、⛔ 无新 spec 键)落地,验收要点:

    • 可排性排除的测量是本 PR 的承重墙:排除 formula 的依据不是猜测——server 侧 UNMATERIALIZED_SORT_TYPES 只含 formula(chore(deps): Bump streamdown from 2.5.0 to 2.6.0 #6994 起硬 400),而 objectstack 自己的一致性测试明文警告"扩到 COMPUTED_VALUE_TYPES 会弄坏两个能用的类型"(summary/autonumber 有实体列)。渲染器的排除集与 server 逐一镜像、理由记在定义处。Grid/list columns offer a sort header on formula fields, which the server refuses as of framework#6994 #3950 的表头面按令未动。
    • 单一事实源纪律成立:reset 走 parseSortConfig(初始 useState 与视图切换已用的那一个 resolver),按 (field, order) 比较而非随机 id;与 handleHeaderSort 同级同通道(host 持久化 reset 与持久化表头点击同路)。无声明排序时隐藏的裁量合理(该控件的契约是"放回声明的",无声明即无物可回;清空已有删行方式,不发明第二个语义),且双分支 pin 防了"控件根本不存在所以 null 检查恒绿"的假阳性。
    • 前提修正接受:triage 指的 SortUI.tsx:166 是独立注册的 'sort-ui' 组件、吃自己的 authored schema,与 ListView 字段集无关——修复全在 ListView.tsx。测量胜过转述。
    • 反向验证中"对照变 pin"的处理诚实:关系型省略提示自身也被白名单门控(白名单只剩 status 时选择器近空且无一字解释)——按实测改标签并记录理由,而不是硬凑模板。6 红 3 绿与预言精确一致;既有两套排序 suite 双侧绿是真对照。
    • CI 20 项收敛全绿;i18n 新键十包同步,drift 门绿。

    #4294 定级采纳(bug 入队):提示文案教用户"加 formula 字段来排序"——恰是 server 唯一拒排的类型,与 objectstack 同场景提示语义相反。真实的反向指导,须修。

    流程注记:revert-before-commit 的事故本日第二起(#4278 同型)。两名 dev 均自救成功且如实披露;commit-then-revert 已写入后续所有派单,另立文档卡把它进 AGENTS.md 的验证手册。

    Flipping ready + auto-merge。


    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

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions