create properties component

pull/128/head
Takayuki Maeda 3 years ago
parent 4bcd4802fc
commit 89a1b8ec7c

@ -8,7 +8,8 @@ use crate::{
components::tab::Tab,
components::{
command, ConnectionsComponent, DatabasesComponent, ErrorComponent, HelpComponent,
RecordTableComponent, SqlEditorComponent, TabComponent, TableComponent,
PropertiesComponent, RecordTableComponent, SqlEditorComponent, TabComponent,
TableComponent,
},
config::Config,
};
@ -30,6 +31,7 @@ pub struct App {
constraint_table: TableComponent,
foreign_key_table: TableComponent,
index_table: TableComponent,
properties: PropertiesComponent,
sql_editor: SqlEditorComponent,
focus: Focus,
tab: TabComponent,
@ -52,6 +54,7 @@ impl App {
constraint_table: TableComponent::new(config.key_config.clone()),
foreign_key_table: TableComponent::new(config.key_config.clone()),
index_table: TableComponent::new(config.key_config.clone()),
properties: PropertiesComponent::new(config.key_config.clone()),
sql_editor: SqlEditorComponent::new(config.key_config.clone()),
tab: TabComponent::new(config.key_config.clone()),
help: HelpComponent::new(config.key_config.clone()),
@ -122,6 +125,10 @@ impl App {
self.sql_editor
.draw(f, right_chunks[1], matches!(self.focus, Focus::Table))?;
}
Tab::Properties => {
self.properties
.draw(f, right_chunks[1], matches!(self.focus, Focus::Table))?;
}
}
self.error.draw(f, Rect::default(), false)?;
self.help.draw(f, Rect::default(), false)?;
@ -193,6 +200,9 @@ impl App {
async fn update_table(&mut self) -> anyhow::Result<()> {
if let Some((database, table)) = self.databases.tree().selected_table() {
self.properties
.update(database.clone(), table.clone(), self.pool.as_ref().unwrap())
.await?;
self.focus = Focus::Table;
self.record_table.reset();
let (headers, records) = self
@ -453,6 +463,11 @@ impl App {
return Ok(EventState::Consumed);
};
}
Tab::Properties => {
if self.properties.event(key)?.is_consumed() {
return Ok(EventState::Consumed);
};
}
};
}
}

