From 29301c3a4caaf0650cd05d0eb52a6888006ea016 Mon Sep 17 00:00:00 2001 From: jze9 Date: Tue, 25 Aug 2026 15:24:46 +0500 Subject: [PATCH] =?UTF-8?q?feat(cabinet):=20=D0=B4=D0=B0=D1=82=D1=8C=20?= =?UTF-8?q?=D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2=D0=B0=D1=82=D0=B5?= =?UTF-8?q?=D0=BB=D1=8E=20=D1=81=D0=B0=D0=BC=D0=BE=D0=BC=D1=83=20=D1=83?= =?UTF-8?q?=D0=B4=D0=B0=D0=BB=D1=8F=D1=82=D1=8C=20=D0=B7=D0=B0=D0=B4=D0=B0?= =?UTF-8?q?=D1=87=D0=B8=20=D0=B8=D0=B7=20=D0=BA=D0=B0=D0=B1=D0=B8=D0=BD?= =?UTF-8?q?=D0=B5=D1=82=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Раньше удалить задачу мог только админ через свою панель — обычный пользователь с зависшей (например, навечно застрявшей в processing) задачей не мог убрать её из кабинета вообще. Кнопка удаления на карточке + снято искусственное ограничение "нельзя удалить, пока processing" (все воркеры уже корректно проверяют task is None перед записью, удаление во время реальной обработки безопасно). --- services/api/app/api/tasks.py | 6 ------ services/frontend/src/components/TaskCard.tsx | 20 +++++++++++++++++-- services/frontend/src/pages/Cabinet.tsx | 14 +++++++++++-- 3 files changed, 30 insertions(+), 10 deletions(-) diff --git a/services/api/app/api/tasks.py b/services/api/app/api/tasks.py index 79e8888..684f614 100644 --- a/services/api/app/api/tasks.py +++ b/services/api/app/api/tasks.py @@ -119,11 +119,5 @@ async def delete_task( if task is None: raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Задача не найдена") - if task.status == "processing": - raise HTTPException( - status_code=status.HTTP_409_CONFLICT, - detail="Нельзя удалить задачу в процессе выполнения", - ) - await db.delete(task) await db.commit() diff --git a/services/frontend/src/components/TaskCard.tsx b/services/frontend/src/components/TaskCard.tsx index d28ff69..4d4eb97 100644 --- a/services/frontend/src/components/TaskCard.tsx +++ b/services/frontend/src/components/TaskCard.tsx @@ -1,13 +1,14 @@ import { Link } from 'react-router-dom'; import { formatDistanceToNow } from 'date-fns'; import { ru } from 'date-fns/locale'; -import { Search, FileText, BookOpen, AlignLeft, ChevronRight } from 'lucide-react'; +import { Search, FileText, BookOpen, AlignLeft, ChevronRight, Trash2 } from 'lucide-react'; import { clsx } from 'clsx'; import { StatusBadge } from './StatusBadge'; import type { Task } from '../types'; interface TaskCardProps { task: Task; + onDelete?: (publicId: string) => void; } const TYPE_CONFIG = { @@ -63,7 +64,7 @@ function getTaskSummary(task: Task): string { return 'Результат готов'; } -export function TaskCard({ task }: TaskCardProps) { +export function TaskCard({ task, onDelete }: TaskCardProps) { const config = TYPE_CONFIG[task.type] || TYPE_CONFIG.search; const Icon = config.icon; const summary = getTaskSummary(task); @@ -94,6 +95,21 @@ export function TaskCard({ task }: TaskCardProps) {

+ {/* Удалить */} + {onDelete && ( + + )} + {/* Стрелка */} diff --git a/services/frontend/src/pages/Cabinet.tsx b/services/frontend/src/pages/Cabinet.tsx index 2eb5d6a..560ec6e 100644 --- a/services/frontend/src/pages/Cabinet.tsx +++ b/services/frontend/src/pages/Cabinet.tsx @@ -1,5 +1,5 @@ import { Navigate, useNavigate, Link } from 'react-router-dom'; -import { useQuery } from '@tanstack/react-query'; +import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'; import { Crown, Search, Shield, BookOpen, ShieldAlert, Settings as SettingsIcon } from 'lucide-react'; import toast from 'react-hot-toast'; import { TaskCard } from '../components/TaskCard'; @@ -17,6 +17,16 @@ const PLAN_BADGE_STYLES = { export function Cabinet() { const { isAuthenticated, user } = useAuthStore(); const navigate = useNavigate(); + const qc = useQueryClient(); + + const deleteTask = useMutation({ + mutationFn: (publicId: string) => tasksApi.delete(publicId), + onSuccess: () => { + qc.invalidateQueries({ queryKey: ['tasks'] }); + toast.success('Задача удалена'); + }, + onError: () => toast.error('Не удалось удалить задачу'), + }); const openAdmin = async () => { try { @@ -144,7 +154,7 @@ export function Cabinet() { {tasks && tasks.length > 0 && (
{tasks.map((task) => ( - + deleteTask.mutate(id)} /> ))}
)}