minor documentation edits; storing completed date; ordering for tracked stats and bug fixed
This commit is contained in:
parent
8fc2b9abd9
commit
fef199cd52
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -825,7 +825,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "toru"
|
name = "toru"
|
||||||
version = "0.1.2"
|
version = "0.1.3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
"clap",
|
"clap",
|
||||||
|
@ -95,10 +95,6 @@ Then you can run `toru new` to create your first task.
|
|||||||
- Error if any circular dependencies are introduced
|
- Error if any circular dependencies are introduced
|
||||||
- Make sure dependencies written to file are only those that could be successfully created
|
- Make sure dependencies written to file are only those that could be successfully created
|
||||||
- List dependencies as a tree on note view below info
|
- List dependencies as a tree on note view below info
|
||||||
- Completed Date
|
|
||||||
- Keep track of completed date, and correctly update upon marking as complete or manual edit
|
|
||||||
- Disallow removing it in a manual edit unless complete is also marked to false
|
|
||||||
- Add to statistics
|
|
||||||
- Statistics
|
- Statistics
|
||||||
- Completed tasks over last x days
|
- Completed tasks over last x days
|
||||||
- Improve formatting to terminal to make easier to read for `tracked` command
|
- Improve formatting to terminal to make easier to read for `tracked` command
|
||||||
|
@ -41,7 +41,7 @@ enum Command {
|
|||||||
View {
|
View {
|
||||||
id_or_name : String,
|
id_or_name : String,
|
||||||
},
|
},
|
||||||
/// Edit a note directly.
|
/// Edit a task directly.
|
||||||
Edit {
|
Edit {
|
||||||
id_or_name : String,
|
id_or_name : String,
|
||||||
/// Edit the info specifically in its own file.
|
/// Edit the info specifically in its own file.
|
||||||
@ -83,7 +83,7 @@ enum Command {
|
|||||||
// - which columns to include
|
// - which columns to include
|
||||||
// - filters which exclude values
|
// - filters which exclude values
|
||||||
},
|
},
|
||||||
/// For tracking time against a note.
|
/// For tracking time against a task.
|
||||||
Track {
|
Track {
|
||||||
id_or_name : String,
|
id_or_name : String,
|
||||||
#[clap(short='H', default_value_t=0)]
|
#[clap(short='H', default_value_t=0)]
|
||||||
@ -294,7 +294,7 @@ fn program() -> Result<(), error::Error> {
|
|||||||
Complete { id_or_name } => {
|
Complete { id_or_name } => {
|
||||||
let id = state.name_or_id_to_id(&id_or_name)?;
|
let id = state.name_or_id_to_id(&id_or_name)?;
|
||||||
let mut task = tasks::Task::load(id, vault_folder, false)?;
|
let mut task = tasks::Task::load(id, vault_folder, false)?;
|
||||||
task.data.complete = true;
|
task.data.completed = Some(chrono::Local::now().naive_local());
|
||||||
task.save()?;
|
task.save()?;
|
||||||
println!("Marked task {} as complete", colour::id(&id.to_string()));
|
println!("Marked task {} as complete", colour::id(&id.to_string()));
|
||||||
},
|
},
|
||||||
|
@ -2,13 +2,13 @@ use crate::tasks;
|
|||||||
use crate::error;
|
use crate::error;
|
||||||
|
|
||||||
use std::path;
|
use std::path;
|
||||||
use std::collections::HashMap;
|
use std::collections::BTreeMap;
|
||||||
|
|
||||||
pub fn time_per_tag(days : u16, vault_folder : &path::Path) -> Result<(), error::Error> {
|
pub fn time_per_tag(days : u16, vault_folder : &path::Path) -> Result<(), error::Error> {
|
||||||
|
|
||||||
let tasks = tasks::Task::load_all(vault_folder, true)?;
|
let tasks = tasks::Task::load_all(vault_folder, true)?;
|
||||||
|
|
||||||
let mut times = HashMap::<String, tasks::Duration>::new();
|
let mut times = BTreeMap::<String, tasks::Duration>::new();
|
||||||
|
|
||||||
for task in &tasks {
|
for task in &tasks {
|
||||||
if !task.data.discarded {
|
if !task.data.discarded {
|
||||||
@ -29,7 +29,7 @@ pub fn time_per_tag(days : u16, vault_folder : &path::Path) -> Result<(), error:
|
|||||||
*time = *time + time_per_tag;
|
*time = *time + time_per_tag;
|
||||||
},
|
},
|
||||||
None => {
|
None => {
|
||||||
times.insert(tag.clone(), time);
|
times.insert(tag.clone(), time_per_tag);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -43,8 +43,8 @@ pub fn time_per_tag(days : u16, vault_folder : &path::Path) -> Result<(), error:
|
|||||||
.set_content_arrangement(comfy_table::ContentArrangement::Dynamic);
|
.set_content_arrangement(comfy_table::ContentArrangement::Dynamic);
|
||||||
table.set_header(vec!["Tag", "Time"]);
|
table.set_header(vec!["Tag", "Time"]);
|
||||||
|
|
||||||
for (tag, duration) in × {
|
|
||||||
|
|
||||||
|
for (tag, duration) in times {
|
||||||
table.add_row(
|
table.add_row(
|
||||||
vec![
|
vec![
|
||||||
tag.clone(),
|
tag.clone(),
|
||||||
|
14
src/tasks.rs
14
src/tasks.rs
@ -76,7 +76,7 @@ pub struct InternalTask {
|
|||||||
pub priority : Priority,
|
pub priority : Priority,
|
||||||
pub due : Option<chrono::NaiveDateTime>,
|
pub due : Option<chrono::NaiveDateTime>,
|
||||||
pub created : chrono::NaiveDateTime,
|
pub created : chrono::NaiveDateTime,
|
||||||
pub complete : bool,
|
pub completed : Option<chrono::NaiveDateTime>,
|
||||||
pub discarded : bool,
|
pub discarded : bool,
|
||||||
pub info : Option<String>,
|
pub info : Option<String>,
|
||||||
pub time_entries : Vec<TimeEntry>,
|
pub time_entries : Vec<TimeEntry>,
|
||||||
@ -109,7 +109,7 @@ impl Task {
|
|||||||
due,
|
due,
|
||||||
time_entries : Vec::new(),
|
time_entries : Vec::new(),
|
||||||
created : chrono::Local::now().naive_local(),
|
created : chrono::Local::now().naive_local(),
|
||||||
complete : false,
|
completed : None,
|
||||||
discarded : false,
|
discarded : false,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -235,7 +235,7 @@ impl Task {
|
|||||||
let discarded = if self.data.discarded { String::from(" (discarded)") } else { String::new() };
|
let discarded = if self.data.discarded { String::from(" (discarded)") } else { String::new() };
|
||||||
|
|
||||||
(
|
(
|
||||||
format!("[{}] {} {}{}", if self.data.complete {"X"} else {" "}, colour::id(id), colour::task_name(&self.data.name), colour::greyed_out(&discarded)),
|
format!("[{}] {} {}{}", if self.data.completed.is_some() {"X"} else {" "}, colour::id(id), colour::task_name(&self.data.name), colour::greyed_out(&discarded)),
|
||||||
5 + self.data.name.chars().count() + id.chars().count() + discarded.chars().count()
|
5 + self.data.name.chars().count() + id.chars().count() + discarded.chars().count()
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
@ -248,7 +248,7 @@ impl Task {
|
|||||||
println!("Created: {}", self.data.created.round_subsecs(0));
|
println!("Created: {}", self.data.created.round_subsecs(0));
|
||||||
|
|
||||||
if let Some(due) = self.data.due {
|
if let Some(due) = self.data.due {
|
||||||
let due = format_due_date(&due, !self.data.complete, true);
|
let due = format_due_date(&due, self.data.completed.is_none(), true);
|
||||||
println!("Due: {}", due);
|
println!("Due: {}", due);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -373,7 +373,7 @@ pub fn list(vault_folder : &path::Path) -> Result<(), error::Error> {
|
|||||||
tasks.sort_by(|t1, t2| t2.data.priority.cmp(&t1.data.priority));
|
tasks.sort_by(|t1, t2| t2.data.priority.cmp(&t1.data.priority));
|
||||||
|
|
||||||
for task in tasks {
|
for task in tasks {
|
||||||
if !task.data.discarded && !task.data.complete {
|
if !task.data.discarded && task.data.completed.is_none() {
|
||||||
|
|
||||||
let duration = TimeEntry::total(&task.data.time_entries);
|
let duration = TimeEntry::total(&task.data.time_entries);
|
||||||
|
|
||||||
@ -384,7 +384,7 @@ pub fn list(vault_folder : &path::Path) -> Result<(), error::Error> {
|
|||||||
format_hash_set(&task.data.tags)?,
|
format_hash_set(&task.data.tags)?,
|
||||||
task.data.priority.to_string(),
|
task.data.priority.to_string(),
|
||||||
if duration == Duration::zero() { String::new() } else { duration.to_string() },
|
if duration == Duration::zero() { String::new() } else { duration.to_string() },
|
||||||
match task.data.due { Some(due) => format_due_date(&due, !task.data.complete, false), None => String::new() },
|
match task.data.due { Some(due) => format_due_date(&due, task.data.completed.is_none(), false), None => String::new() },
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -435,7 +435,7 @@ impl ops::Div<usize> for Duration {
|
|||||||
|
|
||||||
fn div(self, divisor : usize) -> Self::Output {
|
fn div(self, divisor : usize) -> Self::Output {
|
||||||
let total_mins = f64::from(self.hours * 60 + self.minutes);
|
let total_mins = f64::from(self.hours * 60 + self.minutes);
|
||||||
let divided_mins = total_mins / divisor as f64;
|
let divided_mins = total_mins / (divisor as f64);
|
||||||
let divided_mins = divided_mins.round() as u16;
|
let divided_mins = divided_mins.round() as u16;
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
|
Loading…
Reference in New Issue
Block a user