Skip to main content

rusticity_term/kms/
actions.rs

1use crate::app::App;
2use crate::common::{CyclicEnum, InputFocus, PageSize};
3use crate::ui::kms::{filtered_kms_keys, FILTER_CONTROLS};
4
5// ── Navigation ────────────────────────────────────────────────────────────────
6
7pub fn next_item(app: &mut App) {
8    let filtered = filtered_kms_keys(app);
9    if !filtered.is_empty() {
10        app.kms_state.keys.next_item(filtered.len());
11    }
12}
13
14pub fn prev_item(app: &mut App) {
15    app.kms_state.keys.prev_item();
16}
17
18pub fn page_down_filter_input(app: &mut App) {
19    if app.kms_state.input_focus == InputFocus::Filter {
20        let filtered = filtered_kms_keys(app);
21        app.kms_state.keys.page_down(filtered.len());
22    } else {
23        let page_size = app.kms_state.keys.page_size.value();
24        let filtered_count = filtered_kms_keys(app).len();
25        app.kms_state.input_focus.handle_page_down(
26            &mut app.kms_state.keys.selected,
27            &mut app.kms_state.keys.scroll_offset,
28            page_size,
29            filtered_count,
30        );
31    }
32}
33
34pub fn page_down_normal(app: &mut App) {
35    let filtered = filtered_kms_keys(app);
36    app.kms_state.keys.page_down(filtered.len());
37}
38
39pub fn page_up_filter_input(app: &mut App) {
40    if app.kms_state.input_focus == InputFocus::Filter {
41        app.kms_state.keys.page_up();
42    } else {
43        let page_size = app.kms_state.keys.page_size.value();
44        app.kms_state.input_focus.handle_page_up(
45            &mut app.kms_state.keys.selected,
46            &mut app.kms_state.keys.scroll_offset,
47            page_size,
48        );
49    }
50}
51
52pub fn page_up_normal(app: &mut App) {
53    app.kms_state.keys.page_up();
54}
55
56pub fn expand_row(app: &mut App) {
57    app.kms_state.keys.toggle_expand();
58}
59
60pub fn prev_pane(app: &mut App) {
61    app.kms_state.keys.collapse();
62}
63
64pub fn collapse_row(app: &mut App) {
65    app.kms_state.keys.collapse();
66}
67
68pub fn go_to_page(app: &mut App, page: usize) {
69    let filtered_count = filtered_kms_keys(app).len();
70    app.kms_state.keys.goto_page(page, filtered_count);
71}
72
73// ── Filter ────────────────────────────────────────────────────────────────────
74
75pub fn get_active_filter_mut(app: &mut App) -> Option<&mut String> {
76    Some(&mut app.kms_state.keys.filter)
77}
78
79pub fn apply_filter_reset(app: &mut App) {
80    app.kms_state.keys.reset();
81}
82
83pub fn start_filter(app: &mut App) {
84    app.kms_state.input_focus = InputFocus::Filter;
85}
86
87pub fn next_filter_focus(app: &mut App) {
88    app.kms_state.input_focus = app.kms_state.input_focus.next(&FILTER_CONTROLS);
89}
90
91pub fn prev_filter_focus(app: &mut App) {
92    app.kms_state.input_focus = app.kms_state.input_focus.prev(&FILTER_CONTROLS);
93}
94
95pub fn is_pagination_focused(app: &App) -> bool {
96    app.kms_state.input_focus == InputFocus::Pagination
97}
98
99// ── Tab ───────────────────────────────────────────────────────────────────────
100
101pub fn next_detail_tab(app: &mut App) {
102    app.kms_state.tab = app.kms_state.tab.next();
103    app.kms_state.keys.reset();
104    // No reload needed — both tabs read from the same keys.items, filtered client-side
105}
106
107pub fn prev_detail_tab(app: &mut App) {
108    app.kms_state.tab = app.kms_state.tab.prev();
109    app.kms_state.keys.reset();
110    // No reload needed — both tabs read from the same keys.items, filtered client-side
111}
112
113// ── Yank / console URL / breadcrumb ──────────────────────────────────────────
114
115pub fn yank(app: &App) {
116    use crate::app::copy_to_clipboard;
117    let filtered = filtered_kms_keys(app);
118    if let Some(key) = app.kms_state.keys.get_selected(&filtered) {
119        copy_to_clipboard(&key.key_arn);
120    }
121}
122
123pub fn breadcrumb(_app: &App) -> Vec<String> {
124    // Keep stable — the tab switcher inside the view shows the sub-tab name.
125    // Using the sub-tab name here would cause the session tab title to
126    // change on every tab switch, making it disappear/reappear.
127    vec!["KMS".to_string(), "Managed Keys".to_string()]
128}
129
130pub fn console_url(app: &App) -> String {
131    use crate::kms;
132    use crate::ui::kms::Tab;
133    let filtered = filtered_kms_keys(app);
134    if let Some(key) = app.kms_state.keys.get_selected(&filtered) {
135        kms::console_url_key(&app.config.region, &key.key_id)
136    } else {
137        match app.kms_state.tab {
138            Tab::AwsManaged => kms::console_url_aws_managed_keys(&app.config.region),
139            Tab::CustomerManaged => kms::console_url_keys(&app.config.region),
140        }
141    }
142}
143
144// ── Column preferences ────────────────────────────────────────────────────────
145
146pub fn toggle_column(app: &mut App) {
147    let idx = app.column_selector_index;
148    let tab_cols = app.kms_state.tab_column_ids();
149    // idx 0 = Alias (locked, always visible — skip)
150    // idx 1..N = columns (1-based into tab's column list, col at tab_cols[idx-1])
151    // idx N+2 = PageSize section header
152    // idx N+3..N+6 = Ten, TwentyFive, Fifty, OneHundred
153    if idx > 0 && idx <= tab_cols.len() {
154        if let Some(col_id) = tab_cols.get(idx - 1) {
155            // Alias is always visible — don't allow toggling it off
156            if *col_id == crate::kms::key::Column::Alias.id() {
157                return;
158            }
159            let visible = app.kms_state.visible_column_ids_mut();
160            if let Some(pos) = visible.iter().position(|c| c == col_id) {
161                if visible.len() > 1 {
162                    visible.remove(pos);
163                }
164            } else {
165                visible.push(col_id);
166            }
167        }
168    } else {
169        let n = tab_cols.len();
170        if idx == n + 3 {
171            app.kms_state.keys.page_size = PageSize::Ten;
172        } else if idx == n + 4 {
173            app.kms_state.keys.page_size = PageSize::TwentyFive;
174        } else if idx == n + 5 {
175            app.kms_state.keys.page_size = PageSize::Fifty;
176        } else if idx == n + 6 {
177            app.kms_state.keys.page_size = PageSize::OneHundred;
178        }
179    }
180}
181
182pub fn next_preferences(app: &mut App) {
183    let n = app.kms_state.tab_column_ids().len();
184    let page_size_idx = n + 2;
185    if app.column_selector_index < page_size_idx {
186        app.column_selector_index = page_size_idx;
187    } else {
188        app.column_selector_index = 0;
189    }
190}
191
192pub fn prev_preferences(app: &mut App) {
193    let n = app.kms_state.tab_column_ids().len();
194    let page_size_idx = n + 2;
195    if app.column_selector_index >= page_size_idx {
196        app.column_selector_index = 0;
197    } else {
198        app.column_selector_index = page_size_idx;
199    }
200}
201
202pub fn column_selector_max(app: &App) -> usize {
203    app.kms_state.tab_column_ids().len() + 6
204}
205
206pub fn column_count(app: &App) -> usize {
207    app.kms_state.tab_column_ids().len()
208}