ZIm/crates/ai_onboarding/src/agent_api_keys_onboarding.rs
Danilo Leal 00725273e4
agent: Rename "open configuration" action to "open settings" (#35329)
"Settings" is the terminology we use in the agent panel, thus having the
action use "configuration" makes it harder for folks to find this either
via the command palette or the keybinding editor UI in case they'd like
to change it.

Release Notes:

- agent: Renamed the "open configuration" action to "open settings" for
better discoverability and consistency
2025-07-30 09:55:13 -03:00

143 lines
4.9 KiB
Rust

use gpui::{Action, IntoElement, ParentElement, RenderOnce, point};
use language_model::{LanguageModelRegistry, ZED_CLOUD_PROVIDER_ID};
use ui::{Divider, List, prelude::*};
use crate::BulletItem;
pub struct ApiKeysWithProviders {
configured_providers: Vec<(IconName, SharedString)>,
}
impl ApiKeysWithProviders {
pub fn new(cx: &mut Context<Self>) -> Self {
cx.subscribe(
&LanguageModelRegistry::global(cx),
|this: &mut Self, _registry, event: &language_model::Event, cx| match event {
language_model::Event::ProviderStateChanged
| language_model::Event::AddedProvider(_)
| language_model::Event::RemovedProvider(_) => {
this.configured_providers = Self::compute_configured_providers(cx)
}
_ => {}
},
)
.detach();
Self {
configured_providers: Self::compute_configured_providers(cx),
}
}
fn compute_configured_providers(cx: &App) -> Vec<(IconName, SharedString)> {
LanguageModelRegistry::read_global(cx)
.providers()
.iter()
.filter(|provider| {
provider.is_authenticated(cx) && provider.id() != ZED_CLOUD_PROVIDER_ID
})
.map(|provider| (provider.icon(), provider.name().0.clone()))
.collect()
}
}
impl Render for ApiKeysWithProviders {
fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
let configured_providers_list =
self.configured_providers
.iter()
.cloned()
.map(|(icon, name)| {
h_flex()
.gap_1p5()
.child(Icon::new(icon).size(IconSize::XSmall).color(Color::Muted))
.child(Label::new(name))
});
div()
.mx_2p5()
.p_1()
.pb_0()
.gap_2()
.rounded_t_lg()
.border_t_1()
.border_x_1()
.border_color(cx.theme().colors().border.opacity(0.5))
.bg(cx.theme().colors().background.alpha(0.5))
.shadow(vec![gpui::BoxShadow {
color: gpui::black().opacity(0.15),
offset: point(px(1.), px(-1.)),
blur_radius: px(3.),
spread_radius: px(0.),
}])
.child(
h_flex()
.px_2p5()
.py_1p5()
.gap_2()
.flex_wrap()
.rounded_t(px(5.))
.overflow_hidden()
.border_t_1()
.border_x_1()
.border_color(cx.theme().colors().border)
.bg(cx.theme().colors().panel_background)
.child(
h_flex()
.min_w_0()
.gap_2()
.child(
Icon::new(IconName::Info)
.size(IconSize::XSmall)
.color(Color::Muted)
)
.child(
div()
.w_full()
.child(
Label::new("Start now using API keys from your environment for the following providers:")
.color(Color::Muted)
)
)
)
.children(configured_providers_list)
)
}
}
#[derive(IntoElement)]
pub struct ApiKeysWithoutProviders;
impl ApiKeysWithoutProviders {
pub fn new() -> Self {
Self
}
}
impl RenderOnce for ApiKeysWithoutProviders {
fn render(self, _window: &mut Window, cx: &mut App) -> impl IntoElement {
v_flex()
.mt_2()
.gap_1()
.child(
h_flex()
.gap_2()
.child(
Label::new("API Keys")
.size(LabelSize::Small)
.color(Color::Muted)
.buffer_font(cx),
)
.child(Divider::horizontal()),
)
.child(List::new().child(BulletItem::new(
"Add your own keys to use AI without signing in.",
)))
.child(
Button::new("configure-providers", "Configure Providers")
.full_width()
.style(ButtonStyle::Outlined)
.on_click(move |_, window, cx| {
window.dispatch_action(zed_actions::agent::OpenSettings.boxed_clone(), cx);
}),
)
}
}