增加审批组件
This commit is contained in:
parent
ab89ebe994
commit
ab4ea6e367
@ -0,0 +1,559 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import {
|
||||
Dialog,
|
||||
DialogContent,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
} from "@/components/ui/dialog";
|
||||
import {
|
||||
AlertDialog,
|
||||
AlertDialogAction,
|
||||
AlertDialogCancel,
|
||||
AlertDialogContent,
|
||||
AlertDialogDescription,
|
||||
AlertDialogFooter,
|
||||
AlertDialogHeader,
|
||||
AlertDialogTitle,
|
||||
} from "@/components/ui/alert-dialog";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import {
|
||||
Table,
|
||||
TableBody,
|
||||
TableCell,
|
||||
TableHead,
|
||||
TableHeader,
|
||||
TableRow,
|
||||
} from "@/components/ui/table";
|
||||
import {
|
||||
Form,
|
||||
FormControl,
|
||||
FormField,
|
||||
FormItem,
|
||||
FormLabel,
|
||||
FormMessage,
|
||||
} from "@/components/ui/form";
|
||||
import { Textarea } from "@/components/ui/textarea";
|
||||
import { Switch } from "@/components/ui/switch";
|
||||
import { useToast } from "@/components/ui/use-toast";
|
||||
import { useForm } from "react-hook-form";
|
||||
import { DataTablePagination } from '@/components/ui/pagination';
|
||||
import { DEFAULT_PAGE_SIZE, DEFAULT_CURRENT } from '@/utils/page';
|
||||
import {
|
||||
Plus,
|
||||
Edit,
|
||||
Trash2,
|
||||
Search,
|
||||
Loader2,
|
||||
FolderKanban,
|
||||
CheckCircle2,
|
||||
XCircle,
|
||||
} from "lucide-react";
|
||||
import DynamicIcon from '@/components/DynamicIcon';
|
||||
import LucideIconSelect from '@/components/LucideIconSelect';
|
||||
import {
|
||||
getCategories,
|
||||
createCategory,
|
||||
updateCategory,
|
||||
deleteCategory
|
||||
} from '../../Category/service';
|
||||
import type {
|
||||
FormCategoryResponse,
|
||||
FormCategoryRequest,
|
||||
FormCategoryQuery
|
||||
} from '../../Category/types';
|
||||
import type { Page } from '@/types/base';
|
||||
|
||||
interface CategoryManageDialogProps {
|
||||
open: boolean;
|
||||
onOpenChange: (open: boolean) => void;
|
||||
onSuccess?: () => void;
|
||||
}
|
||||
|
||||
const CategoryManageDialog: React.FC<CategoryManageDialogProps> = ({
|
||||
open,
|
||||
onOpenChange,
|
||||
onSuccess
|
||||
}) => {
|
||||
const { toast } = useToast();
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [data, setData] = useState<Page<FormCategoryResponse> | null>(null);
|
||||
const [searchText, setSearchText] = useState('');
|
||||
const [editMode, setEditMode] = useState(false);
|
||||
const [editRecord, setEditRecord] = useState<FormCategoryResponse | null>(null);
|
||||
const [iconSelectOpen, setIconSelectOpen] = useState(false);
|
||||
const [deleteDialogOpen, setDeleteDialogOpen] = useState(false);
|
||||
const [deleteRecord, setDeleteRecord] = useState<FormCategoryResponse | null>(null);
|
||||
|
||||
// 分页状态
|
||||
const [pageNum, setPageNum] = useState(DEFAULT_CURRENT - 1);
|
||||
const [pageSize, setPageSize] = useState(DEFAULT_PAGE_SIZE);
|
||||
|
||||
const form = useForm<FormCategoryRequest>({
|
||||
defaultValues: {
|
||||
name: '',
|
||||
code: '',
|
||||
icon: '',
|
||||
sort: 0,
|
||||
description: '',
|
||||
enabled: true,
|
||||
}
|
||||
});
|
||||
|
||||
// 加载分类列表
|
||||
const loadCategories = async () => {
|
||||
setLoading(true);
|
||||
try {
|
||||
const query: FormCategoryQuery = {
|
||||
name: searchText || undefined,
|
||||
pageNum,
|
||||
pageSize,
|
||||
};
|
||||
const result = await getCategories(query);
|
||||
setData(result || null);
|
||||
} catch (error) {
|
||||
console.error('加载分类失败:', error);
|
||||
toast({
|
||||
variant: "destructive",
|
||||
title: "加载失败",
|
||||
description: error instanceof Error ? error.message : '未知错误',
|
||||
});
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (open) {
|
||||
loadCategories();
|
||||
}
|
||||
}, [open, searchText, pageNum, pageSize]);
|
||||
|
||||
// 搜索
|
||||
const handleSearch = () => {
|
||||
setPageNum(0); // 搜索时重置到第一页
|
||||
};
|
||||
|
||||
// 新建
|
||||
const handleCreate = () => {
|
||||
form.reset({
|
||||
name: '',
|
||||
code: '',
|
||||
icon: '',
|
||||
sort: 0,
|
||||
description: '',
|
||||
enabled: true,
|
||||
});
|
||||
setEditRecord(null);
|
||||
setEditMode(true);
|
||||
};
|
||||
|
||||
// 编辑
|
||||
const handleEdit = (record: FormCategoryResponse) => {
|
||||
setEditRecord(record);
|
||||
form.reset({
|
||||
name: record.name,
|
||||
code: record.code,
|
||||
icon: record.icon || '',
|
||||
sort: record.sort,
|
||||
description: record.description || '',
|
||||
enabled: record.enabled,
|
||||
});
|
||||
setEditMode(true);
|
||||
};
|
||||
|
||||
// 打开删除确认对话框
|
||||
const handleDeleteClick = (record: FormCategoryResponse) => {
|
||||
setDeleteRecord(record);
|
||||
setDeleteDialogOpen(true);
|
||||
};
|
||||
|
||||
// 确认删除
|
||||
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 : '未知错误',
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// 保存
|
||||
const handleSave = async (values: FormCategoryRequest) => {
|
||||
try {
|
||||
if (editRecord) {
|
||||
await updateCategory(editRecord.id, values);
|
||||
toast({
|
||||
title: "更新成功",
|
||||
description: `分类 "${values.name}" 已更新`,
|
||||
});
|
||||
} else {
|
||||
await createCategory(values);
|
||||
toast({
|
||||
title: "创建成功",
|
||||
description: `分类 "${values.name}" 已创建`,
|
||||
});
|
||||
}
|
||||
setEditMode(false);
|
||||
loadCategories();
|
||||
onSuccess?.();
|
||||
} catch (error) {
|
||||
console.error('保存失败:', error);
|
||||
toast({
|
||||
variant: "destructive",
|
||||
title: "保存失败",
|
||||
description: error instanceof Error ? error.message : '未知错误',
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// 取消编辑
|
||||
const handleCancel = () => {
|
||||
setEditMode(false);
|
||||
setEditRecord(null);
|
||||
form.reset();
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Dialog open={open} onOpenChange={onOpenChange}>
|
||||
<DialogContent className="max-w-6xl max-h-[85vh] overflow-y-auto">
|
||||
<DialogHeader>
|
||||
<DialogTitle className="flex items-center gap-2">
|
||||
<FolderKanban className="h-5 w-5" />
|
||||
分类管理
|
||||
</DialogTitle>
|
||||
</DialogHeader>
|
||||
|
||||
{!editMode ? (
|
||||
<div className="space-y-4">
|
||||
{/* 搜索栏 */}
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="relative flex-1">
|
||||
<Search className="absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" />
|
||||
<Input
|
||||
placeholder="搜索分类名称..."
|
||||
value={searchText}
|
||||
onChange={(e) => setSearchText(e.target.value)}
|
||||
onKeyDown={(e) => e.key === 'Enter' && handleSearch()}
|
||||
className="pl-10"
|
||||
/>
|
||||
</div>
|
||||
<Button onClick={handleCreate}>
|
||||
<Plus className="h-4 w-4 mr-2" />
|
||||
新建分类
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
{/* 表格 */}
|
||||
<div className="overflow-x-auto">
|
||||
<Table>
|
||||
<TableHeader>
|
||||
<TableRow>
|
||||
<TableHead className="w-[160px]">分类名称</TableHead>
|
||||
<TableHead className="w-[140px]">分类代码</TableHead>
|
||||
<TableHead className="w-[60px]">图标</TableHead>
|
||||
<TableHead className="w-[80px]">排序</TableHead>
|
||||
<TableHead className="w-[80px]">状态</TableHead>
|
||||
<TableHead className="min-w-[150px]">描述</TableHead>
|
||||
<TableHead className="w-[100px] sticky right-0 bg-background shadow-[-2px_0_4px_rgba(0,0,0,0.05)]">操作</TableHead>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
{loading ? (
|
||||
<TableRow>
|
||||
<TableCell colSpan={7} className="text-center py-8">
|
||||
<div className="flex items-center justify-center">
|
||||
<Loader2 className="h-6 w-6 animate-spin mr-2" />
|
||||
<span className="text-sm text-muted-foreground">加载中...</span>
|
||||
</div>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
) : data?.content && data.content.length > 0 ? (
|
||||
data.content.map((record) => (
|
||||
<TableRow key={record.id}>
|
||||
<TableCell className="font-medium">
|
||||
{record.name}
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<code className="text-xs bg-muted px-2 py-0.5 rounded whitespace-nowrap">
|
||||
{record.code}
|
||||
</code>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
{record.icon ? (
|
||||
<div className="flex items-center justify-center">
|
||||
<DynamicIcon name={record.icon} className="h-5 w-5" />
|
||||
</div>
|
||||
) : (
|
||||
<span className="text-muted-foreground text-sm">-</span>
|
||||
)}
|
||||
</TableCell>
|
||||
<TableCell className="text-center">{record.sort}</TableCell>
|
||||
<TableCell>
|
||||
{record.enabled ? (
|
||||
<CheckCircle2 className="h-4 w-4 text-green-500" />
|
||||
) : (
|
||||
<XCircle className="h-4 w-4 text-gray-400" />
|
||||
)}
|
||||
</TableCell>
|
||||
<TableCell className="max-w-[200px] truncate" title={record.description}>
|
||||
{record.description || '-'}
|
||||
</TableCell>
|
||||
<TableCell className="sticky right-0 bg-background shadow-[-2px_0_4px_rgba(0,0,0,0.05)]">
|
||||
<div className="flex items-center justify-end gap-1">
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
className="h-8 w-8 p-0"
|
||||
onClick={() => handleEdit(record)}
|
||||
>
|
||||
<Edit className="h-3.5 w-3.5" />
|
||||
</Button>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
className="h-8 w-8 p-0"
|
||||
onClick={() => handleDeleteClick(record)}
|
||||
>
|
||||
<Trash2 className="h-3.5 w-3.5 text-destructive" />
|
||||
</Button>
|
||||
</div>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
))
|
||||
) : (
|
||||
<TableRow>
|
||||
<TableCell colSpan={7} className="text-center py-12 text-muted-foreground">
|
||||
<div className="flex flex-col items-center gap-3">
|
||||
<FolderKanban className="h-12 w-12 opacity-20" />
|
||||
<p className="text-sm">暂无分类</p>
|
||||
</div>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
)}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</div>
|
||||
|
||||
{/* 分页 */}
|
||||
{data && data.totalElements > 0 && (
|
||||
<div className="mt-4">
|
||||
<DataTablePagination
|
||||
pageIndex={pageNum + 1}
|
||||
pageSize={pageSize}
|
||||
pageCount={Math.ceil((data.totalElements || 0) / pageSize)}
|
||||
onPageChange={(page) => setPageNum(page - 1)}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
) : (
|
||||
<Form {...form}>
|
||||
<form onSubmit={form.handleSubmit(handleSave)} className="space-y-6">
|
||||
<div className="grid grid-cols-2 gap-4">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="name"
|
||||
rules={{ required: '请输入分类名称' }}
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>分类名称</FormLabel>
|
||||
<FormControl>
|
||||
<Input placeholder="输入分类名称" {...field} />
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="code"
|
||||
rules={{ required: '请输入分类代码' }}
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>分类代码</FormLabel>
|
||||
<FormControl>
|
||||
<Input placeholder="输入分类代码" {...field} />
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="icon"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>图标</FormLabel>
|
||||
<FormControl>
|
||||
<div className="flex items-center gap-2">
|
||||
<Input
|
||||
placeholder="点击选择图标"
|
||||
value={field.value}
|
||||
readOnly
|
||||
onClick={() => setIconSelectOpen(true)}
|
||||
className="cursor-pointer"
|
||||
/>
|
||||
{field.value && (
|
||||
<div className="flex items-center justify-center w-10 h-10 border rounded-md">
|
||||
<DynamicIcon name={field.value} className="h-5 w-5" />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
<LucideIconSelect
|
||||
open={iconSelectOpen}
|
||||
onOpenChange={setIconSelectOpen}
|
||||
value={field.value}
|
||||
onChange={field.onChange}
|
||||
/>
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="sort"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>排序</FormLabel>
|
||||
<FormControl>
|
||||
<Input
|
||||
type="number"
|
||||
placeholder="输入排序值"
|
||||
{...field}
|
||||
onChange={(e) => field.onChange(Number(e.target.value))}
|
||||
/>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="description"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>描述</FormLabel>
|
||||
<FormControl>
|
||||
<Textarea
|
||||
placeholder="输入分类描述"
|
||||
className="resize-none"
|
||||
rows={3}
|
||||
{...field}
|
||||
/>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="enabled"
|
||||
render={({ field }) => (
|
||||
<FormItem className="flex items-center justify-between rounded-lg border p-4">
|
||||
<div className="space-y-0.5">
|
||||
<FormLabel className="text-base">启用状态</FormLabel>
|
||||
<div className="text-sm text-muted-foreground">
|
||||
控制此分类是否可用
|
||||
</div>
|
||||
</div>
|
||||
<FormControl>
|
||||
<Switch
|
||||
checked={field.value}
|
||||
onCheckedChange={field.onChange}
|
||||
/>
|
||||
</FormControl>
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
|
||||
<div className="flex items-center justify-end gap-2 pt-4 border-t">
|
||||
<Button type="button" variant="outline" onClick={handleCancel}>
|
||||
取消
|
||||
</Button>
|
||||
<Button type="submit">
|
||||
保存
|
||||
</Button>
|
||||
</div>
|
||||
</form>
|
||||
</Form>
|
||||
)}
|
||||
</DialogContent>
|
||||
</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>
|
||||
)}
|
||||
</div>
|
||||
</AlertDialogDescription>
|
||||
</AlertDialogHeader>
|
||||
<AlertDialogFooter>
|
||||
<AlertDialogCancel>取消</AlertDialogCancel>
|
||||
<AlertDialogAction
|
||||
onClick={confirmDelete}
|
||||
className="bg-destructive text-destructive-foreground hover:bg-destructive/90"
|
||||
>
|
||||
确认删除
|
||||
</AlertDialogAction>
|
||||
</AlertDialogFooter>
|
||||
</AlertDialogContent>
|
||||
</AlertDialog>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default CategoryManageDialog;
|
||||
|
||||
@ -12,7 +12,7 @@ import { FormRenderer } from '@/components/FormDesigner';
|
||||
import {
|
||||
Loader2, Plus, Search, Eye, Edit, FileText, Ban, Trash2,
|
||||
Database, MoreHorizontal, CheckCircle2, XCircle, Clock, AlertCircle,
|
||||
Folder, Activity, Settings
|
||||
Folder, Activity, Settings, FolderKanban
|
||||
} from 'lucide-react';
|
||||
import {
|
||||
DropdownMenu,
|
||||
@ -30,6 +30,7 @@ import type { Page } from '@/types/base';
|
||||
import { DEFAULT_PAGE_SIZE, DEFAULT_CURRENT } from '@/utils/page';
|
||||
import CreateModal from './components/CreateModal';
|
||||
import EditBasicInfoModal from './components/EditBasicInfoModal';
|
||||
import CategoryManageDialog from './components/CategoryManageDialog';
|
||||
|
||||
/**
|
||||
* 表单定义列表页
|
||||
@ -47,6 +48,9 @@ const FormDefinitionList: React.FC = () => {
|
||||
status: undefined as FormDefinitionStatus | undefined,
|
||||
});
|
||||
|
||||
// 分类管理弹窗
|
||||
const [categoryDialogOpen, setCategoryDialogOpen] = useState(false);
|
||||
|
||||
// 创建表单弹窗
|
||||
const [createModalVisible, setCreateModalVisible] = useState(false);
|
||||
|
||||
@ -297,10 +301,16 @@ const FormDefinitionList: React.FC = () => {
|
||||
创建和管理表单定义,支持版本控制和发布管理
|
||||
</CardDescription>
|
||||
</div>
|
||||
<Button onClick={handleCreate} size="default">
|
||||
<Plus className="h-4 w-4 mr-2" />
|
||||
创建表单
|
||||
</Button>
|
||||
<div className="flex items-center gap-2">
|
||||
<Button variant="outline" onClick={() => setCategoryDialogOpen(true)}>
|
||||
<FolderKanban className="h-4 w-4 mr-2" />
|
||||
分类管理
|
||||
</Button>
|
||||
<Button onClick={handleCreate} size="default">
|
||||
<Plus className="h-4 w-4 mr-2" />
|
||||
创建表单
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</CardHeader>
|
||||
<Separator />
|
||||
@ -606,6 +616,13 @@ const FormDefinitionList: React.FC = () => {
|
||||
loadData();
|
||||
}}
|
||||
/>
|
||||
|
||||
{/* 分类管理弹窗 */}
|
||||
<CategoryManageDialog
|
||||
open={categoryDialogOpen}
|
||||
onOpenChange={setCategoryDialogOpen}
|
||||
onSuccess={loadCategories}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@ -38,6 +38,8 @@ import { Textarea } from "@/components/ui/textarea";
|
||||
import { Switch } from "@/components/ui/switch";
|
||||
import { useToast } from "@/components/ui/use-toast";
|
||||
import { useForm } from "react-hook-form";
|
||||
import { DataTablePagination } from '@/components/ui/pagination';
|
||||
import { DEFAULT_PAGE_SIZE, DEFAULT_CURRENT } from '@/utils/page';
|
||||
import {
|
||||
Plus,
|
||||
Edit,
|
||||
@ -86,6 +88,10 @@ const CategoryManageDialog: React.FC<CategoryManageDialogProps> = ({
|
||||
const [iconSelectOpen, setIconSelectOpen] = useState(false);
|
||||
const [deleteDialogOpen, setDeleteDialogOpen] = useState(false);
|
||||
const [deleteRecord, setDeleteRecord] = useState<WorkflowCategoryResponse | null>(null);
|
||||
|
||||
// 分页状态
|
||||
const [pageNum, setPageNum] = useState(DEFAULT_CURRENT - 1);
|
||||
const [pageSize, setPageSize] = useState(DEFAULT_PAGE_SIZE);
|
||||
|
||||
const form = useForm<WorkflowCategoryRequest>({
|
||||
defaultValues: {
|
||||
@ -104,8 +110,8 @@ const CategoryManageDialog: React.FC<CategoryManageDialogProps> = ({
|
||||
setLoading(true);
|
||||
try {
|
||||
const query: WorkflowCategoryQuery = {
|
||||
pageNum: 0,
|
||||
pageSize: 100,
|
||||
pageNum,
|
||||
pageSize,
|
||||
};
|
||||
if (searchText) {
|
||||
query.name = searchText;
|
||||
@ -128,7 +134,14 @@ const CategoryManageDialog: React.FC<CategoryManageDialogProps> = ({
|
||||
if (open) {
|
||||
loadCategories();
|
||||
}
|
||||
}, [open, searchText]);
|
||||
}, [open, searchText, pageNum, pageSize]);
|
||||
|
||||
// 搜索时重置页码
|
||||
useEffect(() => {
|
||||
if (searchText !== '') {
|
||||
setPageNum(0);
|
||||
}
|
||||
}, [searchText]);
|
||||
|
||||
// 触发方式选项
|
||||
const triggerOptions = [
|
||||
@ -382,6 +395,18 @@ const CategoryManageDialog: React.FC<CategoryManageDialogProps> = ({
|
||||
</TableBody>
|
||||
</Table>
|
||||
</div>
|
||||
|
||||
{/* 分页 */}
|
||||
{data && data.totalElements > 0 && (
|
||||
<div className="mt-4">
|
||||
<DataTablePagination
|
||||
pageIndex={pageNum + 1}
|
||||
pageSize={pageSize}
|
||||
pageCount={Math.ceil((data.totalElements || 0) / pageSize)}
|
||||
onPageChange={(page) => setPageNum(page - 1)}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
) : (
|
||||
/* 编辑表单 */
|
||||
|
||||
Loading…
Reference in New Issue
Block a user