fix: align pane bottoms and wrap navigation help
This commit is contained in:
+1
-1
@@ -5,7 +5,7 @@ edition = "2024"
|
|||||||
description = "Read-only PostgreSQL and SQLite inspection in your terminal"
|
description = "Read-only PostgreSQL and SQLite inspection in your terminal"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
ratatui = { version = "0.30.2", default-features = false, features = ["crossterm"] }
|
ratatui = { version = "0.30.2", default-features = false, features = ["crossterm", "unstable-rendered-line-info"] }
|
||||||
crossterm = "0.29"
|
crossterm = "0.29"
|
||||||
postgres = "0.19"
|
postgres = "0.19"
|
||||||
postgres-native-tls = "0.5"
|
postgres-native-tls = "0.5"
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
- [ ] make sure that sensitive information (e.g. passwords) for configured databases are encrypted in such a way that credentials can't be snatched by malicious programs
|
|
||||||
+10
-5
@@ -159,10 +159,10 @@ impl App {
|
|||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let [header, body, error_area] = Layout::vertical([
|
let [header, error_area, body] = Layout::vertical([
|
||||||
Constraint::Length(1),
|
Constraint::Length(1),
|
||||||
|
Constraint::Length(u16::from(self.error.is_some())),
|
||||||
Constraint::Min(4),
|
Constraint::Min(4),
|
||||||
Constraint::Length(1),
|
|
||||||
])
|
])
|
||||||
.areas(area);
|
.areas(area);
|
||||||
frame.render_widget(
|
frame.render_widget(
|
||||||
@@ -262,7 +262,7 @@ impl App {
|
|||||||
} else if self.page.rows.is_empty() {
|
} else if self.page.rows.is_empty() {
|
||||||
frame.render_widget(
|
frame.render_widget(
|
||||||
Paragraph::new(if self.error.is_some() {
|
Paragraph::new(if self.error.is_some() {
|
||||||
"Could not load rows. See error below."
|
"Could not load rows. See error above."
|
||||||
} else {
|
} else {
|
||||||
"No rows."
|
"No rows."
|
||||||
})
|
})
|
||||||
@@ -361,11 +361,12 @@ mod tests {
|
|||||||
)?;
|
)?;
|
||||||
let mut app = super::App::new(crate::db::Database::open_sqlite(file.path())?)?;
|
let mut app = super::App::new(crate::db::Database::open_sqlite(file.path())?)?;
|
||||||
let mut terminal = ratatui::Terminal::new(ratatui::backend::TestBackend::new(100, 20))?;
|
let mut terminal = ratatui::Terminal::new(ratatui::backend::TestBackend::new(100, 20))?;
|
||||||
for schema in [false, true] {
|
for (schema, error) in [(false, None), (true, None), (false, Some("Read failed"))] {
|
||||||
app.show_schema = schema;
|
app.show_schema = schema;
|
||||||
|
app.error = error.map(str::to_owned);
|
||||||
terminal.draw(|frame| app.draw(frame, frame.area(), true))?;
|
terminal.draw(|frame| app.draw(frame, frame.area(), true))?;
|
||||||
let buffer = terminal.backend().buffer();
|
let buffer = terminal.backend().buffer();
|
||||||
let border: String = (0..100).map(|x| buffer[(x, 18)].symbol()).collect();
|
let border: String = (0..100).map(|x| buffer[(x, 19)].symbol()).collect();
|
||||||
assert!(border.starts_with("└ main.comments [table]"), "{border}");
|
assert!(border.starts_with("└ main.comments [table]"), "{border}");
|
||||||
assert!(border.ends_with('┘'), "{border}");
|
assert!(border.ends_with('┘'), "{border}");
|
||||||
assert!(border.contains(if schema {
|
assert!(border.contains(if schema {
|
||||||
@@ -373,6 +374,10 @@ mod tests {
|
|||||||
} else {
|
} else {
|
||||||
"rows 1–1"
|
"rows 1–1"
|
||||||
}));
|
}));
|
||||||
|
if let Some(error) = error {
|
||||||
|
let message: String = (0..100).map(|x| buffer[(x, 1)].symbol()).collect();
|
||||||
|
assert!(message.starts_with(error), "{message}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-4
@@ -34,8 +34,12 @@ pub fn run(terminal: &mut DefaultTerminal, initial: Option<Database>) -> Result<
|
|||||||
expanded,
|
expanded,
|
||||||
);
|
);
|
||||||
terminal.draw(|frame| {
|
terminal.draw(|frame| {
|
||||||
|
let navigation = Paragraph::new(
|
||||||
|
" Tab focus · Esc explorer · ↑↓/jk move · Enter open · s schema/rows · ←→/hl columns · n/p page · r refresh · c add database · q quit"
|
||||||
|
).wrap(Wrap { trim: true }).style(Style::default().fg(Color::DarkGray));
|
||||||
|
let help_height = navigation.line_count(frame.area().width) as u16;
|
||||||
let [main, help] =
|
let [main, help] =
|
||||||
Layout::vertical([Constraint::Min(1), Constraint::Length(2)]).areas(frame.area());
|
Layout::vertical([Constraint::Min(1), Constraint::Length(help_height)]).areas(frame.area());
|
||||||
let [sidebar, content] = Layout::horizontal([Constraint::Length(32), Constraint::Min(1)])
|
let [sidebar, content] = Layout::horizontal([Constraint::Length(32), Constraint::Min(1)])
|
||||||
.areas(main);
|
.areas(main);
|
||||||
let items = entries.iter().map(|entry| {
|
let items = entries.iter().map(|entry| {
|
||||||
@@ -64,9 +68,7 @@ pub fn run(terminal: &mut DefaultTerminal, initial: Option<Database>) -> Result<
|
|||||||
if let Some(error) = &error {
|
if let Some(error) = &error {
|
||||||
frame.render_widget(Paragraph::new(error.as_str()).style(Style::default().fg(Color::Red)), Rect::new(content.x, content.bottom().saturating_sub(1), content.width, 1));
|
frame.render_widget(Paragraph::new(error.as_str()).style(Style::default().fg(Color::Red)), Rect::new(content.x, content.bottom().saturating_sub(1), content.width, 1));
|
||||||
}
|
}
|
||||||
frame.render_widget(Paragraph::new(
|
frame.render_widget(navigation, help);
|
||||||
" Tab focus · Esc explorer · ↑↓/jk move · Enter open · s schema/rows\n ←→/hl columns · n/p page · r refresh · c add database · q quit"
|
|
||||||
).style(Style::default().fg(Color::DarkGray)), help);
|
|
||||||
if show_form {
|
if show_form {
|
||||||
form.draw(frame);
|
form.draw(frame);
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-2
@@ -39,8 +39,9 @@ Navigation:
|
|||||||
r Refresh relations and the active relation
|
r Refresh relations and the active relation
|
||||||
Connected databases show their tables and views beneath them in the explorer.
|
Connected databases show their tables and views beneath them in the explorer.
|
||||||
Enter on the connected database collapses/expands it without reconnecting.
|
Enter on the connected database collapses/expands it without reconnecting.
|
||||||
Navigation help spans the bottom of the terminal beneath both panes.
|
Navigation help spans the bottom as one line, wrapping only when needed.
|
||||||
Relation, page, and column status appears in the rows/schema bottom border.
|
Explorer and rows/schema bottom borders align; relation/page/column status
|
||||||
|
appears in the rows/schema border. Read errors appear above that pane.
|
||||||
q / Ctrl-C Quit
|
q / Ctrl-C Quit
|
||||||
New database window: Up/Down chooses a provider; Enter starts editing.
|
New database window: Up/Down chooses a provider; Enter starts editing.
|
||||||
Tab/Shift-Tab changes fields; Left/Right changes TLS when that field is focused.
|
Tab/Shift-Tab changes fields; Left/Right changes TLS when that field is focused.
|
||||||
|
|||||||
Reference in New Issue
Block a user