重构前端逻辑

This commit is contained in:
dengqichen 2025-11-07 13:15:14 +08:00
parent ee9c0124fd
commit 344ba25284
9 changed files with 296 additions and 492 deletions

View File

@ -7,16 +7,7 @@ import type { MenuProps } from 'antd';
import { logout } from '@/store/userSlice';
import type { RootState } from '@/store';
import { useToast } from '@/components/ui/use-toast';
import {
AlertDialog,
AlertDialogAction,
AlertDialogCancel,
AlertDialogContent,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogTitle,
} from '@/components/ui/alert-dialog';
import { ConfirmDialog } from '@/components/ui/confirm-dialog';
import { AlertCircle } from 'lucide-react';
import { shallowEqual } from 'react-redux';
@ -44,12 +35,8 @@ const UserPanel: React.FC = React.memo(() => {
setLogoutDialogOpen(true);
};
const confirmLogout = () => {
const confirmLogout = async () => {
dispatch(logout());
toast({
title: '退出成功',
description: '已成功退出系统',
});
navigate('/login', { replace: true });
};
@ -92,25 +79,25 @@ const UserPanel: React.FC = React.memo(() => {
</Dropdown>
{/* 退出登录确认对话框 */}
<AlertDialog open={logoutDialogOpen} onOpenChange={setLogoutDialogOpen}>
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle className="flex items-center gap-2">
<AlertCircle className="h-5 w-5 text-amber-500" />
退
</AlertDialogTitle>
<AlertDialogDescription>
退
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel onClick={() => setLogoutDialogOpen(false)}>
</AlertDialogCancel>
<AlertDialogAction onClick={confirmLogout}></AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
<ConfirmDialog
open={logoutDialogOpen}
onOpenChange={setLogoutDialogOpen}
title={
<div className="flex items-center gap-2">
<AlertCircle className="h-5 w-5 text-amber-500" />
退
</div>
}
description="确定要退出系统吗?"
onConfirm={confirmLogout}
onSuccess={() => {
toast({
title: '退出成功',
description: '已成功退出系统',
});
}}
confirmText="确定"
/>
</>
);
});

View File

@ -6,16 +6,7 @@ import {
DialogBody,
DialogTitle,
} from "@/components/ui/dialog";
import {
AlertDialog,
AlertDialogAction,
AlertDialogCancel,
AlertDialogContent,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogTitle,
} from "@/components/ui/alert-dialog";
import { ConfirmDialog } from '@/components/ui/confirm-dialog';
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import {
@ -175,25 +166,7 @@ const CategoryManageDialog: React.FC<CategoryManageDialogProps> = ({
// 确认删除
const confirmDelete = async () => {
if (!deleteRecord) return;
try {
await deleteCategory(deleteRecord.id);
toast({
title: "删除成功",
description: `分类 "${deleteRecord.name}" 已删除`,
});
loadCategories();
onSuccess?.();
setDeleteDialogOpen(false);
setDeleteRecord(null);
} catch (error) {
console.error('删除失败:', error);
toast({
variant: "destructive",
title: "删除失败",
description: error instanceof Error ? error.message : '未知错误',
});
}
await deleteCategory(deleteRecord.id);
};
// 保存
@ -516,53 +489,52 @@ const CategoryManageDialog: React.FC<CategoryManageDialogProps> = ({
</Dialog>
{/* 删除确认对话框 */}
<AlertDialog open={deleteDialogOpen} onOpenChange={setDeleteDialogOpen}>
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle></AlertDialogTitle>
<AlertDialogDescription asChild>
<div className="space-y-3">
<p></p>
{deleteRecord && (
<div className="rounded-md border p-3 space-y-2 bg-muted/50">
<div className="flex items-center gap-2">
<span className="text-sm font-medium text-muted-foreground">:</span>
<span className="font-medium">{deleteRecord.name}</span>
</div>
<div className="flex items-center gap-2">
<span className="text-sm font-medium text-muted-foreground">:</span>
<code className="text-xs bg-background px-2 py-1 rounded">
{deleteRecord.code}
</code>
</div>
{deleteRecord.icon && (
<div className="flex items-center gap-2">
<span className="text-sm font-medium text-muted-foreground">:</span>
<DynamicIcon name={deleteRecord.icon} className="h-4 w-4" />
</div>
)}
{deleteRecord.description && (
<div className="flex items-start gap-2">
<span className="text-sm font-medium text-muted-foreground">:</span>
<span className="text-sm">{deleteRecord.description}</span>
</div>
)}
</div>
)}
<ConfirmDialog
open={deleteDialogOpen}
onOpenChange={setDeleteDialogOpen}
title="确认删除分类"
description="您确定要删除以下分类吗?此操作无法撤销。"
item={deleteRecord}
onConfirm={confirmDelete}
onSuccess={() => {
toast({
title: "删除成功",
description: `分类 "${deleteRecord?.name}" 已删除`,
});
setDeleteRecord(null);
loadCategories();
onSuccess?.();
}}
variant="destructive"
confirmText="确认删除"
>
{deleteRecord && (
<div className="rounded-md border p-3 space-y-2 bg-muted/50">
<div className="flex items-center gap-2">
<span className="text-sm font-medium text-muted-foreground">:</span>
<span className="font-medium">{deleteRecord.name}</span>
</div>
<div className="flex items-center gap-2">
<span className="text-sm font-medium text-muted-foreground">:</span>
<code className="text-xs bg-background px-2 py-1 rounded">
{deleteRecord.code}
</code>
</div>
{deleteRecord.icon && (
<div className="flex items-center gap-2">
<span className="text-sm font-medium text-muted-foreground">:</span>
<DynamicIcon name={deleteRecord.icon} className="h-4 w-4" />
</div>
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel></AlertDialogCancel>
<AlertDialogAction
onClick={confirmDelete}
className="bg-destructive text-destructive-foreground hover:bg-destructive/90"
>
</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
)}
{deleteRecord.description && (
<div className="flex items-start gap-2">
<span className="text-sm font-medium text-muted-foreground">:</span>
<span className="text-sm">{deleteRecord.description}</span>
</div>
)}
</div>
)}
</ConfirmDialog>
</>
);
};

View File

@ -17,16 +17,7 @@ import {
TableRow,
} from '@/components/ui/table';
import { Badge } from '@/components/ui/badge';
import {
AlertDialog,
AlertDialogAction,
AlertDialogCancel,
AlertDialogContent,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogTitle,
} from '@/components/ui/alert-dialog';
import { ConfirmDialog } from '@/components/ui/confirm-dialog';
import { useToast } from '@/components/ui/use-toast';
import { DataTablePagination } from '@/components/ui/pagination';
import { DEFAULT_PAGE_SIZE, DEFAULT_CURRENT } from '@/utils/page';
@ -176,20 +167,7 @@ const NotificationChannelList: React.FC = () => {
// 删除
const handleDelete = async () => {
if (!deleteId) return;
try {
await deleteChannel(deleteId);
toast({ title: '删除成功' });
setDeleteDialogOpen(false);
setDeleteId(null);
loadData();
} catch (error: any) {
toast({
variant: 'destructive',
title: '删除失败',
description: error.response?.data?.message || error.message,
});
}
await deleteChannel(deleteId);
};
// 启用/禁用
@ -477,20 +455,22 @@ const NotificationChannelList: React.FC = () => {
/>
{/* 删除确认对话框 */}
<AlertDialog open={deleteDialogOpen} onOpenChange={setDeleteDialogOpen}>
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle></AlertDialogTitle>
<AlertDialogDescription>
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel onClick={() => setDeleteId(null)}></AlertDialogCancel>
<AlertDialogAction onClick={handleDelete}></AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
<ConfirmDialog
open={deleteDialogOpen}
onOpenChange={setDeleteDialogOpen}
title="确认删除"
description="确定要删除这个通知渠道吗?此操作不可撤销。"
item={deleteId}
onConfirm={handleDelete}
onSuccess={() => {
toast({ title: '删除成功' });
setDeleteId(null);
loadData();
}}
onCancel={() => setDeleteId(null)}
variant="destructive"
confirmText="删除"
/>
</div>
);
};

View File

@ -6,16 +6,7 @@ import {
DialogBody,
DialogTitle,
} from '@/components/ui/dialog';
import {
AlertDialog,
AlertDialogAction,
AlertDialogCancel,
AlertDialogContent,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogTitle,
} from '@/components/ui/alert-dialog';
import { ConfirmDialog } from '@/components/ui/confirm-dialog';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import {
@ -180,25 +171,7 @@ const CategoryManageDialog: React.FC<CategoryManageDialogProps> = ({
// 确认删除
const confirmDelete = async () => {
if (!deleteRecord) return;
try {
await deleteJobCategory(deleteRecord.id);
toast({
title: '删除成功',
description: `分类 "${deleteRecord.name}" 已删除`,
});
loadCategories();
onSuccess?.();
setDeleteDialogOpen(false);
setDeleteRecord(null);
} catch (error) {
console.error('删除失败:', error);
toast({
variant: 'destructive',
title: '删除失败',
description: error instanceof Error ? error.message : '未知错误',
});
}
await deleteJobCategory(deleteRecord.id);
};
// 保存
@ -542,21 +515,30 @@ const CategoryManageDialog: React.FC<CategoryManageDialogProps> = ({
/>
{/* 删除确认对话框 */}
<AlertDialog open={deleteDialogOpen} onOpenChange={setDeleteDialogOpen}>
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle></AlertDialogTitle>
<AlertDialogDescription>
<span className="font-semibold">{deleteRecord?.name}</span>
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel></AlertDialogCancel>
<AlertDialogAction onClick={confirmDelete}></AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
<ConfirmDialog
open={deleteDialogOpen}
onOpenChange={setDeleteDialogOpen}
title="确认删除"
description={
<>
<span className="font-semibold">{deleteRecord?.name}</span>
</>
}
item={deleteRecord}
onConfirm={confirmDelete}
onSuccess={() => {
toast({
title: '删除成功',
description: `分类 "${deleteRecord?.name}" 已删除`,
});
setDeleteRecord(null);
loadCategories();
onSuccess?.();
}}
variant="destructive"
confirmText="确认删除"
/>
</>
);
};

View File

@ -20,16 +20,7 @@ import CategoryManageDialog from './components/CategoryManageDialog';
import JobLogDialog from './components/JobLogDialog';
import JobEditDialog from './components/JobEditDialog';
import Dashboard from './components/Dashboard';
import {
AlertDialog,
AlertDialogAction,
AlertDialogCancel,
AlertDialogContent,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogTitle,
} from '@/components/ui/alert-dialog';
import { ConfirmDialog } from '@/components/ui/confirm-dialog';
import dayjs from 'dayjs';
/**
@ -123,22 +114,7 @@ const ScheduleJobList: React.FC = () => {
// 确认删除
const confirmDelete = async () => {
if (!deleteJob) return;
try {
await deleteScheduleJob(deleteJob.id);
toast({
title: '删除成功',
description: `任务 "${deleteJob.jobName}" 已删除`,
});
loadData();
setDeleteDialogOpen(false);
setDeleteJob(null);
} catch (error) {
toast({
variant: 'destructive',
title: '删除失败',
description: error instanceof Error ? error.message : '未知错误',
});
}
await deleteScheduleJob(deleteJob.id);
};
// 暂停任务
@ -612,55 +588,53 @@ const ScheduleJobList: React.FC = () => {
/>
{/* 删除确认对话框 */}
<AlertDialog open={deleteDialogOpen} onOpenChange={setDeleteDialogOpen}>
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle></AlertDialogTitle>
<AlertDialogDescription asChild>
<div className="space-y-3">
<p></p>
{deleteJob && (
<div className="rounded-md border p-3 space-y-2 bg-muted/50">
<div className="flex items-center gap-2">
<span className="text-sm font-medium text-muted-foreground">:</span>
<span className="font-medium">{deleteJob.jobName}</span>
</div>
<div className="flex items-center gap-2">
<span className="text-sm font-medium text-muted-foreground">Bean名称:</span>
<code className="text-xs bg-background px-2 py-1 rounded">
{deleteJob.beanName}
</code>
</div>
<div className="flex items-center gap-2">
<span className="text-sm font-medium text-muted-foreground">:</span>
<code className="text-xs bg-background px-2 py-1 rounded">
{deleteJob.methodName}
</code>
</div>
{deleteJob.cronExpression && (
<div className="flex items-center gap-2">
<span className="text-sm font-medium text-muted-foreground">Cron表达式:</span>
<code className="text-xs bg-background px-2 py-1 rounded">
{deleteJob.cronExpression}
</code>
</div>
)}
</div>
)}
<ConfirmDialog
open={deleteDialogOpen}
onOpenChange={setDeleteDialogOpen}
title="确认删除定时任务"
description="您确定要删除以下定时任务吗?此操作无法撤销。"
item={deleteJob}
onConfirm={confirmDelete}
onSuccess={() => {
toast({
title: '删除成功',
description: `任务 "${deleteJob?.jobName}" 已删除`,
});
setDeleteJob(null);
loadData();
}}
variant="destructive"
confirmText="确认删除"
>
{deleteJob && (
<div className="rounded-md border p-3 space-y-2 bg-muted/50">
<div className="flex items-center gap-2">
<span className="text-sm font-medium text-muted-foreground">:</span>
<span className="font-medium">{deleteJob.jobName}</span>
</div>
<div className="flex items-center gap-2">
<span className="text-sm font-medium text-muted-foreground">Bean名称:</span>
<code className="text-xs bg-background px-2 py-1 rounded">
{deleteJob.beanName}
</code>
</div>
<div className="flex items-center gap-2">
<span className="text-sm font-medium text-muted-foreground">:</span>
<code className="text-xs bg-background px-2 py-1 rounded">
{deleteJob.methodName}
</code>
</div>
{deleteJob.cronExpression && (
<div className="flex items-center gap-2">
<span className="text-sm font-medium text-muted-foreground">Cron表达式:</span>
<code className="text-xs bg-background px-2 py-1 rounded">
{deleteJob.cronExpression}
</code>
</div>
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel></AlertDialogCancel>
<AlertDialogAction
onClick={confirmDelete}
className="bg-destructive text-destructive-foreground hover:bg-destructive/90"
>
</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
)}
</div>
)}
</ConfirmDialog>
</TabsContent>
{/* 仪表盘视图 */}

View File

@ -6,16 +6,7 @@ import {
DialogBody,
DialogTitle,
} from "@/components/ui/dialog";
import {
AlertDialog,
AlertDialogAction,
AlertDialogCancel,
AlertDialogContent,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogTitle,
} from "@/components/ui/alert-dialog";
import { ConfirmDialog } from '@/components/ui/confirm-dialog';
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import {
@ -172,25 +163,7 @@ const CategoryManageDialog: React.FC<CategoryManageDialogProps> = ({
// 确认删除
const confirmDelete = async () => {
if (!deleteRecord) return;
try {
await deleteCategory(deleteRecord.id);
toast({
title: "删除成功",
description: `分类 "${deleteRecord.name}" 已删除`,
});
loadCategories();
onSuccess?.();
setDeleteDialogOpen(false);
setDeleteRecord(null);
} catch (error) {
console.error('删除失败:', error);
toast({
variant: "destructive",
title: "删除失败",
description: error instanceof Error ? error.message : '未知错误',
});
}
await deleteCategory(deleteRecord.id);
};
// 保存
@ -509,53 +482,52 @@ const CategoryManageDialog: React.FC<CategoryManageDialogProps> = ({
</Dialog>
{/* 删除确认对话框 */}
<AlertDialog open={deleteDialogOpen} onOpenChange={setDeleteDialogOpen}>
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle></AlertDialogTitle>
<AlertDialogDescription asChild>
<div className="space-y-3">
<p></p>
{deleteRecord && (
<div className="rounded-md border p-3 space-y-2 bg-muted/50">
<div className="flex items-center gap-2">
<span className="text-sm font-medium text-muted-foreground">:</span>
<span className="font-medium">{deleteRecord.name}</span>
</div>
<div className="flex items-center gap-2">
<span className="text-sm font-medium text-muted-foreground">:</span>
<code className="text-xs bg-background px-2 py-1 rounded">
{deleteRecord.code}
</code>
</div>
{deleteRecord.icon && (
<div className="flex items-center gap-2">
<span className="text-sm font-medium text-muted-foreground">:</span>
<DynamicIcon name={deleteRecord.icon} className="h-4 w-4" />
</div>
)}
{deleteRecord.description && (
<div className="flex items-start gap-2">
<span className="text-sm font-medium text-muted-foreground">:</span>
<span className="text-sm">{deleteRecord.description}</span>
</div>
)}
</div>
)}
<ConfirmDialog
open={deleteDialogOpen}
onOpenChange={setDeleteDialogOpen}
title="确认删除分类"
description="您确定要删除以下分类吗?此操作无法撤销。"
item={deleteRecord}
onConfirm={confirmDelete}
onSuccess={() => {
toast({
title: "删除成功",
description: `分类 "${deleteRecord?.name}" 已删除`,
});
setDeleteRecord(null);
loadCategories();
onSuccess?.();
}}
variant="destructive"
confirmText="确认删除"
>
{deleteRecord && (
<div className="rounded-md border p-3 space-y-2 bg-muted/50">
<div className="flex items-center gap-2">
<span className="text-sm font-medium text-muted-foreground">:</span>
<span className="font-medium">{deleteRecord.name}</span>
</div>
<div className="flex items-center gap-2">
<span className="text-sm font-medium text-muted-foreground">:</span>
<code className="text-xs bg-background px-2 py-1 rounded">
{deleteRecord.code}
</code>
</div>
{deleteRecord.icon && (
<div className="flex items-center gap-2">
<span className="text-sm font-medium text-muted-foreground">:</span>
<DynamicIcon name={deleteRecord.icon} className="h-4 w-4" />
</div>
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel></AlertDialogCancel>
<AlertDialogAction
onClick={confirmDelete}
className="bg-destructive text-destructive-foreground hover:bg-destructive/90"
>
</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
)}
{deleteRecord.description && (
<div className="flex items-start gap-2">
<span className="text-sm font-medium text-muted-foreground">:</span>
<span className="text-sm">{deleteRecord.description}</span>
</div>
)}
</div>
)}
</ConfirmDialog>
</>
);
};

View File

@ -33,7 +33,7 @@ import {
TableRow,
} from '@/components/ui/table';
import { useToast } from '@/components/ui/use-toast';
import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle } from '@/components/ui/alert-dialog';
import { ConfirmDialog } from '@/components/ui/confirm-dialog';
import { DataTablePagination } from '@/components/ui/pagination';
import { DEFAULT_PAGE_SIZE, DEFAULT_CURRENT } from '@/utils/page';
import type { ServerCategoryResponse } from '../types';
@ -159,25 +159,7 @@ export const CategoryManageDialog: React.FC<CategoryManageDialogProps> = ({
const confirmDelete = async () => {
if (!categoryToDelete) return;
try {
await deleteServerCategory(categoryToDelete.id);
toast({
title: '删除成功',
description: `分类"${categoryToDelete.name}"已删除`,
});
loadCategories();
onSuccess?.();
} catch (error) {
toast({
variant: 'destructive',
title: '删除失败',
description: '删除服务器分类失败',
});
} finally {
setDeleteConfirmOpen(false);
setCategoryToDelete(null);
}
await deleteServerCategory(categoryToDelete.id);
};
// 提交表单
@ -499,20 +481,25 @@ export const CategoryManageDialog: React.FC<CategoryManageDialogProps> = ({
</Dialog>
{/* 删除确认对话框 */}
<AlertDialog open={deleteConfirmOpen} onOpenChange={setDeleteConfirmOpen}>
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle></AlertDialogTitle>
<AlertDialogDescription>
"{categoryToDelete?.name}"
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel></AlertDialogCancel>
<AlertDialogAction onClick={confirmDelete}></AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
<ConfirmDialog
open={deleteConfirmOpen}
onOpenChange={setDeleteConfirmOpen}
title="确认删除"
description={`确定要删除分类"${categoryToDelete?.name}"吗?此操作无法撤销。`}
item={categoryToDelete}
onConfirm={confirmDelete}
onSuccess={() => {
toast({
title: '删除成功',
description: `分类"${categoryToDelete?.name}"已删除`,
});
setCategoryToDelete(null);
loadCategories();
onSuccess?.();
}}
variant="destructive"
confirmText="确定"
/>
</>
);
};

View File

@ -29,16 +29,7 @@ import {
import {
TooltipProvider,
} from '@/components/ui/tooltip';
import {
AlertDialog,
AlertDialogAction,
AlertDialogCancel,
AlertDialogContent,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogTitle,
} from '@/components/ui/alert-dialog';
import { ConfirmDialog } from '@/components/ui/confirm-dialog';
import { useToast } from '@/components/ui/use-toast';
import { DataTablePagination } from '@/components/ui/pagination';
import { Input } from '@/components/ui/input';
@ -215,25 +206,7 @@ const ServerList: React.FC = () => {
const confirmDelete = async () => {
if (!serverToDelete) return;
try {
await deleteServer(serverToDelete.id);
toast({
title: '删除成功',
description: `服务器"${serverToDelete.serverName}"已删除`,
});
loadServers();
loadStats();
} catch (error: any) {
toast({
variant: 'destructive',
title: '删除失败',
description: error.response?.data?.message || '删除失败',
});
} finally {
setDeleteDialogOpen(false);
setServerToDelete(null);
}
await deleteServer(serverToDelete.id);
};
// 成功回调
@ -600,20 +573,25 @@ const ServerList: React.FC = () => {
/>
{/* 删除确认对话框 */}
<AlertDialog open={deleteDialogOpen} onOpenChange={setDeleteDialogOpen}>
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle></AlertDialogTitle>
<AlertDialogDescription>
"{serverToDelete?.serverName}"
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel></AlertDialogCancel>
<AlertDialogAction onClick={confirmDelete}></AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
<ConfirmDialog
open={deleteDialogOpen}
onOpenChange={setDeleteDialogOpen}
title="确认删除"
description={`确定要删除服务器"${serverToDelete?.serverName}"吗?此操作无法撤销。`}
item={serverToDelete}
onConfirm={confirmDelete}
onSuccess={() => {
toast({
title: '删除成功',
description: `服务器"${serverToDelete?.serverName}"已删除`,
});
setServerToDelete(null);
loadServers();
loadStats();
}}
variant="destructive"
confirmText="确定"
/>
</TooltipProvider>
);
};

View File

@ -6,16 +6,7 @@ import {
DialogBody,
DialogTitle,
} from "@/components/ui/dialog";
import {
AlertDialog,
AlertDialogAction,
AlertDialogCancel,
AlertDialogContent,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogTitle,
} from "@/components/ui/alert-dialog";
import { ConfirmDialog } from '@/components/ui/confirm-dialog';
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import {
@ -190,25 +181,7 @@ const CategoryManageDialog: React.FC<CategoryManageDialogProps> = ({
// 确认删除
const confirmDelete = async () => {
if (!deleteRecord) return;
try {
await deleteWorkflowCategory(deleteRecord.id);
toast({
title: "删除成功",
description: `分类 "${deleteRecord.name}" 已删除`,
});
loadCategories();
onSuccess?.();
setDeleteDialogOpen(false);
setDeleteRecord(null);
} catch (error) {
console.error('删除失败:', error);
toast({
variant: "destructive",
title: "删除失败",
description: error instanceof Error ? error.message : '未知错误',
});
}
await deleteWorkflowCategory(deleteRecord.id);
};
// 保存
@ -588,53 +561,52 @@ const CategoryManageDialog: React.FC<CategoryManageDialogProps> = ({
</Dialog>
{/* 删除确认对话框 */}
<AlertDialog open={deleteDialogOpen} onOpenChange={setDeleteDialogOpen}>
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle></AlertDialogTitle>
<AlertDialogDescription asChild>
<div className="space-y-3">
<p></p>
{deleteRecord && (
<div className="rounded-md border p-3 space-y-2 bg-muted/50">
<div className="flex items-center gap-2">
<span className="text-sm font-medium text-muted-foreground">:</span>
<span className="font-medium">{deleteRecord.name}</span>
</div>
<div className="flex items-center gap-2">
<span className="text-sm font-medium text-muted-foreground">:</span>
<code className="text-xs bg-background px-2 py-1 rounded">
{deleteRecord.code}
</code>
</div>
{deleteRecord.icon && (
<div className="flex items-center gap-2">
<span className="text-sm font-medium text-muted-foreground">:</span>
<DynamicIcon name={deleteRecord.icon} className="h-4 w-4" />
</div>
)}
{deleteRecord.description && (
<div className="flex items-start gap-2">
<span className="text-sm font-medium text-muted-foreground">:</span>
<span className="text-sm">{deleteRecord.description}</span>
</div>
)}
</div>
)}
<ConfirmDialog
open={deleteDialogOpen}
onOpenChange={setDeleteDialogOpen}
title="确认删除分类"
description="您确定要删除以下分类吗?此操作无法撤销。"
item={deleteRecord}
onConfirm={confirmDelete}
onSuccess={() => {
toast({
title: "删除成功",
description: `分类 "${deleteRecord?.name}" 已删除`,
});
setDeleteRecord(null);
loadCategories();
onSuccess?.();
}}
variant="destructive"
confirmText="确认删除"
>
{deleteRecord && (
<div className="rounded-md border p-3 space-y-2 bg-muted/50">
<div className="flex items-center gap-2">
<span className="text-sm font-medium text-muted-foreground">:</span>
<span className="font-medium">{deleteRecord.name}</span>
</div>
<div className="flex items-center gap-2">
<span className="text-sm font-medium text-muted-foreground">:</span>
<code className="text-xs bg-background px-2 py-1 rounded">
{deleteRecord.code}
</code>
</div>
{deleteRecord.icon && (
<div className="flex items-center gap-2">
<span className="text-sm font-medium text-muted-foreground">:</span>
<DynamicIcon name={deleteRecord.icon} className="h-4 w-4" />
</div>
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel></AlertDialogCancel>
<AlertDialogAction
onClick={confirmDelete}
className="bg-destructive text-destructive-foreground hover:bg-destructive/90"
>
</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
)}
{deleteRecord.description && (
<div className="flex items-start gap-2">
<span className="text-sm font-medium text-muted-foreground">:</span>
<span className="text-sm">{deleteRecord.description}</span>
</div>
)}
</div>
)}
</ConfirmDialog>
</>
);
};