agent: Add design adjustments to MCP config flow (#29765)

Mostly somewhat small UI tweaks around the MCP extension config flow and
the settings section.

Release Notes:

- N/A
This commit is contained in:
Danilo Leal 2025-05-01 19:29:59 -03:00 committed by GitHub
parent 7c23d13773
commit 8d4d3badf3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 49 additions and 23 deletions

1
assets/icons/hammer.svg Normal file
View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-hammer-icon lucide-hammer"><path d="m15 12-8.373 8.373a1 1 0 1 1-3-3L12 9"/><path d="m18 15 4-4"/><path d="m21.5 11.5-1.914-1.914A2 2 0 0 1 19 8.172V7l-2.26-2.26a6 6 0 0 0-4.202-1.756L9 2.96l.92.82A6.18 6.18 0 0 1 12 8.4V10l2 2h1.172a2 2 0 0 1 1.414.586L18.5 14.5"/></svg>

After

Width:  |  Height:  |  Size: 475 B

View file

@ -257,7 +257,11 @@ impl AssistantConfiguration {
) )
} }
fn render_context_servers_section(&mut self, cx: &mut Context<Self>) -> impl IntoElement { fn render_context_servers_section(
&mut self,
window: &mut Window,
cx: &mut Context<Self>,
) -> impl IntoElement {
let context_servers = self.context_server_manager.read(cx).all_servers().clone(); let context_servers = self.context_server_manager.read(cx).all_servers().clone();
const SUBHEADING: &str = "Connect to context servers via the Model Context Protocol either via Zed extensions or directly."; const SUBHEADING: &str = "Connect to context servers via the Model Context Protocol either via Zed extensions or directly.";
@ -276,7 +280,7 @@ impl AssistantConfiguration {
.children( .children(
context_servers context_servers
.into_iter() .into_iter()
.map(|context_server| self.render_context_server(context_server, cx)), .map(|context_server| self.render_context_server(context_server, window, cx)),
) )
.child( .child(
h_flex() h_flex()
@ -305,7 +309,7 @@ impl AssistantConfiguration {
.style(ButtonStyle::Filled) .style(ButtonStyle::Filled)
.layer(ElevationIndex::ModalSurface) .layer(ElevationIndex::ModalSurface)
.full_width() .full_width()
.icon(IconName::DatabaseZap) .icon(IconName::Hammer)
.icon_size(IconSize::Small) .icon_size(IconSize::Small)
.icon_position(IconPosition::Start) .icon_position(IconPosition::Start)
.on_click(|_event, window, cx| { .on_click(|_event, window, cx| {
@ -327,6 +331,7 @@ impl AssistantConfiguration {
fn render_context_server( fn render_context_server(
&self, &self,
context_server: Arc<ContextServer>, context_server: Arc<ContextServer>,
window: &mut Window,
cx: &mut Context<Self>, cx: &mut Context<Self>,
) -> impl use<> + IntoElement { ) -> impl use<> + IntoElement {
let tools_by_source = self.tools.read(cx).tools_by_source(cx); let tools_by_source = self.tools.read(cx).tools_by_source(cx);
@ -356,24 +361,26 @@ impl AssistantConfiguration {
.map_or([].as_slice(), |tools| tools.as_slice()); .map_or([].as_slice(), |tools| tools.as_slice());
let tool_count = tools.len(); let tool_count = tools.len();
let border_color = cx.theme().colors().border.opacity(0.6);
v_flex() v_flex()
.id(SharedString::from(context_server.id())) .id(SharedString::from(context_server.id()))
.border_1() .border_1()
.rounded_md() .rounded_md()
.border_color(cx.theme().colors().border) .border_color(border_color)
.bg(cx.theme().colors().background.opacity(0.25)) .bg(cx.theme().colors().background.opacity(0.2))
.overflow_hidden()
.child( .child(
h_flex() h_flex()
.p_1() .p_1()
.justify_between() .justify_between()
.when(are_tools_expanded && tool_count > 1, |element| { .when(
element error.is_some() || are_tools_expanded && tool_count > 1,
.border_b_1() |element| element.border_b_1().border_color(border_color),
.border_color(cx.theme().colors().border) )
})
.child( .child(
h_flex() h_flex()
.gap_2() .gap_1p5()
.child( .child(
Disclosure::new( Disclosure::new(
"tool-list-disclosure", "tool-list-disclosure",
@ -419,7 +426,7 @@ impl AssistantConfiguration {
} }
None => Indicator::dot().color(Color::Muted).into_any_element(), None => Indicator::dot().color(Color::Muted).into_any_element(),
}) })
.child(Label::new(context_server.id())) .child(Label::new(context_server.id()).ml_0p5())
.when(is_running, |this| { .when(is_running, |this| {
this.child( this.child(
Label::new(if tool_count == 1 { Label::new(if tool_count == 1 {
@ -470,12 +477,29 @@ impl AssistantConfiguration {
.map(|parent| { .map(|parent| {
if let Some(error) = error { if let Some(error) = error {
return parent.child( return parent.child(
div().py_1p5().px_2().child( h_flex()
.p_2()
.gap_2()
.items_start()
.child(
h_flex()
.flex_none()
.h(window.line_height() / 1.6_f32)
.justify_center()
.child(
Icon::new(IconName::XCircle)
.size(IconSize::XSmall)
.color(Color::Error),
),
)
.child(
div().w_full().child(
Label::new(error) Label::new(error)
.color(Color::Muted)
.buffer_font(cx) .buffer_font(cx)
.color(Color::Muted)
.size(LabelSize::Small), .size(LabelSize::Small),
), ),
),
); );
} }
@ -510,7 +534,7 @@ impl AssistantConfiguration {
} }
impl Render for AssistantConfiguration { impl Render for AssistantConfiguration {
fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement { fn render(&mut self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
v_flex() v_flex()
.id("assistant-configuration") .id("assistant-configuration")
.key_context("AgentConfiguration") .key_context("AgentConfiguration")
@ -527,7 +551,7 @@ impl Render for AssistantConfiguration {
.overflow_y_scroll() .overflow_y_scroll()
.child(self.render_command_permission(cx)) .child(self.render_command_permission(cx))
.child(Divider::horizontal().color(DividerColor::Border)) .child(Divider::horizontal().color(DividerColor::Border))
.child(self.render_context_servers_section(cx)) .child(self.render_context_servers_section(window, cx))
.child(Divider::horizontal().color(DividerColor::Border)) .child(Divider::horizontal().color(DividerColor::Border))
.child(self.render_provider_configuration_section(cx)), .child(self.render_provider_configuration_section(cx)),
) )

View file

@ -198,10 +198,10 @@ impl ConfigureContextServerModal {
.update(cx, { .update(cx, {
|workspace, cx| { |workspace, cx| {
let status_toast = StatusToast::new( let status_toast = StatusToast::new(
format!("{} MCP configured successfully", id), format!("{} configured successfully.", id),
cx, cx,
|this, _cx| { |this, _cx| {
this.icon(ToastIcon::new(IconName::DatabaseZap).color(Color::Muted)) this.icon(ToastIcon::new(IconName::Hammer).color(Color::Muted))
.action("Dismiss", |_, _| {}) .action("Dismiss", |_, _| {})
}, },
); );
@ -276,7 +276,7 @@ impl Render for ConfigureContextServerModal {
.header(ModalHeader::new().headline(format!("Configure {}", configuration.id))) .header(ModalHeader::new().headline(format!("Configure {}", configuration.id)))
.section( .section(
Section::new() Section::new()
.child(div().py_2().child(MarkdownElement::new( .child(div().pb_2().text_sm().child(MarkdownElement::new(
configuration.installation_instructions.clone(), configuration.installation_instructions.clone(),
default_markdown_style(window, cx), default_markdown_style(window, cx),
))) )))

View file

@ -137,6 +137,7 @@ pub enum IconName {
GitBranchSmall, GitBranchSmall,
Github, Github,
Globe, Globe,
Hammer,
Hash, Hash,
HistoryRerun, HistoryRerun,
Image, Image,