diff --git a/bin/cli/src/command/container.rs b/bin/cli/src/command/container.rs index 7778b79c5..27e206c08 100644 --- a/bin/cli/src/command/container.rs +++ b/bin/cli/src/command/container.rs @@ -23,7 +23,6 @@ use komodo_client::{ use crate::{ command::{ PrintTable, matches_wildcards, parse_wildcards, print_items, - text_link, }, config::cli_config, }; @@ -218,7 +217,15 @@ pub async fn inspect_container( // (Option, Container) impl PrintTable for (Option<&'_ str>, ContainerListItem) { fn header() -> &'static [&'static str] { - &["Container", "State", "Server", "Ports", "Networks", "Image"] + &[ + "Container", + "State", + "Server", + "Ports", + "Networks", + "Image", + "Link", + ] } fn row(self) -> Vec { let color = match self.1.state { @@ -250,20 +257,17 @@ impl PrintTable for (Option<&'_ str>, ContainerListItem) { } else { Cell::new(format!(":{}", ports.join(", :"))) }; - let name = if let Some(server_id) = self.1.server_id { - text_link( - &format!( - "{}/servers/{server_id}/container/{}", - cli_config().host, - self.1.name - ), - &self.1.name, + let link = if let Some(server_id) = self.1.server_id { + format!( + "{}/servers/{server_id}/container/{}", + cli_config().host, + self.1.name ) } else { - self.1.name + String::new() }; vec![ - Cell::new(name).add_attribute(Attribute::Bold), + Cell::new(self.1.name).add_attribute(Attribute::Bold), Cell::new(self.1.state.to_string()) .fg(color) .add_attribute(Attribute::Bold), @@ -271,6 +275,7 @@ impl PrintTable for (Option<&'_ str>, ContainerListItem) { ports, Cell::new(networks.join(", ")), Cell::new(self.1.image.as_deref().unwrap_or("Unknown")), + Cell::new(link), ] } } diff --git a/bin/cli/src/command/list.rs b/bin/cli/src/command/list.rs index c58c04b8d..ab2cd585b 100644 --- a/bin/cli/src/command/list.rs +++ b/bin/cli/src/command/list.rs @@ -42,7 +42,7 @@ use serde::Serialize; use crate::{ command::{ PrintTable, format_timetamp, matches_wildcards, parse_wildcards, - print_items, text_link, + print_items, }, config::cli_config, }; @@ -657,7 +657,7 @@ impl ListResources for AlerterListItem { impl PrintTable for ResourceListItem { fn header() -> &'static [&'static str] { - &["Server", "State", "Address", "Tags"] + &["Server", "State", "Address", "Tags", "Link"] } fn row(self) -> Vec { let color = match self.info.state { @@ -666,24 +666,24 @@ impl PrintTable for ResourceListItem { ServerState::Disabled => Color::Blue, }; vec![ - Cell::new(name_link( - ResourceTargetVariant::Server, - &self.id, - &self.name, - )) - .add_attribute(Attribute::Bold), + Cell::new(self.name).add_attribute(Attribute::Bold), Cell::new(self.info.state.to_string()) .fg(color) .add_attribute(Attribute::Bold), Cell::new(self.info.address), Cell::new(self.tags.join(", ")), + Cell::new(resource_link( + &cli_config().host, + ResourceTargetVariant::Server, + &self.id, + )), ] } } impl PrintTable for ResourceListItem { fn header() -> &'static [&'static str] { - &["Stack", "State", "Server", "Source", "Tags"] + &["Stack", "State", "Server", "Tags", "Link"] } fn row(self) -> Vec { let color = match self.info.state { @@ -693,33 +693,33 @@ impl PrintTable for ResourceListItem { StackState::Unknown => Color::Magenta, _ => Color::Red, }; - let source = if self.info.files_on_host { - "On Host" - } else if !self.info.repo.is_empty() { - self.info.repo_link.as_str() - } else { - "UI Defined" - }; + // let source = if self.info.files_on_host { + // "On Host" + // } else if !self.info.repo.is_empty() { + // self.info.repo_link.as_str() + // } else { + // "UI Defined" + // }; vec![ - Cell::new(name_link( - ResourceTargetVariant::Stack, - &self.id, - &self.name, - )) - .add_attribute(Attribute::Bold), + Cell::new(self.name).add_attribute(Attribute::Bold), Cell::new(self.info.state.to_string()) .fg(color) .add_attribute(Attribute::Bold), Cell::new(self.info.server_id), - Cell::new(source), + // Cell::new(source), Cell::new(self.tags.join(", ")), + Cell::new(resource_link( + &cli_config().host, + ResourceTargetVariant::Stack, + &self.id, + )), ] } } impl PrintTable for ResourceListItem { fn header() -> &'static [&'static str] { - &["Deployment", "State", "Server", "Tags"] + &["Deployment", "State", "Server", "Tags", "Link"] } fn row(self) -> Vec { let color = match self.info.state { @@ -730,24 +730,24 @@ impl PrintTable for ResourceListItem { _ => Color::Red, }; vec![ - Cell::new(name_link( - ResourceTargetVariant::Deployment, - &self.id, - &self.name, - )) - .add_attribute(Attribute::Bold), + Cell::new(self.name).add_attribute(Attribute::Bold), Cell::new(self.info.state.to_string()) .fg(color) .add_attribute(Attribute::Bold), Cell::new(self.info.server_id), Cell::new(self.tags.join(", ")), + Cell::new(resource_link( + &cli_config().host, + ResourceTargetVariant::Deployment, + &self.id, + )), ] } } impl PrintTable for ResourceListItem { fn header() -> &'static [&'static str] { - &["Build", "State", "Builder", "Tags"] + &["Build", "State", "Builder", "Tags", "Link"] } fn row(self) -> Vec { let color = match self.info.state { @@ -757,24 +757,24 @@ impl PrintTable for ResourceListItem { BuildState::Failed => Color::Red, }; vec![ - Cell::new(name_link( - ResourceTargetVariant::Build, - &self.id, - &self.name, - )) - .add_attribute(Attribute::Bold), + Cell::new(self.name).add_attribute(Attribute::Bold), Cell::new(self.info.state.to_string()) .fg(color) .add_attribute(Attribute::Bold), Cell::new(self.info.builder_id), Cell::new(self.tags.join(", ")), + Cell::new(resource_link( + &cli_config().host, + ResourceTargetVariant::Build, + &self.id, + )), ] } } impl PrintTable for ResourceListItem { fn header() -> &'static [&'static str] { - &["Repo", "State", "Link", "Tags"] + &["Repo", "State", "Link", "Tags", "Link"] } fn row(self) -> Vec { let color = match self.info.state { @@ -786,24 +786,24 @@ impl PrintTable for ResourceListItem { RepoState::Failed => Color::Red, }; vec![ - Cell::new(name_link( - ResourceTargetVariant::Repo, - &self.id, - &self.name, - )) - .add_attribute(Attribute::Bold), + Cell::new(self.name).add_attribute(Attribute::Bold), Cell::new(self.info.state.to_string()) .fg(color) .add_attribute(Attribute::Bold), Cell::new(self.info.repo_link), Cell::new(self.tags.join(", ")), + Cell::new(resource_link( + &cli_config().host, + ResourceTargetVariant::Repo, + &self.id, + )), ] } } impl PrintTable for ResourceListItem { fn header() -> &'static [&'static str] { - &["Procedure", "State", "Next Run", "Tags"] + &["Procedure", "State", "Next Run", "Tags", "Link"] } fn row(self) -> Vec { let color = match self.info.state { @@ -822,24 +822,24 @@ impl PrintTable for ResourceListItem { Cell::new(String::from("None")) }; vec![ - Cell::new(name_link( - ResourceTargetVariant::Procedure, - &self.id, - &self.name, - )) - .add_attribute(Attribute::Bold), + Cell::new(self.name).add_attribute(Attribute::Bold), Cell::new(self.info.state.to_string()) .fg(color) .add_attribute(Attribute::Bold), next_run, Cell::new(self.tags.join(", ")), + Cell::new(resource_link( + &cli_config().host, + ResourceTargetVariant::Procedure, + &self.id, + )), ] } } impl PrintTable for ResourceListItem { fn header() -> &'static [&'static str] { - &["Action", "State", "Next Run", "Tags"] + &["Action", "State", "Next Run", "Tags", "Link"] } fn row(self) -> Vec { let color = match self.info.state { @@ -858,24 +858,24 @@ impl PrintTable for ResourceListItem { Cell::new(String::from("None")) }; vec![ - Cell::new(name_link( - ResourceTargetVariant::Action, - &self.id, - &self.name, - )) - .add_attribute(Attribute::Bold), + Cell::new(self.name).add_attribute(Attribute::Bold), Cell::new(self.info.state.to_string()) .fg(color) .add_attribute(Attribute::Bold), next_run, Cell::new(self.tags.join(", ")), + Cell::new(resource_link( + &cli_config().host, + ResourceTargetVariant::Action, + &self.id, + )), ] } } impl PrintTable for ResourceListItem { fn header() -> &'static [&'static str] { - &["Sync", "State", "Tags"] + &["Sync", "State", "Tags", "Link"] } fn row(self) -> Vec { let color = match self.info.state { @@ -887,50 +887,45 @@ impl PrintTable for ResourceListItem { ResourceSyncState::Failed => Color::Red, }; vec![ - Cell::new(name_link( - ResourceTargetVariant::ResourceSync, - &self.id, - &self.name, - )) - .add_attribute(Attribute::Bold), + Cell::new(self.name).add_attribute(Attribute::Bold), Cell::new(self.info.state.to_string()) .fg(color) .add_attribute(Attribute::Bold), Cell::new(self.tags.join(", ")), + Cell::new(resource_link( + &cli_config().host, + ResourceTargetVariant::ResourceSync, + &self.id, + )), ] } } impl PrintTable for ResourceListItem { fn header() -> &'static [&'static str] { - &["Builder", "Type", "Tags"] + &["Builder", "Type", "Tags", "Link"] } fn row(self) -> Vec { vec![ - Cell::new(name_link( - ResourceTargetVariant::Builder, - &self.id, - &self.name, - )) - .add_attribute(Attribute::Bold), + Cell::new(self.name).add_attribute(Attribute::Bold), Cell::new(self.info.builder_type), Cell::new(self.tags.join(", ")), + Cell::new(resource_link( + &cli_config().host, + ResourceTargetVariant::Builder, + &self.id, + )), ] } } impl PrintTable for ResourceListItem { fn header() -> &'static [&'static str] { - &["Alerter", "Type", "Enabled", "Tags"] + &["Alerter", "Type", "Enabled", "Tags", "Link"] } fn row(self) -> Vec { vec![ - Cell::new(name_link( - ResourceTargetVariant::Alerter, - &self.id, - &self.name, - )) - .add_attribute(Attribute::Bold), + Cell::new(self.name).add_attribute(Attribute::Bold), Cell::new(self.info.endpoint_type), if self.info.enabled { Cell::new(self.info.enabled.to_string()).fg(Color::Green) @@ -938,13 +933,18 @@ impl PrintTable for ResourceListItem { Cell::new(self.info.enabled.to_string()).fg(Color::Red) }, Cell::new(self.tags.join(", ")), + Cell::new(resource_link( + &cli_config().host, + ResourceTargetVariant::Alerter, + &self.id, + )), ] } } impl PrintTable for Schedule { fn header() -> &'static [&'static str] { - &["Name", "Type", "Next Run", "Tags"] + &["Name", "Type", "Next Run", "Tags", "Link"] } fn row(self) -> Vec { let next_run = if let Some(ts) = self.next_scheduled_run { @@ -958,22 +958,11 @@ impl PrintTable for Schedule { }; let (resource_type, id) = self.target.extract_variant_id(); vec![ - Cell::new(name_link(resource_type, id, &self.name)) - .add_attribute(Attribute::Bold), + Cell::new(self.name).add_attribute(Attribute::Bold), Cell::new(self.target.extract_variant_id().0), next_run, Cell::new(self.tags.join(", ")), + Cell::new(resource_link(&cli_config().host, resource_type, id)), ] } } - -fn name_link( - resource_type: ResourceTargetVariant, - id: &str, - name: &str, -) -> String { - text_link( - &resource_link(&cli_config().host, resource_type, id), - name, - ) -} diff --git a/bin/cli/src/command/mod.rs b/bin/cli/src/command/mod.rs index 6b185ada9..ed6c1c7f4 100644 --- a/bin/cli/src/command/mod.rs +++ b/bin/cli/src/command/mod.rs @@ -3,7 +3,7 @@ use std::io::Read; use anyhow::{Context, anyhow}; use chrono::TimeZone; use colored::Colorize; -use comfy_table::{Cell, Table}; +use comfy_table::{Attribute, Cell, Table}; use komodo_client::{ KomodoClient, entities::config::cli::args::CliFormat, }; @@ -95,7 +95,13 @@ fn print_items( match format { CliFormat::Table => { let mut table = Table::new(); - table.set_header(T::header()); + table + .load_preset(comfy_table::presets::UTF8_FULL) + .set_header( + T::header() + .into_iter() + .map(|h| Cell::new(h).add_attribute(Attribute::Bold)), + ); for item in items { table.add_row(item.row()); } @@ -150,6 +156,6 @@ fn format_timetamp(ts: i64) -> anyhow::Result { Ok(ts) } -fn text_link(link: &str, text: &str) -> String { - format!("\x1b]8;;{link}\x07{text}\x1b]8;;\x07") -} +// fn text_link(link: &str, text: &str) -> String { +// format!("\x1b]8;;{link}\x07{text}\x1b]8;;\x07") +// }