Add key handling for ConfigureDates (space toggle components) and
DefineFormulas (n new, d delete, text input mode) wizard steps.
Render date component toggles, formula list with input area, and
sample formulas derived from detected measures.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Extend FieldProposal with chrono-based date format detection and
configurable component extraction (Year, Month, Quarter). Add
ConfigureDates and DefineFormulas wizard steps to ImportPipeline.
build_model injects derived date categories and parses formula strings.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Categories on the None axis are excluded from the grid and cell keys.
When evaluating cells, values across hidden dimensions are aggregated
using a per-measure function (default SUM). Adds evaluate_aggregated
to Model, none_cats to GridLayout, and 'n' shortcut in TileSelect.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add row_group_for/col_group_for to GridLayout, replacing inline
backward-search logic. Refactor grid renderer to use col_group_for
instead of pre-filtering col_items. Add gz keybinding for column
group collapse toggle, symmetric with z for rows.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Use csv crate for robust CSV parsing (handles quoted fields, empty values, \r\n)
- Extend --import command to auto-detect format by file extension (.csv or .json)
- Reuse existing ImportPipeline and analyzer for field type detection
- Categories detected automatically (string fields), measures for numeric fields
- Updated help text and welcome screen to mention CSV support
All 201 tests pass.
Builds out two half-finished view features:
Group collapse:
- AxisEntry enum distinguishes GroupHeader from DataItem on grid axes
- expand_category() emits group headers and filters collapsed items
- Grid renders inline group header rows with ▼/▶ indicator
- `z` keybinding toggles collapse of nearest group above cursor
Hide/show item:
- Restore show_item() (was commented out alongside hide_item)
- Add HideItem / ShowItem commands and dispatch
- `H` keybinding hides the current row item
- `:show-item <cat> <item>` command to restore hidden items
- Restore silenced test assertions for hide/show round-trip
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The two tests were previously silenced when item_by_name was removed.
Rewrites them using category.items.get() directly, restoring coverage
of item-name and item-group serialization round-trips.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Removes unused methods (sum_matching, get_mut, item_by_name, item_index,
top_level_groups, is_group_collapsed, show_item) and unused constants
(LABEL_THRESHOLD, MIN_COL_WIDTH).
The sum_matching tests in model.rs were bypassing the formula evaluator
entirely. Replaced them with equivalent tests that call evaluate() against
the existing Total = SUM(Revenue) formula, exercising the real aggregation
code path.
Also fixes a compile error in view.rs prop_tests where View/Axis imports
and a doc comment were incorrectly commented out.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
musl tooling is Linux-only, so guard it behind an isLinux check in
flake.nix and remove the hardcoded musl build target from .cargo/config.toml
(the nix devShell already sets CARGO_BUILD_TARGET on Linux).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Previously --import ran ImportJson headless before the TUI started,
hitting the category limit and printing the error to stderr where it
was invisible. Now it parses the JSON and opens the ImportWizard on
startup, matching :import behavior.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Removed the post-execution mode reset from the caller. execute_command
now sets mode = Normal at the top as the default; commands that open
a new mode (ImportWizard, Quit) simply override it. The caller no
longer needs a special-case exclusion list.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
execute_command set mode to ImportWizard, but the caller immediately
reset it to Normal for any non-Quit mode. Added ImportWizard to the
exclusion list so the wizard survives the reset.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Root cause: set_axis silently ignores unregistered categories, so a
view section appearing before its categories would produce wrong axis
assignments when on_category_added later ran and assigned defaults.
Fix: collect all raw data in pass 1, then build the model in the
correct dependency order in pass 2 (categories → views → data/formulas).
The file can now list sections in any order.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
New format is diffable plain text with categories, items, formulas,
data cells, and views all readable without tooling. Legacy JSON files
(detected by leading '{') still load correctly for backwards compat.
Format overview:
# Model Name
## Category: Type
- Food
- Gas [Essentials]
## Data
Month=Jan, Type=Food = 100
## View: Default (active)
Type: row
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Pressing 't' swaps all Row-axis categories to Column and all
Column-axis categories to Row, leaving Page categories unchanged.
Selection and scroll offsets are reset to (0,0).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Column headers now render one row per column category instead of
joining with '/'. Row headers render one sub-column per row category.
Repeat suppression hides labels when the prefix is unchanged from
the previous row/column.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The CSV export used Box<dyn Iterator<Item = Option<usize>>> to unify
empty and non-empty row iteration, violating the CLAUDE.md rule that
Box/Rc container management should be split from logic. Replaced with a
direct for loop over row indices, removing both the Box and the Option
sentinels used to represent "placeholder empty row/col".
Also removes unused pub use cell::CellKey re-export and an unused
import in cell.rs tests.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>