list.rs

 1use anyhow::Result;
 2use comfy_table::presets::NOTHING;
 3use comfy_table::{Cell, Color, Table};
 4use std::path::Path;
 5
 6use crate::color::{cell_bold, cell_fg, stdout_use_color};
 7use crate::db;
 8
 9pub fn run(
10    root: &Path,
11    status: Option<&str>,
12    priority: Option<db::Priority>,
13    effort: Option<db::Effort>,
14    label: Option<&str>,
15    json: bool,
16) -> Result<()> {
17    let store = db::open(root)?;
18    let mut tasks = store.list_tasks()?;
19
20    if let Some(s) = status {
21        let parsed = db::parse_status(s)?;
22        tasks.retain(|t| t.status == parsed);
23    }
24    if let Some(p) = priority {
25        tasks.retain(|t| t.priority == p);
26    }
27    if let Some(e) = effort {
28        tasks.retain(|t| t.effort == e);
29    }
30    if let Some(l) = label {
31        tasks.retain(|t| t.labels.iter().any(|x| x == l));
32    }
33
34    tasks.sort_by_key(|t| (t.priority.score(), t.created_at.clone()));
35
36    if json {
37        // Keep list JSON lean: include scheduling fields but not full work-log history.
38        let mut value = serde_json::to_value(&tasks)?;
39        if let Some(items) = value.as_array_mut() {
40            for item in items {
41                if let Some(obj) = item.as_object_mut() {
42                    obj.remove("logs");
43                }
44            }
45        }
46        println!("{}", serde_json::to_string(&value)?);
47    } else {
48        let use_color = stdout_use_color();
49        let mut table = Table::new();
50        table.load_preset(NOTHING);
51        table.set_header(vec!["ID", "STATUS", "PRIORITY", "EFFORT", "TITLE"]);
52        for t in &tasks {
53            table.add_row(vec![
54                cell_bold(&t.id, use_color),
55                cell_fg(
56                    format!("[{}]", db::status_label(t.status)),
57                    Color::Yellow,
58                    use_color,
59                ),
60                cell_fg(db::priority_label(t.priority), Color::Red, use_color),
61                cell_fg(db::effort_label(t.effort), Color::Blue, use_color),
62                Cell::new(&t.title),
63            ]);
64        }
65        if !tasks.is_empty() {
66            println!("{table}");
67        }
68    }
69
70    Ok(())
71}