merge: integrate coding default page
# Conflicts: # src/components/layout/Sidebar.tsx # tests/unit/coding-chat-panel.test.tsx
This commit is contained in:
@@ -31,6 +31,10 @@ import {
|
||||
import { getAiModuleForPath } from '@/lib/ai-modules';
|
||||
import { invokeIpc } from '@/lib/api-client';
|
||||
import { getAuthUserDisplayName } from '@/lib/auth-user-display';
|
||||
import {
|
||||
subscribeCodingProjectCreationRequest,
|
||||
subscribeCodingProjectOpenRequest,
|
||||
} from '@/lib/coding-project-entry';
|
||||
import { WORKS_SQUARE_TOKEN_USAGE_STALE_EVENT } from '@/lib/works-square-usage-events';
|
||||
import { fetchWorksTokenUsage, type WorksTokenUsage } from '@/lib/works-square';
|
||||
import { isWorksTokenUsageExhausted } from '@/lib/works-square-token-usage';
|
||||
@@ -385,13 +389,18 @@ export function Sidebar({ workspaceLayout = false, sidebarPeekOpen = false, onSi
|
||||
}, [authUser, refreshTokenUsage]);
|
||||
|
||||
|
||||
const openCreateProject = () => {
|
||||
const openCreateProject = useCallback(() => {
|
||||
setNewProjectName('');
|
||||
setNewProjectSelectedPath('');
|
||||
setNewProjectDirectoryMode('use-selected-directory');
|
||||
setCreateProjectError(null);
|
||||
setCreateDialogOpen(true);
|
||||
};
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (!isProgrammingModule) return undefined;
|
||||
return subscribeCodingProjectCreationRequest(openCreateProject);
|
||||
}, [isProgrammingModule, openCreateProject]);
|
||||
|
||||
const closeCreateProject = () => {
|
||||
if (creatingProject) return;
|
||||
@@ -411,11 +420,11 @@ export function Sidebar({ workspaceLayout = false, sidebarPeekOpen = false, onSi
|
||||
setCreateProjectError(null);
|
||||
};
|
||||
|
||||
const showProjectEntryError = (project: CodingProjectSummary, message: string) => {
|
||||
const showProjectEntryError = useCallback((project: CodingProjectSummary, message: string) => {
|
||||
setProjectEntryError({ project, message });
|
||||
};
|
||||
}, []);
|
||||
|
||||
const enterProject = async (project: CodingProjectSummary) => {
|
||||
const enterProject = useCallback(async (project: CodingProjectSummary) => {
|
||||
const result = await loadProjectConfig(project.id);
|
||||
if (result.status !== 'valid' || !result.config) {
|
||||
showProjectEntryError(project, result.status === 'missing' ? '项目缺少必要的配置文件' : result.error ?? '项目配置无效');
|
||||
@@ -423,16 +432,16 @@ export function Sidebar({ workspaceLayout = false, sidebarPeekOpen = false, onSi
|
||||
}
|
||||
await setActiveProject(project.id);
|
||||
navigate('/chat');
|
||||
};
|
||||
}, [loadProjectConfig, navigate, setActiveProject, showProjectEntryError]);
|
||||
|
||||
const readAndEnterProject = async (project: CodingProjectSummary) => {
|
||||
const readAndEnterProject = useCallback(async (project: CodingProjectSummary) => {
|
||||
setProjectEntryError(null);
|
||||
try {
|
||||
await enterProject(project);
|
||||
} catch (error) {
|
||||
showProjectEntryError(project, error instanceof Error ? error.message : String(error));
|
||||
}
|
||||
};
|
||||
}, [enterProject, showProjectEntryError]);
|
||||
|
||||
|
||||
const confirmCreateProject = async () => {
|
||||
@@ -465,9 +474,17 @@ export function Sidebar({ workspaceLayout = false, sidebarPeekOpen = false, onSi
|
||||
}
|
||||
};
|
||||
|
||||
const openProject = async (project: CodingProjectSummary) => {
|
||||
const openProject = useCallback(async (project: CodingProjectSummary) => {
|
||||
await readAndEnterProject(project);
|
||||
};
|
||||
}, [readAndEnterProject]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!isProgrammingModule) return undefined;
|
||||
return subscribeCodingProjectOpenRequest((projectId) => {
|
||||
const project = visibleProjects.find((candidate) => candidate.id === projectId);
|
||||
if (project) void openProject(project);
|
||||
});
|
||||
}, [isProgrammingModule, openProject, visibleProjects]);
|
||||
|
||||
const requestRemoveUnavailableProject = () => {
|
||||
if (!projectEntryError) return;
|
||||
|
||||
Reference in New Issue
Block a user