From ddc649bdb83b4f0d03f405939c101cb9a50689c8 Mon Sep 17 00:00:00 2001 From: Danilo Leal <67129314+danilo-leal@users.noreply.github.com> Date: Mon, 12 May 2025 11:21:22 -0300 Subject: [PATCH] agent: Don't rely only on color to communicate MCP server status (#30573) The MCP server item in the settings view has an indicator that used to only use colors to communicate the connection status. From an accessibility standpoint, relying on just colors is never a good idea; there should always be a supporting element that complements color for communicating a certain thing. In this case, I added a tooltip, when you hover over the indicator dot, that clearly words out the status. Release Notes: - agent: Improved clarity of MCP server connection status in the Settings view. --- crates/agent/src/agent_configuration.rs | 67 ++++++++++++++----------- 1 file changed, 37 insertions(+), 30 deletions(-) diff --git a/crates/agent/src/agent_configuration.rs b/crates/agent/src/agent_configuration.rs index 8b338a50e8..ec3e2ac44c 100644 --- a/crates/agent/src/agent_configuration.rs +++ b/crates/agent/src/agent_configuration.rs @@ -422,6 +422,7 @@ impl AgentConfiguration { .unwrap_or(ContextServerStatus::Stopped); let is_running = matches!(server_status, ContextServerStatus::Running); + let item_id = SharedString::from(context_server_id.0.clone()); let error = if let ContextServerStatus::Error(error) = server_status.clone() { Some(error) @@ -443,9 +444,38 @@ impl AgentConfiguration { let tool_count = tools.len(); let border_color = cx.theme().colors().border.opacity(0.6); + let success_color = Color::Success.color(cx); + + let (status_indicator, tooltip_text) = match server_status { + ContextServerStatus::Starting => ( + Indicator::dot() + .color(Color::Success) + .with_animation( + SharedString::from(format!("{}-starting", context_server_id.0.clone(),)), + Animation::new(Duration::from_secs(2)) + .repeat() + .with_easing(pulsating_between(0.4, 1.)), + move |this, delta| this.color(success_color.alpha(delta).into()), + ) + .into_any_element(), + "Server is starting.", + ), + ContextServerStatus::Running => ( + Indicator::dot().color(Color::Success).into_any_element(), + "Server is running.", + ), + ContextServerStatus::Error(_) => ( + Indicator::dot().color(Color::Error).into_any_element(), + "Server has an error.", + ), + ContextServerStatus::Stopped => ( + Indicator::dot().color(Color::Muted).into_any_element(), + "Server is stopped.", + ), + }; v_flex() - .id(SharedString::from(context_server_id.0.clone())) + .id(item_id.clone()) .border_1() .rounded_md() .border_color(border_color) @@ -480,35 +510,12 @@ impl AgentConfiguration { } })), ) - .child(match server_status { - ContextServerStatus::Starting => { - let color = Color::Success.color(cx); - Indicator::dot() - .color(Color::Success) - .with_animation( - SharedString::from(format!( - "{}-starting", - context_server_id.0.clone(), - )), - Animation::new(Duration::from_secs(2)) - .repeat() - .with_easing(pulsating_between(0.4, 1.)), - move |this, delta| { - this.color(color.alpha(delta).into()) - }, - ) - .into_any_element() - } - ContextServerStatus::Running => { - Indicator::dot().color(Color::Success).into_any_element() - } - ContextServerStatus::Error(_) => { - Indicator::dot().color(Color::Error).into_any_element() - } - ContextServerStatus::Stopped => { - Indicator::dot().color(Color::Muted).into_any_element() - } - }) + .child( + div() + .id(item_id.clone()) + .tooltip(Tooltip::text(tooltip_text)) + .child(status_indicator), + ) .child(Label::new(context_server_id.0.clone()).ml_0p5()) .when(is_running, |this| { this.child(