@ -135,6 +135,13 @@ pub fn tab_sql_editor(key: &KeyConfig) -> CommandText {
CommandText::new(format!("SQL [{}]", key.tab_sql_editor), CMD_GROUP_TABLE)
}
pub fn tab_properties(key: &KeyConfig) -> CommandText {
CommandText::new(
format!("Properties [{}]", key.tab_properties),
CMD_GROUP_TABLE,
)
}
pub fn toggle_tabs(key_config: &KeyConfig) -> CommandText {
CommandText::new(
format!(

@ -5,6 +5,7 @@ pub mod database_filter;
pub mod databases;
pub mod error;
pub mod help;
pub mod properties;
pub mod record_table;
pub mod sql_editor;
pub mod tab;
@ -24,6 +25,7 @@ pub use database_filter::DatabaseFilterComponent;
pub use databases::DatabasesComponent;
pub use error::ErrorComponent;
pub use help::HelpComponent;
pub use properties::PropertiesComponent;
pub use record_table::RecordTableComponent;
pub use sql_editor::SqlEditorComponent;
pub use tab::TabComponent;

@ -0,0 +1,190 @@
use super::{Component, EventState, StatefulDrawableComponent};
use crate::components::command::{self, CommandInfo};
use crate::components::TableComponent;
use crate::config::KeyConfig;
use crate::database::Pool;
use crate::event::Key;
use anyhow::Result;
use async_trait::async_trait;
use database_tree::{Database, Table as DTable};
use strum_macros::EnumIter;
use tui::{
backend::Backend,
layout::{Constraint, Direction, Layout, Rect},
style::{Color, Style},
widgets::{Block, Borders, List, ListItem},
Frame,
};
#[derive(Debug, EnumIter)]
pub enum Focus {
Column,
Constraint,
ForeignKey,
Index,
}
impl std::fmt::Display for Focus {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{:?}", self)
}
}
pub struct PropertiesComponent {
table: Option<(Database, DTable)>,
column_table: TableComponent,
constraint_table: TableComponent,
foreign_key_table: TableComponent,
index_table: TableComponent,
focus: Focus,
key_config: KeyConfig,
}
impl PropertiesComponent {
pub fn new(key_config: KeyConfig) -> Self {
Self {
table: None,
column_table: TableComponent::new(key_config.clone()),
constraint_table: TableComponent::new(key_config.clone()),
foreign_key_table: TableComponent::new(key_config.clone()),
index_table: TableComponent::new(key_config.clone()),
focus: Focus::Column,
key_config,
}
}
fn focused_component(&mut self) -> &mut TableComponent {
match self.focus {
Focus::Column => &mut self.column_table,
Focus::Constraint => &mut self.constraint_table,
Focus::ForeignKey => &mut self.foreign_key_table,
Focus::Index => &mut self.index_table,
}
}
pub async fn update(
&mut self,
database: Database,
table: DTable,
pool: &Box<dyn Pool>,
) -> Result<()> {
self.column_table.reset();
let columns = pool.get_columns(&database, &table).await?;
if !columns.is_empty() {
self.column_table.update(
columns
.iter()
.map(|c| c.columns())
.collect::<Vec<Vec<String>>>(),
columns.get(0).unwrap().fields(),
database.clone(),
table.clone(),
);
}
self.constraint_table.reset();
let constraints = pool.get_constraints(&database, &table).await?;
if !constraints.is_empty() {
self.constraint_table.update(
constraints
.iter()
.map(|c| c.columns())
.collect::<Vec<Vec<String>>>(),
constraints.get(0).unwrap().fields(),
database.clone(),
table.clone(),
);
}
self.foreign_key_table.reset();
let foreign_keys = pool.get_foreign_keys(&database, &table).await?;
if !foreign_keys.is_empty() {
self.foreign_key_table.update(
foreign_keys
.iter()
.map(|c| c.columns())
.collect::<Vec<Vec<String>>>(),
foreign_keys.get(0).unwrap().fields(),
database.clone(),
table.clone(),
);
}
self.index_table.reset();
let indexes = pool.get_indexes(&database, &table).await?;
if !indexes.is_empty() {
self.index_table.update(
indexes
.iter()
.map(|c| c.columns())
.collect::<Vec<Vec<String>>>(),
indexes.get(0).unwrap().fields(),
database.clone(),
table.clone(),
);
}
Ok(())
}
pub fn reset(&mut self) {
// self.table.reset();
// self.filter.reset();
}
fn tab_names(&self) -> Vec<String> {
vec![
command::tab_columns(&self.key_config).name,
command::tab_constraints(&self.key_config).name,
command::tab_foreign_keys(&self.key_config).name,
command::tab_indexes(&self.key_config).name,
command::tab_sql_editor(&self.key_config).name,
command::tab_properties(&self.key_config).name,
]
}
}
impl StatefulDrawableComponent for PropertiesComponent {
fn draw<B: Backend>(&mut self, f: &mut Frame<B>, area: Rect, focused: bool) -> Result<()> {
let layout = Layout::default()
.direction(Direction::Horizontal)
.constraints(vec![Constraint::Length(20), Constraint::Min(1)])
.split(area);
let tab_names = self
.tab_names()
.iter()
.enumerate()
.map(|(i, c)| {
ListItem::new(c.to_string()).style(if i == 0 {
Style::default().bg(Color::Blue)
} else {
Style::default()
})
})
.collect::<Vec<ListItem>>();
let tab_list = List::new(tab_names)
.block(Block::default().borders(Borders::ALL).style(if focused {
Style::default()
} else {
Style::default().fg(Color::DarkGray)
}))
.style(Style::default());
f.render_widget(tab_list, layout[0]);
self.focused_component().draw(f, layout[1], focused)?;
Ok(())
}
}
#[async_trait]
impl Component for PropertiesComponent {
fn commands(&self, out: &mut Vec<CommandInfo>) {}
fn event(&mut self, key: Key) -> Result<EventState> {
self.focused_component().event(key)?;
Ok(EventState::NotConsumed)
}
async fn async_event(&mut self, _key: Key, pool: &Box<dyn Pool>) -> Result<EventState> {
Ok(EventState::NotConsumed)
}
}

@ -21,6 +21,7 @@ pub enum Tab {
ForeignKeys,
Indexes,
Sql,
Properties,
}
impl std::fmt::Display for Tab {
@ -54,6 +55,7 @@ impl TabComponent {
command::tab_foreign_keys(&self.key_config).name,
command::tab_indexes(&self.key_config).name,
command::tab_sql_editor(&self.key_config).name,
command::tab_properties(&self.key_config).name,
]
}
}
@ -92,8 +94,14 @@ impl Component for TabComponent {
self.selected_tab = Tab::ForeignKeys;
return Ok(EventState::Consumed);
} else if key == self.key_config.tab_indexes {
self.selected_tab = Tab::Indexes;
return Ok(EventState::Consumed);
} else if key == self.key_config.tab_sql_editor {
self.selected_tab = Tab::Sql;
return Ok(EventState::Consumed);
} else if key == self.key_config.tab_properties {
self.selected_tab = Tab::Properties;
return Ok(EventState::Consumed);
}
Ok(EventState::NotConsumed)
}

@ -104,9 +104,10 @@ pub struct KeyConfig {
pub tab_constraints: Key,
pub tab_foreign_keys: Key,
pub tab_indexes: Key,
pub tab_sql_editor: Key,
pub tab_properties: Key,
pub extend_or_shorten_widget_width_to_right: Key,
pub extend_or_shorten_widget_width_to_left: Key,
pub tab_sql_editor: Key,
}
impl Default for KeyConfig {
@ -142,9 +143,10 @@ impl Default for KeyConfig {
tab_constraints: Key::Char('3'),
tab_foreign_keys: Key::Char('4'),
tab_indexes: Key::Char('5'),
tab_sql_editor: Key::Char('6'),
tab_properties: Key::Char('7'),
extend_or_shorten_widget_width_to_right: Key::Char('>'),
extend_or_shorten_widget_width_to_left: Key::Char('<'),
tab_sql_editor: Key::Char('6'),
}
}
}

Loading…
Cancel
Save