rusticity_term/ec2/
actions.rs1use crate::app::App;
2use crate::common::{CyclicEnum, InputFocus, PageSize};
3use crate::ui::ec2::{
4 filtered_ec2_instances, filtered_tags, DetailTab as Ec2DetailTab, FILTER_CONTROLS,
5 STATE_FILTER as EC2_STATE_FILTER,
6};
7use crate::ui::monitoring::MonitoringState;
8
9pub fn apply_filter_reset(app: &mut App) {
12 app.ec2_state.table.reset();
13}
14
15pub fn get_active_filter_mut(app: &mut App) -> Option<&mut String> {
16 if app.ec2_state.current_instance.is_some() && app.ec2_state.detail_tab == Ec2DetailTab::Tags {
17 Some(&mut app.ec2_state.tags.filter)
18 } else {
19 Some(&mut app.ec2_state.table.filter)
20 }
21}
22
23pub fn is_pagination_focused(app: &App) -> bool {
24 app.ec2_state.input_focus == InputFocus::Pagination
25}
26
27pub fn next_filter_focus(app: &mut App) {
28 app.ec2_state.input_focus = app.ec2_state.input_focus.next(&FILTER_CONTROLS);
29}
30
31pub fn prev_filter_focus(app: &mut App) {
32 app.ec2_state.input_focus = app.ec2_state.input_focus.prev(&FILTER_CONTROLS);
33}
34
35pub fn filter_char_push(app: &mut App, c: char) {
36 if app.ec2_state.input_focus == InputFocus::Filter {
37 app.ec2_state.tags.filter.push(c);
38 app.ec2_state.tags.selected = 0;
39 }
40}
41
42pub fn filter_char_pop(app: &mut App) {
43 if app.ec2_state.input_focus == InputFocus::Filter {
44 app.ec2_state.tags.filter.pop();
45 app.ec2_state.tags.selected = 0;
46 }
47}
48
49pub fn toggle_state_filter_next(app: &mut App) {
50 if app.ec2_state.input_focus == EC2_STATE_FILTER {
51 app.ec2_state.state_filter = app.ec2_state.state_filter.next();
52 app.ec2_state.table.reset();
53 }
54}
55
56pub fn toggle_state_filter_prev(app: &mut App) {
57 if app.ec2_state.input_focus == EC2_STATE_FILTER {
58 app.ec2_state.state_filter = app.ec2_state.state_filter.prev();
59 app.ec2_state.table.reset();
60 }
61}
62
63pub fn toggle_filter_checkbox(app: &mut App) {
64 if app.ec2_state.input_focus == EC2_STATE_FILTER {
65 app.ec2_state.state_filter = app.ec2_state.state_filter.next();
66 app.ec2_state.table.reset();
67 }
68}
69
70pub fn next_item(app: &mut App) {
73 if app.ec2_state.current_instance.is_some() && app.ec2_state.detail_tab == Ec2DetailTab::Tags {
74 let filtered = filtered_tags(app);
75 if !filtered.is_empty() {
76 app.ec2_state.tags.next_item(filtered.len());
77 }
78 } else {
79 let filtered = filtered_ec2_instances(app);
80 if !filtered.is_empty() {
81 app.ec2_state.table.next_item(filtered.len());
82 }
83 }
84}
85
86pub fn prev_item(app: &mut App) {
87 if app.ec2_state.current_instance.is_some() && app.ec2_state.detail_tab == Ec2DetailTab::Tags {
88 app.ec2_state.tags.prev_item();
89 } else {
90 app.ec2_state.table.prev_item();
91 }
92}
93
94pub fn page_down_normal(app: &mut App) {
95 let filtered = filtered_ec2_instances(app);
96 if !filtered.is_empty() {
97 app.ec2_state.table.page_down(filtered.len());
98 }
99}
100
101pub fn page_up_normal(app: &mut App) {
102 if app.ec2_state.current_instance.is_some()
103 && app.ec2_state.detail_tab == Ec2DetailTab::Monitoring
104 && !app.ec2_state.is_metrics_loading()
105 {
106 app.ec2_state
107 .set_monitoring_scroll(app.ec2_state.monitoring_scroll().saturating_sub(1));
108 } else {
109 app.ec2_state.table.page_up();
110 }
111}
112
113pub fn scroll_up(app: &mut App) {
114 if app.ec2_state.current_instance.is_some()
115 && app.ec2_state.detail_tab == Ec2DetailTab::Monitoring
116 && !app.ec2_state.is_metrics_loading()
117 {
118 app.ec2_state
119 .set_monitoring_scroll(app.ec2_state.monitoring_scroll().saturating_sub(1));
120 }
121}
122
123pub fn scroll_down(app: &mut App) {
124 if app.ec2_state.current_instance.is_some()
125 && app.ec2_state.detail_tab == Ec2DetailTab::Monitoring
126 && !app.ec2_state.is_metrics_loading()
127 {
128 app.ec2_state
129 .set_monitoring_scroll((app.ec2_state.monitoring_scroll() + 1).min(5));
130 }
131}
132
133pub fn expand_row(app: &mut App) {
134 if app.ec2_state.current_instance.is_some() && app.ec2_state.detail_tab == Ec2DetailTab::Tags {
135 app.ec2_state.tags.toggle_expand();
136 } else if !app.ec2_state.table.is_expanded() {
137 app.ec2_state.table.toggle_expand();
138 }
139}
140
141pub fn prev_pane(app: &mut App) {
142 app.ec2_state.table.collapse();
143}
144
145pub fn collapse_row(app: &mut App) {
146 if app.ec2_state.current_instance.is_some() && app.ec2_state.detail_tab == Ec2DetailTab::Tags {
147 app.ec2_state.tags.collapse();
148 } else {
149 app.ec2_state.table.collapse();
150 }
151}
152
153pub fn select_item(app: &mut App) {
156 if app.ec2_state.current_instance.is_none() {
157 let filtered = filtered_ec2_instances(app);
158 if let Some(instance) = app.ec2_state.table.get_selected(&filtered) {
159 app.ec2_state.current_instance = Some(instance.instance_id.clone());
160 app.view_mode = crate::app::ViewMode::Detail;
161 app.update_current_tab_breadcrumb();
162 }
163 }
164}
165
166pub fn go_back(app: &mut App) {
167 app.ec2_state.current_instance = None;
168 app.view_mode = crate::app::ViewMode::List;
169 app.update_current_tab_breadcrumb();
170}
171
172pub fn next_detail_tab(app: &mut App) {
173 app.ec2_state.detail_tab = app.ec2_state.detail_tab.next();
174 if app.ec2_state.detail_tab == Ec2DetailTab::Tags {
175 app.ec2_state.tags.loading = true;
176 } else if app.ec2_state.detail_tab == Ec2DetailTab::Monitoring {
177 app.ec2_state.set_metrics_loading(true);
178 app.ec2_state.set_monitoring_scroll(0);
179 app.ec2_state.clear_metrics();
180 }
181}
182
183pub fn prev_detail_tab(app: &mut App) {
184 app.ec2_state.detail_tab = app.ec2_state.detail_tab.prev();
185 if app.ec2_state.detail_tab == Ec2DetailTab::Tags {
186 app.ec2_state.tags.loading = true;
187 } else if app.ec2_state.detail_tab == Ec2DetailTab::Monitoring {
188 app.ec2_state.set_metrics_loading(true);
189 app.ec2_state.set_monitoring_scroll(0);
190 app.ec2_state.clear_metrics();
191 }
192}
193
194pub fn block_column_selector(app: &App) -> bool {
195 app.ec2_state.table.expanded_item.is_some() && app.ec2_state.detail_tab != Ec2DetailTab::Tags
196}
197
198pub fn toggle_column(app: &mut App) {
201 let idx = app.column_selector_index;
202 if app.ec2_state.current_instance.is_some() && app.ec2_state.detail_tab == Ec2DetailTab::Tags {
203 if idx > 0 && idx <= app.ec2_state.tag_column_ids.len() {
204 if let Some(col) = app.ec2_state.tag_column_ids.get(idx - 1) {
205 if let Some(pos) = app
206 .ec2_state
207 .tag_visible_column_ids
208 .iter()
209 .position(|c| c == col)
210 {
211 if app.ec2_state.tag_visible_column_ids.len() > 1 {
212 app.ec2_state.tag_visible_column_ids.remove(pos);
213 }
214 } else {
215 app.ec2_state.tag_visible_column_ids.push(col.clone());
216 }
217 }
218 } else if idx == app.ec2_state.tag_column_ids.len() + 3 {
219 app.ec2_state.tags.page_size = PageSize::Ten;
220 } else if idx == app.ec2_state.tag_column_ids.len() + 4 {
221 app.ec2_state.tags.page_size = PageSize::TwentyFive;
222 } else if idx == app.ec2_state.tag_column_ids.len() + 5 {
223 app.ec2_state.tags.page_size = PageSize::Fifty;
224 } else if idx == app.ec2_state.tag_column_ids.len() + 6 {
225 app.ec2_state.tags.page_size = PageSize::OneHundred;
226 }
227 } else {
228 if idx > 0 && idx <= app.ec2_column_ids.len() {
229 if let Some(col) = app.ec2_column_ids.get(idx - 1) {
230 if let Some(pos) = app.ec2_visible_column_ids.iter().position(|c| c == col) {
231 if app.ec2_visible_column_ids.len() > 1 {
232 app.ec2_visible_column_ids.remove(pos);
233 }
234 } else {
235 app.ec2_visible_column_ids.push(*col);
236 }
237 }
238 } else if idx == app.ec2_column_ids.len() + 3 {
239 app.ec2_state.table.page_size = PageSize::Ten;
240 } else if idx == app.ec2_column_ids.len() + 4 {
241 app.ec2_state.table.page_size = PageSize::TwentyFive;
242 } else if idx == app.ec2_column_ids.len() + 5 {
243 app.ec2_state.table.page_size = PageSize::Fifty;
244 } else if idx == app.ec2_column_ids.len() + 6 {
245 app.ec2_state.table.page_size = PageSize::OneHundred;
246 }
247 }
248}
249
250pub fn next_preferences(app: &mut App) {
251 let page_size_idx = app.ec2_column_ids.len() + 2;
252 if app.column_selector_index < page_size_idx {
253 app.column_selector_index = page_size_idx;
254 } else {
255 app.column_selector_index = 0;
256 }
257}
258
259pub fn column_selector_max(app: &App) -> usize {
260 if app.ec2_state.current_instance.is_some() && app.ec2_state.detail_tab == Ec2DetailTab::Tags {
261 app.ec2_state.tag_column_ids.len() + 6
262 } else {
263 app.ec2_column_ids.len() + 6
264 }
265}
266
267pub fn column_count(app: &App) -> usize {
268 if app.ec2_state.current_instance.is_some() && app.ec2_state.detail_tab == Ec2DetailTab::Tags {
269 app.ec2_state.tag_column_ids.len()
270 } else {
271 app.ec2_column_ids.len()
272 }
273}
274
275pub fn breadcrumb(app: &App) -> Vec<String> {
278 let mut parts = vec!["EC2".to_string()];
279 if let Some(id) = &app.ec2_state.current_instance {
280 parts.push(id.clone());
281 } else {
282 parts.push("Instances".to_string());
283 }
284 parts
285}
286
287pub fn console_url(app: &App) -> String {
288 if let Some(instance_id) = &app.ec2_state.current_instance {
289 format!(
290 "https://{}.console.aws.amazon.com/ec2/home?region={}#InstanceDetails:instanceId={}",
291 app.config.region, app.config.region, instance_id
292 )
293 } else {
294 format!(
295 "https://{}.console.aws.amazon.com/ec2/home?region={}#Instances:",
296 app.config.region, app.config.region
297 )
298 }
299}