feat: add new commands for records mode and category management

Add new commands for enhanced data entry and category management.

AddRecordRow: Adds a new record row in records mode with empty value.
TogglePruneEmpty: Toggles pruning of empty rows/columns in pivot mode.
ToggleRecordsMode: Switches between records and pivot layout.
DeleteCategoryAtCursor: Removes a category and all its cells.
ToggleCatExpand: Expands/collapses a category in the tree.
FilterToItem: Filters to show only items matching cursor position.

Model gains remove_category() and remove_item() to delete categories
and items along with all referencing cells and formulas.

Co-Authored-By: fiddlerwoaroof/git-smart-commit (unsloth/Qwen3.5-35B-A3B-GGUF:Q5_K_M)
This commit is contained in:
Edward Langley
2026-04-06 15:09:57 -07:00
parent 5fe553b57a
commit 55cad99ae1
5 changed files with 383 additions and 4 deletions

View File

@ -90,6 +90,68 @@ impl Effect for RemoveFormula {
}
}
/// Re-enter edit mode by reading the cell value at the current cursor.
/// Used after commit+advance to continue data entry.
#[derive(Debug)]
pub struct EnterEditAtCursor;
impl Effect for EnterEditAtCursor {
fn apply(&self, app: &mut App) {
let ctx = app.cmd_context(crossterm::event::KeyCode::Null, crossterm::event::KeyModifiers::NONE);
let value = if let Some(v) = &ctx.records_value {
v.clone()
} else {
ctx.cell_key
.as_ref()
.and_then(|k| ctx.model.get_cell(k).cloned())
.map(|v| v.to_string())
.unwrap_or_default()
};
drop(ctx);
app.buffers.insert("edit".to_string(), value);
app.mode = AppMode::Editing {
buffer: String::new(),
};
}
}
#[derive(Debug)]
pub struct TogglePruneEmpty;
impl Effect for TogglePruneEmpty {
fn apply(&self, app: &mut App) {
let v = app.model.active_view_mut();
v.prune_empty = !v.prune_empty;
}
}
#[derive(Debug)]
pub struct ToggleCatExpand(pub String);
impl Effect for ToggleCatExpand {
fn apply(&self, app: &mut App) {
if !app.expanded_cats.remove(&self.0) {
app.expanded_cats.insert(self.0.clone());
}
}
}
#[derive(Debug)]
pub struct RemoveItem {
pub category: String,
pub item: String,
}
impl Effect for RemoveItem {
fn apply(&self, app: &mut App) {
app.model.remove_item(&self.category, &self.item);
}
}
#[derive(Debug)]
pub struct RemoveCategory(pub String);
impl Effect for RemoveCategory {
fn apply(&self, app: &mut App) {
app.model.remove_category(&self.0);
}
}
// ── View mutations ───────────────────────────────────────────────────────────
#[derive(Debug)]