Skip to content

FilterBuilder 切换行的 field 后 value 原样留下 —— 文本值落到 number 列,输入框显示空而行仍带着该值 #4781

Description

@yinlianghui

发现于 #4768 的实施(PR #4779),回传立单。与 #4768 同一处交互、不同一件事:那边是 operator 停在新桶外,这边是 value 停在新字段的类型外。

事实

packages/components/src/custom/filter-builder.tsx:切换一行的 field 时,PR #4779 只在算子家族发生变化(list/pair/scalar 之间)时用 reshapeFilterValue 重整 value;标量到标量没有形状问题,value 被原样带过去——这是 #4768 明确的边界,也是刻意的:用户敲进去的东西不该因为换了一列就被丢掉。

但字段的类型也换了。把一个 text 列(equals / value "acme")改到 number 列后:

  • 值输入框由 getInputType 变成 type="number",而它的 value 仍是 "acme";浏览器对 number 输入框的非数字 value 一律显示为空,于是输入框显示空白;
  • 行本身仍带着 value: "acme",foldFilterGroupToSpecRules 原样持久化,实时网格拿 amount equals "acme" 去查。

也就是 #4768 那个「控件显示空、行却带着看不见的东西」的同一形状,只是发生在 value 而不是 operator 上。日期 → 文本、布尔 → 文本等组合同理(type="date" 对非日期字符串也显示空)。

复现:筛选面板加一行 → 字段选文本列 → 值输入 acme → 字段改成数字列 → 值输入框空白,但保存下来的规则里 value 仍是 acme。

待做(需要先定一个语义)

这不是照着 #4768 抄一遍就能落的,因为「新类型装不下旧值」时该怎么办有几种都说得通的答案,且都写进公共行为:

  • A. 清空:换到不兼容类型就把 value 清成该家族的空形状(标量 ''、list [])。行为可预期,代价是换列会丢掉用户刚敲的东西——而这正是 PR fix(components): FilterBuilder 切换 field 时把算子归到新桶内 (#4768) #4779 特意不做的。
  • B. 能转则转、不能转才清:"42" 落到 number 列变成 42(MultiValueInput 的 token 已经这么做了),"acme" 清空。保住了大多数真实场景,但「能不能转」的判定要在这里定义一份,且日期/布尔各有各的边界。
  • C. 保留但让它可见:不改 value,改成让输入框在值与类型不匹配时仍显示出来(例如退回 type="text" 并给出提示)。信息不丢,但把一个非法值留在了 spec 面前。

倾向 B,理由是它与本组件已有的两处口径一致(token 输入的数字转换、reshapeFilterValue 的「能带过去就带过去、带不动才丢」),而 A 会让换列这个高频操作变得有惩罚性、C 会把一个查询层要处理的坏值留到存储。但这是公共行为,请 maintainer 定。

参考

Activity

  1. yinlianghui commented on Aug 16, 2026

    @yinlianghui
    CollaboratorAuthor

    【PM 分诊】座位 repo:objectui(session_01GTRjn8xBqp75dk7kFupVRt):挂 needs-user-decision 入决策箱 —— 「field 切换后新类型装不下旧 value 怎么办」三选项(A 清空 / B 能转则转 / C 保留但可见)各有站得住的产品理由,dev 已在正文给出三选项与倾向 B 的论证。PM 不代裁的理由:与 operator 切换(#4762/#4768 已按「重整」落地)不同,field 切换后旧值可能类型兼容且用户有意保留(换列续用同值),清空/转换/保留的取舍是 UX 语义不是契约机械。维护者拍板后转 pm:queue 派发,机制可完全复用 #4768 的 reconcileOperatorForField 形态。


    Generated by Claude Code

  2. os-zhuang commented on Aug 16, 2026

    @os-zhuang
    Contributor

    Maintainer ruling (2026-08-16, recorded by PM session session_01NYgmGheCzM6NrHZN436Cxf). The maintainer approved the report's recommendation for this card (「主线1 3 4:同意」).

    Ruled: Option B — convert when convertible, clear otherwise.

    • "42" moved to a number column becomes 42; "acme" clears to the family's empty shape (scalar '', list []).
    • The convertibility judgement is defined once, in this component, consistent with the two existing precedents the card names (MultiValueInput token conversion; reshapeFilterValue's carry-if-possible semantics). Date/boolean edges: convert only on a clean, unambiguous parse — default to clear.
    • Rationale on record: A punishes the high-frequency column-switch interaction; C leaves an illegal value facing the spec/storage layer. B matches the component's established posture.

    Mechanism can reuse the #4768 / PR #4779 reshapeFilterValue shape, as the dev noted. Label flipped needs-user-decision → pm:queue in the same stroke.


    Generated by Claude Code

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

    @yinlianghui
    CollaboratorAuthor

    【认领】objectui 分片 PM(session_01GTRjn8xBqp75dk7kFupVRt)批次 13 派发,os-dev 实施。分支:claude/issue-4781-filter-value-reconcile。按 2026-08-16 维护者裁定(评论 5306092839,方案 B)执行:可转则转("42"→42),不可转清到该族空形(标量 ''、列表 []);convertibility 一处定义于本组件,与 MultiValueInput token 转换、reshapeFilterValue carry-if-possible 两先例一致;date/boolean 只在干净无歧义解析时转,默认清空;机制复用 #4768/PR4779 的 reshapeFilterValue 形态。文件面:FilterBuilder 组件族 + reshapeFilterValue 所在文件 + 测试(以 PR4779 实际落点为准,认领后 dev 声明具体路径)。与在飞四单(plugin-charts / app-shell / gantt+map+calendar / docs)零交集。


    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

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions