feat: organize project conversations and add coding teacher side chat
This commit is contained in:
1 parent
2f82b9f79c
commit
9242a40d87
45 files changed
+2987
-1137
No files matched your search
@@ -1,3 +1,4 @@
|
||||
import { CodingProjectConversations } from '@/pages/Chat/CodingProjectConversations';
|
||||
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||
import { createPortal } from 'react-dom';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
@@ -21,7 +22,6 @@ import { Button } from '@/components/ui/button';
|
||||
import { ConfirmDialog } from '@/components/ui/confirm-dialog';
|
||||
import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from '@/components/ui/dialog';
|
||||
import { DisclosureContent } from '@/components/ui/disclosure';
|
||||
import { getAgentAvatarSrc } from '@/lib/agent-avatars';
|
||||
import { getAiHardwareOverview, type AiHardwareOverview } from '@/lib/ai-hardware';
|
||||
import {
|
||||
AI_HARDWARE_NAVIGATION_EVENT,
|
||||
@@ -216,7 +216,6 @@ export function Sidebar({
|
||||
const setActiveProject = useCodingWorkspaceStore((state) => state.setActiveProject);
|
||||
const removeProject = useCodingWorkspaceStore((state) => state.removeProject);
|
||||
const createProject = useCodingWorkspaceStore((state) => state.createProject);
|
||||
const projectConfigs = useProjectConfigStore((state) => state.configsByProjectId);
|
||||
const loadProjectConfig = useProjectConfigStore((state) => state.load);
|
||||
const removeProjectConfig = useProjectConfigStore((state) => state.remove);
|
||||
const authUser = useAuthStore((state) => state.user);
|
||||
@@ -251,6 +250,7 @@ export function Sidebar({
|
||||
const accountButtonRef = useRef<HTMLButtonElement | null>(null);
|
||||
const accountMenuRef = useRef<HTMLDivElement | null>(null);
|
||||
const tokenPointRequestIdRef = useRef(0);
|
||||
const projectEntryIntentRef = useRef(0);
|
||||
const resetCardRequestIdRef = useRef(0);
|
||||
const navigate = useNavigate();
|
||||
const location = useLocation();
|
||||
@@ -523,13 +523,15 @@ export function Sidebar({
|
||||
}, []);
|
||||
|
||||
const enterProject = useCallback(async (project: CodingProjectSummary) => {
|
||||
const intent = ++projectEntryIntentRef.current;
|
||||
const result = await loadProjectConfig(project.id);
|
||||
if (intent !== projectEntryIntentRef.current) return;
|
||||
if (result.status !== 'valid' || !result.config) {
|
||||
showProjectEntryError(project, result.status === 'missing' ? '项目缺少必要的配置文件' : result.error ?? '项目配置无效');
|
||||
return;
|
||||
}
|
||||
await setActiveProject(project.id);
|
||||
navigate('/chat');
|
||||
if (intent === projectEntryIntentRef.current) navigate('/chat');
|
||||
}, [loadProjectConfig, navigate, setActiveProject, showProjectEntryError]);
|
||||
|
||||
const readAndEnterProject = useCallback(async (project: CodingProjectSummary) => {
|
||||
@@ -740,12 +742,10 @@ export function Sidebar({
|
||||
) : null}
|
||||
|
||||
{visibleProjects.map((project) => {
|
||||
const projectConfig = projectConfigs[project.id];
|
||||
const active = activeProject?.id === project.id;
|
||||
return (
|
||||
<button
|
||||
<div key={project.id}><button
|
||||
type="button"
|
||||
key={project.id}
|
||||
data-testid={`sidebar-course-project-${project.id}`}
|
||||
aria-label={`进入项目 ${project.name}`}
|
||||
aria-current={active ? 'page' : undefined}
|
||||
@@ -758,23 +758,10 @@ export function Sidebar({
|
||||
)}
|
||||
>
|
||||
<span className="min-w-0 flex-1 truncate text-sm font-semibold">{project.name}</span>
|
||||
<div className="flex shrink-0 -space-x-1.5" aria-label="项目智能体">
|
||||
{projectConfig?.agents.map((agent) => (
|
||||
<span
|
||||
key={agent.id}
|
||||
title={agent.name.trim() || agent.roleName}
|
||||
className="h-5 w-5 overflow-hidden rounded-full border border-background bg-white"
|
||||
>
|
||||
<img
|
||||
src={getAgentAvatarSrc(agent.avatarId, agent.avatarDataUrl)}
|
||||
alt=""
|
||||
className="h-full w-full object-cover [image-rendering:pixelated]"
|
||||
/>
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
<ChevronRight aria-hidden="true" className="h-3.5 w-3.5 shrink-0 -translate-x-0.5 text-muted-foreground opacity-50 transition-[opacity,transform,color] duration-200 ease-out group-hover/project:translate-x-0 group-hover/project:text-foreground group-hover/project:opacity-100 group-focus-visible/project:translate-x-0 group-focus-visible/project:text-foreground group-focus-visible/project:opacity-100" />
|
||||
</button>
|
||||
{active && <CodingProjectConversations key={project.id} projectId={project.id} />}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
|
||||
|
||||
Reference in new issue
Block a user