fix(workbook): align default virtual-category axes with main (improvise-kos)

Workbook::new was setting _Index=Row and _Dim=Column on the default view,
which forced a fresh workbook into records mode on every startup — records
mode auto-activates when both _Index and _Dim sit on axes. The result felt
like broken keybindings: the grid rendered as records instead of an
aggregated pivot, and every navigation key landed in an unexpected spot.

Main fixed this on the Model layer in 709f2df + 6d4b19a (improvise-kos);
the Workbook refactor accidentally reintroduced the pre-fix behavior.
Restore the post-kos defaults: all virtual categories start on Axis::None
(via on_category_added's "_"-prefix rule), then _Measure is bumped to
Axis::Page so aggregated pivot views show one measure at a time. _Index
and _Dim only move onto axes when the user explicitly enters records mode.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Edward Langley
2026-04-15 21:22:59 -07:00
parent f1229a60e4
commit 1c16dc17e8

View File

@ -26,9 +26,12 @@ pub struct Workbook {
impl Workbook { impl Workbook {
/// Create a new workbook with a fresh `Model` and a single `Default` view. /// Create a new workbook with a fresh `Model` and a single `Default` view.
/// Virtual categories (`_Index`, `_Dim`, `_Measure`) are registered on the /// Virtual categories (`_Index`, `_Dim`, `_Measure`) are registered on the
/// default view with their conventional axes (`_Index`=Row, `_Dim`=Column, /// default view. All virtuals default to `Axis::None` via
/// `_Measure`=Page so aggregated pivot views show a single measure by /// `on_category_added` (see improvise-709f2df), then `_Measure` is bumped
/// default; see improvise-kos). /// to `Axis::Page` so aggregated pivot views show a single measure at a
/// time (see improvise-kos). Leaving `_Index`/`_Dim` on None keeps pivot
/// mode the default — records mode activates only when the user moves
/// both onto axes.
pub fn new(name: impl Into<String>) -> Self { pub fn new(name: impl Into<String>) -> Self {
let model = Model::new(name); let model = Model::new(name);
let mut views = IndexMap::new(); let mut views = IndexMap::new();
@ -42,8 +45,6 @@ impl Workbook {
for cat_name in wb.model.categories.keys() { for cat_name in wb.model.categories.keys() {
view.on_category_added(cat_name); view.on_category_added(cat_name);
} }
view.set_axis("_Index", Axis::Row);
view.set_axis("_Dim", Axis::Column);
view.set_axis("_Measure", Axis::Page); view.set_axis("_Measure", Axis::Page);
} }
wb wb
@ -150,8 +151,12 @@ mod tests {
let wb = Workbook::new("Test"); let wb = Workbook::new("Test");
assert_eq!(wb.active_view, "Default"); assert_eq!(wb.active_view, "Default");
let v = wb.active_view(); let v = wb.active_view();
assert_eq!(v.axis_of("_Index"), Axis::Row); // Virtual categories default to Axis::None; _Measure is bumped to Page
assert_eq!(v.axis_of("_Dim"), Axis::Column); // so aggregated pivot views show a single measure by default
// (improvise-kos, improvise-709f2df).
assert_eq!(v.axis_of("_Index"), Axis::None);
assert_eq!(v.axis_of("_Dim"), Axis::None);
assert_eq!(v.axis_of("_Measure"), Axis::Page);
} }
#[test] #[test]