clickup_cli/commands/
checklist.rs1use crate::client::ClickUpClient;
2use crate::commands::auth::resolve_token;
3use crate::error::CliError;
4use crate::git;
5use crate::output::OutputConfig;
6use crate::Cli;
7use clap::Subcommand;
8
9#[derive(Subcommand)]
10pub enum ChecklistCommands {
11 Create {
13 #[arg(long)]
15 name: String,
16 #[arg(long)]
18 task: Option<String>,
19 },
20 Update {
22 id: String,
24 #[arg(long)]
26 name: Option<String>,
27 #[arg(long)]
29 position: Option<i64>,
30 },
31 Delete {
33 id: String,
35 },
36 AddItem {
38 id: String,
40 #[arg(long)]
42 name: String,
43 #[arg(long)]
45 assignee: Option<i64>,
46 },
47 UpdateItem {
49 id: String,
51 item_id: String,
53 #[arg(long)]
55 name: Option<String>,
56 #[arg(long)]
58 resolved: bool,
59 #[arg(long)]
61 assignee: Option<i64>,
62 #[arg(long)]
64 parent: Option<String>,
65 },
66 DeleteItem {
68 id: String,
70 item_id: String,
72 },
73}
74
75pub async fn execute(command: ChecklistCommands, cli: &Cli) -> Result<(), CliError> {
76 let token = resolve_token(cli)?;
77 let client = ClickUpClient::new(&token, cli.timeout)?;
78 let output = OutputConfig::from_cli(&cli.output, &cli.fields, cli.no_header, cli.quiet);
79
80 match command {
81 ChecklistCommands::Create { task, name } => {
82 let task = git::require_task(cli, task.as_deref(), true)?;
83 let body = serde_json::json!({ "name": name });
84 let resp = client
85 .post(&format!("/v2/task/{}/checklist", task.id), &body)
86 .await?;
87 let checklist = resp.get("checklist").cloned().unwrap_or(resp);
88 output.print_single(&checklist, &["id", "name", "task_id", "orderindex"], "id");
89 Ok(())
90 }
91 ChecklistCommands::Update { id, name, position } => {
92 let mut body = serde_json::Map::new();
93 if let Some(n) = name {
94 body.insert("name".into(), serde_json::Value::String(n));
95 }
96 if let Some(p) = position {
97 body.insert("position".into(), serde_json::json!(p));
98 }
99 let resp = client
100 .put(
101 &format!("/v2/checklist/{}", id),
102 &serde_json::Value::Object(body),
103 )
104 .await?;
105 let checklist = resp.get("checklist").cloned().unwrap_or(resp);
106 output.print_single(&checklist, &["id", "name", "orderindex"], "id");
107 Ok(())
108 }
109 ChecklistCommands::Delete { id } => {
110 client.delete(&format!("/v2/checklist/{}", id)).await?;
111 output.print_message(&format!("Checklist {} deleted", id));
112 Ok(())
113 }
114 ChecklistCommands::AddItem { id, name, assignee } => {
115 let mut body = serde_json::json!({ "name": name });
116 if let Some(a) = assignee {
117 body["assignee"] = serde_json::json!(a);
118 }
119 let resp = client
120 .post(&format!("/v2/checklist/{}/checklist_item", id), &body)
121 .await?;
122 let checklist = resp.get("checklist").cloned().unwrap_or(resp);
123 output.print_single(&checklist, &["id", "name"], "id");
124 Ok(())
125 }
126 ChecklistCommands::UpdateItem {
127 id,
128 item_id,
129 name,
130 resolved,
131 assignee,
132 parent,
133 } => {
134 let mut body = serde_json::Map::new();
135 if let Some(n) = name {
136 body.insert("name".into(), serde_json::Value::String(n));
137 }
138 if resolved {
139 body.insert("resolved".into(), serde_json::Value::Bool(true));
140 }
141 if let Some(a) = assignee {
142 body.insert("assignee".into(), serde_json::json!(a));
143 }
144 if let Some(p) = parent {
145 body.insert("parent".into(), serde_json::Value::String(p));
146 }
147 let resp = client
148 .put(
149 &format!("/v2/checklist/{}/checklist_item/{}", id, item_id),
150 &serde_json::Value::Object(body),
151 )
152 .await?;
153 let checklist = resp.get("checklist").cloned().unwrap_or(resp);
154 output.print_single(&checklist, &["id", "name"], "id");
155 Ok(())
156 }
157 ChecklistCommands::DeleteItem { id, item_id } => {
158 client
159 .delete(&format!("/v2/checklist/{}/checklist_item/{}", id, item_id))
160 .await?;
161 output.print_message(&format!("Checklist item {} deleted", item_id));
162 Ok(())
163 }
164 }
165}