Files
mnote/design/04-tree-domain/done/4-37-trash-as-modal-workbench-v1.md
T
lix-2026 384da4e44c feat(tree): checkpoint resource lifecycle work
提交当前顶层 mnote Git 工作区,范围集中在 04-tree-domain 的 resource/trash/filetree 生命周期、mnote-web resource_trash 路由、Convex/Next 兼容接口、sidebar/file-tree 客户端适配、smoke 脚本与对应设计/bug 记录。

不包含被 ignore 的 design/05-editor-mainline/reference-code/leptos-tiptap 嵌套仓库改动。新增 smoke 的测试密码改为运行时读取 MNOTE_E2E_PASSWORD,避免提交明文 credential assignment。
2026-05-16 07:38:45 +08:00

92 lines
4.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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`