Skip to content

feat(library): multi-select rows with marquee and batch actions - #1063

Open
fanrj3 wants to merge 1 commit into
poco-ai:mainfrom
fanrj3:feat/library-multi-select
Open

fanrj3 wants to merge 1 commit into
poco-ai:mainfrom
fanrj3:feat/library-multi-select

Conversation

@fanrj3

@fanrj3 fanrj3 commented Nov 10, 2026

Copy link
Copy Markdown
Contributor

摘要

论文库表格支持多选与批量操作:在表格内拖出矩形选框即进入选择模式(行首复选框 + 表头三态全选),此后点击行是勾选/取消而不再打开论文;统一的右键批量菜单与底部浮层提供「添加到对话 / 复制到文件夹 / 下载缺失 PDF / 删除 N 篇 / 清除选择」。同时新增 paper_copy:把选中的论文文件夹完整复制到 papers/ 下任一目录,副本拥有独立 catalog 行、页数缓存与笔记,源论文的双链与阅读状态不受影响。

类型

  • feat:新功能

场景

现状:论文库一次只能操作一篇——删除、加入对话、整理到另一个专题夹都要逐篇右键,没有任何多选状态。

改动

  • 平时表格与改动前完全一致(没有复选框、不额外占列宽)。在表格内按住左键拖出矩形选框(移动 >4px 才进入)即进入选择模式:表头出现三态全选框,每行左侧出现复选框,框到的行被选中。
  • 选择模式下单击行 = 勾选/取消勾选(不再打开论文);双击复制单元格、右键菜单保持原行为。⌘/Ctrl 点击切换单行、Shift 按当前排序范围选择、⌘A 全选、Delete 移入回收站、Esc 或点击空白处退出选择模式。
  • 全选只作用于当前筛选与作用域内的可见行;搜索、标签筛选、作用域变化或论文被删除后,已隐藏的行自动从选中集合剔除,避免误删看不见的论文。
  • 右键从「每行一个菜单」改为「整表一个菜单」:选中多行时显示批量项,未选中时保持原来的单篇菜单;底部浮出操作条不占布局,框选过程中表格不会位移。
  • 复制到文件夹:目标必须在 papers/ 下(可在弹窗里现建),已存在则不覆盖、只跳过该篇并汇总提示;副本写入新的 catalog 行(同一逻辑 id、不同 path)与页数缓存,笔记/标注/标签是独立副本。
  • paper_copy 复用 move 的路径校验语义(拒绝复制到自身/子孙、半途失败回滚),不重写任何双链;src/lib/core/bindings.ts 已重新生成。
  • 测试:选中状态机与矩形命中抽成纯函数(16 个用例),另加组件级交互测试(9 个用例:默认无复选框 → 拖拽出现并选中 → 选择模式下点击不回开论文 → 表头全选 → Esc 退出 → 单选/批量右键菜单切换)。

无关联 issue:需求在会话中直接提出,已在本地完成验证后提交。

截图(UI / 功能改动必填)

默认表格与改动前完全一致(没有复选框、不额外占列宽),所以「之前」不另附。下面是「之后」:

  1. 框选 3 篇:行首复选框、选中底色、底部操作条「已选 3 篇」
  2. 批量右键菜单:添加到对话 / 复制到文件夹 / 下载缺失 PDF / 删除 3 篇 / 清除选择
  3. 复制到文件夹弹窗:papers/ 下的目标目录列表 + 新建目录输入框

Demo(feat 必填)

21 秒录屏:在论文库拖出选框选中 4 篇 → 底部操作条 → 「添加到对话」→ 4 篇作为上下文进入 Agent 并提问。

自查清单

  • 本地 pre-commit 通过(未使用 --no-verify)——本机 husky 无法被 git exec,改用等价命令手动执行(biome + cargo fmt/clippy + 测试)
  • 前端 tsc --noEmit / biome check / vitest run;Rust cargo fmt --all --check / cargo clippy -p agentero-core -p agentero --all-targets -- -D warnings / cargo test -p agentero-core copy_paper / export_typescript_bindings(无 drift)/ app::events_contract
  • CI 全绿(待跑;见备注:main 的 TypeScript quality 当前本身为红)
  • UI 文案已走 t() 并同步 zh-CN
  • 文档:docs/frontend/library.md(多选/批量)、docs/backend/api.md(paper_copy)
  • 手动验证:dev 版实际框选、选择模式下点击切换、批量菜单、复制弹窗;Rust 单测覆盖文件复制/catalog 行/页数缓存/拒绝覆盖/拒绝自复制

备注:当前 main 的 TypeScript (quality) CI 本身是红的(src/lib/.../buildAssetNameMap 一处 biome 格式),与本改动无关;本机 Rust 1.95 的 clippy 另会报既有的 dsh.rs:55 nonminimal_bool(main 上同样存在)。

Drag a rectangle over the table to enter selection mode: a leading
checkbox column and a tri-state select-all appear, a row click toggles
instead of opening, and one shared context menu plus a floating action
bar act on the whole selection.

- Selection model, Shift ranges and marquee hit-testing as pure modules
  with unit tests; rows stay memoized (no per-frame re-render storm).
- One table-level context menu replaces the per-row menus; single-row
  right-click keeps the previous actions.
- Batch actions: add to chat, download missing PDFs, delete, copy.
- Copy to folder duplicates paper folders into another papers/ folder
  through the new paper_copy command: the copy gets its own catalog row
  and page count, while the source keeps its links and reading state.
- Cmd/Ctrl click, Shift range, Cmd+A, Esc and Delete shortcuts; hidden
  rows are pruned from the selection so batch actions stay visible-only.
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