import { AlertCircle, CheckCircle2, Clock, FileVideo, ListTodo, Loader2, StopCircle, XCircle } from "lucide-react" import React from "react" import { useTranslation } from "react-i18next" import { Badge } from "@/components/ui/badge" import { Button } from "@/components/ui/button" import { DropdownMenu, DropdownMenuContent, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu" import { Progress } from "@/components/ui/progress" import { ScrollArea } from "@/components/ui/scroll-area" import { cn } from "@/lib/utils" import { formatJobDuration, getJobStatusColor, useRenderJobs } from "../hooks/use-render-jobs" import { RenderStatus } from "../types/render" export function RenderJobsDropdown() { const { t } = useTranslation() const { jobs, isLoading, error, cancelJob } = useRenderJobs() // Количество активных задач const activeJobsCount = jobs.filter( (job) => job.status === RenderStatus.Pending || job.status === RenderStatus.Processing, ).length // Иконка для статуса задачи const getStatusIcon = (status: RenderStatus) => { switch (status) { case RenderStatus.Pending: return case RenderStatus.Processing: return case RenderStatus.Completed: return case RenderStatus.Failed: return case RenderStatus.Cancelled: return default: return } } // Функция для получения локализованного статуса const getLocalizedStatus = (status: RenderStatus) => { switch (status) { case RenderStatus.Pending: return t("videoCompiler.status.pending") case RenderStatus.Processing: return t("videoCompiler.status.processing") case RenderStatus.Completed: return t("videoCompiler.status.completed") case RenderStatus.Failed: return t("videoCompiler.status.failed") case RenderStatus.Cancelled: return t("videoCompiler.status.cancelled") default: return status } } // Обработчик отмены задачи const handleCancelJob = async (jobId: string, e: React.MouseEvent) => { e.stopPropagation() const confirmed = window.confirm(t("videoCompiler.cancelTask")) if (confirmed) { await cancelJob(jobId) } } return ( {t("videoCompiler.tasks")} {activeJobsCount > 0 && ( {activeJobsCount} )} {jobs.some((job) => job.status === RenderStatus.Processing) && ( )} {t("videoCompiler.renderTasks")} {isLoading && } {error ? ( {t("videoCompiler.errorLoadingTasks")} {error} ) : jobs.length === 0 ? ( {t("videoCompiler.noActiveTasks")} ) : ( {jobs.map((job) => ( {getStatusIcon(job.status)} {getLocalizedStatus(job.status)} {formatJobDuration(job.created_at)} {job.project_name} {job.output_path} {(job.status === RenderStatus.Pending || job.status === RenderStatus.Processing) && ( handleCancelJob(job.id, e)} className="h-7 px-2" > )} {job.status === RenderStatus.Processing && job.progress && ( {job.progress.stage} {job.progress.current_frame}/{job.progress.total_frames} {t("videoCompiler.frames")} {job.progress.message && ( {job.progress.message} )} )} {job.status === RenderStatus.Failed && job.error_message && ( {job.error_message} )} ))} )} {jobs.length > 0 && ( <> {t("videoCompiler.totalTasks")}: {jobs.length} {t("videoCompiler.activeTasks")}: {activeJobsCount} {t("videoCompiler.completedTasks")}: {jobs.filter((j) => j.status === RenderStatus.Completed).length} > )} ) }
{t("videoCompiler.errorLoadingTasks")}
{error}
{t("videoCompiler.noActiveTasks")}
{job.project_name}
{job.output_path}
{job.progress.message}
{job.error_message}