feat: allow viewing tracking history for user

This commit is contained in:
xeruf 2024-09-23 13:51:16 +02:00
parent d4bca1c26f
commit 96ca945263
3 changed files with 28 additions and 7 deletions

View File

@ -111,7 +111,7 @@ Append `@TIME` to any task creation or change command to record the action with
- `:[IND][PROP]` - add property column PROP at IND or end, - `:[IND][PROP]` - add property column PROP at IND or end,
if it already exists remove property column PROP or IND; empty: list properties if it already exists remove property column PROP or IND; empty: list properties
- `::[PROP]` - sort by property PROP (multiple space-separated values allowed) - `::[PROP]` - sort by property PROP (multiple space-separated values allowed)
- `([TIME]` - list tracked times or insert timetracking with the specified offset - `([TIME]` - list tracked times or insert timetracking with the specified offset (double to view all history)
such as `-1d`, `-15 minutes`, `yesterday 17:20`, `in 2 fortnights` such as `-1d`, `-15 minutes`, `yesterday 17:20`, `in 2 fortnights`
- `)[TIME]` - stop timetracking with optional offset - also convenience helper to move to root - `)[TIME]` - stop timetracking with optional offset - also convenience helper to move to root
- `>[TEXT]` - complete active task and move up, with optional status description - `>[TEXT]` - complete active task and move up, with optional status description

View File

@ -602,15 +602,31 @@ async fn main() -> Result<()> {
Some('(') => { Some('(') => {
if let Some(arg) = arg { if let Some(arg) = arg {
let (first, remaining) = arg.split_at(1);
if first == "(" {
let mut max = usize::MAX;
match remaining.parse::<usize>() {
Ok(number) => max = number,
Err(e) => warn!("Unsure what to do with {:?}", e),
}
let (label, mut times) = tasks.times_tracked();
println!("{}\n{}", label.italic(),
times.rev().take(max).collect_vec().iter().rev().join("\n"));
} else if let Ok(key) = PublicKey::parse(arg) { // TODO also match name
let (label, mut times) = tasks.times_tracked_for(&key);
println!("{}\n{}", label.italic(),
times.join("\n"));
} else {
if tasks.track_from(arg) { if tasks.track_from(arg) {
let (label, times) = tasks.times_tracked(); let (label, times) = tasks.times_tracked();
println!("{}\n{}", label.italic(), println!("{}\n{}", label.italic(),
times.rev().take(15).collect_vec().iter().rev().join("\n")); times.rev().take(15).collect_vec().iter().rev().join("\n"));
} }
// TODO show history of author / pubkey }
} else { } else {
let (label, mut times) = tasks.times_tracked(); let (label, mut times) = tasks.times_tracked();
println!("{}\n{}", label.italic(), times.join("\n")); println!("{}\n{}", label.italic(),
times.rev().take(80).collect_vec().iter().rev().join("\n"));
} }
continue 'repl; continue 'repl;
} }

View File

@ -226,9 +226,13 @@ impl TasksRelay {
/// Dynamic time tracking overview for current task or current user. /// Dynamic time tracking overview for current task or current user.
pub(crate) fn times_tracked(&self) -> (String, Box<dyn DoubleEndedIterator<Item=String>>) { pub(crate) fn times_tracked(&self) -> (String, Box<dyn DoubleEndedIterator<Item=String>>) {
self.times_tracked_for(&self.sender.pubkey())
}
pub(crate) fn times_tracked_for(&self, key: &PublicKey) -> (String, Box<dyn DoubleEndedIterator<Item=String>>) {
match self.get_position_ref() { match self.get_position_ref() {
None => { None => {
if let Some(hist) = self.history.get(&self.sender.pubkey()) { if let Some(hist) = self.history.get(key) {
let mut last = None; let mut last = None;
let mut full = Vec::with_capacity(hist.len()); let mut full = Vec::with_capacity(hist.len());
for event in hist.values() { for event in hist.values() {
@ -249,6 +253,7 @@ impl TasksRelay {
} }
} }
Some(id) => { Some(id) => {
// TODO consider pubkey
let ids = vec![id]; let ids = vec![id];
let history = let history =
self.history.iter().flat_map(|(key, set)| { self.history.iter().flat_map(|(key, set)| {