From c15420643aa0d105540f9e8f5b6028ac44283088 Mon Sep 17 00:00:00 2001 From: scoobybejesus Date: Fri, 29 Nov 2019 17:59:52 -0500 Subject: [PATCH] Added viewable, expandable list of reports to be exported in print-tui. --- Cargo.toml | 2 +- src/mytui/app.rs | 59 +++++++++++++++++++++++++------------- src/mytui/ui.rs | 74 +++++++++++++++++++++++++++++++++--------------- 3 files changed, 91 insertions(+), 44 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index cd97c33..9a2cce4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cryptools" -version = "0.8.3" +version = "0.8.4" authors = ["scoobybejesus "] edition = "2018" description = "Command-line utility for processing cryptocurrency transactions into 'lots' and 'movements'." diff --git a/src/mytui/app.rs b/src/mytui/app.rs index 636de31..cde934b 100644 --- a/src/mytui/app.rs +++ b/src/mytui/app.rs @@ -56,7 +56,8 @@ pub struct PrintWindow<'a> { pub title: &'a str, pub should_quit: bool, pub tasks: ListState<(&'a str)>, - pub to_print: Vec, + pub to_print_by_idx: Vec, + pub to_print_by_title: Vec<(&'a str)>, } impl<'a> PrintWindow<'a> { @@ -66,7 +67,8 @@ impl<'a> PrintWindow<'a> { title, should_quit: false, tasks: ListState::new(REPORTS.to_vec()), - to_print: Vec::with_capacity(REPORTS.len() + 3), + to_print_by_idx: Vec::with_capacity(REPORTS.len()), + to_print_by_title: Vec::with_capacity(REPORTS.len()), } } @@ -83,33 +85,44 @@ impl<'a> PrintWindow<'a> { match c { 'q' => { - self.to_print = Vec::with_capacity(0); + self.to_print_by_idx = Vec::with_capacity(0); self.should_quit = true; } 'p' => { - Self::change_vec_to_chrono_order_and_dedup(&mut self.to_print); self.should_quit = true; } 'x' => { - self.to_print.push(self.tasks.selected) + let selected = self.tasks.selected; + if self.to_print_by_idx.contains(&selected) {} else { + self.to_print_by_idx.push(selected); + self.to_print_by_title.push(self.tasks.items[selected]) + } + Self::change_vecs_to_chrono_order(&mut self.to_print_by_idx, &mut self.to_print_by_title); + self.tasks.select_next(); + } + 'd' => { + let selected_idx = self.tasks.selected; + self.to_print_by_idx.retain(|&x| x != selected_idx ); + let selected_str = self.tasks.items[selected_idx]; + self.to_print_by_title.retain(|&x| x != selected_str ); + self.tasks.select_previous(); } _ => {} } } - fn change_vec_to_chrono_order_and_dedup(vec: &mut Vec) { + fn change_vecs_to_chrono_order(vec: &mut Vec, strvec: &mut Vec<&str>) { let length = vec.len(); for _ in 0..length { for j in 0..length-1 { if vec[j] > vec[j+1] { - vec.swap(j, j+1) + vec.swap(j, j+1); + strvec.swap(j, j+1) } - } } - vec.dedup(); } } @@ -124,11 +137,13 @@ pub fn export( let reports = REPORTS.to_vec(); - for report in app.to_print.iter() { + println!("Attempting to export:"); - println!("Exporting: {}", reports[*report]); + for report_idx in app.to_print_by_idx.iter() { - match report + 1 { + println!(" {}", reports[*report_idx]); + + match report_idx + 1 { 1 => { export_csv::_1_account_sums_to_csv( @@ -202,17 +217,21 @@ pub fn export( )?; } 10 => { - export_je::prepare_non_lk_journal_entries( - &settings, - &action_records_map, - &raw_acct_map, - &account_map, - &transactions_map, - )?; + if !settings.lk_treatment_enabled { + export_je::prepare_non_lk_journal_entries( + &settings, + &action_records_map, + &raw_acct_map, + &account_map, + &transactions_map, + )?; + } else { + println!(" *Skipping non-like-kind report: {}", reports[*report_idx]); + } } _ => {} } } - + println!("Successfully exported."); Ok(()) } \ No newline at end of file diff --git a/src/mytui/ui.rs b/src/mytui/ui.rs index c956437..93dddd9 100644 --- a/src/mytui/ui.rs +++ b/src/mytui/ui.rs @@ -5,7 +5,7 @@ use std::io; use ::tui::Terminal; use ::tui::style::{Color, Modifier, Style}; -use ::tui::widgets::{Widget, Block, Borders, SelectableList, Text, Paragraph}; +use ::tui::widgets::{Widget, Block, Borders, SelectableList, Text, Paragraph, List}; use ::tui::layout::{Layout, Constraint, Direction}; use ::tui::backend::Backend; @@ -16,49 +16,77 @@ pub fn draw(terminal: &mut Terminal, app: &PrintWindow) -> Result terminal.draw(|mut f| { - let chunks = Layout::default() + let instructions = [ + Text::raw("\nPress '"), + Text::styled("x", Style::default().fg(Color::Cyan).modifier(Modifier::BOLD)), + Text::raw("' to add the selected report to the list of reports to print/export.\n"), + Text::raw("\nPress '"), + Text::styled("d", Style::default().fg(Color::Yellow).modifier(Modifier::BOLD)), + Text::raw("' to delete the selected report from the list of reports to print/export.\n"), + Text::raw("\nPress '"), + Text::styled("p", Style::default().fg(Color::Green).modifier(Modifier::BOLD)), + Text::raw("' to print/export the selected reports.\n"), + Text::raw("\nPress '"), + Text::styled("q", Style::default().fg(Color::Red).modifier(Modifier::BOLD)), + Text::raw("' to quit without printing.\n\n"), + ]; + let rpts_to_prnt = app.to_print_by_title.iter().map(|&rpt_to_prnt| { + Text::styled( + format!("{}", rpt_to_prnt), + Style::default().fg(Color::White) + ) + }); + + let top_level_chunks = Layout::default() .constraints([ Constraint::Length(1), - Constraint::Length(8), + Constraint::Length(2 + (instructions.len() as u16 / 3 * 2)), // 2 for title "Instructions", plus 3 TEXT array elements/instruction Constraint::Length(REPORTS.len() as u16 + 2), - Constraint::Percentage(35) + Constraint::Length(rpts_to_prnt.len() as u16 + 2), + Constraint::Length(1), ].as_ref()) .split(f.size()); - let text = [ - Text::raw("\nPress '"), - Text::styled("x", Style::default().fg(Color::LightGreen)), - Text::raw("' to add the selected report to the list of reports to print/export.\n"), - Text::raw("\nPress '"), - Text::styled("p", Style::default().fg(Color::Green)), - Text::raw("' to print/export the selected reports.\n"), - Text::raw("\nPress '"), - Text::styled("q", Style::default().fg(Color::Red)), - Text::raw("' to quit without printing.\n\n"), - ]; - - Paragraph::new(text.iter()) + Paragraph::new(instructions.iter()) .block( Block::default() .borders(Borders::NONE) .title("Instructions") - .title_style(Style::default().fg(Color::Blue).modifier(Modifier::BOLD)), + .title_style(Style::default().fg(Color::Blue).modifier(Modifier::BOLD).modifier(Modifier::UNDERLINED)), ) .wrap(true) - .render(&mut f, chunks[1]); + .render(&mut f, top_level_chunks[1]); - let draw_chunk = Layout::default() + let level_2_chunks = Layout::default() .constraints([Constraint::Percentage(10), Constraint::Percentage(80),Constraint::Percentage(10),].as_ref()) .direction(Direction::Horizontal) - .split(chunks[2]); + .split(top_level_chunks[2]); SelectableList::default() - .block(Block::default().borders(Borders::ALL).title("Report List")) + .block( + Block::default() + .borders(Borders::ALL) + .title("Reports available for exporting") + .title_style(Style::default().fg(Color::White).modifier(Modifier::BOLD).modifier(Modifier::UNDERLINED)) + ) .items(&app.tasks.items) .select(Some(app.tasks.selected)) .highlight_style(Style::default().fg(Color::Yellow).modifier(Modifier::BOLD)) .highlight_symbol(">") - .render(&mut f, draw_chunk[1]); + .render(&mut f, level_2_chunks[1]); + let level_2_chunks = Layout::default() + .constraints([Constraint::Percentage(10), Constraint::Percentage(80),Constraint::Percentage(10),].as_ref()) + .direction(Direction::Horizontal) + .split(top_level_chunks[3]); + + List::new(rpts_to_prnt) + .block( + Block::default() + .borders(Borders::ALL) + .title("Reports to be exported") + .title_style(Style::default().fg(Color::LightYellow).modifier(Modifier::BOLD).modifier(Modifier::UNDERLINED)) + ) + .render(&mut f, level_2_chunks[1]); }) } \ No newline at end of file