rusticity_term/session/
ui.rs

1use super::Session;
2use crate::common::SortDirection;
3use crate::ui::filter_area;
4use crate::ui::table::{self};
5use ratatui::prelude::{Color, Constraint, Direction, Layout, Span, Style};
6use ratatui::widgets::Clear;
7
8enum SessionColumn {
9    Timestamp,
10    Profile,
11    Region,
12    Account,
13    Tabs,
14}
15
16impl table::Column<Session> for SessionColumn {
17    fn name(&self) -> &str {
18        match self {
19            Self::Timestamp => "Timestamp",
20            Self::Profile => "Profile",
21            Self::Region => "Region",
22            Self::Account => "Account",
23            Self::Tabs => "Tabs",
24        }
25    }
26
27    fn width(&self) -> u16 {
28        match self {
29            Self::Timestamp => 25,
30            Self::Profile => 25,
31            Self::Region => 15,
32            Self::Account => 15,
33            Self::Tabs => 8,
34        }
35    }
36
37    fn render(&self, item: &Session) -> (String, Style) {
38        let text = match self {
39            Self::Timestamp => item.timestamp.clone(),
40            Self::Profile => item.profile.clone(),
41            Self::Region => item.region.clone(),
42            Self::Account => item.account_id.clone(),
43            Self::Tabs => item.tabs.len().to_string(),
44        };
45        (text, Style::default())
46    }
47}
48
49pub fn render_session_picker(
50    frame: &mut ratatui::Frame,
51    app: &crate::app::App,
52    area: ratatui::prelude::Rect,
53    centered_rect: fn(u16, u16, ratatui::prelude::Rect) -> ratatui::prelude::Rect,
54) {
55    let popup_area = centered_rect(80, 70, area);
56
57    let chunks = Layout::default()
58        .direction(Direction::Vertical)
59        .constraints([Constraint::Length(3), Constraint::Min(0)])
60        .split(popup_area);
61
62    let cursor = "█";
63    let filter_text = vec![
64        Span::raw(&app.session_filter),
65        Span::styled(cursor, Style::default().fg(Color::Green)),
66    ];
67    let filter = filter_area(filter_text, true);
68
69    frame.render_widget(Clear, popup_area);
70    frame.render_widget(filter, chunks[0]);
71
72    let columns: Vec<Box<dyn table::Column<Session>>> = vec![
73        Box::new(SessionColumn::Timestamp),
74        Box::new(SessionColumn::Profile),
75        Box::new(SessionColumn::Region),
76        Box::new(SessionColumn::Account),
77        Box::new(SessionColumn::Tabs),
78    ];
79
80    let filtered = app.get_filtered_sessions();
81    let config = table::TableConfig {
82        items: filtered,
83        selected_index: app.session_picker_selected,
84        expanded_index: None,
85        columns: &columns,
86        sort_column: "Timestamp",
87        sort_direction: SortDirection::Desc,
88        title: " Sessions ".to_string(),
89        area: chunks[1],
90        get_expanded_content: None,
91        is_active: true,
92    };
93
94    table::render_table(frame, config);
95}