Initial commit: Memind H5 portal with MindSpace, Plaza, and agent jobs.
Track application source and tests; exclude local env, user workspaces, and runtime data via .gitignore. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,97 @@
|
||||
import { useEffect } from 'react';
|
||||
import { useChat } from '../context/ChatProvider';
|
||||
import type { MindSpaceChatContext, MindSpaceSaveCategory, PortalUser } from '../types';
|
||||
import { formatContextChip } from '../utils/mindspaceChatContext';
|
||||
import { ChatPanel } from './ChatPanel';
|
||||
import { TKMindAvatar } from './TKMindAvatar';
|
||||
|
||||
export function SpaceChatPanel({
|
||||
open,
|
||||
context,
|
||||
user,
|
||||
onClose,
|
||||
onOpenFullChat,
|
||||
onPageSaved,
|
||||
}: {
|
||||
open: boolean;
|
||||
context: MindSpaceChatContext;
|
||||
user: PortalUser;
|
||||
onClose: () => void;
|
||||
onOpenFullChat: () => void;
|
||||
onPageSaved?: (result: {
|
||||
kind: 'page' | 'category';
|
||||
pageId?: string;
|
||||
categoryCode?: MindSpaceSaveCategory;
|
||||
}) => void;
|
||||
}) {
|
||||
const {
|
||||
session,
|
||||
messages,
|
||||
chatState,
|
||||
pendingTool,
|
||||
submit,
|
||||
stop,
|
||||
approveTool,
|
||||
error,
|
||||
retryConnect,
|
||||
} = useChat();
|
||||
|
||||
useEffect(() => {
|
||||
if (!open) return;
|
||||
const handleKeyDown = (event: KeyboardEvent) => {
|
||||
if (event.key === 'Escape') onClose();
|
||||
};
|
||||
window.addEventListener('keydown', handleKeyDown);
|
||||
return () => window.removeEventListener('keydown', handleKeyDown);
|
||||
}, [open, onClose]);
|
||||
|
||||
if (!open) return null;
|
||||
|
||||
const contextLabel = formatContextChip(context);
|
||||
|
||||
return (
|
||||
<div className="space-chat-panel" role="dialog" aria-modal="false" aria-label="Agent 对话">
|
||||
<header className="space-chat-panel-header">
|
||||
<div className="space-chat-panel-brand">
|
||||
<TKMindAvatar size="sm" />
|
||||
<div>
|
||||
<strong>TKMind</strong>
|
||||
<span className="space-chat-context-chip" title={context.route}>
|
||||
{contextLabel}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="space-chat-panel-actions">
|
||||
<button type="button" className="ghost-btn" onClick={onOpenFullChat}>
|
||||
打开完整聊天
|
||||
</button>
|
||||
<button type="button" className="space-chat-panel-close" onClick={onClose} aria-label="关闭">
|
||||
×
|
||||
</button>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
{error && (
|
||||
<div className="space-chat-panel-error">
|
||||
<span>{error}</span>
|
||||
<button type="button" onClick={() => void retryConnect()}>
|
||||
重试
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<ChatPanel
|
||||
variant="compact"
|
||||
user={user}
|
||||
messages={messages}
|
||||
chatState={chatState}
|
||||
pendingTool={pendingTool}
|
||||
session={session}
|
||||
onSubmit={(text) => submit(text, { mindspaceContext: context })}
|
||||
onStop={stop}
|
||||
onApproveTool={approveTool}
|
||||
onPageSaved={onPageSaved}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user