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.
This commit is contained in:
Danilo Leal 2025-05-12 11:21:22 -03:00 committed by GitHub
parent 33c896c23d
commit ddc649bdb8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -422,6 +422,7 @@ impl AgentConfiguration {
.unwrap_or(ContextServerStatus::Stopped); .unwrap_or(ContextServerStatus::Stopped);
let is_running = matches!(server_status, ContextServerStatus::Running); 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() { let error = if let ContextServerStatus::Error(error) = server_status.clone() {
Some(error) Some(error)
@ -443,9 +444,38 @@ impl AgentConfiguration {
let tool_count = tools.len(); let tool_count = tools.len();
let border_color = cx.theme().colors().border.opacity(0.6); 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() v_flex()
.id(SharedString::from(context_server_id.0.clone())) .id(item_id.clone())
.border_1() .border_1()
.rounded_md() .rounded_md()
.border_color(border_color) .border_color(border_color)
@ -480,35 +510,12 @@ impl AgentConfiguration {
} }
})), })),
) )
.child(match server_status { .child(
ContextServerStatus::Starting => { div()
let color = Color::Success.color(cx); .id(item_id.clone())
Indicator::dot() .tooltip(Tooltip::text(tooltip_text))
.color(Color::Success) .child(status_indicator),
.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(Label::new(context_server_id.0.clone()).ml_0p5()) .child(Label::new(context_server_id.0.clone()).ml_0p5())
.when(is_running, |this| { .when(is_running, |this| {
this.child( this.child(