fix(production-readiness): 3-batch production readiness cleanup — 12 tasks
Some checks failed
CI / Lint & TypeCheck (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Build Frontend (push) Has been cancelled
CI / Rust Check (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
Some checks failed
CI / Lint & TypeCheck (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Build Frontend (push) Has been cancelled
CI / Rust Check (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
Batch 1 — User-facing fixes: - B1-1: Pipeline verified end-to-end (14 Rust commands, 8 frontend invoke, fully connected) - B1-2: MessageSearch restored to ChatArea with search button in DeerFlow header - B1-3: Viking cleanup — removed 5 orphan invokes (no Rust impl), added addWithMetadata + storeWithSummaries methods + summary generation UI - B1-4: api-fallbacks transparency — added _isFallback markers + console.warn to all 6 fallback functions Batch 2 — System health: - B2-1: Document drift calibration — TRUTH.md/README.md numbers verified and updated - B2-2: @reserved annotations on 15 SaaS handler functions with no frontend callers - B2-3: Scheduled Task Admin V2 — new service + page + route + sidebar navigation - B2-4: TRUTH.md Pipeline/Viking/ScheduledTask records corrected Batch 3 — Long-term quality: - B3-1: hand_run_status/hand_run_list verified as fully implemented (not stubs) - B3-2: Identity snapshot rollback UI added to RightPanel - B3-3: P2 code quality — 4 fixes (TODO comments, fire-and-forget notes, design notes, table name validation), 2 verified N/A, 1 upstream - B3-4: Config PATCH→PUT alignment (admin-v2 config.ts matched to SaaS backend)
This commit is contained in:
@@ -9,7 +9,7 @@ import { useAgentStore } from '../store/agentStore';
|
||||
import { useConfigStore } from '../store/configStore';
|
||||
import { type UnlistenFn } from '@tauri-apps/api/event';
|
||||
import { safeListenEvent } from '../lib/safe-tauri';
|
||||
import { Paperclip, SquarePen, ArrowUp, MessageSquare, Download, X, FileText, Image as ImageIcon } from 'lucide-react';
|
||||
import { Paperclip, SquarePen, ArrowUp, MessageSquare, Download, X, FileText, Image as ImageIcon, Search } from 'lucide-react';
|
||||
import { Button, EmptyState, MessageListSkeleton, LoadingDots } from './ui';
|
||||
import { ResizableChatLayout } from './ai/ResizableChatLayout';
|
||||
import { ArtifactPanel } from './ai/ArtifactPanel';
|
||||
@@ -18,7 +18,7 @@ import { listItemVariants, defaultTransition, fadeInVariants } from '../lib/anim
|
||||
import { FirstConversationPrompt } from './FirstConversationPrompt';
|
||||
import { ClassroomPlayer } from './classroom_player';
|
||||
import { useClassroomStore } from '../store/classroomStore';
|
||||
// MessageSearch temporarily removed during DeerFlow redesign
|
||||
import { MessageSearch } from './MessageSearch';
|
||||
import { OfflineIndicator } from './OfflineIndicator';
|
||||
import {
|
||||
useVirtualizedMessages,
|
||||
@@ -67,6 +67,7 @@ export function ChatArea() {
|
||||
|
||||
const [input, setInput] = useState('');
|
||||
const [pendingFiles, setPendingFiles] = useState<File[]>([]);
|
||||
const [searchOpen, setSearchOpen] = useState(false); const [searchOpen, setSearchOpen] = useState(false);
|
||||
const scrollRef = useRef<HTMLDivElement>(null);
|
||||
const textareaRef = useRef<HTMLTextAreaElement>(null);
|
||||
const messageRefs = useRef<Map<string, HTMLDivElement>>(new Map());
|
||||
@@ -325,6 +326,17 @@ export function ChatArea() {
|
||||
);
|
||||
})()}
|
||||
<OfflineIndicator compact />
|
||||
{messages.length > 0 && (
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
onClick={() => setSearchOpen((prev) => !prev)}
|
||||
className={`flex items-center gap-1 rounded-lg transition-colors ${searchOpen ? 'text-orange-600 dark:text-orange-400 bg-orange-50 dark:bg-orange-900/20' : 'text-gray-600 dark:text-gray-400 hover:bg-gray-50 dark:hover:bg-gray-800'}`}
|
||||
title="搜索消息"
|
||||
>
|
||||
<Search className="w-3.5 h-3.5" />
|
||||
</Button>
|
||||
)}
|
||||
{messages.length > 0 && (
|
||||
<Button
|
||||
variant="ghost"
|
||||
@@ -352,6 +364,27 @@ export function ChatArea() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* MessageSearch panel */}
|
||||
<AnimatePresence>
|
||||
{searchOpen && messages.length > 0 && (
|
||||
<motion.div
|
||||
key="message-search"
|
||||
initial={{ opacity: 0, height: 0 }}
|
||||
animate={{ opacity: 1, height: 'auto' }}
|
||||
exit={{ opacity: 0, height: 0 }}
|
||||
transition={{ duration: 0.2 }}
|
||||
className="border-b border-gray-100 dark:border-gray-800 bg-gray-50 dark:bg-gray-800/50 overflow-hidden"
|
||||
>
|
||||
<div className="px-6 py-3 max-w-4xl mx-auto">
|
||||
<MessageSearch onNavigateToMessage={(id) => {
|
||||
const el = messageRefs.current.get(id);
|
||||
if (el) el.scrollIntoView({ behavior: 'smooth', block: 'center' });
|
||||
}} />
|
||||
</div>
|
||||
</motion.div>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
|
||||
{/* Messages */}
|
||||
<Conversation className="flex-1 bg-white dark:bg-gray-900">
|
||||
<AnimatePresence mode="popLayout">
|
||||
|
||||
Reference in New Issue
Block a user