singularity_cli/commands/
task_group.rs1use anyhow::Result;
2use clap::Subcommand;
3use tabled::Table;
4
5use crate::client::ApiClient;
6use crate::models::task_group::{
7 TaskGroup, TaskGroupCreate, TaskGroupListResponse, TaskGroupUpdate,
8};
9
10#[derive(Subcommand)]
11pub enum TaskGroupCmd {
12 #[command(about = "List task groups, optionally filtered by parent project")]
13 List {
14 #[arg(long, help = "Filter by parent project ID (P-<uuid>)")]
15 parent: Option<String>,
16 #[arg(long, help = "Maximum number of groups to return (max 1000)")]
17 max_count: Option<u32>,
18 #[arg(long, help = "Number of groups to skip for pagination")]
19 offset: Option<u32>,
20 #[arg(long, help = "Include soft-deleted groups")]
21 include_removed: bool,
22 },
23 #[command(about = "Get a single task group by ID")]
24 Get {
25 #[arg(help = "Task group ID (Q-<uuid> format)")]
26 id: String,
27 },
28 #[command(about = "Create a new task group inside a project")]
29 Create {
30 #[arg(long, help = "Group title (required)")]
31 title: String,
32 #[arg(long, help = "Parent project ID (P-<uuid>, required)")]
33 parent: String,
34 #[arg(long, help = "Sort order within parent project")]
35 order: Option<f64>,
36 },
37 #[command(about = "Update an existing task group (only specified fields are changed)")]
38 Update {
39 #[arg(help = "Task group ID to update (Q-<uuid> format)")]
40 id: String,
41 #[arg(long, help = "New group title")]
42 title: Option<String>,
43 #[arg(long, help = "Move to a different project (P-<uuid>)")]
44 parent: Option<String>,
45 #[arg(long, help = "New sort order within parent")]
46 order: Option<f64>,
47 },
48 #[command(about = "Delete a task group by ID (soft-delete)")]
49 Delete {
50 #[arg(help = "Task group ID to delete (Q-<uuid> format)")]
51 id: String,
52 },
53}
54
55pub fn run(client: &ApiClient, cmd: TaskGroupCmd, json: bool) -> Result<()> {
56 match cmd {
57 TaskGroupCmd::List {
58 parent,
59 max_count,
60 offset,
61 include_removed,
62 } => {
63 let mut query: Vec<(&str, String)> = Vec::new();
64 if let Some(ref v) = parent {
65 query.push(("parent", v.to_string()));
66 }
67 if let Some(v) = max_count {
68 query.push(("maxCount", v.to_string()));
69 }
70 if let Some(v) = offset {
71 query.push(("offset", v.to_string()));
72 }
73 if include_removed {
74 query.push(("includeRemoved", "true".to_string()));
75 }
76
77 if json {
78 let resp: serde_json::Value = client.get("/v2/task-group", &query)?;
79 println!("{}", serde_json::to_string_pretty(&resp)?);
80 } else {
81 let resp: TaskGroupListResponse = client.get("/v2/task-group", &query)?;
82 if resp.task_groups.is_empty() {
83 println!("No task groups found.");
84 } else {
85 println!("{}", Table::new(&resp.task_groups));
86 }
87 }
88 }
89 TaskGroupCmd::Get { id } => {
90 if json {
91 let resp: serde_json::Value = client.get(&format!("/v2/task-group/{}", id), &[])?;
92 println!("{}", serde_json::to_string_pretty(&resp)?);
93 } else {
94 let group: TaskGroup = client.get(&format!("/v2/task-group/{}", id), &[])?;
95 group.display_detail();
96 }
97 }
98 TaskGroupCmd::Create {
99 title,
100 parent,
101 order,
102 } => {
103 let data = TaskGroupCreate {
104 title,
105 parent,
106 parent_order: order,
107 fake: None,
108 };
109 if json {
110 let resp: serde_json::Value = client.post("/v2/task-group", &data)?;
111 println!("{}", serde_json::to_string_pretty(&resp)?);
112 } else {
113 let group: TaskGroup = client.post("/v2/task-group", &data)?;
114 println!("Created task group {}", group.id);
115 }
116 }
117 TaskGroupCmd::Update {
118 id,
119 title,
120 parent,
121 order,
122 } => {
123 let data = TaskGroupUpdate {
124 title,
125 parent,
126 parent_order: order,
127 fake: None,
128 };
129 if json {
130 let resp: serde_json::Value =
131 client.patch(&format!("/v2/task-group/{}", id), &data)?;
132 println!("{}", serde_json::to_string_pretty(&resp)?);
133 } else {
134 let group: TaskGroup = client.patch(&format!("/v2/task-group/{}", id), &data)?;
135 println!("Updated task group {}", group.id);
136 }
137 }
138 TaskGroupCmd::Delete { id } => {
139 client.delete(&format!("/v2/task-group/{}", id))?;
140 println!("Deleted task group {}", id);
141 }
142 }
143 Ok(())
144}