Skip to main content

virtuoso_cli/tui/app/
action.rs

1use crate::spectre::jobs::JobStatus;
2use crate::tui::app::overlay::{LogOverlay, Overlay};
3use crate::tui::app::state::{App, StatusKind};
4
5/// Intent produced by the event handler. The event handler must not mutate
6/// anything beyond the event-local state; all data-changing operations flow
7/// through `handle_action`.
8pub enum Action {
9    None,
10    Quit,
11    Refresh,
12    CancelJob(usize),
13    SaveConfig,
14    Status(String, StatusKind),
15}
16
17pub fn handle_action(app: &mut App, action: Action) {
18    match action {
19        Action::None => {}
20        Action::Quit => app.should_quit = true,
21        Action::Refresh => {
22            crate::tui::app::data::refresh(app);
23            let lines = crate::tui::app::data::load_log_lines();
24            // If a log overlay is already open, refresh its content in place;
25            // otherwise just cache nothing — `l` key reopens with fresh data.
26            if let Overlay::Log(_) = app.overlay {
27                app.overlay = Overlay::Log(LogOverlay::new(lines));
28            }
29            app.set_status("Refreshed", StatusKind::Ok);
30        }
31        Action::CancelJob(idx) => {
32            if let Some(job) = app.jobs.get_mut(idx) {
33                if job.status == JobStatus::Running {
34                    let _ = job.cancel();
35                    let id = job.id.clone();
36                    app.set_status(format!("Cancelled job {id}"), StatusKind::Warn);
37                } else {
38                    app.set_status("Job not running", StatusKind::Info);
39                }
40            }
41        }
42        Action::SaveConfig => match crate::tui::app::data::save_config(app) {
43            Ok(_) => app.set_status("Config saved to .env", StatusKind::Ok),
44            Err(e) => app.set_status(format!("Save failed: {e}"), StatusKind::Err),
45        },
46        Action::Status(msg, kind) => app.set_status(msg, kind),
47    }
48}