From 53c6362e2742778b2afc4635af11279246db1958 Mon Sep 17 00:00:00 2001 From: Auto Date: Tue, 30 Dec 2025 19:28:02 +0200 Subject: [PATCH] resize debug viewer --- ui/src/App.tsx | 7 ++- ui/src/components/DebugLogViewer.tsx | 79 ++++++++++++++++++++++++++-- 2 files changed, 81 insertions(+), 5 deletions(-) diff --git a/ui/src/App.tsx b/ui/src/App.tsx index 5365a68..c01be93 100644 --- a/ui/src/App.tsx +++ b/ui/src/App.tsx @@ -28,6 +28,7 @@ function App() { const [selectedFeature, setSelectedFeature] = useState(null) const [setupComplete, setSetupComplete] = useState(true) // Start optimistic const [debugOpen, setDebugOpen] = useState(false) + const [debugPanelHeight, setDebugPanelHeight] = useState(288) // Default height const { data: projects, isLoading: projectsLoading } = useProjects() const { data: features } = useFeatures(selectedProject) @@ -154,7 +155,10 @@ function App() { {/* Main Content */} -
+
{!selectedProject ? (

@@ -224,6 +228,7 @@ function App() { isOpen={debugOpen} onToggle={() => setDebugOpen(!debugOpen)} onClear={wsState.clearLogs} + onHeightChange={setDebugPanelHeight} /> )}

diff --git a/ui/src/components/DebugLogViewer.tsx b/ui/src/components/DebugLogViewer.tsx index 75612b8..11bbfd3 100644 --- a/ui/src/components/DebugLogViewer.tsx +++ b/ui/src/components/DebugLogViewer.tsx @@ -3,16 +3,23 @@ * * Collapsible panel at the bottom of the screen showing real-time * agent output (tool calls, results, steps). Similar to browser DevTools. + * Features a resizable height via drag handle. */ -import { useEffect, useRef, useState } from 'react' -import { ChevronUp, ChevronDown, Trash2, Terminal } from 'lucide-react' +import { useEffect, useRef, useState, useCallback } from 'react' +import { ChevronUp, ChevronDown, Trash2, Terminal, GripHorizontal } from 'lucide-react' + +const MIN_HEIGHT = 150 +const MAX_HEIGHT = 600 +const DEFAULT_HEIGHT = 288 +const STORAGE_KEY = 'debug-panel-height' interface DebugLogViewerProps { logs: Array<{ line: string; timestamp: string }> isOpen: boolean onToggle: () => void onClear: () => void + onHeightChange?: (height: number) => void } type LogLevel = 'error' | 'warn' | 'debug' | 'info' @@ -22,9 +29,16 @@ export function DebugLogViewer({ isOpen, onToggle, onClear, + onHeightChange, }: DebugLogViewerProps) { const scrollRef = useRef(null) const [autoScroll, setAutoScroll] = useState(true) + const [isResizing, setIsResizing] = useState(false) + const [panelHeight, setPanelHeight] = useState(() => { + // Load saved height from localStorage + const saved = localStorage.getItem(STORAGE_KEY) + return saved ? Math.min(Math.max(parseInt(saved, 10), MIN_HEIGHT), MAX_HEIGHT) : DEFAULT_HEIGHT + }) // Auto-scroll to bottom when new logs arrive (if user hasn't scrolled up) useEffect(() => { @@ -33,6 +47,50 @@ export function DebugLogViewer({ } }, [logs, autoScroll, isOpen]) + // Notify parent of height changes + useEffect(() => { + if (onHeightChange && isOpen) { + onHeightChange(panelHeight) + } + }, [panelHeight, isOpen, onHeightChange]) + + // Handle mouse move during resize + const handleMouseMove = useCallback((e: MouseEvent) => { + const newHeight = window.innerHeight - e.clientY + const clampedHeight = Math.min(Math.max(newHeight, MIN_HEIGHT), MAX_HEIGHT) + setPanelHeight(clampedHeight) + }, []) + + // Handle mouse up to stop resizing + const handleMouseUp = useCallback(() => { + setIsResizing(false) + // Save to localStorage + localStorage.setItem(STORAGE_KEY, panelHeight.toString()) + }, [panelHeight]) + + // Set up global mouse event listeners during resize + useEffect(() => { + if (isResizing) { + document.addEventListener('mousemove', handleMouseMove) + document.addEventListener('mouseup', handleMouseUp) + document.body.style.cursor = 'ns-resize' + document.body.style.userSelect = 'none' + } + return () => { + document.removeEventListener('mousemove', handleMouseMove) + document.removeEventListener('mouseup', handleMouseUp) + document.body.style.cursor = '' + document.body.style.userSelect = '' + } + }, [isResizing, handleMouseMove, handleMouseUp]) + + // Start resizing + const handleResizeStart = (e: React.MouseEvent) => { + e.preventDefault() + e.stopPropagation() + setIsResizing(true) + } + // Detect if user scrolled up const handleScroll = (e: React.UIEvent) => { const el = e.currentTarget @@ -87,10 +145,23 @@ export function DebugLogViewer({ return (
+ {/* Resize handle - only visible when open */} + {isOpen && ( +
+
+ +
+
+ )} + {/* Header bar */}