Refactor: split ImportWizard into pure ImportPipeline and UI wrapper

ImportPipeline holds all data and logic (raw JSON, records, proposals,
model_name, build_model). ImportWizard wraps it with UI-only state
(step, cursor, message). Rename WizardState → WizardStep throughout.
Headless import in dispatch.rs now constructs ImportPipeline directly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Ed L
2026-03-21 23:28:27 -07:00
parent 413601517d
commit 197b66e4e1
5 changed files with 303 additions and 169 deletions

View File

@ -6,7 +6,7 @@ use crossterm::event::{KeyCode, KeyEvent, KeyModifiers};
use crate::model::Model;
use crate::model::cell::{CellKey, CellValue};
use crate::formula::parse_formula;
use crate::import::wizard::{ImportWizard, WizardState};
use crate::import::wizard::{ImportWizard, WizardStep};
use crate::persistence;
use crate::view::Axis;
use crate::command::{self, Command};
@ -846,20 +846,20 @@ impl App {
fn handle_wizard_key(&mut self, key: KeyEvent) -> Result<()> {
if let Some(wizard) = &mut self.wizard {
match &wizard.state.clone() {
WizardState::Preview => match key.code {
match &wizard.step.clone() {
WizardStep::Preview => match key.code {
KeyCode::Enter | KeyCode::Char(' ') => wizard.advance(),
KeyCode::Esc => { self.mode = AppMode::Normal; self.wizard = None; }
_ => {}
},
WizardState::SelectArrayPath => match key.code {
WizardStep::SelectArrayPath => match key.code {
KeyCode::Up | KeyCode::Char('k') => wizard.move_cursor(-1),
KeyCode::Down | KeyCode::Char('j') => wizard.move_cursor(1),
KeyCode::Enter => wizard.confirm_path(),
KeyCode::Esc => { self.mode = AppMode::Normal; self.wizard = None; }
_ => {}
},
WizardState::ReviewProposals => match key.code {
WizardStep::ReviewProposals => match key.code {
KeyCode::Up | KeyCode::Char('k') => wizard.move_cursor(-1),
KeyCode::Down | KeyCode::Char('j') => wizard.move_cursor(1),
KeyCode::Char(' ') => wizard.toggle_proposal(),
@ -868,7 +868,7 @@ impl App {
KeyCode::Esc => { self.mode = AppMode::Normal; self.wizard = None; }
_ => {}
},
WizardState::NameModel => match key.code {
WizardStep::NameModel => match key.code {
KeyCode::Char(c) => wizard.push_name_char(c),
KeyCode::Backspace => wizard.pop_name_char(),
KeyCode::Enter => {
@ -890,7 +890,7 @@ impl App {
KeyCode::Esc => { self.mode = AppMode::Normal; self.wizard = None; }
_ => {}
},
WizardState::Done => { self.mode = AppMode::Normal; self.wizard = None; }
WizardStep::Done => { self.mode = AppMode::Normal; self.wizard = None; }
}
}
Ok(())