table
This commit is contained in:
15
src/app.rs
15
src/app.rs
@@ -1,4 +1,3 @@
|
|||||||
use ratatui::widgets::ListState;
|
|
||||||
use sqlite::Connection;
|
use sqlite::Connection;
|
||||||
|
|
||||||
use crate::{data_layer, entities::*, enums::*};
|
use crate::{data_layer, entities::*, enums::*};
|
||||||
@@ -7,11 +6,10 @@ pub struct App {
|
|||||||
pub current_screen: CurrentScreen,
|
pub current_screen: CurrentScreen,
|
||||||
pub current_widget: CurrentWidget,
|
pub current_widget: CurrentWidget,
|
||||||
pub acc_list: AccountList,
|
pub acc_list: AccountList,
|
||||||
pub trx_list: TrxList,
|
pub trx_table: TrxTable,
|
||||||
pub new_account: Account,
|
pub new_account: Account,
|
||||||
pub new_transaction: Transaction,
|
pub new_transaction: Transaction,
|
||||||
pub connection: Connection,
|
pub connection: Connection,
|
||||||
exit: bool,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl App {
|
impl App {
|
||||||
@@ -30,11 +28,10 @@ impl App {
|
|||||||
current_screen: CurrentScreen::Main,
|
current_screen: CurrentScreen::Main,
|
||||||
current_widget: CurrentWidget::AccountList,
|
current_widget: CurrentWidget::AccountList,
|
||||||
acc_list: AccountList::new(),
|
acc_list: AccountList::new(),
|
||||||
trx_list: TrxList::new(),
|
trx_table: TrxTable::new(),
|
||||||
new_account: Account::new(0, String::new(), AccountType::Cash),
|
new_account: Account::new(0, String::new(), AccountType::Cash),
|
||||||
new_transaction: Transaction::new_empty(),
|
new_transaction: Transaction::new_empty(),
|
||||||
connection: con,
|
connection: con,
|
||||||
exit: false,
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,16 +48,16 @@ impl App {
|
|||||||
|
|
||||||
pub fn get_list_trx(&mut self) -> Vec<Transaction> {
|
pub fn get_list_trx(&mut self) -> Vec<Transaction> {
|
||||||
let accounts = self
|
let accounts = self
|
||||||
.trx_list
|
.trx_table
|
||||||
.get_trx(self.acc_list.get_selected_id(), &self.connection);
|
.get_trx(self.acc_list.get_selected_id(), &self.connection);
|
||||||
return accounts.to_vec();
|
return accounts.to_vec();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn next_tr(&mut self) {
|
pub fn next_tr(&mut self) {
|
||||||
self.trx_list.state.select_next();
|
self.trx_table.state.select_next();
|
||||||
}
|
}
|
||||||
pub fn previous_tr(&mut self) {
|
pub fn previous_tr(&mut self) {
|
||||||
self.trx_list.state.select_previous();
|
self.trx_table.state.select_previous();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn save_new_account(&mut self) {
|
pub fn save_new_account(&mut self) {
|
||||||
@@ -71,7 +68,7 @@ impl App {
|
|||||||
|
|
||||||
pub fn save_new_tr(&mut self) {
|
pub fn save_new_tr(&mut self) {
|
||||||
let tr = data_layer::upsert_transaction(&self.connection, self.new_transaction.clone());
|
let tr = data_layer::upsert_transaction(&self.connection, self.new_transaction.clone());
|
||||||
self.trx_list.add_tr(tr);
|
self.trx_table.add_tr(tr);
|
||||||
self.new_transaction = Transaction::new_empty();
|
self.new_transaction = Transaction::new_empty();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -101,8 +101,7 @@ pub fn get_accounts(con: &Connection) -> Vec<Account> {
|
|||||||
let mut statement = con.prepare(query).unwrap();
|
let mut statement = con.prepare(query).unwrap();
|
||||||
let mut vec = Vec::<Account>::new();
|
let mut vec = Vec::<Account>::new();
|
||||||
|
|
||||||
let all = Account::new(0, "All".to_string(), AccountType::Cash);
|
vec.push(Account::new(0, "All".to_string(), AccountType::Cash));
|
||||||
vec.push(all);
|
|
||||||
|
|
||||||
while let Ok(State::Row) = statement.next() {
|
while let Ok(State::Row) = statement.next() {
|
||||||
vec.push(Account::new(
|
vec.push(Account::new(
|
||||||
@@ -209,7 +208,7 @@ pub fn upsert_transaction(con: &Connection, tr: Transaction) -> Transaction {
|
|||||||
id,
|
id,
|
||||||
tr.get_account().get_id(),
|
tr.get_account().get_id(),
|
||||||
tr.get_amount(),
|
tr.get_amount(),
|
||||||
tr.get_date(),
|
tr.get_date_utc(),
|
||||||
tr.get_desc(),
|
tr.get_desc(),
|
||||||
tr.get_type().get_id(),
|
tr.get_type().get_id(),
|
||||||
con,
|
con,
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
pub mod account;
|
pub mod account;
|
||||||
pub mod accountlist;
|
pub mod accountlist;
|
||||||
pub mod transaction;
|
pub mod transaction;
|
||||||
pub mod trxlist;
|
pub mod trxtable;
|
||||||
|
|
||||||
pub use account::{Account, AccountType};
|
pub use account::{Account, AccountType};
|
||||||
pub use accountlist::*;
|
pub use accountlist::*;
|
||||||
pub use transaction::{Transaction, TransactionType};
|
pub use transaction::{Transaction, TransactionType};
|
||||||
pub use trxlist::*;
|
pub use trxtable::*;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
use crate::{data_layer, entities::Account};
|
use crate::{data_layer, entities::Account};
|
||||||
use chrono::{DateTime, Utc};
|
use chrono::{DateTime, Local, TimeZone, Utc};
|
||||||
use sqlite::Connection;
|
use sqlite::Connection;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
@@ -58,7 +58,10 @@ impl Transaction {
|
|||||||
return self.amount;
|
return self.amount;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_date(&self) -> DateTime<Utc> {
|
pub fn get_date(&self) -> DateTime<Local> {
|
||||||
|
return Local.from_utc_datetime(&self.date.naive_local());
|
||||||
|
}
|
||||||
|
pub fn get_date_utc(&self) -> DateTime<Utc> {
|
||||||
return self.date;
|
return self.date;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,18 +1,18 @@
|
|||||||
use ratatui::widgets::ListState;
|
use ratatui::widgets::TableState;
|
||||||
use sqlite::Connection;
|
use sqlite::Connection;
|
||||||
|
|
||||||
use crate::{data_layer, entities::*};
|
use crate::{data_layer, entities::*};
|
||||||
|
|
||||||
pub struct TrxList {
|
pub struct TrxTable {
|
||||||
trx: Vec<Transaction>,
|
trx: Vec<Transaction>,
|
||||||
ac_id: i64,
|
ac_id: i64,
|
||||||
pub state: ListState,
|
pub state: TableState,
|
||||||
}
|
}
|
||||||
impl TrxList {
|
impl TrxTable {
|
||||||
pub fn new() -> TrxList {
|
pub fn new() -> TrxTable {
|
||||||
let mut list_state = ListState::default();
|
let mut list_state = TableState::default();
|
||||||
list_state.select_first();
|
list_state.select_first();
|
||||||
return TrxList {
|
return TrxTable {
|
||||||
trx: Vec::new(),
|
trx: Vec::new(),
|
||||||
state: list_state,
|
state: list_state,
|
||||||
ac_id: 0,
|
ac_id: 0,
|
||||||
60
src/ui.rs
60
src/ui.rs
@@ -8,11 +8,12 @@ use ratatui::{
|
|||||||
layout::{Constraint, Direction, Layout, Rect},
|
layout::{Constraint, Direction, Layout, Rect},
|
||||||
style::{Color, Modifier, Style, Stylize, palette::tailwind::SLATE},
|
style::{Color, Modifier, Style, Stylize, palette::tailwind::SLATE},
|
||||||
text::{Line, Text},
|
text::{Line, Text},
|
||||||
widgets::{Block, Borders, HighlightSpacing, List, ListItem, Paragraph, StatefulWidget, Wrap},
|
widgets::{
|
||||||
|
Block, Borders, HighlightSpacing, List, ListItem, Paragraph, Row, StatefulWidget, Table,
|
||||||
|
Wrap,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const NORMAL_ROW_BG: Color = SLATE.c950;
|
|
||||||
const ALT_ROW_BG_COLOR: Color = SLATE.c900;
|
|
||||||
const TEXT_FG_COLOR: Color = SLATE.c200;
|
const TEXT_FG_COLOR: Color = SLATE.c200;
|
||||||
const SELECTED_STYLE: Style = Style::new().bg(SLATE.c800).add_modifier(Modifier::BOLD);
|
const SELECTED_STYLE: Style = Style::new().bg(SLATE.c800).add_modifier(Modifier::BOLD);
|
||||||
|
|
||||||
@@ -48,10 +49,7 @@ pub fn ui(frame: &mut Frame, app: &mut App) {
|
|||||||
.get_list_accounts()
|
.get_list_accounts()
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.map(|(i, acc)| {
|
.map(|(i, acc)| ListItem::from(acc))
|
||||||
let color = alternate_colors(i);
|
|
||||||
ListItem::from(acc).bg(color)
|
|
||||||
})
|
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let list = List::new(ac_items)
|
let list = List::new(ac_items)
|
||||||
@@ -74,27 +72,32 @@ 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_items: Vec<ListItem> = app
|
let trx_header = Row::new(["Date", "Amount", "Description"]);
|
||||||
.get_list_trx()
|
let trx_rows = app.get_list_trx().into_iter().map(|tr| {
|
||||||
.iter()
|
Row::new([
|
||||||
.enumerate()
|
tr.get_date().format("%Y-%m-%d").to_string(),
|
||||||
.map(|(i, tr)| {
|
tr.get_amount().to_string(),
|
||||||
let color = alternate_colors(i);
|
tr.get_desc(),
|
||||||
ListItem::from(tr).bg(color)
|
])
|
||||||
})
|
});
|
||||||
.collect();
|
let widths = [
|
||||||
|
Constraint::Percentage(30),
|
||||||
let trx_list = List::new(trx_items)
|
Constraint::Percentage(20),
|
||||||
|
Constraint::Percentage(50),
|
||||||
|
];
|
||||||
|
let trx_table = Table::new(trx_rows, widths)
|
||||||
.block(trx_block)
|
.block(trx_block)
|
||||||
.highlight_style(SELECTED_STYLE)
|
.header(trx_header)
|
||||||
|
.row_highlight_style(SELECTED_STYLE)
|
||||||
.highlight_symbol(">")
|
.highlight_symbol(">")
|
||||||
.highlight_spacing(HighlightSpacing::Always);
|
.highlight_spacing(HighlightSpacing::Always)
|
||||||
|
.column_spacing(1);
|
||||||
|
|
||||||
StatefulWidget::render(
|
StatefulWidget::render(
|
||||||
trx_list,
|
trx_table,
|
||||||
right_layout[1],
|
right_layout[1],
|
||||||
frame.buffer_mut(),
|
frame.buffer_mut(),
|
||||||
&mut app.trx_list.state,
|
&mut app.trx_table.state,
|
||||||
);
|
);
|
||||||
|
|
||||||
if let CurrentScreen::NewAccount = app.current_screen {
|
if let CurrentScreen::NewAccount = app.current_screen {
|
||||||
@@ -156,13 +159,6 @@ fn centered_rect(percent_x: u16, percent_y: u16, r: Rect) -> Rect {
|
|||||||
])
|
])
|
||||||
.split(popup_layout[1])[1];
|
.split(popup_layout[1])[1];
|
||||||
}
|
}
|
||||||
const fn alternate_colors(i: usize) -> Color {
|
|
||||||
if i % 2 == 0 {
|
|
||||||
NORMAL_ROW_BG
|
|
||||||
} else {
|
|
||||||
ALT_ROW_BG_COLOR
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<&Account> for ListItem<'_> {
|
impl From<&Account> for ListItem<'_> {
|
||||||
fn from(value: &Account) -> Self {
|
fn from(value: &Account) -> Self {
|
||||||
@@ -173,9 +169,3 @@ impl From<&Account> for ListItem<'_> {
|
|||||||
ListItem::new(line)
|
ListItem::new(line)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl From<&Transaction> for ListItem<'_> {
|
|
||||||
fn from(value: &Transaction) -> Self {
|
|
||||||
let line = Line::styled(value.get_desc(), TEXT_FG_COLOR);
|
|
||||||
ListItem::new(line)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user