datui_lib/widgets/
template_modal.rs1use crate::template::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 create_name_input: TextInput,
50 pub create_description_input: MultiLineTextInput,
51 pub create_exact_path_input: TextInput,
52 pub create_relative_path_input: TextInput,
53 pub create_path_pattern_input: TextInput,
54 pub create_filename_pattern_input: TextInput,
55 pub create_schema_match_enabled: bool,
56 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,
62 pub show_score_details: bool, }
64
65impl TemplateModal {
66 pub fn new() -> Self {
67 Self::default()
68 }
69
70 pub fn selected_template(&self) -> Option<&Template> {
71 self.table_state
72 .selected()
73 .and_then(|i| self.templates.get(i))
74 .map(|(template, _)| template)
75 }
76
77 pub fn next_focus(&mut self) {
78 if self.mode == TemplateModalMode::List {
79 } else {
82 self.create_focus = match self.create_focus {
84 CreateFocus::Name => CreateFocus::Description,
85 CreateFocus::Description => CreateFocus::ExactPath,
86 CreateFocus::ExactPath => CreateFocus::RelativePath,
87 CreateFocus::RelativePath => CreateFocus::PathPattern,
88 CreateFocus::PathPattern => CreateFocus::FilenamePattern,
89 CreateFocus::FilenamePattern => CreateFocus::SchemaMatch,
90 CreateFocus::SchemaMatch => CreateFocus::SaveButton,
91 CreateFocus::SaveButton => CreateFocus::CancelButton,
92 CreateFocus::CancelButton => CreateFocus::Name,
93 };
94 }
95 }
96
97 pub fn prev_focus(&mut self) {
98 if self.mode == TemplateModalMode::List {
99 } else {
102 self.create_focus = match self.create_focus {
104 CreateFocus::Name => CreateFocus::CancelButton,
105 CreateFocus::Description => CreateFocus::Name,
106 CreateFocus::ExactPath => CreateFocus::Description,
107 CreateFocus::RelativePath => CreateFocus::ExactPath,
108 CreateFocus::PathPattern => CreateFocus::RelativePath,
109 CreateFocus::FilenamePattern => CreateFocus::PathPattern,
110 CreateFocus::SchemaMatch => CreateFocus::FilenamePattern,
111 CreateFocus::SaveButton => CreateFocus::SchemaMatch,
112 CreateFocus::CancelButton => CreateFocus::SaveButton,
113 };
114 }
115 }
116
117 pub fn enter_create_mode(&mut self, history_limit: usize, theme: &crate::config::Theme) {
118 self.mode = TemplateModalMode::Create;
119 self.create_focus = CreateFocus::Name;
120 self.editing_template_id = None;
121 self.name_error = None;
122 self.history_limit = history_limit;
123 self.create_name_input = TextInput::new()
125 .with_history_limit(history_limit)
126 .with_theme(theme);
127 self.create_description_input = MultiLineTextInput::new()
128 .with_history_limit(history_limit)
129 .with_theme(theme);
130 self.create_exact_path_input = TextInput::new()
131 .with_history_limit(history_limit)
132 .with_theme(theme);
133 self.create_relative_path_input = TextInput::new()
134 .with_history_limit(history_limit)
135 .with_theme(theme);
136 self.create_path_pattern_input = TextInput::new()
137 .with_history_limit(history_limit)
138 .with_theme(theme);
139 self.create_filename_pattern_input = TextInput::new()
140 .with_history_limit(history_limit)
141 .with_theme(theme);
142 self.create_name_input.clear();
144 self.create_description_input.clear();
145 self.create_exact_path_input.clear();
146 self.create_relative_path_input.clear();
147 self.create_path_pattern_input.clear();
148 self.create_filename_pattern_input.clear();
149 self.create_schema_match_enabled = false;
150 }
151
152 pub fn enter_edit_mode(
153 &mut self,
154 template: &Template,
155 history_limit: usize,
156 theme: &crate::config::Theme,
157 ) {
158 self.mode = TemplateModalMode::Edit;
159 self.create_focus = CreateFocus::Name;
160 self.editing_template_id = Some(template.id.clone());
161 self.history_limit = history_limit;
162 self.create_name_input = TextInput::new()
164 .with_history_limit(history_limit)
165 .with_theme(theme);
166 self.create_description_input = MultiLineTextInput::new()
167 .with_history_limit(history_limit)
168 .with_theme(theme);
169 self.create_exact_path_input = TextInput::new()
170 .with_history_limit(history_limit)
171 .with_theme(theme);
172 self.create_relative_path_input = TextInput::new()
173 .with_history_limit(history_limit)
174 .with_theme(theme);
175 self.create_path_pattern_input = TextInput::new()
176 .with_history_limit(history_limit)
177 .with_theme(theme);
178 self.create_filename_pattern_input = TextInput::new()
179 .with_history_limit(history_limit)
180 .with_theme(theme);
181 self.create_name_input.value = template.name.clone();
183 self.create_name_input.cursor = self.create_name_input.value.chars().count();
184 self.create_description_input.value = template.description.clone().unwrap_or_default();
185 self.create_description_input.cursor = self.create_description_input.value.chars().count();
186 self.create_description_input.update_line_col_from_cursor();
187 self.create_exact_path_input.value = template
188 .match_criteria
189 .exact_path
190 .as_ref()
191 .map(|p| p.to_string_lossy().to_string())
192 .unwrap_or_default();
193 self.create_exact_path_input.cursor = self.create_exact_path_input.value.chars().count();
194 self.create_relative_path_input.value = template
195 .match_criteria
196 .relative_path
197 .clone()
198 .unwrap_or_default();
199 self.create_relative_path_input.cursor =
200 self.create_relative_path_input.value.chars().count();
201 self.create_path_pattern_input.value = template
202 .match_criteria
203 .path_pattern
204 .clone()
205 .unwrap_or_default();
206 self.create_path_pattern_input.cursor =
207 self.create_path_pattern_input.value.chars().count();
208 self.create_filename_pattern_input.value = template
209 .match_criteria
210 .filename_pattern
211 .clone()
212 .unwrap_or_default();
213 self.create_filename_pattern_input.cursor =
214 self.create_filename_pattern_input.value.chars().count();
215 self.create_schema_match_enabled = template.match_criteria.schema_columns.is_some();
216 }
217
218 pub fn exit_create_mode(&mut self) {
219 self.mode = TemplateModalMode::List;
220 self.focus = TemplateFocus::TemplateList;
221 self.editing_template_id = None;
222 }
223}