tabs
This commit is contained in:
20
src/app.rs
20
src/app.rs
@@ -14,6 +14,8 @@ pub struct App {
|
|||||||
pub selected_account_input: AccountInput,
|
pub selected_account_input: AccountInput,
|
||||||
pub current_input: String,
|
pub current_input: String,
|
||||||
pub tr_types: Vec<TransactionType>,
|
pub tr_types: Vec<TransactionType>,
|
||||||
|
pub selected_tab: usize,
|
||||||
|
pub tabs: Vec<String>,
|
||||||
pub connection: Connection,
|
pub connection: Connection,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -40,6 +42,14 @@ impl App {
|
|||||||
selected_account_input: AccountInput::Asset,
|
selected_account_input: AccountInput::Asset,
|
||||||
current_input: String::new(),
|
current_input: String::new(),
|
||||||
tr_types: data_layer::get_transaction_types(&con),
|
tr_types: data_layer::get_transaction_types(&con),
|
||||||
|
selected_tab: 0,
|
||||||
|
tabs: [
|
||||||
|
"Transactions".to_string(),
|
||||||
|
"Chart".to_string(),
|
||||||
|
"Chart 2".to_string(),
|
||||||
|
"Chart 3".to_string(),
|
||||||
|
]
|
||||||
|
.to_vec(),
|
||||||
connection: con,
|
connection: con,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -258,4 +268,14 @@ impl App {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pub fn next_tab(&mut self) {
|
||||||
|
if self.selected_tab < self.tabs.len() {
|
||||||
|
self.selected_tab += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn previous_tab(&mut self) {
|
||||||
|
if self.selected_tab > 0 {
|
||||||
|
self.selected_tab -= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
12
src/main.rs
12
src/main.rs
@@ -90,6 +90,18 @@ where
|
|||||||
app.previous_tr();
|
app.previous_tr();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
KeyCode::Char('l') => match app.current_widget {
|
||||||
|
CurrentWidget::AccountList => {}
|
||||||
|
CurrentWidget::TrxList => {
|
||||||
|
app.next_tab();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
KeyCode::Char('h') => match app.current_widget {
|
||||||
|
CurrentWidget::AccountList => {}
|
||||||
|
CurrentWidget::TrxList => {
|
||||||
|
app.previous_tab();
|
||||||
|
}
|
||||||
|
},
|
||||||
KeyCode::Char('n') => match app.current_widget {
|
KeyCode::Char('n') => match app.current_widget {
|
||||||
CurrentWidget::AccountList => {
|
CurrentWidget::AccountList => {
|
||||||
app.current_screen = CurrentScreen::NewAccount;
|
app.current_screen = CurrentScreen::NewAccount;
|
||||||
|
|||||||
91
src/ui.rs
91
src/ui.rs
@@ -3,7 +3,7 @@ use ratatui::{
|
|||||||
Frame,
|
Frame,
|
||||||
layout::{Constraint, Direction, Layout, Rect},
|
layout::{Constraint, Direction, Layout, Rect},
|
||||||
style::{Color, Modifier, Style, palette::tailwind::SLATE},
|
style::{Color, Modifier, Style, palette::tailwind::SLATE},
|
||||||
text::{Line, Text},
|
text::{Line, Span, Text},
|
||||||
widgets::{
|
widgets::{
|
||||||
Block, Borders, Clear, HighlightSpacing, List, ListItem, Paragraph, Row, StatefulWidget,
|
Block, Borders, Clear, HighlightSpacing, List, ListItem, Paragraph, Row, StatefulWidget,
|
||||||
Table, Wrap,
|
Table, Wrap,
|
||||||
@@ -32,6 +32,7 @@ pub fn ui(frame: &mut Frame, app: &mut App) {
|
|||||||
.borders(Borders::ALL)
|
.borders(Borders::ALL)
|
||||||
.border_style(Style::new().fg(Color::DarkGray));
|
.border_style(Style::new().fg(Color::DarkGray));
|
||||||
let mut trx_block = Block::default()
|
let mut trx_block = Block::default()
|
||||||
|
.title(build_tab_title(app.selected_tab, app.tabs.clone()))
|
||||||
.borders(Borders::ALL)
|
.borders(Borders::ALL)
|
||||||
.border_style(Style::new().fg(Color::DarkGray));
|
.border_style(Style::new().fg(Color::DarkGray));
|
||||||
|
|
||||||
@@ -68,40 +69,43 @@ pub fn ui(frame: &mut Frame, app: &mut App) {
|
|||||||
};
|
};
|
||||||
frame.render_widget(Paragraph::new(info).block(info_block), right_layout[0]);
|
frame.render_widget(Paragraph::new(info).block(info_block), right_layout[0]);
|
||||||
|
|
||||||
let trx_header = Row::new(["Date", "Type", "Amount", "Description"]);
|
if app.selected_tab == 0 {
|
||||||
let trx_rows = app.get_list_trx().into_iter().map(|tr| {
|
let trx_header = Row::new(["Date", "Type", "Amount", "Description"]);
|
||||||
Row::new([
|
let trx_rows = app.get_list_trx().into_iter().map(|tr| {
|
||||||
tr.get_date().format("%Y-%m-%d").to_string(),
|
Row::new([
|
||||||
tr.get_type().get_description(),
|
tr.get_date().format("%Y-%m-%d").to_string(),
|
||||||
tr.get_amount().to_string(),
|
tr.get_type().get_description(),
|
||||||
tr.get_desc(),
|
tr.get_amount().to_string(),
|
||||||
])
|
tr.get_desc(),
|
||||||
.style(Style::new().fg(if tr.get_amount() > 0.0 {
|
])
|
||||||
Color::Green
|
.style(Style::new().fg(if tr.get_amount() > 0.0 {
|
||||||
} else {
|
Color::Green
|
||||||
Color::Red
|
} else {
|
||||||
}))
|
Color::Red
|
||||||
});
|
}))
|
||||||
let widths = [
|
});
|
||||||
Constraint::Percentage(30),
|
let widths = [
|
||||||
Constraint::Percentage(20),
|
Constraint::Percentage(30),
|
||||||
Constraint::Percentage(20),
|
Constraint::Percentage(20),
|
||||||
Constraint::Percentage(50),
|
Constraint::Percentage(20),
|
||||||
];
|
Constraint::Percentage(50),
|
||||||
let trx_table = Table::new(trx_rows, widths)
|
];
|
||||||
.block(trx_block)
|
let trx_table = Table::new(trx_rows, widths)
|
||||||
.header(trx_header)
|
.block(trx_block)
|
||||||
.row_highlight_style(SELECTED_STYLE)
|
.header(trx_header)
|
||||||
.highlight_symbol(">")
|
.row_highlight_style(SELECTED_STYLE)
|
||||||
.highlight_spacing(HighlightSpacing::Always)
|
.highlight_symbol(">")
|
||||||
.column_spacing(1);
|
.highlight_spacing(HighlightSpacing::Always)
|
||||||
|
.column_spacing(1);
|
||||||
|
|
||||||
StatefulWidget::render(
|
StatefulWidget::render(
|
||||||
trx_table,
|
trx_table,
|
||||||
right_layout[1],
|
right_layout[1],
|
||||||
frame.buffer_mut(),
|
frame.buffer_mut(),
|
||||||
&mut app.trx_table.state,
|
&mut app.trx_table.state,
|
||||||
);
|
);
|
||||||
|
} else if app.selected_tab == 1 {
|
||||||
|
}
|
||||||
|
|
||||||
if let CurrentScreen::NewAccount = app.current_screen {
|
if let CurrentScreen::NewAccount = app.current_screen {
|
||||||
let popup = Block::default()
|
let popup = Block::default()
|
||||||
@@ -314,6 +318,25 @@ fn ac_input_str(input: AccountInput, app: &mut App) -> String {
|
|||||||
AccountInput::Asset => app.new_account.get_asset_price().to_string(),
|
AccountInput::Asset => app.new_account.get_asset_price().to_string(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fn build_tab_title(selected: usize, labels: Vec<String>) -> Vec<Span<'static>> {
|
||||||
|
let mut spans = Vec::new();
|
||||||
|
|
||||||
|
for (i, label) in labels.iter().enumerate() {
|
||||||
|
let style = if i == selected {
|
||||||
|
Style::new().fg(Color::Magenta)
|
||||||
|
} else {
|
||||||
|
Style::new()
|
||||||
|
};
|
||||||
|
|
||||||
|
spans.push(Span::raw(label.clone()).style(style));
|
||||||
|
|
||||||
|
if i + 1 < labels.len() {
|
||||||
|
spans.push(Span::raw(" | ").style(Style::new().fg(Color::DarkGray)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return spans;
|
||||||
|
}
|
||||||
impl From<&Account> for ListItem<'_> {
|
impl From<&Account> for ListItem<'_> {
|
||||||
fn from(value: &Account) -> Self {
|
fn from(value: &Account) -> Self {
|
||||||
let line = Line::styled(
|
let line = Line::styled(
|
||||||
|
|||||||
Reference in New Issue
Block a user