Skip to main content

clickup_cli/commands/
member.rs

1use 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 MemberCommands {
10    /// List members of a task or list (use --task or --list)
11    List {
12        /// Task ID
13        #[arg(long, conflicts_with = "list")]
14        task: Option<String>,
15        /// List ID
16        #[arg(long, conflicts_with = "task")]
17        list: Option<String>,
18    },
19}
20
21const MEMBER_FIELDS: &[&str] = &["id", "username", "email", "role"];
22
23pub async fn execute(command: MemberCommands, cli: &Cli) -> Result<(), CliError> {
24    let token = resolve_token(cli)?;
25    let client = ClickUpClient::new(&token, cli.timeout)?;
26    let output = OutputConfig::from_cli(&cli.output, &cli.fields, cli.no_header, cli.quiet);
27
28    match command {
29        MemberCommands::List { task, list } => {
30            let url = if let Some(id) = task {
31                format!("/v2/task/{}/member", id)
32            } else if let Some(id) = list {
33                format!("/v2/list/{}/member", id)
34            } else {
35                return Err(CliError::ClientError {
36                    message: "Specify either --task ID or --list ID".into(),
37                    status: 0,
38                });
39            };
40            let resp = client.get(&url).await?;
41            let members = resp
42                .get("members")
43                .and_then(|m| m.as_array())
44                .cloned()
45                .unwrap_or_default();
46            output.print_items(&members, MEMBER_FIELDS, "id");
47            Ok(())
48        }
49    }
50}