From f019577810a6e13dfc6e7cce29c816551e7664a8 Mon Sep 17 00:00:00 2001 From: Edward Langley Date: Tue, 14 Apr 2026 00:49:31 -0700 Subject: [PATCH] feat(grid): allow drilling into formula cells When drilling into a cell that is the target of a formula, the resulting record set was empty because the formula target coordinate itself does not exist in the raw data. This change strips the '_Measure' coordinate from the drill key if the value is a known formula target, allowing the underlying data records that feed the formula to be discovered. Co-Authored-By: fiddlerwoaroof/git-smart-commit (gemma-4-31B-it-UD-Q4_K_XL.gguf) --- src/command/cmd/grid.rs | 73 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 71 insertions(+), 2 deletions(-) diff --git a/src/command/cmd/grid.rs b/src/command/cmd/grid.rs index 2796c97..cce6573 100644 --- a/src/command/cmd/grid.rs +++ b/src/command/cmd/grid.rs @@ -111,6 +111,57 @@ mod tests { "Expected TogglePruneEmpty, got: {dbg}" ); } + + /// Drilling into a formula cell (e.g. Profit = Revenue - Cost) should + /// return the underlying data records, not an empty result set. The + /// formula target coordinate is stripped from the drill key so that + /// matching_cells finds the raw data backing the formula. + #[test] + fn drill_into_formula_cell_returns_data_records() { + use crate::formula::parse_formula; + use crate::model::Model; + use crate::model::cell::{CellKey, CellValue}; + + let mut m = Model::new("Test"); + m.add_category("Region").unwrap(); + m.category_mut("Region").unwrap().add_item("East"); + m.category_mut("_Measure").unwrap().add_item("Revenue"); + m.category_mut("_Measure").unwrap().add_item("Cost"); + m.set_cell( + CellKey::new(vec![ + ("_Measure".into(), "Revenue".into()), + ("Region".into(), "East".into()), + ]), + CellValue::Number(1000.0), + ); + m.set_cell( + CellKey::new(vec![ + ("_Measure".into(), "Cost".into()), + ("Region".into(), "East".into()), + ]), + CellValue::Number(600.0), + ); + m.add_formula(parse_formula("Profit = Revenue - Cost", "_Measure").unwrap()); + + let layout = make_layout(&m); + let reg = make_registry(); + let ctx = make_ctx(&m, &layout, ®); + + // Drill into the Profit/East cell — a formula-derived cell + let key = CellKey::new(vec![ + ("_Measure".into(), "Profit".into()), + ("Region".into(), "East".into()), + ]); + let cmd = DrillIntoCell { key }; + let effects = cmd.execute(&ctx); + let dbg = effects_debug(&effects); + + // Should find underlying data records, not "0 rows" + assert!( + !dbg.contains("0 rows"), + "Drill into formula cell should find data records, got: {dbg}" + ); + } } // ── Grid operations ───────────────────────────────────────────────────── @@ -233,9 +284,27 @@ impl Cmd for DrillIntoCell { let drill_name = "_Drill".to_string(); let mut effects: Vec> = Vec::new(); + // If drilling into a formula cell, strip the formula target from the + // key so matching_cells finds the underlying raw data records instead + // of returning nothing. + let drill_key = if let Some(measure_val) = self.key.get("_Measure") { + let is_formula_target = ctx + .model + .formulas() + .iter() + .any(|f| f.target_category == "_Measure" && f.target == measure_val); + if is_formula_target { + self.key.without("_Measure") + } else { + self.key.clone() + } + } else { + self.key.clone() + }; + // Capture the records snapshot NOW (before we switch views). let records: Vec<(crate::model::cell::CellKey, crate::model::cell::CellValue)> = - if self.key.0.is_empty() { + if drill_key.0.is_empty() { ctx.model .data .iter_cells() @@ -244,7 +313,7 @@ impl Cmd for DrillIntoCell { } else { ctx.model .data - .matching_cells(&self.key.0) + .matching_cells(&drill_key.0) .into_iter() .map(|(k, v)| (k, v.clone())) .collect()