'use client' import React from 'react' import { trpc } from '@/lib/trpc' import { Button } from '@/components/ui/button' import { FileSearch } from 'lucide-react' import { toast } from 'sonner' import { TaskDialog, BaseTaskProgress } from '@/components/common/task-dialog' import type { AnalyzePackagesProgress } from '@/server/queues' /** * 扩展的分析进度类型 */ interface AnalyzeProgress extends BaseTaskProgress, AnalyzePackagesProgress {} interface PackageAnalyzeDialogProps { open: boolean onOpenChange: (open: boolean) => void jobId: string | null onAnalyzeCompleted: () => void } interface PackageAnalyzeTriggerProps { onStartAnalyze: () => void isStarting: boolean } /** * 依赖包分析触发器按钮 */ export function PackageAnalyzeTrigger({ onStartAnalyze, isStarting }: PackageAnalyzeTriggerProps) { return ( ) } /** * 依赖包分析进度对话框 */ export function PackageAnalyzeDialog({ open, onOpenChange, jobId, onAnalyzeCompleted }: PackageAnalyzeDialogProps) { // 停止分析任务 mutation const cancelMutation = trpc.devArch!.cancelAnalyzePackagesJob.useMutation({ onSuccess: () => { toast.success('已发送停止请求') }, onError: (error) => { toast.error(error.message || '停止任务失败') }, }) // 停止任务 const handleCancelTask = async (taskJobId: string) => { await cancelMutation.mutateAsync({ jobId: taskJobId }) } // 自定义状态消息渲染 const renderStatusMessage = (progress: AnalyzeProgress) => { if (progress.state === 'waiting') { return '任务等待中...' } else if (progress.state === 'active') { if (progress.currentPackage) { return `正在分析: ${progress.currentPackage}` } return '正在分析依赖包...' } else if (progress.state === 'completed') { const successCount = (progress.analyzedPackages || 0) - (progress.failedPackages || 0) const failedCount = progress.failedPackages || 0 const skippedCount = progress.skippedPackages || 0 const parts = [`成功 ${successCount} 个`] if (failedCount > 0) { parts.push(`失败 ${failedCount} 个`) } if (skippedCount > 0) { parts.push(`跳过 ${skippedCount} 个`) } parts.push(`共 ${progress.totalPackages || 0} 个依赖包`) return `分析完成!${parts.join(',')}` } else if (progress.state === 'failed') { return progress.error || '分析失败' } return '' } // 自定义详细信息渲染 const renderDetails = (progress: AnalyzeProgress) => { if (progress.totalPackages === undefined && progress.analyzedPackages === undefined) { return null } const successCount = (progress.analyzedPackages || 0) - (progress.failedPackages || 0) return (
{/* 进度统计 */}
{progress.totalPackages !== undefined && (
依赖包总数: {progress.totalPackages}
)} {progress.analyzedPackages !== undefined && (
已分析: {progress.analyzedPackages}
)} {successCount > 0 && (
成功: {successCount}
)} {progress.failedPackages !== undefined && progress.failedPackages > 0 && (
失败: {progress.failedPackages}
)} {progress.skippedPackages !== undefined && progress.skippedPackages > 0 && (
跳过: {progress.skippedPackages}
)}
{/* 当前处理的依赖包 */} {progress.currentPackage && progress.state === 'active' && (
当前依赖包:
{progress.currentPackage}
)} {/* 最近的错误信息 */} {progress.recentErrors && progress.recentErrors.length > 0 && (
最近的错误 (最多显示10条):
{progress.recentErrors.map((err, index) => (
{err.packageName}
{err.error}
{index < progress.recentErrors!.length - 1 && (
)}
))}
)}
) } return ( open={open} onOpenChange={onOpenChange} useSubscription={trpc.jobs.subscribeAnalyzePackagesProgress.useSubscription} jobId={jobId} title="依赖包分析进度" description="正在使用AI分析项目依赖包,请稍候..." onCancelTask={handleCancelTask} onTaskCompleted={onAnalyzeCompleted} isCancelling={cancelMutation.isPending} renderStatusMessage={renderStatusMessage} renderDetails={renderDetails} /> ) }