mod graphql;
use crate::common::{
authorization_headers::authorization_headers, execute_graphql_request::execute_graphql_request,
fetch_user_id::fetch_user_id, keyring::keyring, lengify::lengify,
pagination_list::pagination_list, print_formatted_error::print_formatted_error,
};
use clap::Args;
use dialoguer::{theme::ColorfulTheme, Select};
use graphql::my_teams::{my_teams, MyTeams};
use graphql::shared_teams::{shared_teams, SharedTeams};
use graphql_client::GraphQLQuery;
use reqwest::Client;
use termimad::crossterm::style::Stylize;
#[derive(Args, Debug)]
pub struct TeamListArgs {
#[clap(
short,
long,
help = "Access token, if not specified, the token will be taken from the keychain"
)]
access_token: Option<String>,
}
enum TeamsOwnership {
MyTeams,
SharedTeams,
}
impl TeamsOwnership {
fn get_all_values() -> Vec<String> {
vec!["My Teams".to_string(), "Shared Teams".to_string()]
}
}
pub fn list(args: &TeamListArgs) {
let access_token = match &args.access_token {
Some(token) => token.clone(),
None => keyring::get("access_token"),
};
let from_team = Select::with_theme(&ColorfulTheme::default())
.with_prompt("Show teams from:")
.items(&TeamsOwnership::get_all_values())
.default(0)
.interact();
let select_error = "Failed to read user's choice.";
let ownership = match from_team {
Ok(index) => match index {
0 => TeamsOwnership::MyTeams,
1 => TeamsOwnership::SharedTeams,
_ => {
print_formatted_error(select_error);
std::process::exit(1);
}
},
Err(_) => {
print_formatted_error(select_error);
std::process::exit(1);
}
};
let authorization_headers = authorization_headers(&access_token);
let teams_error_message = "Teams not found";
let client = Client::new();
let user_id = fetch_user_id(&access_token);
let mut list = Vec::new();
match ownership {
TeamsOwnership::MyTeams => {
let my_teams = execute_graphql_request::<my_teams::Variables, my_teams::ResponseData>(
authorization_headers.clone(),
MyTeams::build_query,
&client,
&teams_error_message,
my_teams::Variables { user_id },
)
.team;
for team in my_teams {
list.push(format!(
"{} {} members: {} owner: {}",
&team.id.to_string()[..4].green(),
lengify(&team.name),
match &team.members_aggregate.aggregate {
Some(aggregate) => {
aggregate.count
}
None => {
print_formatted_error(&teams_error_message);
std::process::exit(1);
}
},
match &team.owner {
Some(owner) => {
&owner.name
}
None => {
print_formatted_error(&teams_error_message);
std::process::exit(1);
}
}
))
}
}
TeamsOwnership::SharedTeams => {
let shared_teams =
execute_graphql_request::<shared_teams::Variables, shared_teams::ResponseData>(
authorization_headers.clone(),
SharedTeams::build_query,
&client,
&teams_error_message,
shared_teams::Variables { user_id },
)
.team;
for team in shared_teams {
list.push(format!(
"{} {} members: {} owner: {}",
&team.id.to_string()[..4].green(),
lengify(&team.name),
match &team.members_aggregate.aggregate {
Some(aggregate) => {
aggregate.count
}
None => {
print_formatted_error(&teams_error_message);
std::process::exit(1);
}
},
match &team.owner {
Some(owner) => {
&owner.name
}
None => {
print_formatted_error(&teams_error_message);
std::process::exit(1);
}
}
))
}
}
}
pagination_list(
list,
format!(
"{} teams:",
match ownership {
TeamsOwnership::MyTeams => "My",
TeamsOwnership::SharedTeams => "Shared",
}
),
"No teams found.",
)
}