feat: add main editor resource tabs
This commit is contained in:
@@ -0,0 +1,136 @@
|
||||
# Main Editor Resource Tabs Implementation Plan
|
||||
|
||||
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
||||
|
||||
**Goal:** 在 MNote 主编辑区增加 VSCode 风格 resource tab,使本地 `.md` / text / code 资源可用 tiptap 编辑,Office/PDF/图片可在主编辑区 tab 打开,并保留右侧 pane 与新窗口能力。
|
||||
|
||||
**Architecture:** 以 `resource input + open target` 为边界,前端新增主编辑区 tab host,local-first 资源读写走新的 `/api/local-folder/resource/*` API。页面正文 session 与资源 session 使用不同 object identity 和保存 endpoint,避免资源编辑污染 Page Aggregate body。
|
||||
|
||||
**Tech Stack:** Rust Axum (`mnote-web` routes), Leptos SSR shell, existing `leptos-tiptap` WASM runtime, Playwright smoke scripts.
|
||||
|
||||
---
|
||||
|
||||
### Task 1: 本地资源读写 API
|
||||
|
||||
**Files:**
|
||||
- Modify: `rust/crates/mnote-web/src/routes/mod.rs`
|
||||
- Modify: `rust/crates/mnote-web/src/routes/local_folder_source.rs`
|
||||
|
||||
- [ ] **Step 1: 增加 API 路由**
|
||||
|
||||
在 `routes/mod.rs` 的 local-folder route 区域添加:
|
||||
|
||||
```rust
|
||||
.route(
|
||||
"/api/local-folder/resource/read",
|
||||
get(local_folder_source::read_local_resource),
|
||||
)
|
||||
.route(
|
||||
"/api/local-folder/resource/write",
|
||||
post(local_folder_source::write_local_resource),
|
||||
)
|
||||
```
|
||||
|
||||
- [ ] **Step 2: 实现读写 handler**
|
||||
|
||||
在 `local_folder_source.rs` 复用 `resolve_local_file_open_path`,读取 raw text 或写入 UTF-8 内容。写入请求字段:
|
||||
|
||||
```json
|
||||
{
|
||||
"rootUri": "file:///tmp/workspace",
|
||||
"path": "Page.assets/note.md",
|
||||
"contentFormat": "tiptapDocument",
|
||||
"tiptapDocument": { "type": "doc", "content": [] },
|
||||
"expectedFileVersion": "sha256:..."
|
||||
}
|
||||
```
|
||||
|
||||
保存 `.md` 使用现有 editor-blocks -> markdown 能力;保存 `.txt` / code 使用 plain text。
|
||||
|
||||
- [ ] **Step 3: 增加单测**
|
||||
|
||||
新增测试覆盖:
|
||||
|
||||
- root escape 被拒绝。
|
||||
- `.md` 读写返回 `text/markdown` 和 `fileVersion`。
|
||||
- 写 `.md` 后不修改页面正文 Markdown。
|
||||
|
||||
### Task 2: 主编辑区 Resource Tab Host
|
||||
|
||||
**Files:**
|
||||
- Modify: `rust/crates/mnote-web/src/ssr/pages/document.rs`
|
||||
- Modify: `rust/crates/mnote-web/src/ssr/styles.rs`
|
||||
- Modify: `rust/crates/mnote-web/src/routes/web_shell.rs`
|
||||
|
||||
- [ ] **Step 1: SSR 增加 tab strip 与 resource host**
|
||||
|
||||
在 `DocumentPage` 的 `.document-workspace` 内添加主编辑区 tab strip 和 resource pane 容器。默认 page tab 对应 primary document pane。
|
||||
|
||||
- [ ] **Step 2: web shell 新增 openResourceInActiveTab**
|
||||
|
||||
新增运行时函数:
|
||||
|
||||
```js
|
||||
window.__mnoteDocumentPaneRuntime.openResourceInActiveTab({
|
||||
objectIdentity,
|
||||
title,
|
||||
kind,
|
||||
rootUri,
|
||||
path,
|
||||
href,
|
||||
officeUrl
|
||||
});
|
||||
```
|
||||
|
||||
同一 `objectIdentity` 已存在时只激活 tab。
|
||||
|
||||
- [ ] **Step 3: 挂载 tiptap resource editor**
|
||||
|
||||
`.md` / `.txt` / code resource tab 创建独立 root,读取 `/api/local-folder/resource/read`,转为 tiptap document 后挂载。change 事件写回 `/api/local-folder/resource/write`。
|
||||
|
||||
### Task 3: 打开路径收口
|
||||
|
||||
**Files:**
|
||||
- Modify: `rust/crates/mnote-web/src/ssr/pages/layout.rs`
|
||||
- Modify: `rust/crates/mnote-web/src/routes/web_shell.rs`
|
||||
|
||||
- [ ] **Step 1: 文件树资源普通点击默认 active-tab**
|
||||
|
||||
修改 `openConvexAssetFromFileTree(detail)`:本地资源优先调用 `openResourceInActiveTab`,失败时 fallback 到旧 `window.open`。
|
||||
|
||||
- [ ] **Step 2: 附件点击默认 active-tab**
|
||||
|
||||
修改 `openEditorAttachmentDetail(detail)`:本地附件优先打开 resource tab,显式下载/新窗口保持旧行为。
|
||||
|
||||
- [ ] **Step 3: 菜单补齐 new-window**
|
||||
|
||||
为文件树资源和附件菜单增加“在新窗口打开”,动作显式调用旧 `window.open` 路径。
|
||||
|
||||
### Task 4: Smoke 与回归
|
||||
|
||||
**Files:**
|
||||
- Modify: `scripts/task174-rust-onlyoffice-attachment-open-smoke.js`
|
||||
- Modify: `scripts/task456-resource-object-shell-sync-smoke.js`
|
||||
- Create: `scripts/task457-main-editor-resource-tab-smoke.js`
|
||||
|
||||
- [ ] **Step 1: 新增 resource tab smoke**
|
||||
|
||||
覆盖上传 `.md`、点击打开主编辑区 tab、编辑保存回资源文件、页面正文不变。
|
||||
|
||||
- [ ] **Step 2: 更新 Office smoke**
|
||||
|
||||
默认点击断言主编辑区 Office resource tab;显式新窗口动作继续断言 `/onlyoffice`。
|
||||
|
||||
- [ ] **Step 3: 运行验证**
|
||||
|
||||
运行:
|
||||
|
||||
```bash
|
||||
cargo test -p mnote-web -- --test-threads=1
|
||||
node scripts/task457-main-editor-resource-tab-smoke.js
|
||||
node scripts/task174-rust-onlyoffice-attachment-open-smoke.js
|
||||
node scripts/task456-resource-object-shell-sync-smoke.js
|
||||
codegraph sync .
|
||||
```
|
||||
|
||||
预期:全部通过。
|
||||
Reference in New Issue
Block a user