use inquire::Select;
use crate::client::ApiClient;
use crate::error::Result;
use crate::output::{ctx, print_table, ProjectRow};
pub fn run_list(client: &ApiClient, workspace_arg: Option<String>) -> Result<()> {
let workspace_id = match workspace_arg {
Some(id) => id,
None => resolve_workspace(client)?,
};
let projects = client.list_projects(&workspace_id)?;
let rows: Vec<ProjectRow> = projects
.into_iter()
.map(|p| ProjectRow {
name: p.name,
environment: p.environment,
id: p.id,
})
.collect();
if rows.is_empty() && !ctx().json {
println!("No projects found in this workspace.");
return Ok(());
}
print_table(rows);
Ok(())
}
fn resolve_workspace(client: &ApiClient) -> Result<String> {
let workspaces = client.list_workspaces()?;
if workspaces.is_empty() {
return Err("No workspaces found. Create one at https://partiri.cloud".into());
}
if workspaces.len() == 1 {
return Ok(workspaces[0].id.clone());
}
if ctx().no_input {
return Err(
"Multiple workspaces — pass --workspace <UUID>. Run 'partiri workspaces list' to see them."
.into(),
);
}
let options: Vec<String> = workspaces
.iter()
.map(|w| format!("{} ({})", w.name, w.id))
.collect();
let choice = Select::new("Select workspace:", options.clone())
.prompt()
.map_err(|e| format!("Selection cancelled: {e}"))?;
let (_, workspace) = options
.into_iter()
.zip(workspaces.into_iter())
.find(|(label, _)| label == &choice)
.ok_or("Selected workspace not found in list")?;
Ok(workspace.id)
}