Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 79 additions & 1 deletion cli/src/tui/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ use anyhow::Result;

use super::state::{
claim_builder_state::ClaimBuilderState, detail_state::DetailState, events_state::EventsState,
modal_state::ModalState, search_state::SearchState, view_state::ViewState,
modal_state::ModalState, search_state::SearchState, stack_builder_state::StackBuilderState,
view_state::ViewState,
};
use super::utils::NavItem;
use crate::current_region_handler;
Expand Down Expand Up @@ -39,6 +40,8 @@ pub enum PendingAction {
ReloadCurrentDeploymentDetail,
SaveClaimToFile,
RunClaimFromBuilder,
OpenStackBuilder,
SaveStackToFile,
}

#[derive(Debug, Clone)]
Expand Down Expand Up @@ -102,6 +105,7 @@ pub struct App {
pub modal_state: ModalState,
pub search_state: SearchState,
pub claim_builder_state: ClaimBuilderState,
pub stack_builder_state: StackBuilderState,

// ==================== LEGACY FIELDS (TRANSITIONING) ====================
// These are kept for backward compatibility during migration.
Expand Down Expand Up @@ -171,6 +175,7 @@ impl App {
let modal_state = ModalState::new();
let search_state = SearchState::new();
let claim_builder_state = ClaimBuilderState::new();
let stack_builder_state = StackBuilderState::new();

Self {
// Core app state
Expand All @@ -190,6 +195,7 @@ impl App {
modal_state,
search_state,
claim_builder_state,
stack_builder_state,

// Legacy fields - initialized from defaults for backward compatibility
// View state
Expand Down Expand Up @@ -641,6 +647,12 @@ impl App {
PendingAction::RunClaimFromBuilder => {
self.run_claim_from_builder().await?;
}
PendingAction::OpenStackBuilder => {
self.open_stack_builder().await?;
}
PendingAction::SaveStackToFile => {
self.save_stack_to_file().await?;
}
}

Ok(())
Expand Down Expand Up @@ -708,6 +720,12 @@ impl App {
PendingAction::RunClaimFromBuilder => {
self.set_loading("Running claim...");
}
PendingAction::OpenStackBuilder => {
self.set_loading("Loading modules...");
}
PendingAction::SaveStackToFile => {
self.set_loading("Saving stack to file...");
}
}
}

Expand Down Expand Up @@ -2346,6 +2364,66 @@ impl App {
self.clear_loading();
Ok(())
}

/// Open the stack builder with all available modules
pub async fn open_stack_builder(&mut self) -> Result<()> {
// Load all modules (from all tracks)
let modules = current_region_handler()
.await
.get_all_latest_module("")
.await?;

self.stack_builder_state.open(modules);
self.clear_loading();

Ok(())
}

/// Save the stack builder's generated YAML to a file
pub async fn save_stack_to_file(&mut self) -> Result<()> {
use std::fs;
use std::path::PathBuf;

// Generate the YAML if not already generated
if self.stack_builder_state.generated_yaml.is_empty() {
self.stack_builder_state.generate_yaml();
}

let mut saved_files = Vec::new();
let mut errors = Vec::new();

// Save each file separately
for (filename, content) in &self.stack_builder_state.generated_files {
let mut filepath = PathBuf::from("./");
filepath.push(filename);

match fs::write(&filepath, content) {
Ok(_) => {
saved_files.push(filepath.display().to_string());
}
Err(e) => {
errors.push(format!("{}: {}", filename, e));
}
}
}

// Show results
if errors.is_empty() {
let file_list = saved_files.join(", ");
self.detail_state
.show_message(format!("✅ Stack saved! Files: {}", file_list));
// Close the stack builder after successful save
self.stack_builder_state.close();
} else {
let error_msg = errors.join("; ");
self.detail_state
.show_error(&format!("Failed to save some files: {}", error_msg));
}

self.clear_loading();

Ok(())
}
}

// Implement VersionItem trait for Module to work with VersionsModal widget
Expand Down
7 changes: 7 additions & 0 deletions cli/src/tui/events/main_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,13 @@ impl MainHandler {
// Handle Ctrl+key combinations first
if modifiers.contains(KeyModifiers::CONTROL) {
match key {
KeyCode::Char('n') => {
if matches!(app.current_view, crate::tui::app::View::Stacks) {
// Open stack builder - load all modules
app.schedule_action(PendingAction::OpenStackBuilder);
}
return Ok(());
}
KeyCode::Char('r') => {
if matches!(app.current_view, crate::tui::app::View::Deployments) {
// Get the current deployment
Expand Down
2 changes: 2 additions & 0 deletions cli/src/tui/events/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ pub mod detail_handler;
pub mod events_handler;
pub mod main_handler;
pub mod modal_handler;
pub mod stack_builder_handler;

pub use claim_builder_handler::ClaimBuilderHandler;
pub use detail_handler::DetailHandler;
pub use events_handler::EventsHandler;
pub use main_handler::MainHandler;
pub use modal_handler::ModalHandler;
pub use stack_builder_handler::StackBuilderHandler;
Loading
Loading