Add desktop search and entry mutation workflows

This commit is contained in:
hugo committed 2026-08-10 19:19:46 +02:00
1 parent bb650c2b5c
commit de5dea28ef
8 files changed
+1292 -30

No files matched your search

+64 -1
View File
@@ -2,7 +2,10 @@
use std::{collections::BTreeSet, path::Path};
use ironstorage::read::{TreeModel, TreeNode, TreeNodeId, TreeNodeIndicators, TreeNodeKind};
use ironstorage::{
read::{TreeModel, TreeNode, TreeNodeId, TreeNodeIndicators, TreeNodeKind},
repository::DirectoryPath,
};
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum NavigationKey {
@@ -86,6 +89,20 @@ impl NavigationTree {
rows
}
pub fn directories(&self) -> Vec<TreeNodeId> {
fn visit(nodes: &[NavigationNode], directories: &mut Vec<TreeNodeId>) {
for node in nodes {
if node.id.is_directory() {
directories.push(node.id.clone());
}
visit(&node.children, directories);
}
}
let mut directories = vec![TreeNodeId::Directory(DirectoryPath::root())];
visit(&self.nodes, &mut directories);
directories
}
pub fn selected_ratio(&self) -> f32 {
let rows = self.rows();
let Some(index) = selected_index(&rows, self.selected.as_ref()) else {
@@ -131,6 +148,19 @@ impl NavigationTree {
true
}
pub fn select_id(&mut self, id: &TreeNodeId) -> bool {
let mut lineage = Vec::new();
if !find_id_lineage(&self.nodes, id, &mut lineage) {
return false;
}
let Some(selected) = lineage.pop() else {
return false;
};
self.expanded.extend(lineage);
self.selected = Some(selected);
true
}
fn activate_selected(&mut self) -> NavigationIntent {
let Some(selected) = self.selected.clone() else {
return NavigationIntent::None;
@@ -274,6 +304,21 @@ fn find_lineage(nodes: &[NavigationNode], path: &str, lineage: &mut Vec<TreeNode
false
}
fn find_id_lineage(
nodes: &[NavigationNode],
target: &TreeNodeId,
lineage: &mut Vec<TreeNodeId>,
) -> bool {
for node in nodes {
lineage.push(node.id.clone());
if &node.id == target || find_id_lineage(&node.children, target, lineage) {
return true;
}
lineage.pop();
}
false
}
#[cfg(test)]
pub(crate) struct TestNode {
pub id: TreeNodeId,
@@ -365,6 +410,24 @@ mod tests {
assert_eq!(tree.rows().len(), 2);
}
#[test]
fn typed_search_and_mutation_identities_expand_and_select_hidden_nodes() {
let mut tree = NavigationTree::default();
tree.replace_test_nodes(populated());
let hidden = TreeNodeId::Entry(EntryPath::parse("personal/email").expect("entry"));
assert!(tree.select_id(&hidden));
assert_eq!(tree.selected(), Some(&hidden));
assert!(tree.rows().iter().any(|row| row.id == hidden));
assert_eq!(
tree.directories(),
vec![
TreeNodeId::Directory(DirectoryPath::root()),
TreeNodeId::Directory(DirectoryPath::parse("personal").expect("personal")),
TreeNodeId::Directory(DirectoryPath::parse("work").expect("work")),
]
);
}
#[test]
fn refresh_preserves_valid_typed_identity_and_clears_removed_state() {
let mut tree = NavigationTree::default();