feat: 收口 mindmap Phase 6 Leptos UI shell

This commit is contained in:
lix-2026
2026-05-11 12:27:40 +08:00
parent b7dddd2a66
commit b5eb27fabc
51 changed files with 8669 additions and 1313 deletions
+187
View File
@@ -43,6 +43,189 @@ pub enum MindmapProjectionOwner {
CompatBlob,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "kebab-case")]
pub enum MindmapProjectionSource {
Kernel,
CompatBlob,
AdapterCache,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct MindmapKernelProjection {
pub schema: String,
pub document_id: String,
pub mindmap_id: String,
pub root_node_id: String,
pub revision: u64,
#[serde(default)]
pub nodes: Vec<MindmapKernelNode>,
#[serde(default)]
pub edges: Vec<MindmapKernelEdge>,
#[serde(default)]
pub summaries: Vec<MindmapSummary>,
#[serde(default)]
pub associative_lines: Vec<MindmapAssociativeLine>,
#[serde(default)]
pub layout: Value,
#[serde(default)]
pub theme: Value,
#[serde(default)]
pub view: Value,
pub capabilities: MindmapKernelCapabilities,
pub source: MindmapProjectionSource,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub struct MindmapKernelNode {
pub node_id: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub parent_id: Option<String>,
pub text: String,
#[serde(default)]
pub order: i64,
#[serde(default)]
pub collapsed: bool,
#[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
pub style: BTreeMap<String, Value>,
#[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
pub refs: BTreeMap<String, Value>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub struct MindmapKernelEdge {
pub edge_id: String,
pub from_node_id: String,
pub to_node_id: String,
pub edge_kind: String,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct MindmapSummary {
pub summary_id: String,
pub parent_node_id: String,
#[serde(default)]
pub node_ids: Vec<String>,
pub text: String,
#[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
pub style: BTreeMap<String, Value>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct MindmapAssociativeLine {
pub line_id: String,
pub from_node_id: String,
pub to_node_id: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub text: Option<String>,
#[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
pub style: BTreeMap<String, Value>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub struct MindmapKernelCapabilities {
pub can_edit: bool,
pub can_edit_text: bool,
pub can_insert_child: bool,
pub can_insert_sibling_after: bool,
pub can_delete_node: bool,
pub can_move_node: bool,
pub can_patch_view: bool,
pub can_set_layout: bool,
pub can_set_theme: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct MindmapAdapterProjection {
pub schema: String,
pub runtime: String,
pub root: Value,
#[serde(default)]
pub layout: Value,
#[serde(default)]
pub theme: Value,
#[serde(default)]
pub theme_config: Value,
#[serde(default)]
pub view: Value,
#[serde(default)]
pub config: Value,
#[serde(default)]
pub compat_payload: Value,
pub kernel_revision: u64,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(tag = "type", rename_all = "camelCase")]
pub enum MindmapKernelCommand {
UpdateText {
#[serde(rename = "mindmapId", alias = "mindmap_id", alias = "mapId")]
mindmap_id: String,
#[serde(rename = "nodeId", alias = "node_id")]
node_id: String,
text: String,
},
InsertChild {
#[serde(rename = "mindmapId", alias = "mindmap_id", alias = "mapId")]
mindmap_id: String,
#[serde(rename = "parentNodeId", alias = "parent_node_id", alias = "parentId")]
parent_node_id: String,
node: MindmapNodeInput,
},
InsertSiblingAfter {
#[serde(rename = "mindmapId", alias = "mindmap_id", alias = "mapId")]
mindmap_id: String,
#[serde(rename = "targetNodeId", alias = "target_node_id")]
target_node_id: String,
node: MindmapNodeInput,
},
DeleteNode {
#[serde(rename = "mindmapId", alias = "mindmap_id", alias = "mapId")]
mindmap_id: String,
#[serde(rename = "nodeId", alias = "node_id")]
node_id: String,
},
MoveNode {
#[serde(rename = "mindmapId", alias = "mindmap_id", alias = "mapId")]
mindmap_id: String,
#[serde(rename = "nodeId", alias = "node_id")]
node_id: String,
#[serde(
rename = "newParentNodeId",
alias = "new_parent_node_id",
alias = "newParentId"
)]
new_parent_node_id: String,
#[serde(rename = "order", alias = "sortOrder", alias = "sort_order")]
order: Option<i64>,
},
PatchView {
#[serde(rename = "mindmapId", alias = "mindmap_id", alias = "mapId")]
mindmap_id: String,
patch: Value,
},
SetLayout {
#[serde(rename = "mindmapId", alias = "mindmap_id", alias = "mapId")]
mindmap_id: String,
layout: Value,
},
SetTheme {
#[serde(rename = "mindmapId", alias = "mindmap_id", alias = "mapId")]
mindmap_id: String,
theme: Value,
#[serde(default)]
#[serde(rename = "themeConfig", alias = "theme_config")]
theme_config: Value,
},
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(tag = "type", rename_all = "camelCase")]
pub enum MindmapCommand {
@@ -136,6 +319,8 @@ pub struct MindmapTreeNode {
pub extra: BTreeMap<String, Value>,
}
/// 兼容 DTO:对应 simple-mind-map / KMind 风格树节点。
/// 长期事实源应使用 `MindmapKernelProjection` 与 kernel command。
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub struct MindmapNodeInput {
@@ -150,6 +335,8 @@ pub struct MindmapNodeInput {
pub refs: Option<Vec<MindmapNodeRef>>,
}
/// 兼容 DTO:用于历史 AI 工具和旧 blob 操作。
/// 新的 leptos-mindmap 写面应优先使用 `MindmapKernelCommand`。
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(tag = "op", rename_all = "camelCase")]
pub enum MindmapOp {