feat: add prune empty feature for pivot views

Add prune_empty feature to hide empty rows/columns in pivot mode.

View gains prune_empty boolean (default false for backward compat).
GridLayout::prune_empty() removes data rows where all columns are
empty and data columns where all rows are empty.

Group headers are preserved if at least one data item survives.
In records mode, pruning is skipped (user drilled in to see all data).

EditOrDrill command updated to check for regular (non-virtual)
categories when determining if a cell is aggregated.

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 55cad99ae1
commit eb83df9984
3 changed files with 185 additions and 7 deletions

View File

@ -672,7 +672,16 @@ impl Cmd for EditOrDrill {
"edit-or-drill"
}
fn execute(&self, ctx: &CmdContext) -> Vec<Box<dyn Effect>> {
let is_aggregated = ctx.records_col.is_none() && !ctx.none_cats.is_empty();
// Only consider regular (non-virtual, non-label) categories on None
// as true aggregation. Virtuals like _Index/_Dim are always None in
// pivot mode and don't imply aggregation.
let regular_none = ctx.none_cats.iter().any(|c| {
ctx.model
.category(c)
.map(|cat| cat.kind.is_regular())
.unwrap_or(false)
});
let is_aggregated = ctx.records_col.is_none() && regular_none;
if is_aggregated {
let Some(key) = ctx.cell_key.clone() else {
return vec![effect::set_status(