Files
mnote/design/04-tree-domain/done/4-37-trash-as-modal-workbench-v1.md
T

92 lines
4.6 KiB
Markdown
Raw Normal View History

# 4-37 [done] 垃圾箱改为居中弹窗工作台 v1
> 更新时间:2026-05-15
>
> 背景:
> - 用户建议:垃圾箱应做成弹窗,而不是单一页面。
> - 当前 `/trash` 是完整页面入口;在本地文件夹 / 云空间切换异常时,用户会通过垃圾箱“找回”原空间页面,这进一步暴露垃圾箱作为导航页面会改变当前工作区上下文。
## 1. 设计目标
把垃圾箱从“离开当前工作区的独立页面”逐步改为“当前工作区内的居中弹窗工作台”。
弹窗形态以 Wolai 居中对话框为准:遮罩覆盖页面,工作台面板在视口中心显示,左右和上下都保留留白;不要做成靠右侧贴边的 drawer / 抽屉。
目标体验:
- 用户点击左下角“垃圾箱”时,不离开当前页面和当前文件树上下文。
- 垃圾箱以居中 modal 打开,不贴右侧边缘,不改变当前 URL。
- 弹窗内展示页面垃圾箱与资源垃圾箱。
- 恢复、彻底删除、清空操作完成后,当前 Sidebar / File Tree / Page Tree 实时同步。
- 关闭弹窗后,用户回到原页面、原选中 row、原滚动位置。
## 2. 非目标
- 本稿不改变删除、恢复、彻底删除的底层命令语义。
- 本稿不一次性废弃 `/trash``/trash` 可作为兼容、直接链接和测试入口保留。
- 本稿不扩大到全局搜索、模板中心等其它 footer 入口。
## 3. 最小实现切片
P0:入口形态
- 左下角“垃圾箱”从普通导航改为打开弹窗。
- 弹窗复用现有 `mnote-trash-workbench` DOM 与 API。
- 打开弹窗不改变当前 URL;如需要可用 `?trash=1` 或 history state,但默认不跳整页。
P1:上下文保持
- 弹窗打开前记录当前 `sourceKind``workspaceId``rootUri`、active row、scrollTop。
- 关闭弹窗后恢复原 File Tree / Page Tree 视图状态。
- 本地文件夹场景下,垃圾箱只展示本地 `.mnote/trash` 能力;Convex 云空间展示 Convex trash。
P2:实时同步
- 页面 restore / purge / empty 后,当前 Sidebar 通过 tree event 或本地 apply 更新。
- 资源 restore / purge / empty 后,File Tree 对应资源 row 同步恢复或消失。
## 4. 验收标准
- 点击“垃圾箱”不会离开当前文档 URL。
- 垃圾箱面板在视口中心显示,左右居中偏差不超过 8px,并保留可见的上下留白。
- 弹窗内能恢复页面、彻底删除页面、清空页面垃圾箱。
- 弹窗内能恢复/彻底删除/清空附件、mindmap、table 等资源。
- 关闭弹窗后,原页面仍打开,File Tree 滚动位置和选中 row 不被无关重置。
- `/trash` 兼容入口仍可访问并通过现有 smoke。
## 5. 当前状态
当前状态:`done`
2026-05-15 已完成最小可用实现:
- 左下角“垃圾箱”入口保留 `href="/trash"` 作为兼容 fallback,但主壳点击会拦截为 `data-mnote-action="open-trash-modal"`
- `PageLayout` 新增垃圾箱 modal:打开后 fetch `/trash?workspaceId=...`,解析并挂载现有 `mnote-trash-workbench`,不改变当前 URL。
- modal 关闭时会关闭 workbench EventSource,并恢复 File Tree `scrollTop`;不改变原页面、active row 或当前文档 URL。
- `/trash` 独立页面继续保留,作为直接链接、兼容入口和现有 smoke 的验证对象。
- 本地文件夹上下文下,modal 保持在本地 source,不跳回 Convex;当前先展示 `.mnote/trash` / `trash-index.json` 的本地垃圾箱说明,后续如需完整 local trash list 可继续扩展。
- 2026-05-15 根据用户参考图修正 modal 形态:从右侧 drawer 改为居中对话框,并在 smoke 中增加居中与上下留白断言,避免后续重复退回侧栏抽屉形态。
代码落点:
- `rust/crates/mnote-web/src/workspace_shell.rs`
- `rust/crates/mnote-web/src/ssr/pages/layout.rs`
- `rust/crates/mnote-web/src/ssr/styles.rs`
- `rust/crates/mnote-web/src/routes/gateway.rs`
- `scripts/task442-trash-modal-workbench-smoke.js`
已通过验证:
```bash
cargo test --manifest-path rust/Cargo.toml -p mnote-web sidebar_tree_runtime -- --nocapture
cargo test --manifest-path rust/Cargo.toml -p mnote-web workspace_shell -- --nocapture
cargo test --manifest-path rust/Cargo.toml -p mnote-web trash_entry -- --nocapture
MNOTE_UI_BASE_URL=http://127.0.0.1:3428 node scripts/task442-trash-modal-workbench-smoke.js
MNOTE_UI_BASE_URL=http://127.0.0.1:3428 node scripts/task432-filetree-trash-page-dual-browser-no-refresh-smoke.js
```
结果文件:
- `tmp/task442-trash-modal-workbench-smoke/result.json`
- `tmp/task432-filetree-trash-page-dual-browser-no-refresh-smoke/result.json`