rusticity_term/
inventory.rs1use crate::clipboard::ClipboardState;
4use crate::common::InputFocus;
5use crate::keymap::{Action, Mode};
6use crate::table::TableState;
7
8const FILTER_CONTROLS: [InputFocus; 2] = [InputFocus::Filter, InputFocus::Pagination];
9
10pub struct InventoryInput<'a, T> {
11 pub table: &'a mut TableState<T>,
12 pub focus: &'a mut InputFocus,
13 pub mode: &'a mut Mode,
14 pub page_input: &'a mut String,
15 pub error_message: &'a mut Option<String>,
16 pub error_scroll: &'a mut usize,
17 pub filtered_count: usize,
18 pub selected_arn: Option<String>,
19 pub clipboard: &'a ClipboardState,
20}
21
22pub fn go_to_page<T>(table: &mut TableState<T>, page: usize, count: usize) {
23 if page == 0 {
24 return;
25 }
26 let pages = table.total_pages(count).max(1);
27 table.goto_page(page.min(pages), count);
28 table.collapse();
29}
30
31pub fn handle_action<T>(input: InventoryInput<'_, T>, action: &Action) -> bool {
32 let InventoryInput {
33 table,
34 focus,
35 mode,
36 page_input,
37 error_message,
38 error_scroll,
39 filtered_count,
40 selected_arn,
41 clipboard,
42 } = input;
43 if *mode == Mode::ErrorModal && *action == Action::RetryLoad {
44 *error_message = None;
45 *error_scroll = 0;
46 *mode = Mode::Normal;
47 table.loading = true;
48 return true;
49 }
50 if *mode == Mode::Normal {
51 match action {
52 Action::NextItem => table.next_item(filtered_count),
53 Action::PrevItem => table.prev_item(),
54 Action::PageDown | Action::ScrollDown => {
55 table.page_down(filtered_count);
56 table.collapse();
57 }
58 Action::PageUp | Action::ScrollUp => {
59 table.page_up();
60 table.collapse();
61 }
62 Action::Select | Action::ExpandRow | Action::NextPane => {
63 if table.selected < filtered_count {
64 table.toggle_expand();
65 }
66 }
67 Action::CollapseRow | Action::PrevPane | Action::GoBack => table.collapse(),
68 Action::StartFilter => {
69 *mode = Mode::FilterInput;
70 *focus = InputFocus::Filter;
71 }
72 Action::Refresh => table.loading = true,
73 Action::Yank => {
74 if let Some(arn) = selected_arn {
75 clipboard.request_text(arn);
76 }
77 }
78 Action::NextDetailTab
80 | Action::PrevDetailTab
81 | Action::CycleSortColumn
82 | Action::ToggleSortDirection
83 | Action::ToggleExactMatch
84 | Action::ToggleShowExpired => {}
85 _ => return false,
86 }
87 return true;
88 }
89 if *mode == Mode::FilterInput {
90 match action {
91 Action::NextFilterFocus => *focus = focus.next(&FILTER_CONTROLS),
92 Action::PrevFilterFocus => *focus = focus.prev(&FILTER_CONTROLS),
93 Action::PageDown | Action::PageUp => {
94 if *focus == InputFocus::Pagination {
95 if *action == Action::PageDown {
96 focus.handle_page_down(
97 &mut table.selected,
98 &mut table.scroll_offset,
99 table.page_size.value(),
100 filtered_count,
101 );
102 } else {
103 focus.handle_page_up(
104 &mut table.selected,
105 &mut table.scroll_offset,
106 table.page_size.value(),
107 );
108 }
109 table.collapse();
110 }
111 }
112 Action::NextItem | Action::PrevItem => {}
113 Action::FilterInput(c) if *focus == InputFocus::Filter => table.filter_push(*c),
114 Action::FilterBackspace if *focus == InputFocus::Filter => table.filter_pop(),
115 Action::ToggleFilterCheckbox if *focus == InputFocus::Filter => table.filter_push(' '),
116 Action::FilterInput(c) if c.is_ascii_digit() => page_input.push(*c),
117 Action::FilterBackspace => {
118 page_input.pop();
119 }
120 Action::FilterInput(_) | Action::ToggleFilterCheckbox => {}
121 Action::ApplyFilter => {
122 if let Ok(page) = page_input.parse() {
123 go_to_page(table, page, filtered_count);
124 }
125 page_input.clear();
126 *mode = Mode::Normal;
127 }
128 Action::CloseMenu => *mode = Mode::Normal,
129 _ => return false,
130 }
131 return true;
132 }
133 false
134}