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)
This commit is contained in:
@ -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<Box<dyn Effect>> = 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()
|
||||
|
||||
Reference in New Issue
Block a user