This commit is contained in:
dengqichen 2025-12-30 15:03:38 +08:00
parent a798dee401
commit 1aa84e9ffe
6 changed files with 42 additions and 9 deletions

View File

@ -73,7 +73,7 @@ export const LogStreamViewer: React.FC<LogStreamViewerProps> = ({
console.log('[LogStreamViewer] Render - status:', currentStatus, 'error:', error, 'shouldShowError:', shouldShowError, 'isConnecting:', isConnecting);
return (
<div className={`flex flex-col h-full ${className}`}>
<div className={`flex flex-col h-full relative ${className}`}>
{/* 自定义控制栏 */}
{customToolbar && (
<div className="flex-shrink-0">
@ -82,7 +82,7 @@ export const LogStreamViewer: React.FC<LogStreamViewerProps> = ({
)}
{/* 日志显示区域 */}
<div className="flex-1 overflow-hidden">
<div className="flex-1 overflow-hidden relative">
{shouldShowError ? (
<div className="h-full flex items-center justify-center p-4 bg-gray-950">
<div className="text-center max-w-md">

View File

@ -12,6 +12,7 @@ export const MonacoLogViewer: React.FC<MonacoLogViewerProps> = ({
fontSize = 12,
theme = 'vs-dark',
height = '100%',
wordWrap = false,
onReady,
className = '',
style = {},
@ -27,6 +28,15 @@ export const MonacoLogViewer: React.FC<MonacoLogViewerProps> = ({
autoScrollRef.current = autoScroll;
}, [autoScroll]);
// 更新wordWrap设置
useEffect(() => {
if (editorRef.current) {
editorRef.current.updateOptions({
wordWrap: wordWrap ? 'on' : 'off',
});
}
}, [wordWrap]);
// Monaco Editor挂载完成
const handleEditorDidMount = (editor: editor.IStandaloneCodeEditor, monaco: Monaco) => {
editorRef.current = editor;
@ -125,7 +135,7 @@ export const MonacoLogViewer: React.FC<MonacoLogViewerProps> = ({
};
return (
<div className={`w-full h-full ${className}`} style={{ height, ...style }}>
<div className={`w-full h-full relative ${className}`} style={{ height, ...style }}>
<Editor
height="100%"
defaultLanguage="plaintext"
@ -137,7 +147,7 @@ export const MonacoLogViewer: React.FC<MonacoLogViewerProps> = ({
readOnly: true,
minimap: { enabled: false },
scrollBeyondLastLine: false,
wordWrap: 'off',
wordWrap: wordWrap ? 'on' : 'off',
lineNumbers: 'on',
glyphMargin: false,
folding: false,

View File

@ -159,6 +159,9 @@ export interface MonacoLogViewerProps {
/** 高度 */
height?: string | number;
/** 自动换行 */
wordWrap?: boolean;
/** 就绪回调 */
onReady?: (api: LogViewerAPI) => void;

View File

@ -199,9 +199,9 @@ export function TerminalWindowManager<TResource = any>({
{windows.map(win => (
<div
key={win.id}
style={{
visibility: win.isMinimized ? 'hidden' : 'visible',
pointerEvents: win.isMinimized ? 'none' : 'auto',
style={{
// 使用 display:none 彻底隐藏最小化窗口避免Monaco滚动条残影
display: win.isMinimized ? 'none' : 'block',
}}
>
<DraggableWindow

View File

@ -214,8 +214,8 @@ export const DraggableWindow: React.FC<DraggableWindowProps> = ({
</div>
</div>
{/* 窗口内容 */}
<div className="flex-1 overflow-hidden">
{/* 窗口内容 - relative定位确保子元素的absolute定位正确 */}
<div className="flex-1 overflow-hidden relative">
{children}
</div>

View File

@ -28,6 +28,7 @@ import {
Loader2,
ChevronUp,
ChevronDown,
WrapText,
} from 'lucide-react';
import { Badge } from '@/components/ui/badge';
import {
@ -76,6 +77,7 @@ const LogViewerContent: React.FC<{
const [loadingPods, setLoadingPods] = useState(app.runtimeType === 'K8S');
const [isControlBarCollapsed, setIsControlBarCollapsed] = useState(false);
const [status, setStatus] = useState<LogStreamStatus>(LogStreamStatus.DISCONNECTED);
const [wordWrap, setWordWrap] = useState(true);
const controlApiRef = useRef<LogStreamControlAPI | null>(null);
const logApiRef = useRef<LogViewerAPI | null>(null);
@ -392,6 +394,9 @@ const LogViewerContent: React.FC<{
controlApiRef.current.send(JSON.stringify(stopMessage));
// 立即更新状态为DISCONNECTED确保UI正确显示开始按钮
setStatus(LogStreamStatus.DISCONNECTED);
setTimeout(() => {
controlApiRef.current?.disconnect();
}, 100);
@ -537,6 +542,20 @@ const LogViewerContent: React.FC<{
</TooltipTrigger>
<TooltipContent></TooltipContent>
</Tooltip>
<Tooltip>
<TooltipTrigger asChild>
<Button
size="sm"
variant={wordWrap ? "default" : "outline"}
onClick={() => setWordWrap(!wordWrap)}
className="h-7 w-7 p-0"
>
<WrapText className="h-3 w-3" />
</Button>
</TooltipTrigger>
<TooltipContent>{wordWrap ? '关闭换行' : '自动换行'}</TooltipContent>
</Tooltip>
</div>
</div>
</TooltipProvider>
@ -587,6 +606,7 @@ const LogViewerContent: React.FC<{
theme: 'vs-dark',
fontSize: 13,
height: '100%',
wordWrap: wordWrap,
}}
onReady={(controlApi, logApi) => {
controlApiRef.current = controlApi;