fix: simplify topbar Runtime status
Cross-platform packages / Validate source (push) Canceled after 0s
Cross-platform packages / Authorize desktop packaging (push) Canceled after 0s
Cross-platform packages / linux arm64 (push) Canceled after 0s
Cross-platform packages / macos arm64 (push) Canceled after 0s
Cross-platform packages / windows arm64 (push) Canceled after 0s
Cross-platform packages / linux x64 (push) Canceled after 0s
Cross-platform packages / macos x64 (push) Canceled after 0s
Cross-platform packages / windows x64 (push) Canceled after 0s
Cross-platform packages / Publish GitHub and OSS release (push) Canceled after 0s

The topbar repeated a textual state after the Runtime or model name even
though it already displayed a compact status indicator. It now uses green,
yellow, and gray dots for ready, connecting, and unavailable states while
keeping detailed status available to assistive technology and tooltips.

Release note: 顶栏 Runtime 状态改用绿、黄、灰三色标记,不再重复显示“就绪”“连接中”或“不可用”文字。
This commit is contained in:
mesalogo
2026-09-03 13:42:41 +08:00
parent c52732441a
commit f18e4abb3c
6 changed files with 42 additions and 16 deletions
+3 -1
View File
@@ -383,7 +383,9 @@
对齐。该栏不重复放置新建入口。
- “新建任务”只位于工作栏“任务索引”标题后方;任务状态筛选占满工作栏可用宽度,四个选项
等分,不能保留内容宽度的短控件。
- Runtime 状态、同步状态等短标签使用 `--font-caption`,不得放大为正文标题。
- Runtime 状态、同步状态等短标签使用 `--font-caption`,不得放大为正文标题。顶栏 Runtime
状态由状态点和 Runtime/模型名称紧凑表达:就绪使用绿色,连接中使用黄色,不可用使用灰色,
不再重复显示状态文字;完整状态详情继续通过可访问说明和工具提示提供。
- 浅色与深色切换属于持续可用的窗口级操作,直接显示太阳或月亮图标,并通过可访问名称说明将切换到的主题。选择必须持久化,切换不得改变布局。
- 顶栏只直接显示当前任务所需的高频操作。已有侧栏账户设置入口时,不再重复显示 Runtime/设置入口;使用帮助优先放在相关操作附近,而不是为单个帮助项创建“更多”菜单。
- 助手工作栏开关固定在上下文栏最右侧并与窗口关闭按钮纵向对齐;展开后该开关保持原位并
@@ -356,8 +356,9 @@
### UX-02 Runtime 显式状态
- **优先级 / 状态:** P1 / 已完成
- **范围:** 顶栏显示就绪、连接中、不可用等文字,并通过 `aria-describedby` 暴露原因。
- **验收:** 不依赖颜色或 `title` 即可理解 Runtime 状态和发送不可用原因。
- **范围:** 顶栏以状态点和 Runtime/模型名称紧凑表达状态:就绪为绿色,连接中为黄色,
不可用为灰色;不重复显示状态文字,并通过 `aria-describedby` 暴露完整原因。
- **验收:** 三种状态均不重复显示状态文字;发送不可用原因仍由发送控件的可访问说明提供。
### UX-03 等待审批实时通知
+15 -1
View File
@@ -1429,7 +1429,11 @@ describe('App', () => {
)
expect(runtimeStatus).not.toBeNull()
expect(
within(runtimeStatus!).getByText('就绪')
within(runtimeStatus!).queryByText('就绪')
).not.toBeInTheDocument()
expect(runtimeStatus).toHaveClass('runtime-status--ready')
expect(
runtimeStatus?.querySelector('.runtime-status__dot')
).toBeInTheDocument()
expect(runtimeStatus).toHaveAttribute(
'aria-describedby',
@@ -1449,6 +1453,16 @@ describe('App', () => {
).not.toBeInTheDocument()
})
it('uses a compact color indicator while connecting to a Runtime', () => {
render(<App />)
const connectingStatus = document.querySelector<HTMLElement>(
'.runtime-status'
)
expect(connectingStatus).toHaveClass('runtime-status--connecting')
expect(within(connectingStatus!).queryByText('连接中'))
.not.toBeInTheDocument()
})
it('loads customized branding into the primary sidebar', async () => {
expect(
saveBrandingPreferences({
+1 -8
View File
@@ -9127,20 +9127,13 @@ function App(): React.JSX.Element {
<div className="topbar__actions">
<span
aria-describedby={runtimeDetailId}
className={
runtimeState === 'ready'
? 'runtime-status runtime-status--online'
: 'runtime-status'
}
className={`runtime-status runtime-status--${runtimeState}`}
title={runtimeDetail}
>
<span className="runtime-status__dot" />
<span className="runtime-status__label">
{runtime?.label ?? t('runtime.detecting')}
</span>
<span className="runtime-status__state">
{t(`runtime.state.${runtimeState}`)}
</span>
{runtime?.capability === 'image-generation' && (
<span className="runtime-capability-badge">
{t('runtime.imageGeneration')}
@@ -80,6 +80,18 @@ describe('WorkspacePrimitives', () => {
cleanup()
})
it('uses semantic colors for compact Runtime status dots', () => {
expect(stylesheet).toMatch(
/\.runtime-status--ready \.runtime-status__dot\s*\{[^}]*background:\s*var\(--success\);/u
)
expect(stylesheet).toMatch(
/\.runtime-status--connecting \.runtime-status__dot\s*\{[^}]*background:\s*var\(--warning\);/u
)
expect(stylesheet).toMatch(
/\.runtime-status--unavailable \.runtime-status__dot\s*\{[^}]*background:\s*var\(--text-muted\);/u
)
})
it('keeps shared switch rows aligned without standalone dividers', () => {
const toggleRowStyles = stylesheet.match(
/\.toggle-row\s*\{(?<rules>[^}]*)\}/u
+8 -4
View File
@@ -5061,12 +5061,16 @@ button > svg {
background: var(--text-muted);
}
.runtime-status--online {
color: var(--success);
.runtime-status--ready .runtime-status__dot {
background: var(--success);
}
.runtime-status--online .runtime-status__dot {
background: var(--success);
.runtime-status--connecting .runtime-status__dot {
background: var(--warning);
}
.runtime-status--unavailable .runtime-status__dot {
background: var(--text-muted);
}
.chat-scroll-region {