moving add table to the same way as add logic

This commit is contained in:
Priec
2025-08-31 23:07:57 +02:00
parent 347802b2a4
commit 62c54dc1eb
5 changed files with 136 additions and 48 deletions

View File

@@ -4,7 +4,7 @@ use crate::config::binds::config::Config;
use crate::movement::MovementAction;
use crate::pages::admin_panel::add_table::nav;
use crate::pages::admin_panel::add_table::nav::SaveTableResultSender;
use crate::pages::admin_panel::add_table::state::{AddTableFocus, AddTableState};
use crate::pages::admin_panel::add_table::state::{AddTableFocus, AddTableFormState};
use crate::services::GrpcClient;
use crate::state::app::state::AppState;
use crossterm::event::KeyEvent;
@@ -19,16 +19,16 @@ pub fn handle_add_table_event(
movement_action: Option<MovementAction>,
config: &Config,
app_state: &mut AppState,
state: &mut AddTableState,
page: &mut AddTableFormState,
grpc_client: GrpcClient,
save_result_sender: SaveTableResultSender,
command_message: &mut String,
) -> bool {
// 1) Try movement first (keeps focus cycling consistent)
// 1) Try movement first
if let Some(ma) = movement_action {
if state.handle_movement(ma) {
if page.state.handle_movement(ma) {
let is_canvas_input = matches!(
state.current_focus,
page.current_focus(),
AddTableFocus::InputTableName
| AddTableFocus::InputColumnName
| AddTableFocus::InputColumnType
@@ -38,12 +38,12 @@ pub fn handle_add_table_event(
}
}
// 2) Rich actions/navigation for AddTable
// 2) Rich actions/navigation
nav::handle_add_table_navigation(
key_event,
config,
app_state,
state,
&mut page.state,
grpc_client,
save_result_sender,
command_message,

View File

@@ -1,6 +1,7 @@
// src/pages/admin_panel/add_table/state.rs
use canvas::{DataProvider, AppMode};
use canvas::FormEditor;
use ratatui::widgets::TableState;
use serde::{Deserialize, Serialize};
use crate::movement::{move_focus, MovementAction};
@@ -381,3 +382,77 @@ impl AddTableState {
move_focus(&ORDER, &mut self.current_focus, action)
}
}
pub struct AddTableFormState {
pub state: AddTableState,
pub editor: FormEditor<AddTableState>,
pub focus_outside_canvas: bool,
}
impl std::fmt::Debug for AddTableFormState {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("AddTableFormState")
.field("state", &self.state)
.field("focus_outside_canvas", &self.focus_outside_canvas)
.finish()
}
}
impl AddTableFormState {
pub fn new(profile_name: String) -> Self {
let mut state = AddTableState::default();
state.profile_name = profile_name;
let editor = FormEditor::new(state.clone());
Self {
state,
editor,
focus_outside_canvas: false,
}
}
pub fn from_state(state: AddTableState) -> Self {
let editor = FormEditor::new(state.clone());
Self {
state,
editor,
focus_outside_canvas: false,
}
}
/// Sync state from editors snapshot
pub fn sync_from_editor(&mut self) {
self.state = self.editor.data_provider().clone();
}
// === Delegates to AddTableState fields ===
pub fn current_focus(&self) -> AddTableFocus {
self.state.current_focus
}
pub fn set_current_focus(&mut self, focus: AddTableFocus) {
self.state.current_focus = focus;
}
pub fn profile_name(&self) -> &str {
&self.state.profile_name
}
pub fn table_name(&self) -> &str {
&self.state.table_name
}
pub fn columns(&self) -> &Vec<ColumnDefinition> {
&self.state.columns
}
pub fn indexes(&self) -> &Vec<IndexDefinition> {
&self.state.indexes
}
pub fn links(&self) -> &Vec<LinkDefinition> {
&self.state.links
}
pub fn column_table_state(&mut self) -> &mut TableState {
&mut self.state.column_table_state
}
pub fn index_table_state(&mut self) -> &mut TableState {
&mut self.state.index_table_state
}
pub fn link_table_state(&mut self) -> &mut TableState {
&mut self.state.link_table_state
}
}

View File

@@ -1,8 +1,8 @@
// src/pages/admin_panel/add_table/ui.rs
use crate::config::colors::themes::Theme;
use crate::state::app::state::AppState;
use crate::pages::admin_panel::add_table::state::{AddTableFocus, AddTableState};
use canvas::{render_canvas, FormEditor};
use crate::pages::admin_panel::add_table::state::{AddTableFocus, AddTableFormState};
use canvas::render_canvas;
use ratatui::{
layout::{Alignment, Constraint, Direction, Layout, Rect},
style::{Modifier, Style},
@@ -19,7 +19,7 @@ pub fn render_add_table(
area: Rect,
theme: &Theme,
app_state: &AppState,
add_table_state: &mut AddTableState,
add_table_state: &mut AddTableFormState,
) {
// --- Configuration ---
// Threshold width to switch between wide and narrow layouts
@@ -27,7 +27,7 @@ pub fn render_add_table(
// --- State Checks ---
let focus_on_canvas_inputs = matches!(
add_table_state.current_focus,
add_table_state.current_focus(),
AddTableFocus::InputTableName
| AddTableFocus::InputColumnName
| AddTableFocus::InputColumnType
@@ -45,11 +45,11 @@ pub fn render_add_table(
f.render_widget(main_block, area);
// --- Fullscreen Columns Table Check (Narrow Screens Only) ---
if area.width < NARROW_LAYOUT_THRESHOLD && add_table_state.current_focus == AddTableFocus::InsideColumnsTable {
if area.width < NARROW_LAYOUT_THRESHOLD && add_table_state.current_focus() == AddTableFocus::InsideColumnsTable {
// Render ONLY the columns table taking the full inner area
let columns_border_style = Style::default().fg(theme.highlight); // Always highlighted when fullscreen
let column_rows: Vec<Row<'_>> = add_table_state
.columns
.columns()
.iter()
.map(|col_def| {
Row::new(vec![
@@ -80,16 +80,16 @@ pub fn render_add_table(
.fg(theme.highlight),
)
.highlight_symbol(" > "); // Use the inside symbol
f.render_stateful_widget(columns_table, inner_area, &mut add_table_state.column_table_state);
f.render_stateful_widget(columns_table, inner_area, add_table_state.column_table_state());
return; // IMPORTANT: Stop rendering here for fullscreen mode
}
// --- Fullscreen Indexes Table Check ---
if add_table_state.current_focus == AddTableFocus::InsideIndexesTable { // Remove width check
if add_table_state.current_focus() == AddTableFocus::InsideIndexesTable { // Remove width check
// Render ONLY the indexes table taking the full inner area
let indexes_border_style = Style::default().fg(theme.highlight); // Always highlighted when fullscreen
let index_rows: Vec<Row<'_>> = add_table_state
.indexes
.indexes()
.iter()
.map(|index_def| {
Row::new(vec![
@@ -115,16 +115,16 @@ pub fn render_add_table(
)
.row_highlight_style(Style::default().add_modifier(Modifier::REVERSED).fg(theme.highlight))
.highlight_symbol(" > "); // Use the inside symbol
f.render_stateful_widget(indexes_table, inner_area, &mut add_table_state.index_table_state);
f.render_stateful_widget(indexes_table, inner_area, &mut add_table_state.index_table_state());
return; // IMPORTANT: Stop rendering here for fullscreen mode
}
// --- Fullscreen Links Table Check ---
if add_table_state.current_focus == AddTableFocus::InsideLinksTable {
if add_table_state.current_focus() == AddTableFocus::InsideLinksTable {
// Render ONLY the links table taking the full inner area
let links_border_style = Style::default().fg(theme.highlight); // Always highlighted when fullscreen
let link_rows: Vec<Row<'_>> = add_table_state
.links
.links()
.iter()
.map(|link_def| {
Row::new(vec![
@@ -151,7 +151,7 @@ pub fn render_add_table(
)
.row_highlight_style(Style::default().add_modifier(Modifier::REVERSED).fg(theme.highlight))
.highlight_symbol(" > "); // Use the inside symbol
f.render_stateful_widget(links_table, inner_area, &mut add_table_state.link_table_state);
f.render_stateful_widget(links_table, inner_area, &mut add_table_state.link_table_state());
return; // IMPORTANT: Stop rendering here for fullscreen mode
}
@@ -220,11 +220,11 @@ pub fn render_add_table(
// --- Top Info Rendering (Wide - 2 lines) ---
let profile_text = Paragraph::new(vec![
Line::from(Span::styled(
format!("Profile: {}", add_table_state.profile_name),
format!("Profile: {}", add_table_state.profile_name()),
theme.fg,
)),
Line::from(Span::styled(
format!("Table name: {}", add_table_state.table_name),
format!("Table name: {}", add_table_state.table_name()),
theme.fg,
)),
])
@@ -276,14 +276,14 @@ pub fn render_add_table(
.split(top_info_area);
let profile_text = Paragraph::new(Span::styled(
format!("Profile: {}", add_table_state.profile_name),
format!("Profile: {}", add_table_state.profile_name()),
theme.fg,
))
.alignment(Alignment::Left);
f.render_widget(profile_text, top_info_chunks[0]);
let table_name_text = Paragraph::new(Span::styled(
format!("Table: {}", add_table_state.table_name),
format!("Table: {}", add_table_state.table_name()),
theme.fg,
))
.alignment(Alignment::Left);
@@ -293,14 +293,14 @@ pub fn render_add_table(
// --- Common Widget Rendering (Uses calculated areas) ---
// --- Columns Table Rendering ---
let columns_focused = matches!(add_table_state.current_focus, AddTableFocus::ColumnsTable | AddTableFocus::InsideColumnsTable);
let columns_focused = matches!(add_table_state.current_focus(), AddTableFocus::ColumnsTable | AddTableFocus::InsideColumnsTable);
let columns_border_style = if columns_focused {
Style::default().fg(theme.highlight)
} else {
Style::default().fg(theme.secondary)
};
let column_rows: Vec<Row<'_>> = add_table_state
.columns
.columns()
.iter()
.map(|col_def| {
Row::new(vec![
@@ -341,12 +341,11 @@ pub fn render_add_table(
f.render_stateful_widget(
columns_table,
columns_area,
&mut add_table_state.column_table_state,
&mut add_table_state.column_table_state(),
);
// --- Canvas Rendering (Column Definition Input) - USING CANVAS LIBRARY ---
let editor = FormEditor::new(add_table_state.clone());
let _active_field_rect = render_canvas(f, canvas_area, &editor, theme);
let _active_field_rect = render_canvas(f, canvas_area, &add_table_state.editor, theme);
// --- Button Style Helpers ---
let get_button_style = |button_focus: AddTableFocus, current_focus| {
@@ -374,11 +373,11 @@ pub fn render_add_table(
// --- Add Button Rendering ---
// Determine if the add button is focused
let is_add_button_focused = add_table_state.current_focus == AddTableFocus::AddColumnButton;
let is_add_button_focused = add_table_state.current_focus() == AddTableFocus::AddColumnButton;
// Create the Add button Paragraph widget
let add_button = Paragraph::new(" Add ")
.style(get_button_style(AddTableFocus::AddColumnButton, add_table_state.current_focus)) // Use existing closure
.style(get_button_style(AddTableFocus::AddColumnButton, add_table_state.current_focus())) // Use existing closure
.alignment(Alignment::Center)
.block(
Block::default()
@@ -391,14 +390,14 @@ pub fn render_add_table(
f.render_widget(add_button, add_button_area);
// --- Indexes Table Rendering ---
let indexes_focused = matches!(add_table_state.current_focus, AddTableFocus::IndexesTable | AddTableFocus::InsideIndexesTable);
let indexes_focused = matches!(add_table_state.current_focus(), AddTableFocus::IndexesTable | AddTableFocus::InsideIndexesTable);
let indexes_border_style = if indexes_focused {
Style::default().fg(theme.highlight)
} else {
Style::default().fg(theme.secondary)
};
let index_rows: Vec<Row<'_>> = add_table_state
.indexes
.indexes()
.iter()
.map(|index_def| { // Use index_def now
Row::new(vec![
@@ -432,18 +431,18 @@ pub fn render_add_table(
f.render_stateful_widget(
indexes_table,
indexes_area,
&mut add_table_state.index_table_state,
&mut add_table_state.index_table_state(),
);
// --- Links Table Rendering ---
let links_focused = matches!(add_table_state.current_focus, AddTableFocus::LinksTable | AddTableFocus::InsideLinksTable);
let links_focused = matches!(add_table_state.current_focus(), AddTableFocus::LinksTable | AddTableFocus::InsideLinksTable);
let links_border_style = if links_focused {
Style::default().fg(theme.highlight)
} else {
Style::default().fg(theme.secondary)
};
let link_rows: Vec<Row<'_>> = add_table_state
.links
.links()
.iter()
.map(|link_def| {
Row::new(vec![
@@ -477,7 +476,7 @@ pub fn render_add_table(
f.render_stateful_widget(
links_table,
links_area,
&mut add_table_state.link_table_state,
&mut add_table_state.link_table_state(),
);
// --- Save/Cancel Buttons Rendering ---
@@ -493,7 +492,7 @@ pub fn render_add_table(
let save_button = Paragraph::new(" Save table ")
.style(get_button_style(
AddTableFocus::SaveButton,
add_table_state.current_focus,
add_table_state.current_focus(),
))
.alignment(Alignment::Center)
.block(
@@ -501,7 +500,7 @@ pub fn render_add_table(
.borders(Borders::ALL)
.border_type(BorderType::Rounded)
.border_style(get_button_border_style(
add_table_state.current_focus == AddTableFocus::SaveButton, // Pass bool
add_table_state.current_focus() == AddTableFocus::SaveButton, // Pass bool
theme,
)),
);
@@ -510,7 +509,7 @@ pub fn render_add_table(
let delete_button = Paragraph::new(" Delete Selected ")
.style(get_button_style(
AddTableFocus::DeleteSelectedButton,
add_table_state.current_focus,
add_table_state.current_focus(),
))
.alignment(Alignment::Center)
.block(
@@ -518,7 +517,7 @@ pub fn render_add_table(
.borders(Borders::ALL)
.border_type(BorderType::Rounded)
.border_style(get_button_border_style(
add_table_state.current_focus == AddTableFocus::DeleteSelectedButton, // Pass bool
add_table_state.current_focus() == AddTableFocus::DeleteSelectedButton, // Pass bool
theme,
)),
);
@@ -527,7 +526,7 @@ pub fn render_add_table(
let cancel_button = Paragraph::new(" Cancel ")
.style(get_button_style(
AddTableFocus::CancelButton,
add_table_state.current_focus,
add_table_state.current_focus(),
))
.alignment(Alignment::Center)
.block(
@@ -535,7 +534,7 @@ pub fn render_add_table(
.borders(Borders::ALL)
.border_type(BorderType::Rounded)
.border_style(get_button_border_style(
add_table_state.current_focus == AddTableFocus::CancelButton, // Pass bool
add_table_state.current_focus() == AddTableFocus::CancelButton, // Pass bool
theme,
)),
);

View File

@@ -1,7 +1,7 @@
// src/pages/routing/router.rs
use crate::state::pages::auth::AuthState;
use crate::pages::admin_panel::add_logic::state::AddLogicFormState;
use crate::pages::admin_panel::add_table::state::AddTableState;
use crate::pages::admin_panel::add_table::state::AddTableFormState;
use crate::pages::admin::AdminState;
use crate::pages::forms::FormState;
use crate::pages::login::LoginFormState;
@@ -15,7 +15,7 @@ pub enum Page {
Register(RegisterFormState),
Admin(AdminState),
AddLogic(AddLogicFormState),
AddTable(AddTableState),
AddTable(AddTableFormState),
Form(String),
}

View File

@@ -12,6 +12,7 @@ use crate::state::pages::auth::AuthState;
use crate::state::pages::auth::UserRole;
use crate::pages::login::LoginFormState;
use crate::pages::register::RegisterFormState;
use crate::pages::admin_panel::add_table;
use crate::pages::admin_panel::add_logic;
use crate::pages::admin::AdminState;
use crate::pages::admin::AdminFocus;
@@ -424,7 +425,17 @@ pub async fn run_ui() -> Result<()> {
router.navigate(Page::Admin(admin_state.clone()));
}
AppView::AddTable => router.navigate(Page::AddTable(admin_state.add_table_state.clone())),
AppView::AddTable => {
router.navigate(Page::AddTable(
add_table::state::AddTableFormState::from_state(
admin_state.add_table_state.clone(),
),
));
if let Page::AddTable(page) = &mut router.current {
// Ensure keymap is set once
page.editor.set_keymap(config.build_canvas_keymap());
}
}
AppView::AddLogic => {
if let Page::AddLogic(page) = &mut router.current {
// Ensure keymap is set once
@@ -640,6 +651,9 @@ pub async fn run_ui() -> Result<()> {
if let Page::Register(page) = &router.current {
let _ = CursorManager::update_for_mode(page.editor.mode());
}
if let Page::AddTable(page) = &router.current {
let _ = CursorManager::update_for_mode(page.editor.mode());
}
if let Page::AddLogic(page) = &router.current {
let _ = CursorManager::update_for_mode(page.editor.mode());
}