Repository navigation
FilterBuilder 切换行的 field 后 value 原样留下 —— 文本值落到 number 列,输入框显示空而行仍带着该值 #4781
Description
Activity
【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
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 becomes42;"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 (
MultiValueInputtoken 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
reshapeFilterValueshape, as the dev noted. Label flippedneeds-user-decision→pm:queuein the same stroke.
Generated by Claude Code
【认领】objectui 分片 PM(session_01GTRjn8xBqp75dk7kFupVRt)批次 13 派发,os-dev 实施。分支:
claude/issue-4781-filter-value-reconcile。按 2026-08-16 维护者裁定(评论 5306092839,方案 B)执行:可转则转("42"→42),不可转清到该族空形(标量''、列表[]);convertibility 一处定义于本组件,与 MultiValueInput token 转换、reshapeFilterValuecarry-if-possible 两先例一致;date/boolean 只在干净无歧义解析时转,默认清空;机制复用 #4768/PR4779 的reshapeFilterValue形态。文件面:FilterBuilder 组件族 +reshapeFilterValue所在文件 + 测试(以 PR4779 实际落点为准,认领后 dev 声明具体路径)。与在飞四单(plugin-charts / app-shell / gantt+map+calendar / docs)零交集。
Generated by Claude Code
- added a commit that references this issue
on Aug 16, 2026
发现于 #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 抄一遍就能落的,因为「新类型装不下旧值」时该怎么办有几种都说得通的答案,且都写进公共行为:
''、list[])。行为可预期,代价是换列会丢掉用户刚敲的东西——而这正是 PR fix(components): FilterBuilder 切换 field 时把算子归到新桶内 (#4768) #4779 特意不做的。"42"落到 number 列变成42(MultiValueInput的 token 已经这么做了),"acme"清空。保住了大多数真实场景,但「能不能转」的判定要在这里定义一份,且日期/布尔各有各的边界。type="text"并给出提示)。信息不丢,但把一个非法值留在了 spec 面前。倾向 B,理由是它与本组件已有的两处口径一致(token 输入的数字转换、
reshapeFilterValue的「能带过去就带过去、带不动才丢」),而 A 会让换列这个高频操作变得有惩罚性、C 会把一个查询层要处理的坏值留到存储。但这是公共行为,请 maintainer 定。参考
in/notInoperators, which the spec now refuses (objectstack#6227) #3958 / PR fix(components): FilterBuilder 为 in/not_in/between 渲染匹配形状的值输入,家族判定改读 spec 词表 (#3958) #4762(reshapeFilterValue的家族语义)