rusticity_term/cfn/
actions.rs1use crate::app::App;
2use crate::common::{CyclicEnum, InputFocus, PageSize};
3use crate::ui::cfn::{
4 filtered_change_sets, filtered_cloudformation_stacks, filtered_events, filtered_outputs,
5 filtered_parameters, filtered_resources, DetailTab as CfnDetailTab,
6 EventsView as CfnEventsView, State as CfnStateConstants, STATUS_FILTER, VIEW_NESTED,
7};
8
9pub fn apply_filter_reset(app: &mut App) {
12 if app.cfn_state.current_stack.is_some() && app.cfn_state.detail_tab == CfnDetailTab::Parameters
13 {
14 app.cfn_state.parameters.reset();
15 } else if app.cfn_state.current_stack.is_some()
16 && app.cfn_state.detail_tab == CfnDetailTab::Outputs
17 {
18 app.cfn_state.outputs.reset();
19 } else if app.cfn_state.current_stack.is_some()
20 && app.cfn_state.detail_tab == CfnDetailTab::Events
21 {
22 app.cfn_state.events.reset();
23 } else if app.cfn_state.current_stack.is_some()
24 && app.cfn_state.detail_tab == CfnDetailTab::ChangeSets
25 {
26 app.cfn_state.change_sets.reset();
27 } else {
28 app.cfn_state.table.reset();
29 }
30}
31
32pub fn reset_on_service_select(app: &mut App) {
33 app.cfn_state.table.reset();
34}
35
36pub fn is_pagination_focused(app: &App) -> bool {
37 app.cfn_state.input_focus == InputFocus::Pagination
38}
39
40pub fn filter_char_push(app: &mut App, c: char) {
41 if app.cfn_state.current_stack.is_some() && app.cfn_state.detail_tab == CfnDetailTab::Parameters
42 {
43 if app.cfn_state.parameters_input_focus == InputFocus::Filter {
44 app.cfn_state.parameters.filter.push(c);
45 app.cfn_state.parameters.selected = 0;
46 }
47 } else if app.cfn_state.current_stack.is_some()
48 && app.cfn_state.detail_tab == CfnDetailTab::Outputs
49 {
50 if app.cfn_state.outputs_input_focus == InputFocus::Filter {
51 app.cfn_state.outputs.filter.push(c);
52 app.cfn_state.outputs.selected = 0;
53 }
54 } else if app.cfn_state.current_stack.is_some()
55 && app.cfn_state.detail_tab == CfnDetailTab::Resources
56 {
57 if app.cfn_state.resources_input_focus == InputFocus::Filter {
58 app.cfn_state.resources.filter.push(c);
59 app.cfn_state.resources.selected = 0;
60 }
61 } else if app.cfn_state.current_stack.is_some()
62 && app.cfn_state.detail_tab == CfnDetailTab::Events
63 {
64 if app.cfn_state.events_input_focus == InputFocus::Filter {
65 app.cfn_state.events.filter.push(c);
66 app.cfn_state.events.selected = 0;
67 }
68 } else if app.cfn_state.current_stack.is_some()
69 && app.cfn_state.detail_tab == CfnDetailTab::ChangeSets
70 {
71 if app.cfn_state.change_sets_input_focus == InputFocus::Filter {
72 app.cfn_state.change_sets.filter.push(c);
73 app.cfn_state.change_sets.selected = 0;
74 }
75 } else if app.cfn_state.input_focus == InputFocus::Filter {
76 app.cfn_state.table.filter.push(c);
77 app.cfn_state.table.selected = 0;
78 }
79}
80
81pub fn filter_char_pop(app: &mut App) {
82 if app.cfn_state.current_stack.is_some() && app.cfn_state.detail_tab == CfnDetailTab::Parameters
83 {
84 if app.cfn_state.parameters_input_focus == InputFocus::Filter {
85 app.cfn_state.parameters.filter.pop();
86 app.cfn_state.parameters.selected = 0;
87 }
88 } else if app.cfn_state.current_stack.is_some()
89 && app.cfn_state.detail_tab == CfnDetailTab::Outputs
90 {
91 if app.cfn_state.outputs_input_focus == InputFocus::Filter {
92 app.cfn_state.outputs.filter.pop();
93 app.cfn_state.outputs.selected = 0;
94 }
95 } else if app.cfn_state.current_stack.is_some()
96 && app.cfn_state.detail_tab == CfnDetailTab::Resources
97 {
98 if app.cfn_state.resources_input_focus == InputFocus::Filter {
99 app.cfn_state.resources.filter.pop();
100 app.cfn_state.resources.selected = 0;
101 }
102 } else if app.cfn_state.current_stack.is_some()
103 && app.cfn_state.detail_tab == CfnDetailTab::Events
104 {
105 if app.cfn_state.events_input_focus == InputFocus::Filter {
106 app.cfn_state.events.filter.pop();
107 app.cfn_state.events.selected = 0;
108 }
109 } else if app.cfn_state.current_stack.is_some()
110 && app.cfn_state.detail_tab == CfnDetailTab::ChangeSets
111 {
112 if app.cfn_state.change_sets_input_focus == InputFocus::Filter {
113 app.cfn_state.change_sets.filter.pop();
114 app.cfn_state.change_sets.selected = 0;
115 }
116 } else if app.cfn_state.input_focus == InputFocus::Filter {
117 app.cfn_state.table.filter.pop();
118 app.cfn_state.table.selected = 0;
119 }
120}
121
122pub fn start_filter(app: &mut App) {
123 if app.cfn_state.current_stack.is_some() && app.cfn_state.detail_tab == CfnDetailTab::Parameters
124 {
125 app.cfn_state.parameters_input_focus = InputFocus::Filter;
126 } else if app.cfn_state.current_stack.is_some()
127 && app.cfn_state.detail_tab == CfnDetailTab::Outputs
128 {
129 app.cfn_state.outputs_input_focus = InputFocus::Filter;
130 } else if app.cfn_state.current_stack.is_some()
131 && app.cfn_state.detail_tab == CfnDetailTab::Events
132 {
133 app.cfn_state.events_input_focus = InputFocus::Filter;
134 } else if app.cfn_state.current_stack.is_some()
135 && app.cfn_state.detail_tab == CfnDetailTab::ChangeSets
136 {
137 app.cfn_state.change_sets_input_focus = InputFocus::Filter;
138 } else {
139 app.cfn_state.input_focus = InputFocus::Filter;
140 }
141}
142
143pub fn next_filter_focus(app: &mut App) {
144 if app.cfn_state.current_stack.is_some() && app.cfn_state.detail_tab == CfnDetailTab::Parameters
145 {
146 app.cfn_state.parameters_input_focus = app
147 .cfn_state
148 .parameters_input_focus
149 .next(&CfnStateConstants::PARAMETERS_FILTER_CONTROLS);
150 } else if app.cfn_state.current_stack.is_some()
151 && app.cfn_state.detail_tab == CfnDetailTab::Outputs
152 {
153 app.cfn_state.outputs_input_focus = app
154 .cfn_state
155 .outputs_input_focus
156 .next(&CfnStateConstants::OUTPUTS_FILTER_CONTROLS);
157 } else if app.cfn_state.current_stack.is_some()
158 && app.cfn_state.detail_tab == CfnDetailTab::Resources
159 {
160 app.cfn_state.resources_input_focus = app
161 .cfn_state
162 .resources_input_focus
163 .next(&CfnStateConstants::RESOURCES_FILTER_CONTROLS);
164 } else if app.cfn_state.current_stack.is_some()
165 && app.cfn_state.detail_tab == CfnDetailTab::Events
166 {
167 app.cfn_state.events_input_focus = app
168 .cfn_state
169 .events_input_focus
170 .next(&CfnStateConstants::EVENTS_FILTER_CONTROLS);
171 } else if app.cfn_state.current_stack.is_some()
172 && app.cfn_state.detail_tab == CfnDetailTab::ChangeSets
173 {
174 app.cfn_state.change_sets_input_focus = app
175 .cfn_state
176 .change_sets_input_focus
177 .next(&CfnStateConstants::CHANGE_SETS_FILTER_CONTROLS);
178 } else {
179 app.cfn_state.input_focus = app
180 .cfn_state
181 .input_focus
182 .next(&CfnStateConstants::FILTER_CONTROLS);
183 }
184}
185
186pub fn prev_filter_focus(app: &mut App) {
187 if app.cfn_state.current_stack.is_some() && app.cfn_state.detail_tab == CfnDetailTab::Parameters
188 {
189 app.cfn_state.parameters_input_focus = app
190 .cfn_state
191 .parameters_input_focus
192 .prev(&CfnStateConstants::PARAMETERS_FILTER_CONTROLS);
193 } else if app.cfn_state.current_stack.is_some()
194 && app.cfn_state.detail_tab == CfnDetailTab::Outputs
195 {
196 app.cfn_state.outputs_input_focus = app
197 .cfn_state
198 .outputs_input_focus
199 .prev(&CfnStateConstants::OUTPUTS_FILTER_CONTROLS);
200 } else if app.cfn_state.current_stack.is_some()
201 && app.cfn_state.detail_tab == CfnDetailTab::Resources
202 {
203 app.cfn_state.resources_input_focus = app
204 .cfn_state
205 .resources_input_focus
206 .prev(&CfnStateConstants::RESOURCES_FILTER_CONTROLS);
207 } else if app.cfn_state.current_stack.is_some()
208 && app.cfn_state.detail_tab == CfnDetailTab::Events
209 {
210 app.cfn_state.events_input_focus = app
211 .cfn_state
212 .events_input_focus
213 .prev(&CfnStateConstants::EVENTS_FILTER_CONTROLS);
214 } else if app.cfn_state.current_stack.is_some()
215 && app.cfn_state.detail_tab == CfnDetailTab::ChangeSets
216 {
217 app.cfn_state.change_sets_input_focus = app
218 .cfn_state
219 .change_sets_input_focus
220 .prev(&CfnStateConstants::CHANGE_SETS_FILTER_CONTROLS);
221 } else {
222 app.cfn_state.input_focus = app
223 .cfn_state
224 .input_focus
225 .prev(&CfnStateConstants::FILTER_CONTROLS);
226 }
227}
228
229pub fn toggle_filter_checkbox(app: &mut App) {
230 match app.cfn_state.input_focus {
231 STATUS_FILTER => {
232 app.cfn_state.status_filter = app.cfn_state.status_filter.next();
233 app.cfn_state.table.reset();
234 }
235 VIEW_NESTED => {
236 app.cfn_state.view_nested = !app.cfn_state.view_nested;
237 app.cfn_state.expanded_items.clear();
239 app.cfn_state.table.reset();
241 app.cfn_state.table.loading = true;
242 }
243 _ => {}
244 }
245}
246
247pub fn block_column_selector(app: &App) -> bool {
248 app.cfn_state.current_stack.is_some()
249 && (app.cfn_state.detail_tab == CfnDetailTab::Template
250 || app.cfn_state.detail_tab == CfnDetailTab::GitSync)
251}
252
253pub fn next_item(app: &mut App) {
256 if app.cfn_state.current_stack.is_some() && app.cfn_state.detail_tab == CfnDetailTab::Template {
257 scroll_down_template(app);
258 } else if app.cfn_state.current_stack.is_some()
259 && app.cfn_state.detail_tab == CfnDetailTab::Parameters
260 {
261 let filtered = filtered_parameters(app);
262 app.cfn_state.parameters.next_item(filtered.len());
263 } else if app.cfn_state.current_stack.is_some()
264 && app.cfn_state.detail_tab == CfnDetailTab::Outputs
265 {
266 let filtered = filtered_outputs(app);
267 app.cfn_state.outputs.next_item(filtered.len());
268 } else if app.cfn_state.current_stack.is_some()
269 && app.cfn_state.detail_tab == CfnDetailTab::Resources
270 {
271 let filtered = filtered_resources(app);
272 app.cfn_state.resources.next_item(filtered.len());
273 } else if app.cfn_state.current_stack.is_some()
274 && app.cfn_state.detail_tab == CfnDetailTab::Events
275 {
276 let filtered = filtered_events(app);
277 app.cfn_state.events.next_item(filtered.len());
278 } else if app.cfn_state.current_stack.is_some()
279 && app.cfn_state.detail_tab == CfnDetailTab::ChangeSets
280 {
281 let filtered = filtered_change_sets(app);
282 app.cfn_state.change_sets.next_item(filtered.len());
283 } else {
284 let filtered = filtered_cloudformation_stacks(app);
285 let next_selected =
287 (app.cfn_state.table.selected + 1).min(filtered.len().saturating_sub(1));
288 let extra_rows = if let Some(exp_idx) = app.cfn_state.table.expanded_item {
289 let page_size = app.cfn_state.table.page_size.value();
290 let scroll = app.cfn_state.table.scroll_offset;
291 if exp_idx >= scroll && exp_idx < scroll + page_size && exp_idx < next_selected {
293 app.cfn_visible_column_ids.len()
294 } else {
295 0
296 }
297 } else {
298 0
299 };
300 app.cfn_state
301 .table
302 .next_item_with_expansion(filtered.len(), extra_rows);
303 }
304}
305
306pub fn next_item_filter_input(app: &mut App) {
307 if app.cfn_state.input_focus == STATUS_FILTER {
308 app.cfn_state.status_filter = app.cfn_state.status_filter.next();
309 app.cfn_state.table.reset();
310 }
311}
312
313pub fn prev_item(app: &mut App) {
314 if app.cfn_state.current_stack.is_some() && app.cfn_state.detail_tab == CfnDetailTab::Template {
315 scroll_up_template(app);
316 } else if app.cfn_state.current_stack.is_some()
317 && app.cfn_state.detail_tab == CfnDetailTab::Parameters
318 {
319 app.cfn_state.parameters.prev_item();
320 } else if app.cfn_state.current_stack.is_some()
321 && app.cfn_state.detail_tab == CfnDetailTab::Outputs
322 {
323 app.cfn_state.outputs.prev_item();
324 } else if app.cfn_state.current_stack.is_some()
325 && app.cfn_state.detail_tab == CfnDetailTab::Resources
326 {
327 app.cfn_state.resources.prev_item();
328 } else if app.cfn_state.current_stack.is_some()
329 && app.cfn_state.detail_tab == CfnDetailTab::Events
330 {
331 app.cfn_state.events.prev_item();
332 } else if app.cfn_state.current_stack.is_some()
333 && app.cfn_state.detail_tab == CfnDetailTab::ChangeSets
334 {
335 app.cfn_state.change_sets.prev_item();
336 } else {
337 app.cfn_state.table.prev_item();
338 }
339}
340
341pub fn prev_item_filter_input(app: &mut App) {
342 if app.cfn_state.input_focus == STATUS_FILTER {
343 app.cfn_state.status_filter = app.cfn_state.status_filter.prev();
344 app.cfn_state.table.reset();
345 }
346}
347
348pub fn page_down_filter_input(app: &mut App) {
349 if app.cfn_state.current_stack.is_some() && app.cfn_state.detail_tab == CfnDetailTab::Parameters
350 {
351 let page_size = app.cfn_state.parameters.page_size.value();
352 let filtered_count = filtered_parameters(app).len();
353 app.cfn_state.parameters_input_focus.handle_page_down(
354 &mut app.cfn_state.parameters.selected,
355 &mut app.cfn_state.parameters.scroll_offset,
356 page_size,
357 filtered_count,
358 );
359 } else if app.cfn_state.current_stack.is_some()
360 && app.cfn_state.detail_tab == CfnDetailTab::Outputs
361 {
362 let page_size = app.cfn_state.outputs.page_size.value();
363 let filtered_count = filtered_outputs(app).len();
364 app.cfn_state.outputs_input_focus.handle_page_down(
365 &mut app.cfn_state.outputs.selected,
366 &mut app.cfn_state.outputs.scroll_offset,
367 page_size,
368 filtered_count,
369 );
370 } else if app.cfn_state.current_stack.is_some()
371 && app.cfn_state.detail_tab == CfnDetailTab::Resources
372 {
373 let page_size = app.cfn_state.resources.page_size.value();
374 let filtered_count = filtered_resources(app).len();
375 app.cfn_state.resources_input_focus.handle_page_down(
376 &mut app.cfn_state.resources.selected,
377 &mut app.cfn_state.resources.scroll_offset,
378 page_size,
379 filtered_count,
380 );
381 } else if app.cfn_state.current_stack.is_some()
382 && app.cfn_state.detail_tab == CfnDetailTab::Events
383 {
384 let page_size = app.cfn_state.events.page_size.value();
385 let filtered_count = filtered_events(app).len();
386 app.cfn_state.events_input_focus.handle_page_down(
387 &mut app.cfn_state.events.selected,
388 &mut app.cfn_state.events.scroll_offset,
389 page_size,
390 filtered_count,
391 );
392 } else if app.cfn_state.current_stack.is_some()
393 && app.cfn_state.detail_tab == CfnDetailTab::ChangeSets
394 {
395 let page_size = app.cfn_state.change_sets.page_size.value();
396 let filtered_count = filtered_change_sets(app).len();
397 app.cfn_state.change_sets_input_focus.handle_page_down(
398 &mut app.cfn_state.change_sets.selected,
399 &mut app.cfn_state.change_sets.scroll_offset,
400 page_size,
401 filtered_count,
402 );
403 } else {
404 let page_size = app.cfn_state.table.page_size.value();
405 let filtered_count = filtered_cloudformation_stacks(app).len();
406 app.cfn_state.input_focus.handle_page_down(
407 &mut app.cfn_state.table.selected,
408 &mut app.cfn_state.table.scroll_offset,
409 page_size,
410 filtered_count,
411 );
412 }
413}
414
415pub fn page_down_normal(app: &mut App) {
416 if app.cfn_state.current_stack.is_some() && app.cfn_state.detail_tab == CfnDetailTab::Parameters
417 {
418 let filtered = filtered_parameters(app);
419 app.cfn_state.parameters.page_down(filtered.len());
420 } else if app.cfn_state.current_stack.is_some()
421 && app.cfn_state.detail_tab == CfnDetailTab::Outputs
422 {
423 let filtered = filtered_outputs(app);
424 app.cfn_state.outputs.page_down(filtered.len());
425 } else if app.cfn_state.current_stack.is_some()
426 && app.cfn_state.detail_tab == CfnDetailTab::Resources
427 {
428 let filtered = filtered_resources(app);
429 app.cfn_state.resources.page_down(filtered.len());
430 } else if app.cfn_state.current_stack.is_some()
431 && app.cfn_state.detail_tab == CfnDetailTab::Events
432 {
433 let filtered = filtered_events(app);
434 app.cfn_state.events.page_down(filtered.len());
435 } else if app.cfn_state.current_stack.is_some()
436 && app.cfn_state.detail_tab == CfnDetailTab::ChangeSets
437 {
438 let filtered = filtered_change_sets(app);
439 app.cfn_state.change_sets.page_down(filtered.len());
440 } else {
441 let filtered = filtered_cloudformation_stacks(app);
442 app.cfn_state.table.page_down(filtered.len());
443 }
444}
445
446pub fn page_up_filter_input(app: &mut App) {
447 if app.cfn_state.current_stack.is_some() && app.cfn_state.detail_tab == CfnDetailTab::Parameters
448 {
449 let page_size = app.cfn_state.parameters.page_size.value();
450 app.cfn_state.parameters_input_focus.handle_page_up(
451 &mut app.cfn_state.parameters.selected,
452 &mut app.cfn_state.parameters.scroll_offset,
453 page_size,
454 );
455 } else if app.cfn_state.current_stack.is_some()
456 && app.cfn_state.detail_tab == CfnDetailTab::Outputs
457 {
458 let page_size = app.cfn_state.outputs.page_size.value();
459 app.cfn_state.outputs_input_focus.handle_page_up(
460 &mut app.cfn_state.outputs.selected,
461 &mut app.cfn_state.outputs.scroll_offset,
462 page_size,
463 );
464 } else if app.cfn_state.current_stack.is_some()
465 && app.cfn_state.detail_tab == CfnDetailTab::Resources
466 {
467 let page_size = app.cfn_state.resources.page_size.value();
468 app.cfn_state.resources_input_focus.handle_page_up(
469 &mut app.cfn_state.resources.selected,
470 &mut app.cfn_state.resources.scroll_offset,
471 page_size,
472 );
473 } else if app.cfn_state.current_stack.is_some()
474 && app.cfn_state.detail_tab == CfnDetailTab::Events
475 {
476 let page_size = app.cfn_state.events.page_size.value();
477 app.cfn_state.events_input_focus.handle_page_up(
478 &mut app.cfn_state.events.selected,
479 &mut app.cfn_state.events.scroll_offset,
480 page_size,
481 );
482 } else if app.cfn_state.current_stack.is_some()
483 && app.cfn_state.detail_tab == CfnDetailTab::ChangeSets
484 {
485 let page_size = app.cfn_state.change_sets.page_size.value();
486 app.cfn_state.change_sets_input_focus.handle_page_up(
487 &mut app.cfn_state.change_sets.selected,
488 &mut app.cfn_state.change_sets.scroll_offset,
489 page_size,
490 );
491 } else {
492 let page_size = app.cfn_state.table.page_size.value();
493 app.cfn_state.input_focus.handle_page_up(
494 &mut app.cfn_state.table.selected,
495 &mut app.cfn_state.table.scroll_offset,
496 page_size,
497 );
498 }
499}
500
501pub fn page_up_normal(app: &mut App) {
502 if app.cfn_state.current_stack.is_some() && app.cfn_state.detail_tab == CfnDetailTab::Parameters
503 {
504 app.cfn_state.parameters.page_up();
505 } else if app.cfn_state.current_stack.is_some()
506 && app.cfn_state.detail_tab == CfnDetailTab::Outputs
507 {
508 app.cfn_state.outputs.page_up();
509 } else if app.cfn_state.current_stack.is_some()
510 && app.cfn_state.detail_tab == CfnDetailTab::Resources
511 {
512 app.cfn_state.resources.page_up();
513 } else if app.cfn_state.current_stack.is_some()
514 && app.cfn_state.detail_tab == CfnDetailTab::Events
515 {
516 app.cfn_state.events.page_up();
517 } else if app.cfn_state.current_stack.is_some()
518 && app.cfn_state.detail_tab == CfnDetailTab::ChangeSets
519 {
520 app.cfn_state.change_sets.page_up();
521 } else {
522 app.cfn_state.table.page_up();
523 }
524}
525
526pub fn scroll_up_template(app: &mut App) {
527 app.cfn_state.template_scroll = app.cfn_state.template_scroll.saturating_sub(1);
528}
529
530pub fn scroll_down_template(app: &mut App) {
531 let lines = app.cfn_state.template_body.lines().count();
532 let max_scroll = lines.saturating_sub(1);
533 app.cfn_state.template_scroll = (app.cfn_state.template_scroll + 1).min(max_scroll);
534}
535
536pub fn scroll_up_template_fast(app: &mut App) {
537 app.cfn_state.template_scroll = app.cfn_state.template_scroll.saturating_sub(10);
538}
539
540pub fn scroll_down_template_fast(app: &mut App) {
541 let lines = app.cfn_state.template_body.lines().count();
542 let max_scroll = lines.saturating_sub(1);
543 app.cfn_state.template_scroll = (app.cfn_state.template_scroll + 10).min(max_scroll);
544}
545
546pub fn expand_row(app: &mut App) {
547 if app.cfn_state.current_stack.is_none() {
548 app.cfn_state.table.toggle_expand();
549 if app.cfn_state.table.expanded_item.is_some() {
551 let detail_rows = app.cfn_visible_column_ids.len();
552 let page_size = app.cfn_state.table.page_size.value();
553 app.cfn_state
554 .table
555 .ensure_expansion_visible(detail_rows, page_size);
556 }
557 } else if app.cfn_state.detail_tab == CfnDetailTab::Parameters {
558 app.cfn_state.parameters.toggle_expand();
559 } else if app.cfn_state.detail_tab == CfnDetailTab::Outputs {
560 app.cfn_state.outputs.toggle_expand();
561 } else if app.cfn_state.detail_tab == CfnDetailTab::Resources {
562 app.cfn_state.resources.toggle_expand();
563 } else if app.cfn_state.detail_tab == CfnDetailTab::Events {
564 app.cfn_state.events.toggle_expand();
565 } else if app.cfn_state.detail_tab == CfnDetailTab::ChangeSets {
566 app.cfn_state.change_sets.toggle_expand();
567 }
568}
569
570pub fn prev_pane(app: &mut App) {
571 if app.cfn_state.current_stack.is_none() {
572 app.cfn_state.table.collapse();
573 } else if app.cfn_state.detail_tab == CfnDetailTab::Parameters {
574 app.cfn_state.parameters.collapse();
575 } else if app.cfn_state.detail_tab == CfnDetailTab::Outputs {
576 app.cfn_state.outputs.collapse();
577 } else if app.cfn_state.detail_tab == CfnDetailTab::Resources {
578 app.cfn_state.resources.collapse();
579 } else if app.cfn_state.detail_tab == CfnDetailTab::Events {
580 app.cfn_state.events.collapse();
581 } else if app.cfn_state.detail_tab == CfnDetailTab::ChangeSets {
582 app.cfn_state.change_sets.collapse();
583 }
584}
585
586pub fn collapse_row(app: &mut App) {
587 if app.cfn_state.current_stack.is_some() {
588 match app.cfn_state.detail_tab {
589 CfnDetailTab::Resources => app.cfn_state.resources.collapse(),
590 CfnDetailTab::Parameters => app.cfn_state.parameters.collapse(),
591 CfnDetailTab::Outputs => app.cfn_state.outputs.collapse(),
592 CfnDetailTab::Events => app.cfn_state.events.collapse(),
593 CfnDetailTab::ChangeSets => app.cfn_state.change_sets.collapse(),
594 _ => {}
595 }
596 } else {
597 app.cfn_state.table.collapse();
598 }
599}
600
601pub fn go_to_page(app: &mut App, page: usize) {
602 let filtered_count = filtered_cloudformation_stacks(app).len();
603 app.cfn_state.table.goto_page(page, filtered_count);
604}
605
606pub fn select_item(app: &mut App) {
609 if app.cfn_state.current_stack.is_none() {
610 let filtered = filtered_cloudformation_stacks(app);
611 if let Some(stack) = app.cfn_state.table.get_selected(&filtered) {
612 let stack_name = stack.name.clone();
613 let mut tags = stack.tags.clone();
614 tags.sort_by(|a, b| a.0.cmp(&b.0));
615 app.cfn_state.current_stack = Some(stack_name);
616 app.cfn_state.tags.items = tags;
617 app.cfn_state.tags.reset();
618 app.cfn_state.table.loading = true;
619 app.update_current_tab_breadcrumb();
620 }
621 }
622}
623
624pub fn go_back(app: &mut App) {
625 app.cfn_state.current_stack = None;
626 app.update_current_tab_breadcrumb();
627}
628
629pub fn next_detail_tab(app: &mut App) {
630 app.cfn_state.detail_tab = app.cfn_state.detail_tab.next();
631}
632
633pub fn prev_detail_tab(app: &mut App) {
634 app.cfn_state.detail_tab = app.cfn_state.detail_tab.prev();
635}
636
637pub fn toggle_events_view(app: &mut App) {
639 app.cfn_state.events_view = match app.cfn_state.events_view {
640 CfnEventsView::Table => CfnEventsView::Timeline,
641 CfnEventsView::Timeline => CfnEventsView::Table,
642 };
643}
644
645pub fn yank(app: &App) {
646 use crate::app::copy_to_clipboard;
647 if let Some(stack_name) = &app.cfn_state.current_stack {
648 if app.cfn_state.detail_tab == CfnDetailTab::Template {
650 if !app.cfn_state.template_body.is_empty() {
651 copy_to_clipboard(&app.cfn_state.template_body);
652 }
653 return;
654 }
655 if let Some(stack) = app
656 .cfn_state
657 .table
658 .items
659 .iter()
660 .find(|s| &s.name == stack_name)
661 {
662 copy_to_clipboard(&stack.stack_id);
663 }
664 } else {
665 let filtered = filtered_cloudformation_stacks(app);
666 if let Some(stack) = app.cfn_state.table.get_selected(&filtered) {
667 copy_to_clipboard(&stack.stack_id);
668 }
669 }
670}
671
672pub fn toggle_column(app: &mut App) {
675 let idx = app.column_selector_index;
676 if app.cfn_state.current_stack.is_some() && app.cfn_state.detail_tab == CfnDetailTab::StackInfo
677 {
678 if idx == 4 {
680 app.cfn_state.tags.page_size = PageSize::Ten;
681 } else if idx == 5 {
682 app.cfn_state.tags.page_size = PageSize::TwentyFive;
683 } else if idx == 6 {
684 app.cfn_state.tags.page_size = PageSize::Fifty;
685 } else if idx == 7 {
686 app.cfn_state.tags.page_size = PageSize::OneHundred;
687 }
688 } else if app.cfn_state.current_stack.is_some()
689 && app.cfn_state.detail_tab == CfnDetailTab::Parameters
690 {
691 if idx > 0 && idx <= app.cfn_parameter_column_ids.len() {
692 if let Some(col) = app.cfn_parameter_column_ids.get(idx - 1) {
693 if let Some(pos) = app
694 .cfn_parameter_visible_column_ids
695 .iter()
696 .position(|c| c == col)
697 {
698 if app.cfn_parameter_visible_column_ids.len() > 1 {
699 app.cfn_parameter_visible_column_ids.remove(pos);
700 }
701 } else {
702 app.cfn_parameter_visible_column_ids.push(col);
703 }
704 }
705 } else if idx == app.cfn_parameter_column_ids.len() + 3 {
706 app.cfn_state.parameters.page_size = PageSize::Ten;
707 } else if idx == app.cfn_parameter_column_ids.len() + 4 {
708 app.cfn_state.parameters.page_size = PageSize::TwentyFive;
709 } else if idx == app.cfn_parameter_column_ids.len() + 5 {
710 app.cfn_state.parameters.page_size = PageSize::Fifty;
711 } else if idx == app.cfn_parameter_column_ids.len() + 6 {
712 app.cfn_state.parameters.page_size = PageSize::OneHundred;
713 }
714 } else if app.cfn_state.current_stack.is_some()
715 && app.cfn_state.detail_tab == CfnDetailTab::Outputs
716 {
717 if idx > 0 && idx <= app.cfn_output_column_ids.len() {
718 if let Some(col) = app.cfn_output_column_ids.get(idx - 1) {
719 if let Some(pos) = app
720 .cfn_output_visible_column_ids
721 .iter()
722 .position(|c| c == col)
723 {
724 if app.cfn_output_visible_column_ids.len() > 1 {
725 app.cfn_output_visible_column_ids.remove(pos);
726 }
727 } else {
728 app.cfn_output_visible_column_ids.push(col);
729 }
730 }
731 } else if idx == app.cfn_output_column_ids.len() + 3 {
732 app.cfn_state.outputs.page_size = PageSize::Ten;
733 } else if idx == app.cfn_output_column_ids.len() + 4 {
734 app.cfn_state.outputs.page_size = PageSize::TwentyFive;
735 } else if idx == app.cfn_output_column_ids.len() + 5 {
736 app.cfn_state.outputs.page_size = PageSize::Fifty;
737 } else if idx == app.cfn_output_column_ids.len() + 6 {
738 app.cfn_state.outputs.page_size = PageSize::OneHundred;
739 }
740 } else if app.cfn_state.current_stack.is_some()
741 && app.cfn_state.detail_tab == CfnDetailTab::Resources
742 {
743 if idx > 0 && idx <= app.cfn_resource_column_ids.len() {
744 if let Some(col) = app.cfn_resource_column_ids.get(idx - 1) {
745 if let Some(pos) = app
746 .cfn_resource_visible_column_ids
747 .iter()
748 .position(|c| c == col)
749 {
750 if app.cfn_resource_visible_column_ids.len() > 1 {
751 app.cfn_resource_visible_column_ids.remove(pos);
752 }
753 } else {
754 app.cfn_resource_visible_column_ids.push(col);
755 }
756 }
757 } else if idx == app.cfn_resource_column_ids.len() + 3 {
758 app.cfn_state.resources.page_size = PageSize::Ten;
759 } else if idx == app.cfn_resource_column_ids.len() + 4 {
760 app.cfn_state.resources.page_size = PageSize::TwentyFive;
761 } else if idx == app.cfn_resource_column_ids.len() + 5 {
762 app.cfn_state.resources.page_size = PageSize::Fifty;
763 } else if idx == app.cfn_resource_column_ids.len() + 6 {
764 app.cfn_state.resources.page_size = PageSize::OneHundred;
765 }
766 } else if app.cfn_state.current_stack.is_some()
767 && app.cfn_state.detail_tab == CfnDetailTab::Events
768 {
769 if idx > 0 && idx <= app.cfn_event_column_ids.len() {
770 if let Some(col) = app.cfn_event_column_ids.get(idx - 1) {
771 if let Some(pos) = app
772 .cfn_event_visible_column_ids
773 .iter()
774 .position(|c| c == col)
775 {
776 if app.cfn_event_visible_column_ids.len() > 1 {
777 app.cfn_event_visible_column_ids.remove(pos);
778 }
779 } else {
780 app.cfn_event_visible_column_ids.push(col);
781 }
782 }
783 } else if idx == app.cfn_event_column_ids.len() + 3 {
784 app.cfn_state.events.page_size = PageSize::Ten;
785 } else if idx == app.cfn_event_column_ids.len() + 4 {
786 app.cfn_state.events.page_size = PageSize::TwentyFive;
787 } else if idx == app.cfn_event_column_ids.len() + 5 {
788 app.cfn_state.events.page_size = PageSize::Fifty;
789 } else if idx == app.cfn_event_column_ids.len() + 6 {
790 app.cfn_state.events.page_size = PageSize::OneHundred;
791 }
792 } else if app.cfn_state.current_stack.is_some()
793 && app.cfn_state.detail_tab == CfnDetailTab::ChangeSets
794 {
795 if idx > 0 && idx <= app.cfn_change_set_column_ids.len() {
796 if let Some(col) = app.cfn_change_set_column_ids.get(idx - 1) {
797 if let Some(pos) = app
798 .cfn_change_set_visible_column_ids
799 .iter()
800 .position(|c| c == col)
801 {
802 if app.cfn_change_set_visible_column_ids.len() > 1 {
803 app.cfn_change_set_visible_column_ids.remove(pos);
804 }
805 } else {
806 app.cfn_change_set_visible_column_ids.push(col);
807 }
808 }
809 } else if idx == app.cfn_change_set_column_ids.len() + 3 {
810 app.cfn_state.change_sets.page_size = PageSize::Ten;
811 } else if idx == app.cfn_change_set_column_ids.len() + 4 {
812 app.cfn_state.change_sets.page_size = PageSize::TwentyFive;
813 } else if idx == app.cfn_change_set_column_ids.len() + 5 {
814 app.cfn_state.change_sets.page_size = PageSize::Fifty;
815 } else if idx == app.cfn_change_set_column_ids.len() + 6 {
816 app.cfn_state.change_sets.page_size = PageSize::OneHundred;
817 }
818 } else if app.cfn_state.current_stack.is_none() {
819 if idx > 0 && idx <= app.cfn_column_ids.len() {
820 if let Some(col) = app.cfn_column_ids.get(idx - 1) {
821 if let Some(pos) = app.cfn_visible_column_ids.iter().position(|c| c == col) {
822 if app.cfn_visible_column_ids.len() > 1 {
823 app.cfn_visible_column_ids.remove(pos);
824 }
825 } else {
826 app.cfn_visible_column_ids.push(*col);
827 }
828 }
829 } else if idx == app.cfn_column_ids.len() + 3 {
830 app.cfn_state.table.page_size = PageSize::Ten;
831 } else if idx == app.cfn_column_ids.len() + 4 {
832 app.cfn_state.table.page_size = PageSize::TwentyFive;
833 } else if idx == app.cfn_column_ids.len() + 5 {
834 app.cfn_state.table.page_size = PageSize::Fifty;
835 } else if idx == app.cfn_column_ids.len() + 6 {
836 app.cfn_state.table.page_size = PageSize::OneHundred;
837 }
838 }
839}
840
841pub fn next_preferences(app: &mut App) {
842 let cols = column_count(app);
843 let page_size_idx = cols + 2;
844 if app.column_selector_index < page_size_idx {
845 app.column_selector_index = page_size_idx;
846 } else {
847 app.column_selector_index = 0;
848 }
849}
850
851pub fn prev_preferences(app: &mut App) {
852 let cols = column_count(app);
853 let page_size_idx = cols + 2;
854 if app.column_selector_index >= page_size_idx {
855 app.column_selector_index = 0;
856 } else {
857 app.column_selector_index = page_size_idx;
858 }
859}
860
861pub fn column_selector_max(app: &App) -> usize {
862 column_count(app) + 6
863}
864
865pub fn column_count(app: &App) -> usize {
866 if app.cfn_state.current_stack.is_some() {
867 match app.cfn_state.detail_tab {
868 CfnDetailTab::Parameters => app.cfn_parameter_column_ids.len(),
869 CfnDetailTab::Outputs => app.cfn_output_column_ids.len(),
870 CfnDetailTab::Resources => app.cfn_resource_column_ids.len(),
871 CfnDetailTab::Events => app.cfn_event_column_ids.len(),
872 CfnDetailTab::ChangeSets => app.cfn_change_set_column_ids.len(),
873 _ => 0,
874 }
875 } else {
876 app.cfn_column_ids.len()
877 }
878}
879
880pub fn breadcrumb(app: &App) -> Vec<String> {
883 let mut parts = vec!["CloudFormation".to_string()];
884 if let Some(stack_name) = &app.cfn_state.current_stack {
885 parts.push(stack_name.clone());
886 } else {
887 parts.push("Stacks".to_string());
888 }
889 parts
890}
891
892pub fn console_url(app: &App) -> String {
893 use crate::cfn;
894 if let Some(stack_name) = &app.cfn_state.current_stack {
895 if let Some(stack) = app
896 .cfn_state
897 .table
898 .items
899 .iter()
900 .find(|s| &s.name == stack_name)
901 {
902 return cfn::console_url_stack_detail_with_tab(
903 &app.config.region,
904 &stack.stack_id,
905 &app.cfn_state.detail_tab,
906 );
907 }
908 }
909 cfn::console_url_stacks(&app.config.region)
910}