From 6011682296a68302ff151e7a085a9d60d4afb8be Mon Sep 17 00:00:00 2001 From: Jesse Luehrs Date: Sat, 17 Aug 2019 06:49:51 -0400 Subject: add support for refreshing the list contents --- src/views/txn_table.rs | 171 +++++++++++++++++++++++++++++++++---------------- src/ynab/budget.rs | 5 ++ src/ynab/client.rs | 11 ++-- 3 files changed, 127 insertions(+), 60 deletions(-) diff --git a/src/views/txn_table.rs b/src/views/txn_table.rs index 042131c..c952ebc 100644 --- a/src/views/txn_table.rs +++ b/src/views/txn_table.rs @@ -208,62 +208,7 @@ fn txn_table( txn.selected = !txn.selected; } }); - - let outflows: Vec<_> = s - .call_on_id("outflows_table", |v: &mut TxnTableView| { - v.borrow_items() - .iter() - .filter(|t| t.selected) - .map(|t| t.amount) - .collect() - }) - .unwrap(); - let inflows: Vec<_> = s - .call_on_id("inflows_table", |v: &mut TxnTableView| { - v.borrow_items() - .iter() - .filter(|t| t.selected) - .map(|t| t.amount) - .collect() - }) - .unwrap(); - let outflow: i64 = outflows.iter().sum(); - let inflow: i64 = inflows.iter().sum(); - let amount = outflow + inflow; - s.call_on_id( - "selected_total", - |v: &mut cursive::views::TextView| { - let mut sstr = - cursive::utils::markup::StyledString::plain( - "Selected: ", - ); - let color = if amount == 0 - && outflows.len() + inflows.len() != 0 - { - cursive::theme::Color::Dark( - cursive::theme::BaseColor::Green, - ) - } else { - cursive::theme::Color::TerminalDefault - }; - sstr.append( - cursive::utils::markup::StyledString::styled( - crate::ynab::format_amount(amount), - color, - ), - ); - sstr.append(format!( - " ({} transaction{}", - outflows.len() + inflows.len(), - if outflows.len() + inflows.len() == 1 { - ") " - } else { - "s)" - } - )); - v.set_content(sstr); - }, - ); + render_selected_total(s); }) .on_event('h', |s| { s.on_event(cursive::event::Event::Key(cursive::event::Key::Left)) @@ -288,6 +233,73 @@ fn txn_table( v.set_selected_row(v.len() - 1); }) .unwrap(); + }) + .on_event('r', move |s| { + let budget: &mut crate::ynab::Budget = s.user_data().unwrap(); + budget.refresh(); + + let mut inflows: Vec<_> = budget + .reimbursables() + .iter() + .filter(|t| !t.reimbursed && t.amount > 0) + .cloned() + .collect(); + s.call_on_id("inflows_table", |v: &mut TxnTableView| { + let selected: std::collections::HashSet<_> = v + .borrow_items() + .iter() + .filter(|t| t.selected) + .map(|t| t.id.clone()) + .collect(); + let row = v + .item() + .and_then(|idx| v.borrow_item(idx).map(|t| t.id.clone())); + for mut t in inflows.iter_mut() { + if selected.contains(&t.id) { + t.selected = true; + } + } + let idx = row + .and_then(|id| inflows.iter().position(|t| t.id == id)); + v.set_items(inflows); + if let Some(idx) = idx { + v.set_selected_item(idx); + } + }) + .unwrap(); + + let budget: &mut crate::ynab::Budget = s.user_data().unwrap(); + let mut outflows: Vec<_> = budget + .reimbursables() + .iter() + .filter(|t| !t.reimbursed && t.amount <= 0) + .cloned() + .collect(); + s.call_on_id("outflows_table", |v: &mut TxnTableView| { + let selected: std::collections::HashSet<_> = v + .borrow_items() + .iter() + .filter(|t| t.selected) + .map(|t| t.id.clone()) + .collect(); + let row = v + .item() + .and_then(|idx| v.borrow_item(idx).map(|t| t.id.clone())); + for mut t in outflows.iter_mut() { + if selected.contains(&t.id) { + t.selected = true; + } + } + let idx = row + .and_then(|id| outflows.iter().position(|t| t.id == id)); + v.set_items(outflows); + if let Some(idx) = idx { + v.set_selected_item(idx); + } + }) + .unwrap(); + + render_selected_total(s); }); TableView { view } } @@ -334,3 +346,50 @@ pub fn txn_tables(budget: &crate::ynab::Budget) -> impl cursive::view::View { layout } + +fn render_selected_total(s: &mut cursive::Cursive) { + let outflows: Vec<_> = s + .call_on_id("outflows_table", |v: &mut TxnTableView| { + v.borrow_items() + .iter() + .filter(|t| t.selected) + .map(|t| t.amount) + .collect() + }) + .unwrap(); + let inflows: Vec<_> = s + .call_on_id("inflows_table", |v: &mut TxnTableView| { + v.borrow_items() + .iter() + .filter(|t| t.selected) + .map(|t| t.amount) + .collect() + }) + .unwrap(); + let outflow: i64 = outflows.iter().sum(); + let inflow: i64 = inflows.iter().sum(); + let amount = outflow + inflow; + s.call_on_id("selected_total", |v: &mut cursive::views::TextView| { + let mut sstr = + cursive::utils::markup::StyledString::plain("Selected: "); + let color = if amount == 0 && outflows.len() + inflows.len() != 0 { + cursive::theme::Color::Dark(cursive::theme::BaseColor::Green) + } else { + cursive::theme::Color::TerminalDefault + }; + sstr.append(cursive::utils::markup::StyledString::styled( + crate::ynab::format_amount(amount), + color, + )); + sstr.append(format!( + " ({} transaction{}", + outflows.len() + inflows.len(), + if outflows.len() + inflows.len() == 1 { + ") " + } else { + "s)" + } + )); + v.set_content(sstr); + }); +} diff --git a/src/ynab/budget.rs b/src/ynab/budget.rs index c5a9cde..1d3b80a 100644 --- a/src/ynab/budget.rs +++ b/src/ynab/budget.rs @@ -17,6 +17,11 @@ impl Budget { } } + pub fn refresh(&mut self) { + self.budget = self.client.default_budget(); + self.reimbursables = Self::get_reimbursables(&self.budget) + } + pub fn name(&self) -> String { self.budget.name.clone() } diff --git a/src/ynab/client.rs b/src/ynab/client.rs index 9467750..9e2d3ea 100644 --- a/src/ynab/client.rs +++ b/src/ynab/client.rs @@ -15,17 +15,20 @@ impl Client { } } - pub fn into_default_budget(self) -> super::budget::Budget { + pub fn default_budget(&self) -> ynab_api::models::BudgetDetail { let budgets = self.api.budgets_api().get_budgets().unwrap().data.budgets; let budget = budgets.iter().next().unwrap(); - let full_budget = self - .api + self.api .budgets_api() .get_budget_by_id(&budget.id, 0) .unwrap() .data - .budget; + .budget + } + + pub fn into_default_budget(self) -> super::budget::Budget { + let full_budget = self.default_budget(); super::budget::Budget::new(self, full_budget) } -- cgit v1.2.3