Skip to main content

clickup_cli/commands/
template.rs

1use crate::client::ClickUpClient;
2use crate::commands::auth::resolve_token;
3use crate::commands::workspace::resolve_workspace;
4use crate::error::CliError;
5use crate::output::OutputConfig;
6use crate::Cli;
7use clap::Subcommand;
8
9#[derive(Subcommand)]
10pub enum TemplateCommands {
11    /// List task templates for the workspace. Honours global --all/--page/--limit.
12    List {},
13    /// Apply a task template to a list
14    #[command(name = "apply-task")]
15    ApplyTask {
16        /// Template ID
17        template_id: String,
18        /// List ID to create the task in
19        #[arg(long)]
20        list: String,
21        /// Task name
22        #[arg(long)]
23        name: String,
24    },
25    /// Apply a list template to a folder or space
26    #[command(name = "apply-list")]
27    ApplyList {
28        /// Template ID
29        template_id: String,
30        /// Folder ID (mutually exclusive with --space)
31        #[arg(long, conflicts_with = "space")]
32        folder: Option<String>,
33        /// Space ID (mutually exclusive with --folder)
34        #[arg(long)]
35        space: Option<String>,
36        /// List name
37        #[arg(long)]
38        name: String,
39    },
40    /// Apply a folder template to a space
41    #[command(name = "apply-folder")]
42    ApplyFolder {
43        /// Template ID
44        template_id: String,
45        /// Space ID
46        #[arg(long)]
47        space: String,
48        /// Folder name
49        #[arg(long)]
50        name: String,
51    },
52}
53
54const TEMPLATE_FIELDS: &[&str] = &["id", "name"];
55
56pub async fn execute(command: TemplateCommands, cli: &Cli) -> Result<(), CliError> {
57    let token = resolve_token(cli)?;
58    let client = ClickUpClient::new(&token, cli.timeout)?;
59    let output = OutputConfig::from_cli(&cli.output, &cli.fields, cli.no_header, cli.quiet);
60
61    match command {
62        TemplateCommands::List {} => {
63            let ws_id = resolve_workspace(cli)?;
64            let templates =
65                crate::commands::pagination::walk_page(cli, &client, "templates", |p| {
66                    format!("/v2/team/{}/taskTemplate?page={}", ws_id, p)
67                })
68                .await?;
69            output.print_items(&templates, TEMPLATE_FIELDS, "id");
70            Ok(())
71        }
72        TemplateCommands::ApplyTask {
73            template_id,
74            list,
75            name,
76        } => {
77            let body = serde_json::json!({ "name": name });
78            let resp = client
79                .post(
80                    &format!("/v2/list/{}/taskTemplate/{}", list, template_id),
81                    &body,
82                )
83                .await?;
84            println!("{}", serde_json::to_string_pretty(&resp).unwrap());
85            Ok(())
86        }
87        TemplateCommands::ApplyList {
88            template_id,
89            folder,
90            space,
91            name,
92        } => {
93            let body = serde_json::json!({ "name": name });
94            let path = if let Some(f) = folder {
95                format!("/v2/folder/{}/list_template/{}", f, template_id)
96            } else if let Some(s) = space {
97                format!("/v2/space/{}/list_template/{}", s, template_id)
98            } else {
99                return Err(CliError::ClientError {
100                    message: "Specify --folder or --space".into(),
101                    status: 0,
102                });
103            };
104            let resp = client.post(&path, &body).await?;
105            println!("{}", serde_json::to_string_pretty(&resp).unwrap());
106            Ok(())
107        }
108        TemplateCommands::ApplyFolder {
109            template_id,
110            space,
111            name,
112        } => {
113            let body = serde_json::json!({ "name": name });
114            let resp = client
115                .post(
116                    &format!("/v2/space/{}/folder_template/{}", space, template_id),
117                    &body,
118                )
119                .await?;
120            println!("{}", serde_json::to_string_pretty(&resp).unwrap());
121            Ok(())
122        }
123    }
124}