clickup_cli/commands/
tag.rs1use clap::Subcommand;
2use crate::client::ClickUpClient;
3use crate::commands::auth::resolve_token;
4use crate::error::CliError;
5use crate::output::OutputConfig;
6use crate::Cli;
7
8#[derive(Subcommand)]
9pub enum TagCommands {
10 List {
12 #[arg(long)]
14 space: String,
15 },
16 Create {
18 #[arg(long)]
20 space: String,
21 #[arg(long)]
23 name: String,
24 #[arg(long)]
26 fg_color: Option<String>,
27 #[arg(long)]
29 bg_color: Option<String>,
30 },
31 Update {
33 #[arg(long)]
35 space: String,
36 #[arg(long)]
38 tag: String,
39 #[arg(long)]
41 name: Option<String>,
42 #[arg(long)]
44 fg_color: Option<String>,
45 #[arg(long)]
47 bg_color: Option<String>,
48 },
49 Delete {
51 #[arg(long)]
53 space: String,
54 #[arg(long)]
56 tag: String,
57 },
58}
59
60const TAG_FIELDS: &[&str] = &["name", "tag_fg", "tag_bg"];
61
62pub async fn execute(command: TagCommands, cli: &Cli) -> Result<(), CliError> {
63 let token = resolve_token(cli)?;
64 let client = ClickUpClient::new(&token, cli.timeout)?;
65 let output = OutputConfig::from_cli(&cli.output, &cli.fields, cli.no_header, cli.quiet);
66
67 match command {
68 TagCommands::List { space } => {
69 let resp = client
70 .get(&format!("/v2/space/{}/tag", space))
71 .await?;
72 let tags = resp
73 .get("tags")
74 .and_then(|t| t.as_array())
75 .cloned()
76 .unwrap_or_default();
77 output.print_items(&tags, TAG_FIELDS, "name");
78 Ok(())
79 }
80 TagCommands::Create {
81 space,
82 name,
83 fg_color,
84 bg_color,
85 } => {
86 let mut tag_obj = serde_json::json!({ "name": name });
87 if let Some(fg) = fg_color {
88 tag_obj["tag_fg"] = serde_json::Value::String(fg);
89 }
90 if let Some(bg) = bg_color {
91 tag_obj["tag_bg"] = serde_json::Value::String(bg);
92 }
93 let body = serde_json::json!({ "tag": tag_obj });
94 let resp = client
95 .post(&format!("/v2/space/{}/tag", space), &body)
96 .await?;
97 output.print_single(&resp, TAG_FIELDS, "name");
98 Ok(())
99 }
100 TagCommands::Update {
101 space,
102 tag,
103 name,
104 fg_color,
105 bg_color,
106 } => {
107 let mut tag_obj = serde_json::Map::new();
108 if let Some(n) = name {
109 tag_obj.insert("name".into(), serde_json::Value::String(n));
110 }
111 if let Some(fg) = fg_color {
113 tag_obj.insert("fg_color".into(), serde_json::Value::String(fg));
114 }
115 if let Some(bg) = bg_color {
116 tag_obj.insert("bg_color".into(), serde_json::Value::String(bg));
117 }
118 let body = serde_json::json!({ "tag": serde_json::Value::Object(tag_obj) });
119 let resp = client
120 .put(&format!("/v2/space/{}/tag/{}", space, tag), &body)
121 .await?;
122 output.print_single(&resp, TAG_FIELDS, "name");
123 Ok(())
124 }
125 TagCommands::Delete { space, tag } => {
126 client
127 .delete(&format!("/v2/space/{}/tag/{}", space, tag))
128 .await?;
129 output.print_message(&format!("Tag '{}' deleted from space {}", tag, space));
130 Ok(())
131 }
132 }
133}