use clap::Subcommand;
use crate::client::ClickUpClient;
use crate::commands::auth::resolve_token;
use crate::error::CliError;
use crate::output::OutputConfig;
use crate::Cli;
#[derive(Subcommand)]
pub enum ChecklistCommands {
Create {
#[arg(long)]
task: String,
#[arg(long)]
name: String,
},
Update {
id: String,
#[arg(long)]
name: Option<String>,
#[arg(long)]
position: Option<i64>,
},
Delete {
id: String,
},
AddItem {
id: String,
#[arg(long)]
name: String,
#[arg(long)]
assignee: Option<i64>,
},
UpdateItem {
id: String,
item_id: String,
#[arg(long)]
name: Option<String>,
#[arg(long)]
resolved: bool,
#[arg(long)]
assignee: Option<i64>,
#[arg(long)]
parent: Option<String>,
},
DeleteItem {
id: String,
item_id: String,
},
}
pub async fn execute(command: ChecklistCommands, cli: &Cli) -> Result<(), CliError> {
let token = resolve_token(cli)?;
let client = ClickUpClient::new(&token, cli.timeout)?;
let output = OutputConfig::from_cli(&cli.output, &cli.fields, cli.no_header, cli.quiet);
match command {
ChecklistCommands::Create { task, name } => {
let body = serde_json::json!({ "name": name });
let resp = client
.post(&format!("/v2/task/{}/checklist", task), &body)
.await?;
let checklist = resp.get("checklist").cloned().unwrap_or(resp);
output.print_single(&checklist, &["id", "name", "task_id", "orderindex"], "id");
Ok(())
}
ChecklistCommands::Update { id, name, position } => {
let mut body = serde_json::Map::new();
if let Some(n) = name {
body.insert("name".into(), serde_json::Value::String(n));
}
if let Some(p) = position {
body.insert("position".into(), serde_json::json!(p));
}
let resp = client
.put(&format!("/v2/checklist/{}", id), &serde_json::Value::Object(body))
.await?;
let checklist = resp.get("checklist").cloned().unwrap_or(resp);
output.print_single(&checklist, &["id", "name", "orderindex"], "id");
Ok(())
}
ChecklistCommands::Delete { id } => {
client.delete(&format!("/v2/checklist/{}", id)).await?;
output.print_message(&format!("Checklist {} deleted", id));
Ok(())
}
ChecklistCommands::AddItem { id, name, assignee } => {
let mut body = serde_json::json!({ "name": name });
if let Some(a) = assignee {
body["assignee"] = serde_json::json!(a);
}
let resp = client
.post(&format!("/v2/checklist/{}/checklist_item", id), &body)
.await?;
let checklist = resp.get("checklist").cloned().unwrap_or(resp);
output.print_single(&checklist, &["id", "name"], "id");
Ok(())
}
ChecklistCommands::UpdateItem {
id,
item_id,
name,
resolved,
assignee,
parent,
} => {
let mut body = serde_json::Map::new();
if let Some(n) = name {
body.insert("name".into(), serde_json::Value::String(n));
}
if resolved {
body.insert("resolved".into(), serde_json::Value::Bool(true));
}
if let Some(a) = assignee {
body.insert("assignee".into(), serde_json::json!(a));
}
if let Some(p) = parent {
body.insert("parent".into(), serde_json::Value::String(p));
}
let resp = client
.put(
&format!("/v2/checklist/{}/checklist_item/{}", id, item_id),
&serde_json::Value::Object(body),
)
.await?;
let checklist = resp.get("checklist").cloned().unwrap_or(resp);
output.print_single(&checklist, &["id", "name"], "id");
Ok(())
}
ChecklistCommands::DeleteItem { id, item_id } => {
client
.delete(&format!("/v2/checklist/{}/checklist_item/{}", id, item_id))
.await?;
output.print_message(&format!("Checklist item {} deleted", item_id));
Ok(())
}
}
}