canvas fixes3
This commit is contained in:
@@ -3,7 +3,7 @@ use crate::config::colors::themes::Theme;
|
|||||||
use crate::state::app::highlight::HighlightState;
|
use crate::state::app::highlight::HighlightState;
|
||||||
use crate::state::app::state::AppState;
|
use crate::state::app::state::AppState;
|
||||||
use crate::state::pages::add_table::{AddTableFocus, AddTableState};
|
use crate::state::pages::add_table::{AddTableFocus, AddTableState};
|
||||||
use canvas::canvas::{render_canvas, CanvasState, HighlightState as CanvasHighlightState};
|
use canvas::{render_canvas_default, HighlightState as CanvasHighlightState};
|
||||||
use ratatui::{
|
use ratatui::{
|
||||||
layout::{Alignment, Constraint, Direction, Layout, Rect},
|
layout::{Alignment, Constraint, Direction, Layout, Rect},
|
||||||
style::{Modifier, Style},
|
style::{Modifier, Style},
|
||||||
@@ -358,13 +358,10 @@ pub fn render_add_table(
|
|||||||
|
|
||||||
// --- Canvas Rendering (Column Definition Input) - USING CANVAS LIBRARY ---
|
// --- Canvas Rendering (Column Definition Input) - USING CANVAS LIBRARY ---
|
||||||
let canvas_highlight_state = convert_highlight_state(highlight_state);
|
let canvas_highlight_state = convert_highlight_state(highlight_state);
|
||||||
let _active_field_rect = render_canvas(
|
let _active_field_rect = render_canvas_default(
|
||||||
f,
|
f,
|
||||||
canvas_area,
|
canvas_area,
|
||||||
add_table_state, // AddTableState implements CanvasState
|
add_table_state, // will later be wrapped in FormEditor
|
||||||
theme, // Theme implements CanvasTheme
|
|
||||||
is_edit_mode && focus_on_canvas_inputs,
|
|
||||||
&canvas_highlight_state,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// --- Button Style Helpers ---
|
// --- Button Style Helpers ---
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
// src/state/pages/add_table.rs
|
// src/state/pages/add_table.rs
|
||||||
use canvas::canvas::{CanvasState, ActionContext, CanvasAction, AppMode};
|
|
||||||
|
use canvas::{DataProvider, CanvasAction, AppMode};
|
||||||
use ratatui::widgets::TableState;
|
use ratatui::widgets::TableState;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
@@ -169,138 +170,3 @@ impl AddTableState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Implement external library's CanvasState for AddTableState
|
|
||||||
impl CanvasState for AddTableState {
|
|
||||||
fn current_field(&self) -> usize {
|
|
||||||
match self.current_focus {
|
|
||||||
AddTableFocus::InputTableName => 0,
|
|
||||||
AddTableFocus::InputColumnName => 1,
|
|
||||||
AddTableFocus::InputColumnType => 2,
|
|
||||||
// If focus is elsewhere, return the last canvas field used
|
|
||||||
_ => self.last_canvas_field,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn current_cursor_pos(&self) -> usize {
|
|
||||||
match self.current_focus {
|
|
||||||
AddTableFocus::InputTableName => self.table_name_cursor_pos,
|
|
||||||
AddTableFocus::InputColumnName => self.column_name_cursor_pos,
|
|
||||||
AddTableFocus::InputColumnType => self.column_type_cursor_pos,
|
|
||||||
_ => 0, // Default if focus is not on an input field
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_current_field(&mut self, index: usize) {
|
|
||||||
// Update both current focus and last canvas field
|
|
||||||
self.current_focus = match index {
|
|
||||||
0 => {
|
|
||||||
self.last_canvas_field = 0;
|
|
||||||
AddTableFocus::InputTableName
|
|
||||||
},
|
|
||||||
1 => {
|
|
||||||
self.last_canvas_field = 1;
|
|
||||||
AddTableFocus::InputColumnName
|
|
||||||
},
|
|
||||||
2 => {
|
|
||||||
self.last_canvas_field = 2;
|
|
||||||
AddTableFocus::InputColumnType
|
|
||||||
},
|
|
||||||
_ => self.current_focus, // Stay on current focus if index is out of bounds
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_current_cursor_pos(&mut self, pos: usize) {
|
|
||||||
match self.current_focus {
|
|
||||||
AddTableFocus::InputTableName => self.table_name_cursor_pos = pos,
|
|
||||||
AddTableFocus::InputColumnName => self.column_name_cursor_pos = pos,
|
|
||||||
AddTableFocus::InputColumnType => self.column_type_cursor_pos = pos,
|
|
||||||
_ => {} // Do nothing if focus is not on an input field
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_current_input(&self) -> &str {
|
|
||||||
match self.current_focus {
|
|
||||||
AddTableFocus::InputTableName => &self.table_name_input,
|
|
||||||
AddTableFocus::InputColumnName => &self.column_name_input,
|
|
||||||
AddTableFocus::InputColumnType => &self.column_type_input,
|
|
||||||
_ => "", // Should not happen if called correctly
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_current_input_mut(&mut self) -> &mut String {
|
|
||||||
match self.current_focus {
|
|
||||||
AddTableFocus::InputTableName => &mut self.table_name_input,
|
|
||||||
AddTableFocus::InputColumnName => &mut self.column_name_input,
|
|
||||||
AddTableFocus::InputColumnType => &mut self.column_type_input,
|
|
||||||
_ => &mut self.table_name_input, // Fallback
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn inputs(&self) -> Vec<&String> {
|
|
||||||
vec![&self.table_name_input, &self.column_name_input, &self.column_type_input]
|
|
||||||
}
|
|
||||||
|
|
||||||
fn fields(&self) -> Vec<&str> {
|
|
||||||
// These must match the order used in render_add_table
|
|
||||||
vec!["Table name", "Name", "Type"]
|
|
||||||
}
|
|
||||||
|
|
||||||
fn has_unsaved_changes(&self) -> bool {
|
|
||||||
self.has_unsaved_changes
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_has_unsaved_changes(&mut self, changed: bool) {
|
|
||||||
self.has_unsaved_changes = changed;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn handle_feature_action(&mut self, action: &CanvasAction, _context: &ActionContext) -> Option<String> {
|
|
||||||
match action {
|
|
||||||
// Handle adding column when user presses Enter on the Add button or uses specific action
|
|
||||||
CanvasAction::Custom(action_str) if action_str == "add_column" => {
|
|
||||||
self.add_column_from_inputs()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle table saving
|
|
||||||
CanvasAction::Custom(action_str) if action_str == "save_table" => {
|
|
||||||
if self.table_name_input.trim().is_empty() {
|
|
||||||
Some("Table name is required".to_string())
|
|
||||||
} else if self.columns.is_empty() {
|
|
||||||
Some("At least one column is required".to_string())
|
|
||||||
} else {
|
|
||||||
Some(format!("Saving table: {}", self.table_name_input))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle deleting selected items
|
|
||||||
CanvasAction::Custom(action_str) if action_str == "delete_selected" => {
|
|
||||||
self.delete_selected_items()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle canceling (clear form)
|
|
||||||
CanvasAction::Custom(action_str) if action_str == "cancel" => {
|
|
||||||
// Reset to defaults but keep profile_name
|
|
||||||
let profile = self.profile_name.clone();
|
|
||||||
*self = Self::default();
|
|
||||||
self.profile_name = profile;
|
|
||||||
Some("Form cleared".to_string())
|
|
||||||
}
|
|
||||||
|
|
||||||
// Custom validation when moving between fields
|
|
||||||
CanvasAction::NextField => {
|
|
||||||
// When leaving table name field, update the table_name for display
|
|
||||||
if self.current_field() == 0 && !self.table_name_input.trim().is_empty() {
|
|
||||||
self.table_name = self.table_name_input.trim().to_string();
|
|
||||||
}
|
|
||||||
None // Let canvas library handle the normal field movement
|
|
||||||
}
|
|
||||||
|
|
||||||
// Let canvas library handle everything else
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn current_mode(&self) -> AppMode {
|
|
||||||
self.app_mode
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ use crate::state::app::buffer::{AppView, BufferState};
|
|||||||
use crate::config::storage::storage::{StoredAuthData, save_auth_data};
|
use crate::config::storage::storage::{StoredAuthData, save_auth_data};
|
||||||
use crate::ui::handlers::context::DialogPurpose;
|
use crate::ui::handlers::context::DialogPurpose;
|
||||||
use common::proto::komp_ac::auth::LoginResponse;
|
use common::proto::komp_ac::auth::LoginResponse;
|
||||||
use canvas::canvas::CanvasState;
|
|
||||||
use anyhow::{Context, Result};
|
use anyhow::{Context, Result};
|
||||||
use tokio::spawn;
|
use tokio::spawn;
|
||||||
use tokio::sync::mpsc;
|
use tokio::sync::mpsc;
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ use crate::state::{
|
|||||||
use crate::ui::handlers::context::DialogPurpose;
|
use crate::ui::handlers::context::DialogPurpose;
|
||||||
use crate::state::app::buffer::{AppView, BufferState};
|
use crate::state::app::buffer::{AppView, BufferState};
|
||||||
use common::proto::komp_ac::auth::AuthResponse;
|
use common::proto::komp_ac::auth::AuthResponse;
|
||||||
use canvas::canvas::CanvasState;
|
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use tokio::spawn;
|
use tokio::spawn;
|
||||||
use tokio::sync::mpsc;
|
use tokio::sync::mpsc;
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
// src/tui/functions/form.rs
|
// src/tui/functions/form.rs
|
||||||
use crate::state::pages::form::FormState;
|
use crate::state::pages::form::FormState;
|
||||||
use crate::services::grpc_client::GrpcClient;
|
use crate::services::grpc_client::GrpcClient;
|
||||||
use canvas::canvas::CanvasState;
|
|
||||||
use anyhow::{anyhow, Result};
|
use anyhow::{anyhow, Result};
|
||||||
|
|
||||||
pub async fn handle_action(
|
pub async fn handle_action(
|
||||||
|
|||||||
Reference in New Issue
Block a user