From b59f672033c0f1adab5d0344468ef930a6bf6351 Mon Sep 17 00:00:00 2001 From: gongzhiyong Date: Wed, 15 Apr 2026 01:29:31 +0800 Subject: [PATCH] feat(ui): replace collapsible config summary bar with always-visible tool chips MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove the "Auto · 云费用 1" summary toggle button that occupied a dedicated line below the textarea. Model mode and tool group chips are now displayed inline and always visible, eliminating the redundant status row while keeping all selection controls accessible. Co-Authored-By: Claude Sonnet 4.6 --- langgraph/src/components/ChatInput.tsx | 3 +- langgraph/src/components/ConfigPanel.tsx | 165 +++++++++-------------- langgraph/src/main.tsx | 16 +-- 3 files changed, 66 insertions(+), 118 deletions(-) diff --git a/langgraph/src/components/ChatInput.tsx b/langgraph/src/components/ChatInput.tsx index d864d39..e205cb3 100644 --- a/langgraph/src/components/ChatInput.tsx +++ b/langgraph/src/components/ChatInput.tsx @@ -1,6 +1,6 @@ import { type RefObject } from "react"; import { Square, Loader2 } from "lucide-react"; -import { QUICK_PROMPTS, type ToolKey } from "@/utils/tool-maps"; +import { QUICK_PROMPTS } from "@/utils/tool-maps"; import FileUploadButton, { type SelectedFile } from "@/components/FileUploadButton.tsx"; import FileAttachmentPreview from "@/components/FileAttachmentPreview.tsx"; @@ -16,7 +16,6 @@ interface ChatInputProps { setSourceLabel: (v: string | null) => void; concurrentStatus: "idle" | "generating" | "stopping" | "cancelling"; setConcurrentStatus: (s: "idle" | "generating" | "stopping" | "cancelling") => void; - activeTools: Set; onSubmit: (e: React.FormEvent) => void; onStop: () => void; onPaste: (e: React.ClipboardEvent) => void; diff --git a/langgraph/src/components/ConfigPanel.tsx b/langgraph/src/components/ConfigPanel.tsx index 3ec5bf3..706c1d1 100644 --- a/langgraph/src/components/ConfigPanel.tsx +++ b/langgraph/src/components/ConfigPanel.tsx @@ -1,13 +1,11 @@ import { type RefObject } from "react"; -import { ChevronDown, Sparkles } from "lucide-react"; +import { Sparkles } from "lucide-react"; import { cn } from "@/lib/utils"; import { TOOL_GROUPS, type ToolKey, type ModelMode, MODEL_OPTIONS } from "@/utils/tool-maps"; import { ExportButton } from "@/components/shared/ExportButton"; import type { Message } from "@langchain/langgraph-sdk"; interface ConfigPanelProps { - configOpen: boolean; - setConfigOpen: (open: boolean | ((prev: boolean) => boolean)) => void; configPanelRef: RefObject; modelMode: ModelMode; setModelMode: (mode: ModelMode) => void; @@ -18,8 +16,6 @@ interface ConfigPanelProps { } export function ConfigPanel({ - configOpen, - setConfigOpen, configPanelRef, modelMode, setModelMode, @@ -28,113 +24,74 @@ export function ConfigPanel({ toggleTool, activeMessages, }: ConfigPanelProps) { - const modelLabel = modelMode === "flash" ? "Flash" : modelMode === "pro" ? "Pro" : "Auto"; - const activeToolLabels = TOOL_GROUPS - .filter((g) => activeTools.has(g.key)) - .map((g) => g.label); - const summary = - activeToolLabels.length === 0 - ? modelLabel - : activeToolLabels.length <= 2 - ? `${modelLabel} · ${activeToolLabels.join(" + ")}` - : `${modelLabel} · ${activeToolLabels.length} 个工具`; - return (
-
+
{/* Export button — hidden when no messages */} {activeMessages.length > 0 && ( >} /> )} - {/* Summary bar */} - - {/* Expanded panel — opens upward */} - {configOpen && ( -
- {/* Model mode row */} -
- 模型模式 -
- {MODEL_OPTIONS.map(({ value, label, icon: Icon }) => ( - - ))} -
-
+ {/* Model mode chips */} +
+ {MODEL_OPTIONS.map(({ value, label, icon: Icon }) => ( + + ))} +
- {/* Tool toggles row */} -
- 工具 -
- {/* Auto chip */} - - {TOOL_GROUPS.map(({ key, label, icon: Icon }) => { - const isOn = activeTools.has(key); - return ( - - ); - })} -
-
-
- )} + {/* Divider */} +
+ + {/* Tool chips */} +
+ + {TOOL_GROUPS.map(({ key, label, icon: Icon }) => { + const isOn = activeTools.has(key); + return ( + + ); + })} +
); diff --git a/langgraph/src/main.tsx b/langgraph/src/main.tsx index 4e9a398..ead4e47 100644 --- a/langgraph/src/main.tsx +++ b/langgraph/src/main.tsx @@ -12,7 +12,7 @@ import CanvasPanel, { type CanvasDoc } from "@/components/CanvasPanel.tsx"; import { type SelectedFile } from "@/components/FileUploadButton.tsx"; import { TOOL_GROUPS } from "@/utils/tool-maps"; import { deduplicateMessages, type UIMsgLocal } from "@/utils/thread-management"; -import { setupGlobalKeyboardShortcuts, autoResizeTextarea, setupConfigPanelEscapeClose, setupPrefillInputListener, setupRetryToolListener } from "@/utils/input-handling"; +import { setupGlobalKeyboardShortcuts, autoResizeTextarea, setupPrefillInputListener, setupRetryToolListener } from "@/utils/input-handling"; import { createLangGraphClient } from "@/utils/api-client"; import { remoteLog } from "@/utils/remote-log"; import { useConversation } from "@/hooks/useConversation"; @@ -34,7 +34,7 @@ function App() { const [showScrollBtn, setShowScrollBtn] = useState(false); const isComposingRef = useRef(false); - const { activeTools, setActiveTools, modelMode, setModelMode, configOpen, setConfigOpen, toggleTool } = useConfig(); + const { activeTools, setActiveTools, modelMode, setModelMode, toggleTool } = useConfig(); const { threads, setThreads, @@ -132,11 +132,6 @@ function App() { setTimeout(() => textareaRef.current?.focus(), 50); }), []); - // Close config panel when clicking outside or pressing Escape - useEffect(() => { - if (!configOpen) return; - return setupConfigPanelEscapeClose(configPanelRef, { onClose: () => setConfigOpen(false) }); - }, [configOpen]); // Global keyboard shortcuts useEffect(() => setupGlobalKeyboardShortcuts({ @@ -411,10 +406,8 @@ function App() { resetLoading={resetLoading} /> - {/* Config summary bar */} + {/* Config panel */}