Close workbench P0 resource lifecycle gaps

This commit is contained in:
lix-2026
2026-05-20 20:48:18 +08:00
parent e0b0e70fb8
commit fe13444dbc
14 changed files with 610 additions and 7 deletions
@@ -8,6 +8,8 @@ use std::collections::{BTreeMap, BTreeSet};
pub struct FileTreeRuntimeEnvironment {
pub visible_row_ids: Vec<String>,
pub rows: Vec<FileTreeRuntimeRow>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub root_uri: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
@@ -468,12 +470,12 @@ fn resolve_open_target(
asset_id: row.asset_id.clone()?,
}),
"local-file" | "local_file" => Some(FileTreeOpenTarget::LocalFile {
root_uri: String::new(),
root_uri: env.root_uri.clone().unwrap_or_default(),
path: row.asset_id.clone().unwrap_or_default(),
resource_kind: None,
}),
"directory" => Some(FileTreeOpenTarget::Directory {
root_uri: String::new(),
root_uri: env.root_uri.clone().unwrap_or_default(),
path: row.asset_id.clone().unwrap_or_default(),
}),
"asset" => Some(FileTreeOpenTarget::Asset {
@@ -545,6 +547,7 @@ mod tests {
asset_id: Some("image".into()),
},
],
root_uri: Some("file:///tmp/mnote".into()),
}
}
@@ -865,4 +868,55 @@ mod tests {
})
);
}
#[test]
fn filetree_open_target_uses_environment_root_uri_for_local_targets() {
let mut env = env();
env.visible_row_ids = ids(&["local-file:Page/资源.ext", "local-dir:Page/assets"]);
env.rows = vec![
FileTreeRuntimeRow {
row_id: "local-file:Page/资源.ext".into(),
row_kind: "local-file".into(),
document_id: None,
asset_id: Some("Page/资源.ext".into()),
},
FileTreeRuntimeRow {
row_id: "local-dir:Page/assets".into(),
row_kind: "directory".into(),
document_id: None,
asset_id: Some("Page/assets".into()),
},
];
let open_file = FileTreeRuntimeState::default().reduce(
&env,
FileTreeRuntimeAction::OpenRow {
row_id: "local-file:Page/资源.ext".into(),
},
);
assert!(open_file.outputs.contains(&FileTreeRuntimeOutput::Intent(
FileTreeIntentEvent::Open {
target: FileTreeOpenTarget::LocalFile {
root_uri: "file:///tmp/mnote".into(),
path: "Page/资源.ext".into(),
resource_kind: None,
},
},
)));
let open_dir = FileTreeRuntimeState::default().reduce(
&env,
FileTreeRuntimeAction::OpenRow {
row_id: "local-dir:Page/assets".into(),
},
);
assert!(open_dir.outputs.contains(&FileTreeRuntimeOutput::Intent(
FileTreeIntentEvent::Open {
target: FileTreeOpenTarget::Directory {
root_uri: "file:///tmp/mnote".into(),
path: "Page/assets".into(),
},
},
)));
}
}
@@ -605,6 +605,7 @@ mod tests {
asset_id: Some("image".into()),
},
],
root_uri: None,
},
state: FileTreeRuntimeState::default(),
action: FileTreeRuntimeAction::SelectRow {
@@ -645,6 +646,7 @@ mod tests {
asset_id: Some("image".into()),
},
],
root_uri: None,
},
state: FileTreeRuntimeState {
selection: FileTreeSelectionState::from_selected(&["asset:image".to_string()]),
@@ -688,6 +690,7 @@ mod tests {
asset_id: Some("image".into()),
},
],
root_uri: None,
},
state: FileTreeRuntimeState::default(),
action: FileTreeRuntimeAction::UpdateDropTarget {
@@ -726,6 +729,7 @@ mod tests {
asset_id: Some("image".into()),
},
],
root_uri: None,
},
state: FileTreeRuntimeState {
drag_row_ids: ids(&["asset:image"]),
@@ -774,6 +778,7 @@ mod tests {
document_id: Some("root".into()),
asset_id: None,
}],
root_uri: None,
},
state: FileTreeRuntimeState::default(),
action: FileTreeRuntimeAction::DispatchExternalDrop {