feat: add main editor resource tabs
This commit is contained in:
@@ -0,0 +1,98 @@
|
||||
# 5-15 主编辑区 Resource Tab 与 VSCode 打开目标对齐 v1
|
||||
|
||||
> 状态:done
|
||||
>
|
||||
> 日期:2026-05-20
|
||||
|
||||
## 目标
|
||||
|
||||
把当前资源打开行为从“资源点击直接 `window.open` 或单独右侧 pane”收口为 VSCode 风格的打开目标模型:
|
||||
|
||||
- `active-tab`:在主编辑区打开或激活 resource tab。
|
||||
- `side`:保留当前右侧 pane 打开能力。
|
||||
- `new-window`:显式在新浏览器窗口打开。
|
||||
|
||||
本轮重点实现 `active-tab`,并保持已有右侧 pane 与新窗口路径不退化。
|
||||
|
||||
## VSCode 对齐口径
|
||||
|
||||
VSCode Explorer 不按文件类型散落处理打开行为,而是把资源交给 editor service:
|
||||
|
||||
- 普通打开进入当前 editor group。
|
||||
- `Open to the Side` 进入 side group。
|
||||
- 同一资源应激活已有 editor tab,而不是无限重复打开。
|
||||
- side group 与主 editor group 可以同时持有各自 tab。
|
||||
|
||||
MNote 对应关系:
|
||||
|
||||
- 主编辑区 tab host 对应 VSCode active editor group。
|
||||
- 当前 secondary document pane 对应 VSCode side group。
|
||||
- 浏览器新窗口只作为显式外部打开目标。
|
||||
|
||||
## 资源编辑规则
|
||||
|
||||
`.md`、`.markdown`、`.txt`、常见代码文件在主编辑区 resource tab 中继续使用 tiptap runtime 打开。
|
||||
|
||||
关键约束:
|
||||
|
||||
- 页面正文 tiptap 保存到 Page Aggregate body / 页面 Markdown。
|
||||
- 资源 tiptap 保存到对应 resource 文件本身。
|
||||
- resource tab 必须使用独立 object identity 与独立 session key。
|
||||
- resource tab 保存不得调用 `page.body.save` 或 `/api/page-body/write`。
|
||||
- 上传的 `.md` 资源不能因为用 tiptap 打开而重新变成 File Tree / Page Tree 页面。
|
||||
|
||||
## 最小实现范围
|
||||
|
||||
本轮只做浏览器内主编辑区 resource tab host 的最小闭环:
|
||||
|
||||
- 在文档 workspace 顶部增加 tab strip。
|
||||
- 默认页面正文是一个固定 page tab。
|
||||
- 点击本地上传或文件树资源时打开 resource tab。
|
||||
- Office tab 内嵌 `/onlyoffice?...`。
|
||||
- PDF / 图片使用 iframe/img 预览。
|
||||
- `.md` / text / code 使用 tiptap runtime 编辑,并保存回本地资源文件。
|
||||
- 右键菜单保留“在右侧边栏打开”和“在新窗口打开”。
|
||||
|
||||
Convex 远端资源本轮仅保留新窗口 fallback;主闭环优先覆盖 local-first 资源。
|
||||
|
||||
## 详细 Checklist
|
||||
|
||||
- [x] 定义前端 open target:`active-tab`、`side`、`new-window`。
|
||||
- [x] 为本地资源生成稳定 `objectIdentity`:`resource:file:<rootUri>:<relativePath>`。
|
||||
- [x] 新增本地资源读写 API:
|
||||
- [x] `GET /api/local-folder/resource/read?rootUri=&path=`
|
||||
- [x] `POST /api/local-folder/resource/write`
|
||||
- [x] 读写均复用 root escape 校验。
|
||||
- [x] 写入返回 `fileVersion` / `conflictDetectionKey`。
|
||||
- [x] 主编辑区新增 resource tab strip:
|
||||
- [x] page tab 默认存在。
|
||||
- [x] resource tab 重复打开时激活已有 tab。
|
||||
- [x] 关闭 resource tab 后回到 page tab。
|
||||
- [x] 打开 resource tab 不关闭 secondary pane。
|
||||
- [x] tiptap resource editor:
|
||||
- [x] `.md` / `.markdown` / `.txt` / code 资源挂载 tiptap。
|
||||
- [x] session key 与页面正文 session key 隔离。
|
||||
- [x] 保存写 `/api/local-folder/resource/write`。
|
||||
- [x] 保存 payload 中保留 `tiptapDocument`,服务端转 Markdown / text 后写回文件。
|
||||
- [x] Office / PDF / 图片 resource tab:
|
||||
- [x] Office 使用 `/onlyoffice?...` iframe,主编辑区默认 `mode=view`。
|
||||
- [x] PDF 使用 iframe。
|
||||
- [x] 图片使用 img。
|
||||
- [x] 不触发页面正文保存。
|
||||
- [x] 菜单与默认行为:
|
||||
- [x] 文件树资源普通点击默认 `active-tab`。
|
||||
- [x] 附件普通点击默认 `active-tab`。
|
||||
- [x] “在右侧边栏打开”继续走 `side`。
|
||||
- [x] “在新窗口打开”继续走 `new-window`,Office 保留 `mode=edit`。
|
||||
- [x] Smoke:
|
||||
- [x] 上传 `.md` 后点击资源,在主编辑区出现 resource tab 和 tiptap。
|
||||
- [x] 编辑 `.md` resource tab 后文件内容写回资源文件,不写页面正文。
|
||||
- [x] 上传 Office 后点击资源,在主编辑区出现 Office resource tab。
|
||||
- [x] 显式新窗口打开仍打开 `/onlyoffice` 或文件 URL。
|
||||
|
||||
## 非目标
|
||||
|
||||
- 不在本轮实现多 tab 持久化恢复。
|
||||
- 不在本轮实现 Convex 远端资源的主编辑区写回。
|
||||
- 不在本轮引入完整代码编辑器或语法高亮。
|
||||
- 不改变 Resource Tree / File Tree / Page Tree 的真源关系。
|
||||
Reference in New Issue
Block a user