Skip to content

fix(web): 取消全选会清掉其他页的选中项 - #7714

Open
kevin9327 wants to merge 1 commit into
labring:mainfrom
kevin9327:fix/table-select-all-uncheck-scope
Open

kevin9327 wants to merge 1 commit into
labring:mainfrom
kevin9327:fix/table-select-all-uncheck-scope

Conversation

@kevin9327

Copy link
Copy Markdown
Contributor

现象

在「应用 → 对话日志」里:

  1. 第 1 页勾选几条记录,底部显示「已选 3 条」
  2. 翻到第 2 页,点表头/底部的「全选」把本页也选上(已选 3 + 本页)
  3. 再点一次取消全选

第 1 页勾选的记录也一起没了,计数直接归零,只能重新翻回去勾一遍。

同一个 hook 还用在知识库集合列表、模型表格、工具批量更新抽屉上,凡是 list 会因为翻页或搜索变化的地方都会遇到;搜索场景更容易踩到:勾了几行 → 输入关键词让列表变短 → 全选 → 取消全选,之前勾的行被清掉。

原因

packages/web/hooks/useTableMultipleSelect.tsx 里勾选和取消不对称:

const selectAllTrigger = useCallback(() => {
  if (isSelecteAll) {
    setSelectedItems([]);                                                  // 清空全部
  } else {
    setSelectedItems((pre) => [...pre, ...list.filter((item) => !isSelected(item))]);  // 只加当前 list
  }
}, [isSelecteAll, list, isSelected]);

isSelecteAll 的语义是 list.length > 0 && list.every(isSelected),也就是「当前 list 全选中」,勾选也只作用于当前 list;取消却是全局清空。selectedItems 本身会跨 list 变化累积(toggleSelect 不会重置),所以差异就暴露出来了。

修改

取消时只过滤掉当前 list 的 id,和勾选保持对称:

const listIds = new Set(list.map((item) => getItemId(item)));
setSelectedItems((pre) => pre.filter((item) => !listIds.has(getItemId(item))));

list 就是全部数据的单页场景下,两种写法结果一致,行为不变。

验证

新增 packages/web/test/hooks/useTableMultipleSelect.test.ts,用 jsdom 渲染一个只调用该 hook 的壳组件,模拟翻页(切换 list):

cd packages/web
vitest run --config vitest.config.ts --coverage.enabled=false --maxWorkers=1 --no-fileParallelism \
  test/hooks/useTableMultipleSelect.test.ts
  • 修改前(只加测试、不改实现):Tests 1 failed | 1 passed (2)

    FAIL  取消全选时只清除当前列表的选中项
    AssertionError: expected [] to deeply equal [ 'a' ]
    
  • 修改后,跑完整 test/hooks 目录:Test Files 7 passed (7)Tests 21 passed (21)

两个用例分别钉住了跨页取消只影响当前页、以及单页取消仍然清空,避免以后改回去。

prettier --checkgit diff --check 均通过。

useTableMultipleSelect 勾选「全选」时只把当前 list 追加进已选,取消时却
直接 setSelectedItems([])。分页或搜索让 list 变化后,取消全选会把不在当前
list 里的选中项一起清掉。

对话日志页复现:第 1 页勾几条 → 翻到第 2 页 → 全选 → 再取消全选,第 1 页
选中的记录也没了,「已选 N 条」直接归零。

取消时改成只过滤掉当前 list 的 id,与勾选保持对称;单页场景行为不变。
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@cla-assistant

cla-assistant Bot commented Sep 10, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@c121914yu

c121914yu commented Sep 11, 2026

Copy link
Copy Markdown
Collaborator

反选 全选,移除全部应该是符合预期的,需要产品确认。

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants