use crate::client::ClickUpClient;
use crate::commands::auth::resolve_token;
use crate::error::CliError;
use crate::output::OutputConfig;
use crate::Cli;
use clap::Subcommand;
#[derive(Subcommand)]
pub enum FolderCommands {
List {
#[arg(long)]
space: String,
#[arg(long)]
archived: bool,
},
Get {
id: String,
},
Create {
#[arg(long)]
space: String,
#[arg(long)]
name: String,
},
Update {
id: String,
#[arg(long)]
name: String,
},
Delete {
id: String,
},
}
pub async fn execute(command: FolderCommands, 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 {
FolderCommands::List { space, archived } => {
let resp = client
.get(&format!("/v2/space/{}/folder?archived={}", space, archived))
.await?;
let folders = resp
.get("folders")
.and_then(|f| f.as_array())
.cloned()
.unwrap_or_default();
let items: Vec<serde_json::Value> = folders
.iter()
.map(|f| {
let list_count = f
.get("lists")
.and_then(|l| l.as_array())
.map(|a| a.len())
.unwrap_or(0);
serde_json::json!({
"id": f.get("id"),
"name": f.get("name"),
"task_count": f.get("task_count"),
"list_count": list_count,
})
})
.collect();
output.print_items(&items, &["id", "name", "task_count", "list_count"], "id");
Ok(())
}
FolderCommands::Get { id } => {
let resp = client.get(&format!("/v2/folder/{}", id)).await?;
let list_count = resp
.get("lists")
.and_then(|l| l.as_array())
.map(|a| a.len())
.unwrap_or(0);
let mut item = resp.clone();
item.as_object_mut()
.map(|o| o.insert("list_count".into(), serde_json::json!(list_count)));
output.print_single(&item, &["id", "name", "task_count", "list_count"], "id");
Ok(())
}
FolderCommands::Create { space, name } => {
let body = serde_json::json!({ "name": name });
let resp = client
.post(&format!("/v2/space/{}/folder", space), &body)
.await?;
output.print_single(&resp, &["id", "name"], "id");
Ok(())
}
FolderCommands::Update { id, name } => {
let body = serde_json::json!({ "name": name });
let resp = client.put(&format!("/v2/folder/{}", id), &body).await?;
output.print_single(&resp, &["id", "name"], "id");
Ok(())
}
FolderCommands::Delete { id } => {
client.delete(&format!("/v2/folder/{}", id)).await?;
output.print_message(&format!("Folder {} deleted", id));
Ok(())
}
}
}