more improvements

This commit is contained in:
Priec
2025-08-20 23:52:14 +02:00
parent aea2c39215
commit 1320884409
5 changed files with 67 additions and 58 deletions

View File

@@ -8,7 +8,7 @@ license.workspace = true
anyhow = { workspace = true }
async-trait = "0.1.88"
common = { path = "../common" }
canvas = { path = "../canvas", features = ["gui", "suggestions"] }
canvas = { path = "../canvas", features = ["gui", "suggestions", "cursor-style"] }
ratatui = { workspace = true }
crossterm = { workspace = true }

View File

@@ -1,5 +1,6 @@
// src/components/form/form.rs
use crate::config::colors::themes::Theme;
use crate::state::app::state::AppState;
use crate::state::pages::form::FormState;
use ratatui::{
layout::{Alignment, Constraint, Direction, Layout, Margin, Rect},
@@ -8,19 +9,17 @@ use ratatui::{
Frame,
};
use canvas::canvas::HighlightState;
use canvas::{FormEditor, render_canvas_default, render_canvas, render_suggestions_dropdown, DefaultCanvasTheme};
use canvas::{
render_canvas, render_suggestions_dropdown, DefaultCanvasTheme, FormEditor,
};
pub fn render_form(
f: &mut Frame,
area: Rect,
form_state: &FormState,
fields: &[&str], // no longer needed, FormEditor handles this
current_field_idx: &usize, // no longer needed
inputs: &[&String], // no longer needed
app_state: &AppState,
form_state: &FormState, // not needed directly anymore, editor holds it
table_name: &str,
theme: &Theme,
is_edit_mode: bool, // FormEditor tracks mode internally
highlight_state: &HighlightState,
total_count: u64,
current_position: u64,
) {
@@ -62,15 +61,9 @@ pub fn render_form(
.alignment(Alignment::Left);
f.render_widget(count_para, main_layout[0]);
// --- FORM RENDERING (Using new canvas API) ---
let editor = FormEditor::new(form_state.clone());
let active_field_rect = render_canvas(
f,
main_layout[1],
&editor,
theme,
);
// --- FORM RENDERING (Using persistent FormEditor) ---
if let Some(editor) = &app_state.form_editor {
let active_field_rect = render_canvas(f, main_layout[1], editor, theme);
// --- SUGGESTIONS DROPDOWN ---
if let Some(active_rect) = active_field_rect {
@@ -79,7 +72,8 @@ pub fn render_form(
main_layout[1],
active_rect,
&DefaultCanvasTheme,
&editor,
editor,
);
}
}
}

View File

@@ -16,7 +16,7 @@ use crate::modes::{
};
use crate::services::auth::AuthClient;
use crate::services::grpc_client::GrpcClient;
use canvas::FormEditor;
use canvas::{FormEditor, AppMode as CanvasMode};
use crate::state::{
app::{
buffer::{AppView, BufferState},
@@ -42,7 +42,6 @@ use crate::ui::handlers::context::UiContext;
use crate::ui::handlers::rat_state::UiStateHandler;
use anyhow::Result;
use common::proto::komp_ac::search::search_response::Hit;
use crossterm::cursor::SetCursorStyle;
use crossterm::event::KeyModifiers;
use crossterm::event::{Event, KeyCode, KeyEvent};
use tokio::sync::mpsc;
@@ -695,10 +694,12 @@ impl EventHandler {
else if config.get_read_only_action_for_key(key_code, modifiers).as_deref() == Some("enter_edit_mode_before")
&& ModeManager::can_enter_edit_mode(current_mode)
{
if let Some(editor) = &mut app_state.form_editor {
editor.enter_edit_mode();
}
self.is_edit_mode = true;
self.edit_mode_cooldown = true;
self.command_message = "Edit mode".to_string();
terminal.set_cursor_style(SetCursorStyle::BlinkingBar)?;
return Ok(EventOutcome::Ok(self.command_message.clone()));
}
else if config.get_read_only_action_for_key(key_code, modifiers).as_deref() == Some("enter_edit_mode_after")
@@ -734,16 +735,21 @@ impl EventHandler {
);
}
if let Some(editor) = &mut app_state.form_editor {
editor.enter_edit_mode();
}
self.is_edit_mode = true;
self.edit_mode_cooldown = true;
app_state.ui.focus_outside_canvas = false;
self.command_message = "Edit mode (after cursor)".to_string();
terminal.set_cursor_style(SetCursorStyle::BlinkingBar)?;
return Ok(EventOutcome::Ok(self.command_message.clone()));
}
else if config.get_read_only_action_for_key(key_code, modifiers) == Some("enter_command_mode")
&& ModeManager::can_enter_command_mode(current_mode)
{
if let Some(editor) = &mut app_state.form_editor {
editor.set_mode(CanvasMode::Command);
}
self.command_mode = true;
self.command_input.clear();
self.command_message.clear();
@@ -772,25 +778,28 @@ impl EventHandler {
// Try canvas action for form first
if app_state.ui.show_form {
let mut editor = FormEditor::new(form_state.clone());
if let Some(editor) = &mut app_state.form_editor {
if let Ok(Some(canvas_message)) = self.handle_form_canvas_action(
key_event,
&mut editor,
editor,
config,
false,
).await {
return Ok(EventOutcome::Ok(canvas_message));
}
}
}
return Ok(EventOutcome::Ok(self.command_message.clone()));
}
AppMode::Highlight => {
if config.get_highlight_action_for_key(key_code, modifiers) == Some("exit_highlight_mode") {
if let Some(editor) = &mut app_state.form_editor {
editor.exit_highlight_mode();
}
self.highlight_state = HighlightState::Off;
self.command_message = "Exited highlight mode".to_string();
terminal.set_cursor_style(SetCursorStyle::SteadyBlock)?;
return Ok(EventOutcome::Ok(self.command_message.clone()));
} else if config.get_highlight_action_for_key(key_code, modifiers) == Some("enter_highlight_mode_linewise") {
if let HighlightState::Characterwise { anchor } = self.highlight_state {
@@ -827,10 +836,10 @@ impl EventHandler {
// Try canvas action for form first
if app_state.ui.show_form {
let mut editor = FormEditor::new(form_state.clone());
if let Some(editor) = &mut app_state.form_editor {
if let Ok(Some(canvas_message)) = self.handle_form_canvas_action(
key_event,
&mut editor,
editor,
config,
true,
).await {
@@ -840,6 +849,7 @@ impl EventHandler {
return Ok(EventOutcome::Ok(canvas_message));
}
}
}
return Ok(EventOutcome::Ok(self.command_message.clone()));
}
@@ -850,6 +860,9 @@ impl EventHandler {
self.command_message.clear();
self.command_mode = false;
self.key_sequence_tracker.reset();
if let Some(editor) = &mut app_state.form_editor {
editor.set_mode(CanvasMode::ReadOnly);
}
return Ok(EventOutcome::Ok(
"Exited command mode".to_string(),
));
@@ -1079,6 +1092,9 @@ impl EventHandler {
}
}
"force_quit" => {
if let Some(editor) = &mut app_state.form_editor {
editor.cleanup_cursor()?;
}
terminal.cleanup()?;
Ok(EventOutcome::Exit(
"Force exiting without saving.".to_string(),
@@ -1106,6 +1122,9 @@ impl EventHandler {
SaveOutcome::CreatedNew(_) => "New entry created.".to_string(),
}
};
if let Some(editor) = &mut app_state.form_editor {
editor.cleanup_cursor()?;
}
terminal.cleanup()?;
Ok(EventOutcome::Exit(format!(
"{}. Exiting application.",

View File

@@ -7,6 +7,8 @@ use common::proto::komp_ac::table_structure::TableStructureResponse;
use crate::modes::handlers::mode_manager::AppMode;
use crate::state::app::search::SearchState;
use crate::ui::handlers::context::DialogPurpose;
use canvas::FormEditor;
use crate::state::pages::form::FormState;
use std::collections::HashMap;
use std::env;
use std::sync::Arc;
@@ -67,6 +69,8 @@ pub struct AppState {
// UI preferences
pub ui: UiState,
pub form_editor: Option<FormEditor<FormState>>,
#[cfg(feature = "ui-debug")]
pub debug_state: Option<DebugState>,
}
@@ -86,6 +90,7 @@ impl AppState {
pending_table_structure_fetch: None,
search_state: None,
ui: UiState::default(),
form_editor: None,
#[cfg(feature = "ui-debug")]
debug_state: None,

View File

@@ -228,15 +228,6 @@ impl FormState {
self.autocomplete_loading = false;
}
// NEW: Add these methods to change modes
pub fn set_edit_mode(&mut self) {
self.app_mode = AppMode::Edit;
}
pub fn set_readonly_mode(&mut self) {
self.app_mode = AppMode::ReadOnly;
}
// Legacy method compatibility
pub fn fields(&self) -> Vec<&str> {
self.fields