diff --git a/README.md b/README.md index adc7c0a..c6dd32f 100644 --- a/README.md +++ b/README.md @@ -95,7 +95,6 @@ Then you can run `toru new` to create your first task. - Error if any circular dependencies are introduced - Make sure dependencies written to file are only those that could be successfully created - List dependencies as a tree on note view below info -- Statistics - - Completed tasks over last x days - - Improve formatting to terminal to make easier to read for `tracked` command - Automatically added recurring notes system +- Visual changes + - All tabled, listed commands need to have cleaner and clearer output, more consistent with viewing individual tasks diff --git a/src/main.rs b/src/main.rs index f0f4340..8426673 100644 --- a/src/main.rs +++ b/src/main.rs @@ -109,10 +109,16 @@ enum Command { #[derive(clap::Subcommand, Debug, PartialEq, Eq)] enum StatsCommand { + /// View time tracked per tag recently. Tracked { #[clap(short, long, default_value_t=7)] days : u16, }, + /// View recently completed tasks. + Completed { + #[clap(short, long, default_value_t=7)] + days : u16, + }, } #[derive(clap::Subcommand, Debug, PartialEq, Eq)] @@ -281,6 +287,9 @@ fn program() -> Result<(), error::Error> { match command { Tracked { days } => { stats::time_per_tag(days, vault_folder)?; + }, + Completed { days } => { + stats::completed_tasks(days, vault_folder)?; } } }, diff --git a/src/stats.rs b/src/stats.rs index 1f18583..2c9702f 100644 --- a/src/stats.rs +++ b/src/stats.rs @@ -3,6 +3,34 @@ use crate::error; use std::path; use std::collections::BTreeMap; +use chrono::SubsecRound; + +pub fn completed_tasks(days : u16, vault_folder : &path::Path) -> Result<(), error::Error> { + let tasks = tasks::Task::load_all(vault_folder, true)?; + + let mut table = comfy_table::Table::new(); + table + .load_preset(comfy_table::presets::UTF8_FULL) + .apply_modifier(comfy_table::modifiers::UTF8_ROUND_CORNERS) + .set_content_arrangement(comfy_table::ContentArrangement::Dynamic); + table.set_header(vec!["Task", "Completed"]); + + for task in tasks { + if let Some(completed_date) = task.data.completed { + let time_diff = chrono::Local::now().naive_local() - completed_date; + if time_diff < chrono::Duration::days(i64::from(days)) && time_diff > chrono::Duration::zero() { + table.add_row(vec![ + task.data.name.clone(), + completed_date.round_subsecs(0).to_string() + ]); + } + } + } + + println!("{}", table); + + Ok(()) +} pub fn time_per_tag(days : u16, vault_folder : &path::Path) -> Result<(), error::Error> {