Skip to content

fix(ui): keep one state for the transaction type filter, shared by both controls - #230

Merged
argszero merged 1 commit into
mainfrom
fix/tx-type-filter-single-state
Sep 14, 2026
Merged

argszero merged 1 commit into
mainfrom
fix/tx-type-filter-single-state

Conversation

@argszero

Copy link
Copy Markdown
Owner

Summary

交易页的类型筛选有两套控件(顶部 #tx-tabs 全部/消费/收益 + 「类型」列表头的 select.th-filter,6 个库内值),状态却分成两份:tab 写模块级 txTab,列筛选写 txTable.filters.typeloadTransactions 按固定优先级取 filters.type || txTab ⇒ 列筛选一旦出值就永久盖住 tab:

  • 死控件:点 tab 只改 txTab、重画高亮,请求仍带列筛选的值 ⇒ 这一点击什么都没发生;
  • 说谎的指示器:高亮按 txTab 画 ⇒ 列筛选选「赠送」时列表是赠送行,而「全部」仍然亮着。

同一个筛选概念只能有一份状态。本改动删掉第二份(txTab),两套控件都走 txTypeFilter()(读)/ setTxTypeFilter()(写,并同步已渲染的 select —— #148 之后表头不重建,控件不会自己跟上状态)。生效值不属于 all/consume/earn 时(topup / withdraw / gift / expire)没有任何 tab 自称生效:把「全部」点亮而列表只有赠送行,同样是在说谎。

Related Issue

(无关联 issue;本轮为自测复现的缺陷修复)

Changes

  • ui/js/app.js:删除 txTab;新增 txTypeFilter() / setTxTypeFilter() 作为唯一读/写入口;tab 高亮改由生效状态派生;tab 点击只写状态,重拉交给既有的筛选签名比对
  • ui/index.htmlapp.js?v=20260914-7(cache-bust)
  • ui/README.md:记录「一份状态、两套控件」的约定与冒烟测试注意点
  • 涉及配置/数据结构的改动已同步示例文件 —— 不适用(纯前端,零 Rust、零新 i18n 键)

Tests

  • cargo test 全部通过(235 passed,与改前一致)
  • cargo fmt --check 通过
  • cargo clippy 无新增 warning
  • 新增/更新了单元测试(如适用)—— 本改动为前端行为,用 jsdom 端到端探针验收(见下),未新增 Rust 测试

验收探针(jsdom,真 ui/index.html + 四个真脚本,只 stub fetch

探针驱动真控件(真 tab 点击、真 select + 真 input 事件),并把三个产物(请求参数 / tab 高亮 / select 的值)与同一个派生 wantTabs(type) 比较 —— 不用字面量,否则应用的高亮恰好拼对时会误绿。

A/B(基线钉在 d1faab6git show 取改前文件;驱动在「基线 == 修复」时直接 ABORT,避免变成空对照):

leg 含义 结果
v0_orig 改前文件 5/11,红 = {B2 indicator, B3 deadcontrol, B4 agree-select, B5 agree-highlight, C1 sibling-topup, C2 sibling-all}
m_dead 点 tab 不再写状态 4/11(红 A1/A2/A3/B3/B4/B5/C2)
m_nosync 写状态但不同步 select 9/11(红 B4/C2)
m_ind 高亮取自常量而非状态 7/11(红 A2/B2/B5/C1)
live 修复后的工作树 11/11,红集为空

内建阴性对照 A0(探针能看见已渲染的表格)在每一条腿都是绿的。如实记录一点:m_nosync 的红集是 m_dead 的子集(回退「写状态」本身就包含了「不同步 select」),两者非互斥;互斥的是 m_deadm_ind

Checklist

  • 分支命名符合约定(fix/tx-type-filter-single-state
  • Commit message 使用 Conventional Commits 格式(fix(ui): ...
  • 单一职责,改动最小化(3 文件,+42/−8,零 Rust)

…th controls

The transactions view filters by type through TWO controls — the `#tx-tabs` strip
(全部/消费/收益) and the 类型 column's `select.th-filter` (the six database
values) — but the state was split: the tabs wrote a module-level `txTab`, the
select wrote `txTable.filters.type`, and `loadTransactions` resolved them with a
documented precedence, `const type = colType || (txTab === "all" ? "" : txTab)`.
The column select therefore wins permanently: once it has a value, a tab click
sets `txTab` and repaints nothing else, so the click is a NO-OP (the request
still carries the column filter). And because the highlight was painted from
`txTab` alone, the strip meanwhile claims a filter that is not the applied one —
with the 类型 select on 赠送, the list shows gift rows while 全部 stays lit.

This is one filtered concept with one state that must be the single source for
the request parameter, the tab highlight, and the select: the fix deletes the
second state (`txTab`) and routes both controls through `txTypeFilter()`
(read) / `setTxTypeFilter()` (write — it also syncs the already-rendered select,
since #148 stopped rebuilding the thead and the widget no longer follows the
state by itself). When the effective value is not one of all/consume/earn
(topup / withdraw / gift / expire), no tab claims to be active: lighting 全部
while the list holds gift rows would be the same lie in the other direction.

Verified with a jsdom probe (real ui/index.html + js/api.js + data.js + i18n.js
+ app.js, only `fetch` stubbed) that drives the real controls and compares all
three artifacts against ONE derivation, `wantTabs(type)` — never a literal, which
would pass by accident whenever the stale highlight happens to spell it.
A/B (baseline pinned to d1faab6 via `git show`; the driver aborts if the
baseline equals the fix): pre-change 5/11 (red B2/B3/B4/B5/C1/C2), three wrong
fixes each rejected — dead click 4/11, unsynced select 9/11, constant highlight
7/11 — fixed tree 11/11 with the built-in control A0 green in every leg.
@argszero
argszero merged commit 2be0d54 into main Sep 14, 2026
1 check passed
@argszero
argszero deleted the fix/tx-type-filter-single-state branch September 14, 2026 00:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant