fix(i18n): Wave 3 清零 - status-orb + OmniTerminal + sse-states
- status-orb.tsx: 狀態 label 改用 useTranslations - OmniTerminal.tsx: 'SSE Live'/'Offline' 改用 i18n - sse-states.ts: label 改為 i18n key (connection.xxx) - 新增 subscribing/streaming 翻譯 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -153,7 +153,9 @@
|
||||
"connection": {
|
||||
"disconnected": "Disconnected",
|
||||
"connecting": "Connecting...",
|
||||
"subscribing": "Subscribing...",
|
||||
"connected": "Live",
|
||||
"streaming": "Streaming",
|
||||
"reconnecting": "Reconnecting...",
|
||||
"error": "Connection Error",
|
||||
"mockMode": "MOCK"
|
||||
|
||||
@@ -153,7 +153,9 @@
|
||||
"connection": {
|
||||
"disconnected": "已斷線",
|
||||
"connecting": "連線中...",
|
||||
"subscribing": "訂閱中...",
|
||||
"connected": "即時",
|
||||
"streaming": "串流中",
|
||||
"reconnecting": "重新連線...",
|
||||
"error": "連線錯誤",
|
||||
"mockMode": "模擬"
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
'use client'
|
||||
|
||||
/**
|
||||
* StatusOrb - Agent 狀態指示燈
|
||||
* ============================
|
||||
* i18n: 100% 使用 useTranslations
|
||||
* 修復: 2026-03-29 Wave 3 i18n 清零
|
||||
*/
|
||||
|
||||
import { useTranslations } from 'next-intl'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
||||
type AgentStatus = 'idle' | 'thinking' | 'executing' | 'waiting_approval'
|
||||
@@ -10,25 +18,29 @@ interface StatusOrbProps {
|
||||
className?: string
|
||||
}
|
||||
|
||||
const statusConfig: Record<AgentStatus, { color: string; label: string; animate: boolean }> = {
|
||||
// i18n key 對應表
|
||||
const statusI18nKey: Record<AgentStatus, string> = {
|
||||
idle: 'idle',
|
||||
thinking: 'thinking',
|
||||
executing: 'executing',
|
||||
waiting_approval: 'waitingApproval',
|
||||
}
|
||||
|
||||
const statusConfig: Record<AgentStatus, { color: string; animate: boolean }> = {
|
||||
idle: {
|
||||
color: 'bg-nothing-gray-600',
|
||||
label: 'Idle',
|
||||
animate: false,
|
||||
},
|
||||
thinking: {
|
||||
color: 'bg-status-warning',
|
||||
label: 'Thinking',
|
||||
animate: true,
|
||||
},
|
||||
executing: {
|
||||
color: 'bg-status-healthy',
|
||||
label: 'Executing',
|
||||
animate: true,
|
||||
},
|
||||
waiting_approval: {
|
||||
color: 'bg-status-critical',
|
||||
label: 'Awaiting Approval',
|
||||
animate: true,
|
||||
},
|
||||
}
|
||||
@@ -40,8 +52,10 @@ const sizeConfig = {
|
||||
}
|
||||
|
||||
export function StatusOrb({ status, size = 'md', className }: StatusOrbProps) {
|
||||
const t = useTranslations('status')
|
||||
const config = statusConfig[status]
|
||||
const sizeClass = sizeConfig[size]
|
||||
const label = t(statusI18nKey[status])
|
||||
|
||||
return (
|
||||
<div className={cn('relative', className)}>
|
||||
@@ -70,7 +84,7 @@ export function StatusOrb({ status, size = 'md', className }: StatusOrbProps) {
|
||||
{/* Label */}
|
||||
<div className="absolute -bottom-6 left-1/2 -translate-x-1/2 whitespace-nowrap">
|
||||
<span className="font-mono text-xs text-nothing-gray-500">
|
||||
{config.label}
|
||||
{label}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -205,7 +205,7 @@ export const OmniTerminal = () => {
|
||||
</span>
|
||||
<div className="flex items-center gap-1 opacity-60">
|
||||
<span className={`w-2 h-2 rounded-full ${isConnected ? 'bg-green-500' : 'bg-gray-400'}`}></span>
|
||||
<span className="text-xs uppercase font-mono hidden sm:inline">{isConnected ? 'SSE Live' : 'Offline'}</span>
|
||||
<span className="text-xs uppercase font-mono hidden sm:inline">{isConnected ? t('sseLive') : t('offline')}</span>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
|
||||
@@ -109,10 +109,13 @@ export interface SSEStateInfo {
|
||||
|
||||
/**
|
||||
* 狀態資訊對照表
|
||||
*
|
||||
* Note: label 是 i18n key (connection.xxx),使用時需呼叫 t(label)
|
||||
* 修復: 2026-03-29 Wave 3 i18n 清零
|
||||
*/
|
||||
export const SSE_STATE_INFO: Record<SSEConnectionState, SSEStateInfo> = {
|
||||
disconnected: {
|
||||
label: 'Offline',
|
||||
label: 'disconnected', // i18n: connection.disconnected
|
||||
isLoading: false,
|
||||
isConnected: false,
|
||||
isStreaming: false,
|
||||
@@ -120,7 +123,7 @@ export const SSE_STATE_INFO: Record<SSEConnectionState, SSEStateInfo> = {
|
||||
color: 'text-gray-400',
|
||||
},
|
||||
connecting: {
|
||||
label: 'Connecting...',
|
||||
label: 'connecting', // i18n: connection.connecting
|
||||
isLoading: true,
|
||||
isConnected: false,
|
||||
isStreaming: false,
|
||||
@@ -128,7 +131,7 @@ export const SSE_STATE_INFO: Record<SSEConnectionState, SSEStateInfo> = {
|
||||
color: 'text-yellow-500',
|
||||
},
|
||||
subscribing: {
|
||||
label: 'Subscribing...',
|
||||
label: 'subscribing', // i18n: connection.subscribing
|
||||
isLoading: true,
|
||||
isConnected: false,
|
||||
isStreaming: false,
|
||||
@@ -136,7 +139,7 @@ export const SSE_STATE_INFO: Record<SSEConnectionState, SSEStateInfo> = {
|
||||
color: 'text-yellow-500',
|
||||
},
|
||||
connected: {
|
||||
label: 'SSE Live',
|
||||
label: 'connected', // i18n: connection.connected
|
||||
isLoading: false,
|
||||
isConnected: true,
|
||||
isStreaming: false,
|
||||
@@ -144,7 +147,7 @@ export const SSE_STATE_INFO: Record<SSEConnectionState, SSEStateInfo> = {
|
||||
color: 'text-green-500',
|
||||
},
|
||||
streaming: {
|
||||
label: 'Streaming',
|
||||
label: 'streaming', // i18n: connection.streaming
|
||||
isLoading: false,
|
||||
isConnected: true,
|
||||
isStreaming: true,
|
||||
@@ -152,7 +155,7 @@ export const SSE_STATE_INFO: Record<SSEConnectionState, SSEStateInfo> = {
|
||||
color: 'text-claw-blue',
|
||||
},
|
||||
reconnecting: {
|
||||
label: 'Reconnecting...',
|
||||
label: 'reconnecting', // i18n: connection.reconnecting
|
||||
isLoading: true,
|
||||
isConnected: false,
|
||||
isStreaming: false,
|
||||
@@ -160,7 +163,7 @@ export const SSE_STATE_INFO: Record<SSEConnectionState, SSEStateInfo> = {
|
||||
color: 'text-orange-500',
|
||||
},
|
||||
error: {
|
||||
label: 'Error',
|
||||
label: 'error', // i18n: connection.error
|
||||
isLoading: false,
|
||||
isConnected: false,
|
||||
isStreaming: false,
|
||||
|
||||
Reference in New Issue
Block a user