datui_lib/widgets/
template_modal.rs1use crate::template::{BrokenTemplate, Template};
2use crate::widgets::multiline_text_input::MultiLineTextInput;
3use crate::widgets::text_input::TextInput;
4use ratatui::widgets::TableState;
5
6#[derive(Debug, Default, PartialEq, Eq, Clone, Copy)]
7pub enum TemplateModalMode {
8 #[default]
9 List,
10 Create,
11 Edit,
12}
13
14#[derive(Debug, Default, PartialEq, Eq, Clone, Copy)]
15pub enum TemplateFocus {
16 #[default]
17 TemplateList,
18 CreateButton,
19 EditButton,
20 DeleteButton,
21 HelpButton,
22 SaveButton,
23 CancelButton,
24}
25
26#[derive(Debug, Default, PartialEq, Eq, Clone, Copy)]
27pub enum CreateFocus {
28 #[default]
29 Name,
30 Description,
31 ExactPath,
32 RelativePath,
33 PathPattern,
34 FilenamePattern,
35 SchemaMatch,
36 SaveButton,
37 CancelButton,
38}
39
40#[derive(Default)]
41pub struct TemplateModal {
42 pub active: bool,
43 pub mode: TemplateModalMode,
44 pub focus: TemplateFocus,
45 pub create_focus: CreateFocus,
46 pub table_state: TableState,
47 pub templates: Vec<(Template, f64)>, pub broken_templates: Vec<BrokenTemplate>, pub create_name_input: TextInput,
51 pub create_description_input: MultiLineTextInput,
52 pub create_exact_path_input: TextInput,
53 pub create_relative_path_input: TextInput,
54 pub create_path_pattern_input: TextInput,
55 pub create_filename_pattern_input: TextInput,
56 pub create_schema_match_enabled: bool,
57 pub editing_template_id: Option<String>, pub show_help: bool, pub delete_confirm: bool, pub delete_confirm_focus: bool, pub name_error: Option<String>, pub history_limit: usize,
63 pub show_score_details: bool, }
65
66impl TemplateModal {
67 pub fn new() -> Self {
68 Self::default()
69 }
70
71 pub fn selected_template(&self) -> Option<&Template> {
72 self.table_state
73 .selected()
74 .and_then(|i| self.templates.get(i))
75 .map(|(template, _)| template)
76 }
77
78 pub fn next_focus(&mut self) {
79 if self.mode == TemplateModalMode::List {
80 } else {
83 self.create_focus = match self.create_focus {
85 CreateFocus::Name => CreateFocus::Description,
86 CreateFocus::Description => CreateFocus::ExactPath,
87 CreateFocus::ExactPath => CreateFocus::RelativePath,
88 CreateFocus::RelativePath => CreateFocus::PathPattern,
89 CreateFocus::PathPattern => CreateFocus::FilenamePattern,
90 CreateFocus::FilenamePattern => CreateFocus::SchemaMatch,
91 CreateFocus::SchemaMatch => CreateFocus::SaveButton,
92 CreateFocus::SaveButton => CreateFocus::CancelButton,
93 CreateFocus::CancelButton => CreateFocus::Name,
94 };
95 }
96 }
97
98 pub fn prev_focus(&mut self) {
99 if self.mode == TemplateModalMode::List {
100 } else {
103 self.create_focus = match self.create_focus {
105 CreateFocus::Name => CreateFocus::CancelButton,
106 CreateFocus::Description => CreateFocus::Name,
107 CreateFocus::ExactPath => CreateFocus::Description,
108 CreateFocus::RelativePath => CreateFocus::ExactPath,
109 CreateFocus::PathPattern => CreateFocus::RelativePath,
110 CreateFocus::FilenamePattern => CreateFocus::PathPattern,
111 CreateFocus::SchemaMatch => CreateFocus::FilenamePattern,
112 CreateFocus::SaveButton => CreateFocus::SchemaMatch,
113 CreateFocus::CancelButton => CreateFocus::SaveButton,
114 };
115 }
116 }
117
118 pub fn enter_create_mode(&mut self, history_limit: usize, theme: &crate::config::Theme) {
119 self.mode = TemplateModalMode::Create;
120 self.create_focus = CreateFocus::Name;
121 self.editing_template_id = None;
122 self.name_error = None;
123 self.history_limit = history_limit;
124 self.create_name_input = TextInput::new()
126 .with_history_limit(history_limit)
127 .with_theme(theme);
128 self.create_description_input = MultiLineTextInput::new()
129 .with_history_limit(history_limit)
130 .with_theme(theme);
131 self.create_exact_path_input = TextInput::new()
132 .with_history_limit(history_limit)
133 .with_theme(theme);
134 self.create_relative_path_input = TextInput::new()
135 .with_history_limit(history_limit)
136 .with_theme(theme);
137 self.create_path_pattern_input = TextInput::new()
138 .with_history_limit(history_limit)
139 .with_theme(theme);
140 self.create_filename_pattern_input = TextInput::new()
141 .with_history_limit(history_limit)
142 .with_theme(theme);
143 self.create_name_input.clear();
145 self.create_description_input.clear();
146 self.create_exact_path_input.clear();
147 self.create_relative_path_input.clear();
148 self.create_path_pattern_input.clear();
149 self.create_filename_pattern_input.clear();
150 self.create_schema_match_enabled = false;
151 }
152
153 pub fn enter_edit_mode(
154 &mut self,
155 template: &Template,
156 history_limit: usize,
157 theme: &crate::config::Theme,
158 ) {
159 self.mode = TemplateModalMode::Edit;
160 self.create_focus = CreateFocus::Name;
161 self.editing_template_id = Some(template.id.clone());
162 self.history_limit = history_limit;
163 self.create_name_input = TextInput::new()
165 .with_history_limit(history_limit)
166 .with_theme(theme);
167 self.create_description_input = MultiLineTextInput::new()
168 .with_history_limit(history_limit)
169 .with_theme(theme);
170 self.create_exact_path_input = TextInput::new()
171 .with_history_limit(history_limit)
172 .with_theme(theme);
173 self.create_relative_path_input = TextInput::new()
174 .with_history_limit(history_limit)
175 .with_theme(theme);
176 self.create_path_pattern_input = TextInput::new()
177 .with_history_limit(history_limit)
178 .with_theme(theme);
179 self.create_filename_pattern_input = TextInput::new()
180 .with_history_limit(history_limit)
181 .with_theme(theme);
182 self.create_name_input.value = template.name.clone();
184 self.create_name_input.cursor = self.create_name_input.value.chars().count();
185 self.create_description_input.value = template.description.clone().unwrap_or_default();
186 self.create_description_input.cursor = self.create_description_input.value.chars().count();
187 self.create_description_input.update_line_col_from_cursor();
188 self.create_exact_path_input.value = template
189 .match_criteria
190 .exact_path
191 .as_ref()
192 .map(|p| p.to_string_lossy().to_string())
193 .unwrap_or_default();
194 self.create_exact_path_input.cursor = self.create_exact_path_input.value.chars().count();
195 self.create_relative_path_input.value = template
196 .match_criteria
197 .relative_path
198 .clone()
199 .unwrap_or_default();
200 self.create_relative_path_input.cursor =
201 self.create_relative_path_input.value.chars().count();
202 self.create_path_pattern_input.value = template
203 .match_criteria
204 .path_pattern
205 .clone()
206 .unwrap_or_default();
207 self.create_path_pattern_input.cursor =
208 self.create_path_pattern_input.value.chars().count();
209 self.create_filename_pattern_input.value = template
210 .match_criteria
211 .filename_pattern
212 .clone()
213 .unwrap_or_default();
214 self.create_filename_pattern_input.cursor =
215 self.create_filename_pattern_input.value.chars().count();
216 self.create_schema_match_enabled = template.match_criteria.schema_columns.is_some();
217 }
218
219 pub fn exit_create_mode(&mut self) {
220 self.mode = TemplateModalMode::List;
221 self.focus = TemplateFocus::TemplateList;
222 self.editing_template_id = None;
223 }
224}