diff options
| author | blackhao <13851610112@163.com> | 2025-12-10 20:12:21 -0600 |
|---|---|---|
| committer | blackhao <13851610112@163.com> | 2025-12-10 20:12:21 -0600 |
| commit | 9646da833bc3d94564c10649b62a378d0190471e (patch) | |
| tree | d0c9c0584b8c4f167c281f5970f713b239a1d7c5 /frontend/src/components | |
| parent | 9ba956c7aa601f0e6cd0fe2ede907cbc558fa1b8 (diff) | |
user data
Diffstat (limited to 'frontend/src/components')
| -rw-r--r-- | frontend/src/components/LeftSidebar.tsx | 43 | ||||
| -rw-r--r-- | frontend/src/components/Sidebar.tsx | 45 |
2 files changed, 69 insertions, 19 deletions
diff --git a/frontend/src/components/LeftSidebar.tsx b/frontend/src/components/LeftSidebar.tsx index aff2df8..1df63fe 100644 --- a/frontend/src/components/LeftSidebar.tsx +++ b/frontend/src/components/LeftSidebar.tsx @@ -2,9 +2,10 @@ import React, { useEffect, useMemo, useRef, useState, useCallback } from 'react' import { useReactFlow } from 'reactflow'; import { Folder, FileText, Archive, ChevronLeft, ChevronRight, Trash2, MessageSquare, - MoreVertical, Download, Upload, Plus, RefreshCw, Edit3, Loader2 + MoreVertical, Download, Upload, Plus, RefreshCw, Edit3, Loader2, LogOut, User } from 'lucide-react'; import useFlowStore, { type FSItem, type BlueprintDocument, type FileMeta } from '../store/flowStore'; +import { useAuthStore } from '../store/authStore'; interface LeftSidebarProps { isOpen: boolean; @@ -39,6 +40,7 @@ const LeftSidebar: React.FC<LeftSidebarProps> = ({ isOpen, onToggle }) => { serializeBlueprint, clearBlueprint } = useFlowStore(); + const { user, logout } = useAuthStore(); const { setViewport, getViewport } = useReactFlow(); const isDark = theme === 'dark'; const fileInputRef = useRef<HTMLInputElement | null>(null); @@ -443,13 +445,38 @@ const LeftSidebar: React.FC<LeftSidebarProps> = ({ isOpen, onToggle }) => { <div className={`p-3 border-b flex justify-between items-center ${ isDark ? 'border-gray-700 bg-gray-900' : 'border-gray-200 bg-gray-50' }`}> - <h2 className={`font-bold text-sm uppercase ${isDark ? 'text-gray-300' : 'text-gray-700'}`}>Workspace</h2> - <button - onClick={onToggle} - className={`p-1 rounded ${isDark ? 'hover:bg-gray-700' : 'hover:bg-gray-200'}`} - > - <ChevronLeft size={16} className={isDark ? 'text-gray-400' : 'text-gray-500'} /> - </button> + <div className="flex items-center gap-2"> + <h2 className={`font-bold text-sm uppercase ${isDark ? 'text-gray-300' : 'text-gray-700'}`}>Workspace</h2> + {user && ( + <span className={`text-xs px-2 py-0.5 rounded-full ${ + isDark ? 'bg-gray-700 text-gray-400' : 'bg-gray-200 text-gray-600' + }`}> + <User size={10} className="inline mr-1" /> + {user.username} + </span> + )} + </div> + <div className="flex items-center gap-1"> + {user && ( + <button + onClick={logout} + className={`p-1 rounded transition-colors ${ + isDark + ? 'hover:bg-red-900/50 text-gray-400 hover:text-red-400' + : 'hover:bg-red-50 text-gray-500 hover:text-red-500' + }`} + title="Logout" + > + <LogOut size={16} /> + </button> + )} + <button + onClick={onToggle} + className={`p-1 rounded ${isDark ? 'hover:bg-gray-700' : 'hover:bg-gray-200'}`} + > + <ChevronLeft size={16} className={isDark ? 'text-gray-400' : 'text-gray-500'} /> + </button> + </div> </div> {/* Tabs */} diff --git a/frontend/src/components/Sidebar.tsx b/frontend/src/components/Sidebar.tsx index a8dd82e..17050aa 100644 --- a/frontend/src/components/Sidebar.tsx +++ b/frontend/src/components/Sidebar.tsx @@ -1,9 +1,10 @@ import React, { useState, useEffect, useRef, useMemo } from 'react'; import { useReactFlow } from 'reactflow'; import useFlowStore from '../store/flowStore'; +import { useAuthStore } from '../store/authStore'; import type { NodeData, Trace, Message, MergedTrace, MergeStrategy, FileMeta } from '../store/flowStore'; import ReactMarkdown from 'react-markdown'; -import { Play, Settings, Info, Save, ChevronLeft, ChevronRight, Maximize2, Edit3, X, Check, FileText, MessageCircle, Send, GripVertical, GitMerge, Trash2, AlertCircle, Loader2, Navigation, Upload, Search, Link } from 'lucide-react'; +import { Play, Settings, Info, Save, ChevronLeft, ChevronRight, Maximize2, Edit3, X, Check, FileText, MessageCircle, Send, GripVertical, GitMerge, Trash2, AlertCircle, Loader2, Navigation, Upload, Search, Link, LogOut } from 'lucide-react'; interface SidebarProps { isOpen: boolean; @@ -19,6 +20,7 @@ const Sidebar: React.FC<SidebarProps> = ({ isOpen, onToggle, onInteract }) => { files, uploadFile, refreshFiles, addFileScope, removeFileScope, currentBlueprintPath, saveCurrentBlueprint } = useFlowStore(); + const { getAuthHeader, user, logout } = useAuthStore(); const { setCenter, getViewport } = useReactFlow(); const isDark = theme === 'dark'; const [activeTab, setActiveTab] = useState<'interact' | 'settings' | 'debug'>('interact'); @@ -295,7 +297,7 @@ const Sidebar: React.FC<SidebarProps> = ({ isOpen, onToggle, onInteract }) => { try { const response = await fetch('http://localhost:8000/api/run_node_stream', { method: 'POST', - headers: { 'Content-Type': 'application/json' }, + headers: { 'Content-Type': 'application/json', ...getAuthHeader() }, body: JSON.stringify({ node_id: runningNodeId, incoming_contexts: [{ messages: context }], @@ -386,7 +388,7 @@ const Sidebar: React.FC<SidebarProps> = ({ isOpen, onToggle, onInteract }) => { try { const res = await fetch('http://localhost:8000/api/summarize', { method: 'POST', - headers: { 'Content-Type': 'application/json' }, + headers: { 'Content-Type': 'application/json', ...getAuthHeader() }, body: JSON.stringify({ content: selectedNode.data.response, model: summaryModel @@ -412,7 +414,7 @@ const Sidebar: React.FC<SidebarProps> = ({ isOpen, onToggle, onInteract }) => { try { const res = await fetch('http://localhost:8000/api/generate_title', { method: 'POST', - headers: { 'Content-Type': 'application/json' }, + headers: { 'Content-Type': 'application/json', ...getAuthHeader() }, body: JSON.stringify({ user_prompt: userPrompt, response }) }); @@ -489,7 +491,7 @@ const Sidebar: React.FC<SidebarProps> = ({ isOpen, onToggle, onInteract }) => { const res = await fetch('http://localhost:8000/api/summarize', { method: 'POST', - headers: { 'Content-Type': 'application/json' }, + headers: { 'Content-Type': 'application/json', ...getAuthHeader() }, body: JSON.stringify({ content, model_name: 'gpt-5-nano', @@ -1003,7 +1005,7 @@ const Sidebar: React.FC<SidebarProps> = ({ isOpen, onToggle, onInteract }) => { // Call LLM API with current messages as context const response = await fetch('http://localhost:8000/api/run_node_stream', { method: 'POST', - headers: { 'Content-Type': 'application/json' }, + headers: { 'Content-Type': 'application/json', ...getAuthHeader() }, body: JSON.stringify({ node_id: 'quick_chat_temp', incoming_contexts: [{ messages: messagesBeforeSend }], @@ -1835,17 +1837,30 @@ const Sidebar: React.FC<SidebarProps> = ({ isOpen, onToggle, onInteract }) => { {activeTab === 'settings' && ( <div className="space-y-4"> {/* Attachments Section */} + {(() => { + const isGemini = selectedNode.data.model.startsWith('gemini'); + return ( <div className={`p-3 rounded border ${isDark ? 'bg-gray-800 border-gray-700' : 'bg-gray-50 border-gray-200'}`}> <label className={`block text-xs font-bold uppercase tracking-wider mb-2 ${isDark ? 'text-gray-400' : 'text-gray-500'}`}> Attached Files </label> + {isGemini && ( + <p className={`text-xs mb-2 ${isDark ? 'text-yellow-400' : 'text-yellow-600'}`}> + File attachments are not supported for Gemini models. + </p> + )} + <div className="flex gap-2 mb-3"> <button onClick={() => settingsUploadRef.current?.click()} + disabled={isGemini} className={`flex-1 flex items-center justify-center gap-1.5 py-1.5 px-3 rounded text-xs font-medium transition-colors ${ - isDark ? 'bg-blue-600 hover:bg-blue-700 text-white' : 'bg-blue-600 hover:bg-blue-700 text-white' + isGemini + ? 'opacity-50 cursor-not-allowed bg-gray-400 text-gray-200' + : isDark ? 'bg-blue-600 hover:bg-blue-700 text-white' : 'bg-blue-600 hover:bg-blue-700 text-white' }`} + title={isGemini ? 'Not supported for Gemini models' : 'Upload & Attach'} > <Upload size={14} /> Upload & Attach @@ -1862,11 +1877,15 @@ const Sidebar: React.FC<SidebarProps> = ({ isOpen, onToggle, onInteract }) => { refreshFiles(); setShowAttachModal(true); }} + disabled={isGemini} className={`flex-1 flex items-center justify-center gap-1.5 py-1.5 px-3 rounded text-xs font-medium border transition-colors ${ - isDark - ? 'border-gray-600 hover:bg-gray-700 text-gray-200' - : 'border-gray-300 hover:bg-gray-100 text-gray-700' + isGemini + ? 'opacity-50 cursor-not-allowed border-gray-400 text-gray-400' + : isDark + ? 'border-gray-600 hover:bg-gray-700 text-gray-200' + : 'border-gray-300 hover:bg-gray-100 text-gray-700' }`} + title={isGemini ? 'Not supported for Gemini models' : 'Attach Existing File'} > <Link size={14} /> Attach Existing @@ -1908,6 +1927,8 @@ const Sidebar: React.FC<SidebarProps> = ({ isOpen, onToggle, onInteract }) => { </div> )} </div> + ); + })()} <div> <label className={`block text-sm font-medium mb-1 ${isDark ? 'text-gray-300' : 'text-gray-700'}`}>Merge Strategy</label> @@ -2562,7 +2583,8 @@ const Sidebar: React.FC<SidebarProps> = ({ isOpen, onToggle, onInteract }) => { </label> )} - {/* File Attachment Buttons */} + {/* File Attachment Buttons - Hidden for Gemini */} + {!quickChatModel.startsWith('gemini') && ( <div className="flex items-center gap-1 ml-auto"> <button onClick={() => quickChatUploadRef.current?.click()} @@ -2603,6 +2625,7 @@ const Sidebar: React.FC<SidebarProps> = ({ isOpen, onToggle, onInteract }) => { onChange={handleQuickChatUpload} /> </div> + )} </div> {/* Input Area */} |
