From cc1d66b530655da654310682bcd8d34293ffda6f Mon Sep 17 00:00:00 2001 From: chenmi Date: Mon, 10 Nov 2025 00:00:31 +0800 Subject: [PATCH] agent_ui: Improve API key configuration UI display (#42306) Improve the layout and text display of API key configuration in multiple language model providers to ensure proper text wrapping and ellipsis handling when API URLs are long. Before: image After: image Changes include: - Add proper flex layout with overflow handling - Replace truncate_and_trailoff with CSS text ellipsis - Ensure consistent UI behavior across all providers Release Notes: - Improved API key configuration display in language model settings --- .../language_models/src/provider/anthropic.rs | 54 ++++++++----- .../language_models/src/provider/deepseek.rs | 47 ++++++----- crates/language_models/src/provider/google.rs | 56 ++++++++----- .../language_models/src/provider/mistral.rs | 78 +++++++++++-------- .../language_models/src/provider/open_ai.rs | 56 ++++++++----- .../src/provider/open_ai_compatible.rs | 46 +++++++---- .../src/provider/open_router.rs | 54 ++++++++----- crates/language_models/src/provider/vercel.rs | 54 ++++++++----- crates/language_models/src/provider/x_ai.rs | 54 ++++++++----- 9 files changed, 305 insertions(+), 194 deletions(-) diff --git a/crates/language_models/src/provider/anthropic.rs b/crates/language_models/src/provider/anthropic.rs index 9eb96cb79815bdbdc06c58ca4156e68e2962b0a4..86cc81cb7bc7b89967e69949ced891a7cb845cea 100644 --- a/crates/language_models/src/provider/anthropic.rs +++ b/crates/language_models/src/provider/anthropic.rs @@ -22,7 +22,7 @@ use std::sync::{Arc, LazyLock}; use strum::IntoEnumIterator; use ui::{Icon, IconName, List, Tooltip, prelude::*}; use ui_input::InputField; -use util::{ResultExt, truncate_and_trailoff}; +use util::ResultExt; use zed_env_vars::{EnvVar, env_var}; use crate::api_key::ApiKeyState; @@ -953,30 +953,42 @@ impl Render for ConfigurationView { .bg(cx.theme().colors().background) .child( h_flex() + .flex_1() + .min_w_0() .gap_1() .child(Icon::new(IconName::Check).color(Color::Success)) - .child(Label::new(if env_var_set { - format!("API key set in {API_KEY_ENV_VAR_NAME} environment variable") - } else { - let api_url = AnthropicLanguageModelProvider::api_url(cx); - if api_url == ANTHROPIC_API_URL { - "API key configured".to_string() - } else { - format!("API key configured for {}", truncate_and_trailoff(&api_url, 32)) - } - })), + .child( + div() + .w_full() + .overflow_x_hidden() + .text_ellipsis() + .child(Label::new(if env_var_set { + format!("API key set in {API_KEY_ENV_VAR_NAME} environment variable") + } else { + let api_url = AnthropicLanguageModelProvider::api_url(cx); + if api_url == ANTHROPIC_API_URL { + "API key configured".to_string() + } else { + format!("API key configured for {}", api_url) + } + })) + ), ) .child( - Button::new("reset-key", "Reset Key") - .label_size(LabelSize::Small) - .icon(Some(IconName::Trash)) - .icon_size(IconSize::Small) - .icon_position(IconPosition::Start) - .disabled(env_var_set) - .when(env_var_set, |this| { - this.tooltip(Tooltip::text(format!("To reset your API key, unset the {API_KEY_ENV_VAR_NAME} environment variable."))) - }) - .on_click(cx.listener(|this, _, window, cx| this.reset_api_key(window, cx))), + h_flex() + .flex_shrink_0() + .child( + Button::new("reset-key", "Reset Key") + .label_size(LabelSize::Small) + .icon(Some(IconName::Trash)) + .icon_size(IconSize::Small) + .icon_position(IconPosition::Start) + .disabled(env_var_set) + .when(env_var_set, |this| { + this.tooltip(Tooltip::text(format!("To reset your API key, unset the {API_KEY_ENV_VAR_NAME} environment variable."))) + }) + .on_click(cx.listener(|this, _, window, cx| this.reset_api_key(window, cx))), + ), ) .into_any() } diff --git a/crates/language_models/src/provider/deepseek.rs b/crates/language_models/src/provider/deepseek.rs index 8784d3805f22974ffa441ecd04ddea4b56be911b..103d068d671acf331fbba73072e3edf2fcc10411 100644 --- a/crates/language_models/src/provider/deepseek.rs +++ b/crates/language_models/src/provider/deepseek.rs @@ -21,7 +21,7 @@ use std::sync::{Arc, LazyLock}; use ui::{Icon, IconName, List, prelude::*}; use ui_input::InputField; -use util::{ResultExt, truncate_and_trailoff}; +use util::ResultExt; use zed_env_vars::{EnvVar, env_var}; use crate::{api_key::ApiKeyState, ui::InstructionListItem}; @@ -640,32 +640,37 @@ impl Render for ConfigurationView { .bg(cx.theme().colors().background) .child( h_flex() + .flex_1() + .min_w_0() .gap_1() .child(Icon::new(IconName::Check).color(Color::Success)) - .child(Label::new(if env_var_set { - format!("API key set in {API_KEY_ENV_VAR_NAME} environment variable") - } else { - let api_url = DeepSeekLanguageModelProvider::api_url(cx); - if api_url == DEEPSEEK_API_URL { - "API key configured".to_string() - } else { + .child(div().w_full().overflow_x_hidden().text_ellipsis().child( + Label::new(if env_var_set { format!( - "API key configured for {}", - truncate_and_trailoff(&api_url, 32) + "API key set in {API_KEY_ENV_VAR_NAME} environment variable" ) - } - })), + } else { + let api_url = DeepSeekLanguageModelProvider::api_url(cx); + if api_url == DEEPSEEK_API_URL { + "API key configured".to_string() + } else { + format!("API key configured for {}", api_url) + } + }), + )), ) .child( - Button::new("reset-key", "Reset Key") - .label_size(LabelSize::Small) - .icon(Some(IconName::Trash)) - .icon_size(IconSize::Small) - .icon_position(IconPosition::Start) - .disabled(env_var_set) - .on_click( - cx.listener(|this, _, window, cx| this.reset_api_key(window, cx)), - ), + h_flex().flex_shrink_0().child( + Button::new("reset-key", "Reset Key") + .label_size(LabelSize::Small) + .icon(Some(IconName::Trash)) + .icon_size(IconSize::Small) + .icon_position(IconPosition::Start) + .disabled(env_var_set) + .on_click( + cx.listener(|this, _, window, cx| this.reset_api_key(window, cx)), + ), + ), ) .into_any() } diff --git a/crates/language_models/src/provider/google.rs b/crates/language_models/src/provider/google.rs index a4d1202bee4fc4b2f1e071a815bc2f5887d2457d..a9c97ca939ac55c621bf38b62736af91ab2211ee 100644 --- a/crates/language_models/src/provider/google.rs +++ b/crates/language_models/src/provider/google.rs @@ -30,7 +30,7 @@ use std::sync::{ use strum::IntoEnumIterator; use ui::{Icon, IconName, List, Tooltip, prelude::*}; use ui_input::InputField; -use util::{ResultExt, truncate_and_trailoff}; +use util::ResultExt; use zed_env_vars::EnvVar; use crate::api_key::ApiKey; @@ -876,30 +876,44 @@ impl Render for ConfigurationView { .bg(cx.theme().colors().background) .child( h_flex() + .flex_1() + .min_w_0() .gap_1() .child(Icon::new(IconName::Check).color(Color::Success)) - .child(Label::new(if env_var_set { - format!("API key set in {} environment variable", API_KEY_ENV_VAR.name) - } else { - let api_url = GoogleLanguageModelProvider::api_url(cx); - if api_url == google_ai::API_URL { - "API key configured".to_string() - } else { - format!("API key configured for {}", truncate_and_trailoff(&api_url, 32)) - } - })), + .child( + div() + .w_full() + .overflow_x_hidden() + .text_ellipsis() + .child(Label::new( + if env_var_set { + format!("API key set in {} environment variable", API_KEY_ENV_VAR.name) + } else { + let api_url = GoogleLanguageModelProvider::api_url(cx); + if api_url == google_ai::API_URL { + "API key configured".to_string() + } else { + format!("API key configured for {}", api_url) + } + } + )) + ), ) .child( - Button::new("reset-key", "Reset Key") - .label_size(LabelSize::Small) - .icon(Some(IconName::Trash)) - .icon_size(IconSize::Small) - .icon_position(IconPosition::Start) - .disabled(env_var_set) - .when(env_var_set, |this| { - this.tooltip(Tooltip::text(format!("To reset your API key, make sure {GEMINI_API_KEY_VAR_NAME} and {GOOGLE_AI_API_KEY_VAR_NAME} environment variables are unset."))) - }) - .on_click(cx.listener(|this, _, window, cx| this.reset_api_key(window, cx))), + h_flex() + .flex_shrink_0() + .child( + Button::new("reset-key", "Reset Key") + .label_size(LabelSize::Small) + .icon(Some(IconName::Trash)) + .icon_size(IconSize::Small) + .icon_position(IconPosition::Start) + .disabled(env_var_set) + .when(env_var_set, |this| { + this.tooltip(Tooltip::text(format!("To reset your API key, make sure {GEMINI_API_KEY_VAR_NAME} and {GOOGLE_AI_API_KEY_VAR_NAME} environment variables are unset."))) + }) + .on_click(cx.listener(|this, _, window, cx| this.reset_api_key(window, cx))), + ), ) .into_any() } diff --git a/crates/language_models/src/provider/mistral.rs b/crates/language_models/src/provider/mistral.rs index acd4a1c768e0d6ffdffbc3d69dcdc2bfd37fa928..e0bfa5d8eb66ec4ec390bc534ceebe0663610197 100644 --- a/crates/language_models/src/provider/mistral.rs +++ b/crates/language_models/src/provider/mistral.rs @@ -21,7 +21,7 @@ use std::sync::{Arc, LazyLock}; use strum::IntoEnumIterator; use ui::{Icon, IconName, List, Tooltip, prelude::*}; use ui_input::InputField; -use util::{ResultExt, truncate_and_trailoff}; +use util::ResultExt; use zed_env_vars::{EnvVar, env_var}; use crate::{api_key::ApiKeyState, ui::InstructionListItem}; @@ -998,40 +998,56 @@ impl Render for ConfigurationView { .bg(cx.theme().colors().background) .child( h_flex() + .flex_1() + .min_w_0() .gap_1() .child(Icon::new(IconName::Check).color(Color::Success)) - .child(Label::new(if env_var_set { - format!( - "API key set in {API_KEY_ENV_VAR_NAME} environment variable" - ) - } else { - let api_url = MistralLanguageModelProvider::api_url(cx); - if api_url == MISTRAL_API_URL { - "API key configured".to_string() - } else { - format!( - "API key configured for {}", - truncate_and_trailoff(&api_url, 32) - ) - } - })), + .child( + div() + .w_full() + .overflow_x_hidden() + .text_ellipsis() + .child( + Label::new( + if env_var_set { + format!( + "API key set in {API_KEY_ENV_VAR_NAME} environment variable" + ) + } else { + let api_url = MistralLanguageModelProvider::api_url(cx); + if api_url == MISTRAL_API_URL { + "API key configured".to_string() + } else { + format!( + "API key configured for {}", + api_url + ) + } + } + ) + ), + ), ) .child( - Button::new("reset-key", "Reset Key") - .label_size(LabelSize::Small) - .icon(Some(IconName::Trash)) - .icon_size(IconSize::Small) - .icon_position(IconPosition::Start) - .disabled(env_var_set) - .when(env_var_set, |this| { - this.tooltip(Tooltip::text(format!( - "To reset your API key, \ - unset the {API_KEY_ENV_VAR_NAME} environment variable." - ))) - }) - .on_click(cx.listener(|this, _, window, cx| { - this.reset_api_key(window, cx) - })), + h_flex() + .flex_shrink_0() + .child( + Button::new("reset-key", "Reset Key") + .label_size(LabelSize::Small) + .icon(Some(IconName::Trash)) + .icon_size(IconSize::Small) + .icon_position(IconPosition::Start) + .disabled(env_var_set) + .when(env_var_set, |this| { + this.tooltip(Tooltip::text(format!( + "To reset your API key, \ + unset the {API_KEY_ENV_VAR_NAME} environment variable." + ))) + }) + .on_click(cx.listener(|this, _, window, cx| { + this.reset_api_key(window, cx) + })), + ), ), ) .child(self.render_codestral_api_key_editor(cx)) diff --git a/crates/language_models/src/provider/open_ai.rs b/crates/language_models/src/provider/open_ai.rs index 38bf373c6f0de19362560f2c906c3e24a0833cae..aa925a9b582adae5c1ade0b9cdce6765e8614cb6 100644 --- a/crates/language_models/src/provider/open_ai.rs +++ b/crates/language_models/src/provider/open_ai.rs @@ -22,7 +22,7 @@ use std::sync::{Arc, LazyLock}; use strum::IntoEnumIterator; use ui::{ElevationIndex, List, Tooltip, prelude::*}; use ui_input::InputField; -use util::{ResultExt, truncate_and_trailoff}; +use util::ResultExt; use zed_env_vars::{EnvVar, env_var}; use crate::{api_key::ApiKeyState, ui::InstructionListItem}; @@ -807,30 +807,44 @@ impl Render for ConfigurationView { .bg(cx.theme().colors().background) .child( h_flex() + .flex_1() + .min_w_0() .gap_1() .child(Icon::new(IconName::Check).color(Color::Success)) - .child(Label::new(if env_var_set { - format!("API key set in {API_KEY_ENV_VAR_NAME} environment variable") - } else { - let api_url = OpenAiLanguageModelProvider::api_url(cx); - if api_url == OPEN_AI_API_URL { - "API key configured".to_string() - } else { - format!("API key configured for {}", truncate_and_trailoff(&api_url, 32)) - } - })), + .child( + div() + .w_full() + .overflow_x_hidden() + .text_ellipsis() + .child(Label::new( + if env_var_set { + format!("API key set in {API_KEY_ENV_VAR_NAME} environment variable") + } else { + let api_url = OpenAiLanguageModelProvider::api_url(cx); + if api_url == OPEN_AI_API_URL { + "API key configured".to_string() + } else { + format!("API key configured for {}", api_url) + } + } + )) + ), ) .child( - Button::new("reset-api-key", "Reset API Key") - .label_size(LabelSize::Small) - .icon(IconName::Undo) - .icon_size(IconSize::Small) - .icon_position(IconPosition::Start) - .layer(ElevationIndex::ModalSurface) - .when(env_var_set, |this| { - this.tooltip(Tooltip::text(format!("To reset your API key, unset the {API_KEY_ENV_VAR_NAME} environment variable."))) - }) - .on_click(cx.listener(|this, _, window, cx| this.reset_api_key(window, cx))), + h_flex() + .flex_shrink_0() + .child( + Button::new("reset-api-key", "Reset API Key") + .label_size(LabelSize::Small) + .icon(IconName::Undo) + .icon_size(IconSize::Small) + .icon_position(IconPosition::Start) + .layer(ElevationIndex::ModalSurface) + .when(env_var_set, |this| { + this.tooltip(Tooltip::text(format!("To reset your API key, unset the {API_KEY_ENV_VAR_NAME} environment variable."))) + }) + .on_click(cx.listener(|this, _, window, cx| this.reset_api_key(window, cx))), + ), ) .into_any() }; diff --git a/crates/language_models/src/provider/open_ai_compatible.rs b/crates/language_models/src/provider/open_ai_compatible.rs index c8a1da5f5af9feb72ec514854403d15d6e73774b..4ed0de851244d65b0f838c582ccdffe763d6775f 100644 --- a/crates/language_models/src/provider/open_ai_compatible.rs +++ b/crates/language_models/src/provider/open_ai_compatible.rs @@ -15,7 +15,7 @@ use settings::{Settings, SettingsStore}; use std::sync::Arc; use ui::{ElevationIndex, Tooltip, prelude::*}; use ui_input::InputField; -use util::{ResultExt, truncate_and_trailoff}; +use util::ResultExt; use zed_env_vars::EnvVar; use crate::api_key::ApiKeyState; @@ -455,25 +455,39 @@ impl Render for ConfigurationView { .bg(cx.theme().colors().background) .child( h_flex() + .flex_1() + .min_w_0() .gap_1() .child(Icon::new(IconName::Check).color(Color::Success)) - .child(Label::new(if env_var_set { - format!("API key set in {env_var_name} environment variable") - } else { - format!("API key configured for {}", truncate_and_trailoff(&state.settings.api_url, 32)) - })), + .child( + div() + .w_full() + .overflow_x_hidden() + .text_ellipsis() + .child(Label::new( + if env_var_set { + format!("API key set in {env_var_name} environment variable") + } else { + format!("API key configured for {}", &state.settings.api_url) + } + )) + ), ) .child( - Button::new("reset-api-key", "Reset API Key") - .label_size(LabelSize::Small) - .icon(IconName::Undo) - .icon_size(IconSize::Small) - .icon_position(IconPosition::Start) - .layer(ElevationIndex::ModalSurface) - .when(env_var_set, |this| { - this.tooltip(Tooltip::text(format!("To reset your API key, unset the {env_var_name} environment variable."))) - }) - .on_click(cx.listener(|this, _, window, cx| this.reset_api_key(window, cx))), + h_flex() + .flex_shrink_0() + .child( + Button::new("reset-api-key", "Reset API Key") + .label_size(LabelSize::Small) + .icon(IconName::Undo) + .icon_size(IconSize::Small) + .icon_position(IconPosition::Start) + .layer(ElevationIndex::ModalSurface) + .when(env_var_set, |this| { + this.tooltip(Tooltip::text(format!("To reset your API key, unset the {env_var_name} environment variable."))) + }) + .on_click(cx.listener(|this, _, window, cx| this.reset_api_key(window, cx))), + ), ) .into_any() }; diff --git a/crates/language_models/src/provider/open_router.rs b/crates/language_models/src/provider/open_router.rs index 50131f0a8ef7076420df9a9dc1dbdcd4c840a5c2..0cc3711489ab25b80c9e995558f18917fbfad343 100644 --- a/crates/language_models/src/provider/open_router.rs +++ b/crates/language_models/src/provider/open_router.rs @@ -19,7 +19,7 @@ use std::str::FromStr as _; use std::sync::{Arc, LazyLock}; use ui::{Icon, IconName, List, Tooltip, prelude::*}; use ui_input::InputField; -use util::{ResultExt, truncate_and_trailoff}; +use util::ResultExt; use zed_env_vars::{EnvVar, env_var}; use crate::{api_key::ApiKeyState, ui::InstructionListItem}; @@ -818,30 +818,42 @@ impl Render for ConfigurationView { .bg(cx.theme().colors().background) .child( h_flex() + .flex_1() + .min_w_0() .gap_1() .child(Icon::new(IconName::Check).color(Color::Success)) - .child(Label::new(if env_var_set { - format!("API key set in {API_KEY_ENV_VAR_NAME} environment variable") - } else { - let api_url = OpenRouterLanguageModelProvider::api_url(cx); - if api_url == OPEN_ROUTER_API_URL { - "API key configured".to_string() - } else { - format!("API key configured for {}", truncate_and_trailoff(&api_url, 32)) - } - })), + .child( + div() + .w_full() + .overflow_x_hidden() + .text_ellipsis() + .child(Label::new(if env_var_set { + format!("API key set in {API_KEY_ENV_VAR_NAME} environment variable") + } else { + let api_url = OpenRouterLanguageModelProvider::api_url(cx); + if api_url == OPEN_ROUTER_API_URL { + "API key configured".to_string() + } else { + format!("API key configured for {}", api_url) + } + })) + ), ) .child( - Button::new("reset-key", "Reset Key") - .label_size(LabelSize::Small) - .icon(Some(IconName::Trash)) - .icon_size(IconSize::Small) - .icon_position(IconPosition::Start) - .disabled(env_var_set) - .when(env_var_set, |this| { - this.tooltip(Tooltip::text(format!("To reset your API key, unset the {API_KEY_ENV_VAR_NAME} environment variable."))) - }) - .on_click(cx.listener(|this, _, window, cx| this.reset_api_key(window, cx))), + h_flex() + .flex_shrink_0() + .child( + Button::new("reset-key", "Reset Key") + .label_size(LabelSize::Small) + .icon(Some(IconName::Trash)) + .icon_size(IconSize::Small) + .icon_position(IconPosition::Start) + .disabled(env_var_set) + .when(env_var_set, |this| { + this.tooltip(Tooltip::text(format!("To reset your API key, unset the {API_KEY_ENV_VAR_NAME} environment variable."))) + }) + .on_click(cx.listener(|this, _, window, cx| this.reset_api_key(window, cx))), + ), ) .into_any() } diff --git a/crates/language_models/src/provider/vercel.rs b/crates/language_models/src/provider/vercel.rs index ff5d4567c60423939c38d00a1203f613df353ccf..9adc794ceaf255756736b401fff45f1131d4b310 100644 --- a/crates/language_models/src/provider/vercel.rs +++ b/crates/language_models/src/provider/vercel.rs @@ -16,7 +16,7 @@ use std::sync::{Arc, LazyLock}; use strum::IntoEnumIterator; use ui::{ElevationIndex, List, Tooltip, prelude::*}; use ui_input::InputField; -use util::{ResultExt, truncate_and_trailoff}; +use util::ResultExt; use vercel::{Model, VERCEL_API_URL}; use zed_env_vars::{EnvVar, env_var}; @@ -489,30 +489,42 @@ impl Render for ConfigurationView { .bg(cx.theme().colors().background) .child( h_flex() + .flex_1() + .min_w_0() .gap_1() .child(Icon::new(IconName::Check).color(Color::Success)) - .child(Label::new(if env_var_set { - format!("API key set in {API_KEY_ENV_VAR_NAME} environment variable") - } else { - let api_url = VercelLanguageModelProvider::api_url(cx); - if api_url == VERCEL_API_URL { - "API key configured".to_string() - } else { - format!("API key configured for {}", truncate_and_trailoff(&api_url, 32)) - } - })), + .child( + div() + .w_full() + .overflow_x_hidden() + .text_ellipsis() + .child(Label::new(if env_var_set { + format!("API key set in {API_KEY_ENV_VAR_NAME} environment variable") + } else { + let api_url = VercelLanguageModelProvider::api_url(cx); + if api_url == VERCEL_API_URL { + "API key configured".to_string() + } else { + format!("API key configured for {}", api_url) + } + })) + ), ) .child( - Button::new("reset-api-key", "Reset API Key") - .label_size(LabelSize::Small) - .icon(IconName::Undo) - .icon_size(IconSize::Small) - .icon_position(IconPosition::Start) - .layer(ElevationIndex::ModalSurface) - .when(env_var_set, |this| { - this.tooltip(Tooltip::text(format!("To reset your API key, unset the {API_KEY_ENV_VAR_NAME} environment variable."))) - }) - .on_click(cx.listener(|this, _, window, cx| this.reset_api_key(window, cx))), + h_flex() + .flex_shrink_0() + .child( + Button::new("reset-api-key", "Reset API Key") + .label_size(LabelSize::Small) + .icon(IconName::Undo) + .icon_size(IconSize::Small) + .icon_position(IconPosition::Start) + .layer(ElevationIndex::ModalSurface) + .when(env_var_set, |this| { + this.tooltip(Tooltip::text(format!("To reset your API key, unset the {API_KEY_ENV_VAR_NAME} environment variable."))) + }) + .on_click(cx.listener(|this, _, window, cx| this.reset_api_key(window, cx))), + ), ) .into_any() }; diff --git a/crates/language_models/src/provider/x_ai.rs b/crates/language_models/src/provider/x_ai.rs index 8b51ca12099691e4ae70084b509c6c40547bd432..979824442c6d03a8f735448003425e94a83e46ea 100644 --- a/crates/language_models/src/provider/x_ai.rs +++ b/crates/language_models/src/provider/x_ai.rs @@ -16,7 +16,7 @@ use std::sync::{Arc, LazyLock}; use strum::IntoEnumIterator; use ui::{ElevationIndex, List, Tooltip, prelude::*}; use ui_input::InputField; -use util::{ResultExt, truncate_and_trailoff}; +use util::ResultExt; use x_ai::{Model, XAI_API_URL}; use zed_env_vars::{EnvVar, env_var}; @@ -486,30 +486,42 @@ impl Render for ConfigurationView { .bg(cx.theme().colors().background) .child( h_flex() + .flex_1() + .min_w_0() .gap_1() .child(Icon::new(IconName::Check).color(Color::Success)) - .child(Label::new(if env_var_set { - format!("API key set in {API_KEY_ENV_VAR_NAME} environment variable") - } else { - let api_url = XAiLanguageModelProvider::api_url(cx); - if api_url == XAI_API_URL { - "API key configured".to_string() - } else { - format!("API key configured for {}", truncate_and_trailoff(&api_url, 32)) - } - })), + .child( + div() + .w_full() + .overflow_x_hidden() + .text_ellipsis() + .child(Label::new(if env_var_set { + format!("API key set in {API_KEY_ENV_VAR_NAME} environment variable") + } else { + let api_url = XAiLanguageModelProvider::api_url(cx); + if api_url == XAI_API_URL { + "API key configured".to_string() + } else { + format!("API key configured for {}", api_url) + } + })) + ), ) .child( - Button::new("reset-api-key", "Reset API Key") - .label_size(LabelSize::Small) - .icon(IconName::Undo) - .icon_size(IconSize::Small) - .icon_position(IconPosition::Start) - .layer(ElevationIndex::ModalSurface) - .when(env_var_set, |this| { - this.tooltip(Tooltip::text(format!("To reset your API key, unset the {API_KEY_ENV_VAR_NAME} environment variable."))) - }) - .on_click(cx.listener(|this, _, window, cx| this.reset_api_key(window, cx))), + h_flex() + .flex_shrink_0() + .child( + Button::new("reset-api-key", "Reset API Key") + .label_size(LabelSize::Small) + .icon(IconName::Undo) + .icon_size(IconSize::Small) + .icon_position(IconPosition::Start) + .layer(ElevationIndex::ModalSurface) + .when(env_var_set, |this| { + this.tooltip(Tooltip::text(format!("To reset your API key, unset the {API_KEY_ENV_VAR_NAME} environment variable."))) + }) + .on_click(cx.listener(|this, _, window, cx| this.reset_api_key(window, cx))), + ), ) .into_any() };