rusticity_term/session/
ui.rs1use super::Session;
2use crate::common::SortDirection;
3
4pub fn render_session_picker(
5 frame: &mut ratatui::Frame,
6 app: &crate::app::App,
7 area: ratatui::prelude::Rect,
8 centered_rect: fn(u16, u16, ratatui::prelude::Rect) -> ratatui::prelude::Rect,
9) {
10 use crate::ui::table::{render_table, Column as TableColumn, TableConfig};
11 use ratatui::{prelude::*, widgets::*};
12
13 let popup_area = centered_rect(80, 70, area);
14
15 let chunks = Layout::default()
16 .direction(Direction::Vertical)
17 .constraints([Constraint::Length(3), Constraint::Min(0)])
18 .split(popup_area);
19
20 let cursor = "█";
21 let filter = Paragraph::new(Line::from(vec![
22 Span::raw(&app.session_filter),
23 Span::styled(cursor, Style::default().fg(Color::Green)),
24 ]))
25 .block(
26 Block::default()
27 .title(" 🔍 ")
28 .borders(Borders::ALL)
29 .border_style(crate::ui::active_border()),
30 )
31 .style(Style::default());
32
33 frame.render_widget(Clear, popup_area);
34 frame.render_widget(filter, chunks[0]);
35
36 struct SessionTimestampColumn;
37 impl TableColumn<Session> for SessionTimestampColumn {
38 fn name(&self) -> &str {
39 "Timestamp"
40 }
41 fn width(&self) -> u16 {
42 25
43 }
44 fn render(&self, item: &Session) -> (String, Style) {
45 (item.timestamp.clone(), Style::default())
46 }
47 }
48
49 struct SessionProfileColumn;
50 impl TableColumn<Session> for SessionProfileColumn {
51 fn name(&self) -> &str {
52 "Profile"
53 }
54 fn width(&self) -> u16 {
55 25
56 }
57 fn render(&self, item: &Session) -> (String, Style) {
58 (item.profile.clone(), Style::default())
59 }
60 }
61
62 struct SessionRegionColumn;
63 impl TableColumn<Session> for SessionRegionColumn {
64 fn name(&self) -> &str {
65 "Region"
66 }
67 fn width(&self) -> u16 {
68 15
69 }
70 fn render(&self, item: &Session) -> (String, Style) {
71 (item.region.clone(), Style::default())
72 }
73 }
74
75 struct SessionAccountColumn;
76 impl TableColumn<Session> for SessionAccountColumn {
77 fn name(&self) -> &str {
78 "Account"
79 }
80 fn width(&self) -> u16 {
81 15
82 }
83 fn render(&self, item: &Session) -> (String, Style) {
84 (item.account_id.clone(), Style::default())
85 }
86 }
87
88 struct SessionTabsColumn;
89 impl TableColumn<Session> for SessionTabsColumn {
90 fn name(&self) -> &str {
91 "Tabs"
92 }
93 fn width(&self) -> u16 {
94 8
95 }
96 fn render(&self, item: &Session) -> (String, Style) {
97 (item.tabs.len().to_string(), Style::default())
98 }
99 }
100
101 let columns: Vec<Box<dyn TableColumn<Session>>> = vec![
102 Box::new(SessionTimestampColumn),
103 Box::new(SessionProfileColumn),
104 Box::new(SessionRegionColumn),
105 Box::new(SessionAccountColumn),
106 Box::new(SessionTabsColumn),
107 ];
108
109 let filtered = app.get_filtered_sessions();
110 let config = TableConfig {
111 items: filtered,
112 selected_index: app.session_picker_selected,
113 expanded_index: None,
114 columns: &columns,
115 sort_column: "Timestamp",
116 sort_direction: SortDirection::Desc,
117 title: " Sessions ".to_string(),
118 area: chunks[1],
119 get_expanded_content: None,
120 is_active: true,
121 };
122
123 render_table(frame, config);
124}