feat: 添加执行加载状态和全局执行ID去重,优化CLI视图和MCP配置获取

This commit is contained in:
catlog22
2026-02-17 21:01:09 +08:00
parent c588aa69d2
commit 5a937732f4
5 changed files with 136 additions and 23 deletions

View File

@@ -15,6 +15,7 @@ import {
import { useCliStreamStore, type CliExecutionState, type CliOutputLine } from '@/stores/cliStreamStore';
import { MonitorBody } from '@/components/shared/CliStreamMonitor/MonitorBody';
import { MessageRenderer } from '@/components/shared/CliStreamMonitor/MessageRenderer';
import { useActiveCliExecutions } from '@/hooks/useActiveCliExecutions';
// ========== Types ==========
@@ -68,6 +69,25 @@ function ExecutionNotFoundState({ executionId }: { executionId: string }) {
);
}
/**
* FIX-002: Loading state while syncing executions from server
* Shown after page refresh while execution data is being recovered
*/
function ExecutionLoadingState() {
const { formatMessage } = useIntl();
return (
<div className="flex-1 flex flex-col items-center justify-center text-muted-foreground gap-4">
<Loader2 className="h-8 w-8 animate-spin opacity-50" />
<div className="text-center">
<p className="text-sm">
{formatMessage({ id: 'cliViewer.syncingExecution', defaultMessage: 'Syncing execution data...' })}
</p>
</div>
</div>
);
}
/**
* Single output line component with type-based styling
*/
@@ -157,10 +177,14 @@ function CliOutputDisplay({ execution, executionId }: { execution: CliExecutionS
export function ContentArea({ paneId, className }: ContentAreaProps) {
// Get active tab using the selector
const activeTab = useViewerStore((state) => selectActiveTab(state, paneId));
// Get execution data from cliStreamStore
const executions = useCliStreamStore((state) => state.executions);
// FIX-002: Get loading state from useActiveCliExecutions
// This helps distinguish between "not found" and "still loading"
const { isLoading: isSyncing } = useActiveCliExecutions(true);
const execution = useMemo(() => {
if (!activeTab?.executionId) return null;
return executions[activeTab.executionId] || null;
@@ -173,14 +197,19 @@ export function ContentArea({ paneId, className }: ContentAreaProps) {
return <EmptyTabState />;
}
// No execution data found
// FIX-002: Show loading state while syncing if execution not yet available
if (!execution && isSyncing) {
return <ExecutionLoadingState />;
}
// No execution data found (after sync completed)
if (!execution) {
return <ExecutionNotFoundState executionId={activeTab.executionId} />;
}
// Show CLI output
return <CliOutputDisplay execution={execution} executionId={activeTab.executionId} />;
}, [activeTab, execution]);
}, [activeTab, execution, isSyncing]);
return (
<div