migrating to the new canvas library
This commit is contained in:
@@ -1,7 +1,8 @@
|
||||
// src/state/pages/form.rs
|
||||
|
||||
use crate::config::colors::themes::Theme;
|
||||
use canvas::canvas::{CanvasState, CanvasAction, ActionContext, HighlightState, AppMode};
|
||||
use canvas::{DataProvider, AppMode, EditorState, FormEditor};
|
||||
use canvas::canvas::HighlightState;
|
||||
use common::proto::komp_ac::search::search_response::Hit;
|
||||
use ratatui::layout::Rect;
|
||||
use ratatui::Frame;
|
||||
@@ -122,26 +123,19 @@ impl FormState {
|
||||
area: Rect,
|
||||
theme: &Theme,
|
||||
is_edit_mode: bool,
|
||||
highlight_state: &HighlightState, // Now using canvas::HighlightState
|
||||
highlight_state: &HighlightState,
|
||||
) {
|
||||
let fields_str_slice: Vec<&str> =
|
||||
self.fields().iter().map(|s| *s).collect();
|
||||
let values_str_slice: Vec<&String> = self.values.iter().collect();
|
||||
|
||||
crate::components::form::form::render_form(
|
||||
f,
|
||||
area,
|
||||
self,
|
||||
&fields_str_slice,
|
||||
&self.current_field,
|
||||
&values_str_slice,
|
||||
&self.table_name,
|
||||
theme,
|
||||
is_edit_mode,
|
||||
highlight_state,
|
||||
self.total_count,
|
||||
self.current_position,
|
||||
);
|
||||
// Wrap in FormEditor for new API
|
||||
let mut editor = FormEditor::new(self.clone());
|
||||
|
||||
// Use new canvas rendering
|
||||
canvas::render_canvas_default(f, area, &editor);
|
||||
|
||||
// If autocomplete is active, render suggestions
|
||||
if self.autocomplete_active && !self.autocomplete_suggestions.is_empty() {
|
||||
// Note: This will need to be updated when suggestions are integrated
|
||||
// canvas::render_suggestions_dropdown(f, area, input_rect, &canvas::DefaultCanvasTheme, &editor);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn reset_to_empty(&mut self) {
|
||||
@@ -242,97 +236,84 @@ impl FormState {
|
||||
pub fn set_readonly_mode(&mut self) {
|
||||
self.app_mode = AppMode::ReadOnly;
|
||||
}
|
||||
}
|
||||
|
||||
impl CanvasState for FormState {
|
||||
fn current_field(&self) -> usize {
|
||||
self.current_field
|
||||
}
|
||||
|
||||
fn current_cursor_pos(&self) -> usize {
|
||||
self.current_cursor_pos
|
||||
}
|
||||
|
||||
fn has_unsaved_changes(&self) -> bool {
|
||||
self.has_unsaved_changes
|
||||
}
|
||||
|
||||
fn inputs(&self) -> Vec<&String> {
|
||||
self.values.iter().collect()
|
||||
}
|
||||
|
||||
fn get_current_input(&self) -> &str {
|
||||
FormState::get_current_input(self)
|
||||
}
|
||||
|
||||
fn get_current_input_mut(&mut self) -> &mut String {
|
||||
FormState::get_current_input_mut(self)
|
||||
}
|
||||
|
||||
fn fields(&self) -> Vec<&str> {
|
||||
// Legacy method compatibility
|
||||
pub fn fields(&self) -> Vec<&str> {
|
||||
self.fields
|
||||
.iter()
|
||||
.map(|f| f.display_name.as_str())
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn set_current_field(&mut self, index: usize) {
|
||||
pub fn get_display_value_for_field(&self, index: usize) -> &str {
|
||||
if let Some(display_text) = self.link_display_map.get(&index) {
|
||||
return display_text.as_str();
|
||||
}
|
||||
self.values
|
||||
.get(index)
|
||||
.map(|s| s.as_str())
|
||||
.unwrap_or("")
|
||||
}
|
||||
|
||||
pub fn has_display_override(&self, index: usize) -> bool {
|
||||
self.link_display_map.contains_key(&index)
|
||||
}
|
||||
|
||||
pub fn current_mode(&self) -> AppMode {
|
||||
self.app_mode
|
||||
}
|
||||
|
||||
// Add missing methods that used to come from CanvasState trait
|
||||
pub fn has_unsaved_changes(&self) -> bool {
|
||||
self.has_unsaved_changes
|
||||
}
|
||||
|
||||
pub fn set_has_unsaved_changes(&mut self, changed: bool) {
|
||||
self.has_unsaved_changes = changed;
|
||||
}
|
||||
|
||||
pub fn current_field(&self) -> usize {
|
||||
self.current_field
|
||||
}
|
||||
|
||||
pub fn set_current_field(&mut self, index: usize) {
|
||||
if index < self.fields.len() {
|
||||
self.current_field = index;
|
||||
}
|
||||
self.deactivate_autocomplete();
|
||||
}
|
||||
|
||||
fn set_current_cursor_pos(&mut self, pos: usize) {
|
||||
pub fn current_cursor_pos(&self) -> usize {
|
||||
self.current_cursor_pos
|
||||
}
|
||||
|
||||
pub fn set_current_cursor_pos(&mut self, pos: usize) {
|
||||
self.current_cursor_pos = pos;
|
||||
}
|
||||
}
|
||||
|
||||
fn set_has_unsaved_changes(&mut self, changed: bool) {
|
||||
self.has_unsaved_changes = changed;
|
||||
// Step 2: Implement DataProvider for FormState
|
||||
impl DataProvider for FormState {
|
||||
fn field_count(&self) -> usize {
|
||||
self.fields.len()
|
||||
}
|
||||
|
||||
// --- FEATURE-SPECIFIC ACTION HANDLING ---
|
||||
fn handle_feature_action(&mut self, action: &CanvasAction, _context: &ActionContext) -> Option<String> {
|
||||
match action {
|
||||
CanvasAction::SelectSuggestion => {
|
||||
if let Some(selected_idx) = self.selected_suggestion_index {
|
||||
if let Some(hit) = self.autocomplete_suggestions.get(selected_idx).cloned() {
|
||||
// Extract the value from the selected suggestion
|
||||
if let Ok(content_map) = serde_json::from_str::<HashMap<String, serde_json::Value>>(&hit.content_json) {
|
||||
let current_field_def = &self.fields[self.current_field];
|
||||
if let Some(value) = content_map.get(¤t_field_def.data_key) {
|
||||
let new_value = json_value_to_string(value);
|
||||
let display_name = self.get_display_name_for_hit(&hit);
|
||||
*self.get_current_input_mut() = new_value.clone();
|
||||
self.set_current_cursor_pos(new_value.len());
|
||||
self.set_has_unsaved_changes(true);
|
||||
self.deactivate_autocomplete();
|
||||
return Some(format!("Selected: {}", display_name));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
_ => None, // Let canvas handle other actions
|
||||
fn field_name(&self, index: usize) -> &str {
|
||||
&self.fields[index].display_name
|
||||
}
|
||||
|
||||
fn field_value(&self, index: usize) -> &str {
|
||||
&self.values[index]
|
||||
}
|
||||
|
||||
fn set_field_value(&mut self, index: usize, value: String) {
|
||||
if let Some(v) = self.values.get_mut(index) {
|
||||
*v = value;
|
||||
self.has_unsaved_changes = true;
|
||||
}
|
||||
}
|
||||
|
||||
fn get_display_value_for_field(&self, index: usize) -> &str {
|
||||
if let Some(display_text) = self.link_display_map.get(&index) {
|
||||
return display_text.as_str();
|
||||
}
|
||||
self.inputs()
|
||||
.get(index)
|
||||
.map(|s| s.as_str())
|
||||
.unwrap_or("")
|
||||
}
|
||||
|
||||
fn has_display_override(&self, index: usize) -> bool {
|
||||
self.link_display_map.contains_key(&index)
|
||||
}
|
||||
|
||||
fn current_mode(&self) -> AppMode {
|
||||
self.app_mode
|
||||
fn supports_suggestions(&self, field_index: usize) -> bool {
|
||||
self.fields.get(field_index).map(|f| f.is_link).unwrap_or(false)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user