- add local-folder OnlyOffice sign/callback writeback and edit-tab handling - align main resource tabs, attachment edit menu, slash isolation, and filetree context behavior - record Sidex/Hermes gap reviews and Reasonix task checklists
100 lines
7.4 KiB
Markdown
100 lines
7.4 KiB
Markdown
# Workbench Filetree / Office / Slash Bug Review V1
|
||
|
||
日期:2026-05-21
|
||
|
||
## 范围
|
||
|
||
本轮覆盖用户截图 23-26 中的 6 个 P0/P1 缺陷:
|
||
|
||
1. 文件树删除页面后,页面进入资源垃圾箱,页面垃圾箱没有使用。
|
||
2. 主编辑区 tab 标题与实际打开页面标题不一致。
|
||
3. 上传 docx 后页面卡死,docx 打不开。
|
||
4. 不应自动出现“初始化的新页面”;空白工作区应保持空白。
|
||
5. 文件树右键菜单大量动作不可用,需对照 Sidex / VSCode 文件资源管理器收敛到可用动作。
|
||
6. 主栏打开 slash 菜单时,侧栏也出现 slash 菜单。
|
||
|
||
## 当前证据
|
||
|
||
- `rust/crates/mnote-web/src/routes/local_folder_source.rs`
|
||
- `ensure_default_workspace_home_page` 会创建 `初始化的新页面/初始化的新页面.md`。
|
||
- `create_default_local_workspace_for_actor_at_base_creates_manifest_and_root_only` 仍断言该默认页面存在。
|
||
- `trash_local_entry` 先解析 `local-dir:*`,再解析 `local-file:*`,最后才走 `trash_local_markdown_page`。
|
||
- 文件树中页面 bundle 目录在 `scan_directory` 中是 `rowKind=folder`,因此删除会走 `trash_local_directory`,`resourceKind=local_directory`。
|
||
- `rust/crates/mnote-web/src/routes/web_shell.rs`
|
||
- `replacePaneDocument` / `updatePaneChrome` 会更新正文、面包屑、`document.title`,但没有同步 `[data-mnote-main-tab="page"] .mnote-main-tab-title`。
|
||
- `openUnsupportedSideTarget` 会替换 secondary root 为不支持占位;`positionSlashMenuForRoot` 仍允许 fallback 到 `document.querySelector('[data-testid="mnote-leptos-tiptap-slash-menu"]')`,存在跨 pane 定位/展示风险。
|
||
- `openResourceAsSideTarget` 对 markdown/text/code/office 全部进入 unsupported,占位会污染侧栏;这与用户期望“不可用动作不要误打开侧栏”冲突。
|
||
- `rust/crates/mnote-web/src/ssr/pages/layout.rs`
|
||
- 文件树右键菜单直接展示 `open-right / new-file / new-folder / paste / refresh / collapse / reveal / duplicate / rename / delete`,其中部分 disabled 或仅 dispatch event,无真实实现。
|
||
- `openConvexAssetFromFileTree` 对 local office 可走主 tab 的 iframe,但 Convex office 仍直接 `window.open(buildOnlyOfficeOpenUrl(...))`。
|
||
- 附件上传 `insertUploadedAssetIntoEditor` 和 `enhanceEditorAttachmentLink` 已尝试统一附件 UI;docx 卡死需要先确认是上传阶段阻塞、OnlyOffice iframe 回源失败,还是 active-tab iframe 加载导致主页面阻塞。
|
||
- Sidex / VSCode 参考:
|
||
- Sidex 保留 VSCode 的 `MenuId.ExplorerContext` 菜单体系,文件树动作来源在 `reference-code/sidex-main/src/vs/workbench/contrib/files/browser/fileActions.contribution.ts`。
|
||
- 可对照的基础动作是 Open to the Side、New File、New Folder、Reveal、Copy Path、Rename、Delete;动作是否显示/启用由 context key 决定,不是把所有潜在动作硬塞进菜单。
|
||
- Sidex workspace 层有 `FileClipboard`、`InlineInputKind::{Rename, NewFile, NewFolder}` 等状态,说明新建/重命名应走内联输入或明确命令,而不是菜单项只发事件。
|
||
|
||
## 修改策略
|
||
|
||
- Bug1 / Bug4 属于本地文件夹 tree/source 口径问题,优先修 Rust kernel-facing 路径:
|
||
- 默认工作区不再创建“初始化的新页面”。
|
||
- bundle 页面删除必须以 Markdown 页面生命周期入 trash,页面垃圾箱可识别,不应按 `local_directory` 资源归类。
|
||
- 空 root page tree 可返回空列表;UI 不渲染占位页面。
|
||
- Bug2 属于主编辑区 tab chrome 同步:
|
||
- `updatePaneChrome(primary)` 同步 page tab 标题、`data-document-id` 和 active 状态。
|
||
- 页面标题保存事件也应更新 page tab。
|
||
- Bug3 属于 Office 打开链路:
|
||
- 上传本地 docx 后,主 tab 打开应使用 `/onlyoffice?...fileUrl=/api/local-folder/files/open...`,并避免在主线程同步读取/解析大文件。
|
||
- 如果 OnlyOffice DocumentServer 不可连,应显示非阻塞错误,不应卡死整个页面。
|
||
- Bug5 属于菜单可用性:
|
||
- 菜单只显示/启用已有真实实现。
|
||
- “在右侧边栏打开”只对已支持侧栏打开的页面显示;资源侧栏未支持时不要打开 unsupported placeholder。
|
||
- `Copy Path` 对 local folder 应复制真实 relative path,不是复制标题。
|
||
- New Folder 在 local_folder 下应接入 `create_folder`,否则隐藏。
|
||
- Bug6 属于 editor host 隔离:
|
||
- Slash 菜单定位只能操作当前 root 内的菜单,不能 fallback 到别的 pane 的菜单。
|
||
- 不支持侧栏资源时应清理 secondary editor/slash overlay,或完全不打开侧栏。
|
||
|
||
## 不做事项
|
||
|
||
- 不回滚当前工作区已有 ACP/Hermes 改动。
|
||
- 不把资源 tab、side pane、OnlyOffice 做成全新架构;只修当前 P0 可见缺陷。
|
||
- 不复活旧 React / BlockNote 运行时。
|
||
- 不把 Sidex 菜单实现照搬成通用命令注册系统;本轮只借鉴“按可用能力显示动作”的原则。
|
||
|
||
## 验收
|
||
|
||
- Rust targeted tests 至少覆盖:
|
||
- local workspace 默认初始化不创建“初始化的新页面”。
|
||
- 删除页面 bundle 进入 page/document trash,而不是 `local_directory` resource trash。
|
||
- 主 page tab 随 active primary document 标题更新。
|
||
- local docx onlyoffice URL / content-type / proxy 回源可达。
|
||
- 文件树菜单不可用动作隐藏或禁用,已显示动作有真实 handler。
|
||
- slash menu 不跨 primary/secondary/resource pane 显示。
|
||
- UI 类最终必须做真实浏览器或 smoke 验证,并保留截图/输出。
|
||
|
||
## 本轮执行结果
|
||
|
||
- 已完成并移动到 `done/`:
|
||
- `bugs/04-tree-domain/done/4-45-local-folder-page-trash-and-empty-workspace-v1.md`
|
||
- `bugs/05-editor-mainline/done/5-28-main-page-tab-title-active-sync-v1.md`
|
||
- `bugs/05-editor-mainline/done/5-29-onlyoffice-docx-upload-open-freeze-v1.md`
|
||
- `bugs/05-editor-mainline/done/5-30-filetree-context-menu-sidex-alignment-v1.md`
|
||
- `bugs/05-editor-mainline/done/5-31-side-pane-slash-overlay-isolation-v1.md`
|
||
- Rust 验证:
|
||
- `cargo test -p mnote-web -- --test-threads=1`:481 passed。
|
||
- 新增 `local_tree_command_delete_page_bundle_directory_uses_page_trash`,锁定 `local-dir:*` 页面 bundle 删除进入 `markdown_bundle` 页面垃圾箱。
|
||
- Smoke / 浏览器验证:
|
||
- `node scripts/task463-onlyoffice-resolver-smoke.js`:通过。
|
||
- `node scripts/task462-resource-tab-error-placeholder-smoke.js`:通过。
|
||
- `node scripts/task455-local-folder-mindmap-clean-smoke.js`:通过。
|
||
- `node scripts/task458-local-create-page-no-conflict-smoke.js`:通过。
|
||
- `node scripts/task464-local-folder-resource-trash-ui-smoke.js`:通过。
|
||
- `node scripts/task472-side-target-secondary-pane-smoke.js`:通过。
|
||
- 真实浏览器证据:
|
||
- `tmp/bug-20260521-workbench-browser-verify/result-title-docx-menu.json`
|
||
- `tmp/bug-20260521-workbench-browser-verify/result-slash.json`
|
||
- `tmp/bug-20260521-workbench-browser-verify/result-trash.json`
|
||
- 截图覆盖:主 tab 标题同步、真实 docx resource tab、资源右键菜单、primary/secondary slash 隔离、页面 bundle 垃圾箱分类。
|
||
- 历史 smoke 注意:
|
||
- `node scripts/task432-filetree-trash-page-dual-browser-no-refresh-smoke.js` 当前失败在 convex-source 双浏览器 live delta 未插入新建子页;失败点早于本轮页面删除/垃圾箱断言,不代表本地页面 bundle 垃圾箱修复失败。后续应按实时同步历史 smoke 单独修复或退役。
|