use crate::client::Client;
use crate::config;
use crate::output;
use clap::{Args, Subcommand};
#[derive(Args)]
pub struct BoardArgs {
#[command(subcommand)]
pub command: BoardCommand,
}
#[derive(Subcommand)]
pub enum BoardCommand {
List {
repo: Option<String>,
},
}
pub async fn run(args: BoardArgs) -> Result<(), Box<dyn std::error::Error>> {
match args.command {
BoardCommand::List { repo } => list(repo.as_deref()).await,
}
}
async fn list(repo: Option<&str>) -> Result<(), Box<dyn std::error::Error>> {
let client = Client::from_config()?;
let (org, name) = config::resolve_repo(repo)?;
let resp: serde_json::Value = match client.get(&format!("/{org}/{name}/board/columns")).await {
Ok(resp) => resp,
Err(e) => {
let err_str = format!("{}", e);
if err_str.contains("404") || err_str.contains("Feature") {
output::error("Board feature is not enabled for this repository.");
return Ok(());
}
return Err(e.into());
}
};
let columns = resp
.get("columns")
.and_then(|v| v.as_array())
.cloned()
.unwrap_or_default();
if columns.is_empty() {
output::info("No board columns found.");
return Ok(());
}
for col in &columns {
let col_name = col.get("name").and_then(|v| v.as_str()).unwrap_or("?");
let issue_count = col
.get("issues")
.and_then(|v| v.as_array())
.map(|a| a.len() as u64)
.or_else(|| col.get("issue_count").and_then(|v| v.as_u64()))
.unwrap_or(0);
output::header(&format!("{} ({})", col_name, issue_count));
if let Some(issue_list) = col.get("issues").and_then(|v| v.as_array()) {
for issue in issue_list {
let num = issue.get("number").and_then(|v| v.as_u64()).unwrap_or(0);
let title = issue.get("title").and_then(|v| v.as_str()).unwrap_or("?");
output::detail(&format!("#{}", num), title);
}
} else if let Some(count) = col.get("issue_count").and_then(|v| v.as_u64()) {
if count > 0 {
output::detail(" ", &format!("{} issue(s)", count));
}
}
}
Ok(())
}