Fix delete confirmation safety, expand_all, tree lines, auto-refresh msg
- CRITICAL: confirm_delete was never reset when pressing other keys after 'd'. User could navigate, re-mark, press 'd' again and snapshots would be deleted without confirmation - expand_all: only expanded currently visible datasets, not nested collapsed ones. Now recursively collects from root_entries - is_last for snapshots: showed wrong tree connector when parent had both child datasets and snapshots (snapshots are always last) - auto-refresh message hardcoded "30s" instead of config value
This commit is contained in:
parent
24960398db
commit
617a05fbcd
Binary file not shown.
36
src/app.rs
36
src/app.rs
@ -190,14 +190,13 @@ impl App {
|
|||||||
);
|
);
|
||||||
items.extend(child_items);
|
items.extend(child_items);
|
||||||
|
|
||||||
// Add snapshots
|
// Add snapshots (rendered after children, so last snapshot is always last item)
|
||||||
let snap_len = entry.snapshots.len();
|
let snap_len = entry.snapshots.len();
|
||||||
let children_empty = entry.children.is_empty();
|
|
||||||
for (j, snap) in entry.snapshots.iter().enumerate() {
|
for (j, snap) in entry.snapshots.iter().enumerate() {
|
||||||
items.push(TreeItem {
|
items.push(TreeItem {
|
||||||
item: ListItem::Snapshot(snap.clone()),
|
item: ListItem::Snapshot(snap.clone()),
|
||||||
depth: depth + 1,
|
depth: depth + 1,
|
||||||
is_last: j == snap_len - 1 && children_empty,
|
is_last: j == snap_len - 1,
|
||||||
parent_is_last: child_parent_is_last.clone(),
|
parent_is_last: child_parent_is_last.clone(),
|
||||||
visible: true,
|
visible: true,
|
||||||
parent_path: entry.full_name.clone(),
|
parent_path: entry.full_name.clone(),
|
||||||
@ -354,14 +353,24 @@ impl App {
|
|||||||
self.marked.iter().any(|x| x == name)
|
self.marked.iter().any(|x| x == name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Reset confirm_delete state — call on any action that isn't 'd'
|
||||||
|
pub fn reset_confirm(&mut self) {
|
||||||
|
if self.confirm_delete {
|
||||||
|
self.confirm_delete = false;
|
||||||
|
self.message = Some("Delete cancelled".to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn delete_marked(&mut self) -> Result<()> {
|
pub fn delete_marked(&mut self) -> Result<()> {
|
||||||
if self.marked.is_empty() {
|
if self.marked.is_empty() {
|
||||||
|
self.confirm_delete = false;
|
||||||
self.message = Some("No snapshots marked".to_string());
|
self.message = Some("No snapshots marked".to_string());
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
// In dry-run mode, just show what would happen
|
// In dry-run mode, just show what would happen
|
||||||
if self.dry_run_mode {
|
if self.dry_run_mode {
|
||||||
|
self.confirm_delete = false;
|
||||||
self.show_dry_run_preview();
|
self.show_dry_run_preview();
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
@ -672,19 +681,22 @@ impl App {
|
|||||||
self.message = Some(format!("Inverted {} in scope", count));
|
self.message = Some(format!("Inverted {} in scope", count));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Expand all datasets
|
// Expand all datasets (recursively from root_entries, not just visible tree)
|
||||||
pub fn expand_all(&mut self) {
|
pub fn expand_all(&mut self) {
|
||||||
for ti in &self.tree_items {
|
Self::collect_expandable(&self.root_entries, &mut self.expanded);
|
||||||
if let ListItem::Dataset(d) = &ti.item {
|
|
||||||
if d.has_children() {
|
|
||||||
self.expanded.insert(d.full_name.clone());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
self.rebuild_tree();
|
self.rebuild_tree();
|
||||||
self.message = Some("Expanded all".to_string());
|
self.message = Some("Expanded all".to_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn collect_expandable(entries: &[ZfsEntry], expanded: &mut HashSet<String>) {
|
||||||
|
for entry in entries {
|
||||||
|
if entry.has_children() {
|
||||||
|
expanded.insert(entry.full_name.clone());
|
||||||
|
}
|
||||||
|
Self::collect_expandable(&entry.children, expanded);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Collapse all datasets
|
// Collapse all datasets
|
||||||
pub fn collapse_all(&mut self) {
|
pub fn collapse_all(&mut self) {
|
||||||
self.expanded.clear();
|
self.expanded.clear();
|
||||||
@ -751,7 +763,7 @@ impl App {
|
|||||||
pub fn toggle_auto_refresh(&mut self) {
|
pub fn toggle_auto_refresh(&mut self) {
|
||||||
self.auto_refresh = !self.auto_refresh;
|
self.auto_refresh = !self.auto_refresh;
|
||||||
if self.auto_refresh {
|
if self.auto_refresh {
|
||||||
self.message = Some("Auto-refresh ON (30s)".to_string());
|
self.message = Some(format!("Auto-refresh ON ({}s)", self.auto_refresh_interval));
|
||||||
} else {
|
} else {
|
||||||
self.message = Some("Auto-refresh OFF".to_string());
|
self.message = Some("Auto-refresh OFF".to_string());
|
||||||
}
|
}
|
||||||
|
|||||||
@ -133,6 +133,11 @@ fn run_app<B: ratatui::backend::Backend>(terminal: &mut Terminal<B>, app: &mut A
|
|||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Reset delete confirmation on any key except 'd'/F8
|
||||||
|
if key.code != KeyCode::Char('d') && key.code != KeyCode::F(8) {
|
||||||
|
app.reset_confirm();
|
||||||
|
}
|
||||||
|
|
||||||
match key.code {
|
match key.code {
|
||||||
// Navigation
|
// Navigation
|
||||||
KeyCode::Up | KeyCode::Char('k') => app.previous(),
|
KeyCode::Up | KeyCode::Char('k') => app.previous(),
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user