Skip to main content

autom8/ui/tui/
views.rs

1//! View definitions for the Monitor TUI.
2//!
3//! The monitor supports three views:
4//! - Active Runs: Shows real-time status of running autom8 processes
5//! - Project List: Shows all projects with their status
6//! - Run History: Shows past runs across projects
7
8use std::fmt;
9
10/// The available views in the monitor TUI.
11#[derive(Debug, Clone, Copy, PartialEq, Eq)]
12pub enum View {
13    /// Shows real-time status of active autom8 runs.
14    /// This view is hidden if no runs are active.
15    ActiveRuns,
16    /// Shows all projects with their status.
17    /// This is the default view when no runs are active.
18    ProjectList,
19    /// Shows past runs across all projects (or filtered to one project).
20    RunHistory,
21}
22
23impl View {
24    /// Returns the display name for this view.
25    pub fn name(&self) -> &'static str {
26        match self {
27            View::ActiveRuns => "Active Runs",
28            View::ProjectList => "Projects",
29            View::RunHistory => "Run History",
30        }
31    }
32
33    /// Get all views in order.
34    pub fn all() -> &'static [View] {
35        &[View::ActiveRuns, View::ProjectList, View::RunHistory]
36    }
37
38    /// Get the next view in the cycle, optionally skipping ActiveRuns.
39    pub fn next(&self, skip_active_runs: bool) -> View {
40        let views = View::all();
41        let current_idx = views.iter().position(|v| v == self).unwrap_or(0);
42        let mut next_idx = (current_idx + 1) % views.len();
43
44        // Skip ActiveRuns if requested
45        if skip_active_runs && views[next_idx] == View::ActiveRuns {
46            next_idx = (next_idx + 1) % views.len();
47        }
48
49        views[next_idx]
50    }
51
52    /// Get the default view based on whether there are active runs.
53    pub fn default_view(has_active_runs: bool) -> View {
54        if has_active_runs {
55            View::ActiveRuns
56        } else {
57            View::ProjectList
58        }
59    }
60}
61
62impl fmt::Display for View {
63    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
64        write!(f, "{}", self.name())
65    }
66}
67
68#[cfg(test)]
69mod tests {
70    use super::*;
71
72    #[test]
73    fn test_view_name() {
74        assert_eq!(View::ActiveRuns.name(), "Active Runs");
75        assert_eq!(View::ProjectList.name(), "Projects");
76        assert_eq!(View::RunHistory.name(), "Run History");
77    }
78
79    #[test]
80    fn test_view_all() {
81        let all = View::all();
82        assert_eq!(all.len(), 3);
83        assert_eq!(all[0], View::ActiveRuns);
84        assert_eq!(all[1], View::ProjectList);
85        assert_eq!(all[2], View::RunHistory);
86    }
87
88    #[test]
89    fn test_view_next_without_skip() {
90        assert_eq!(View::ActiveRuns.next(false), View::ProjectList);
91        assert_eq!(View::ProjectList.next(false), View::RunHistory);
92        assert_eq!(View::RunHistory.next(false), View::ActiveRuns);
93    }
94
95    #[test]
96    fn test_view_next_with_skip_active_runs() {
97        // From ActiveRuns, should go to ProjectList (normal)
98        assert_eq!(View::ActiveRuns.next(true), View::ProjectList);
99        // From ProjectList, should skip ActiveRuns and go to RunHistory, then cycle
100        assert_eq!(View::ProjectList.next(true), View::RunHistory);
101        // From RunHistory, should skip ActiveRuns and go to ProjectList
102        assert_eq!(View::RunHistory.next(true), View::ProjectList);
103    }
104
105    #[test]
106    fn test_default_view_with_active_runs() {
107        assert_eq!(View::default_view(true), View::ActiveRuns);
108    }
109
110    #[test]
111    fn test_default_view_without_active_runs() {
112        assert_eq!(View::default_view(false), View::ProjectList);
113    }
114
115    #[test]
116    fn test_view_display() {
117        assert_eq!(format!("{}", View::ActiveRuns), "Active Runs");
118        assert_eq!(format!("{}", View::ProjectList), "Projects");
119        assert_eq!(format!("{}", View::RunHistory), "Run History");
120    }
121}