"use client"; import { Badge } from "@workspace/ui/components/badge"; import { Button } from "@workspace/ui/components/button"; import { Card, CardContent, CardDescription, CardHeader, CardTitle, } from "@workspace/ui/components/card"; import { ConfirmButton } from "@workspace/ui/composed/confirm-button"; import { ProTable, type ProTableActions, } from "@workspace/ui/composed/pro-table/pro-table"; import { createNodeGroup, deleteNodeGroup, getNodeGroupList, updateNodeGroup, } from "@workspace/ui/services/admin/group"; import { useEffect, useRef, useState } from "react"; import { useTranslation } from "react-i18next"; import { toast } from "sonner"; import NodeGroupForm from "./node-group-form"; export default function NodeGroups() { const { t } = useTranslation("group"); const [loading, setLoading] = useState(false); const [allNodeGroups, setAllNodeGroups] = useState([]); const ref = useRef(null); // 获取所有节点组数据(用于冲突检测) useEffect(() => { const fetchAllNodeGroups = async () => { try { const { data } = await getNodeGroupList({ page: 1, size: 1000 }); setAllNodeGroups(data.data?.list || []); } catch (error) { console.error("Failed to fetch node groups:", error); } }; fetchAllNodeGroups(); }, []); return (
{t("nodeGroups", "Node Groups")} {t( "nodeGroupsDescription", "Manage node groups for user access control" )} action={ref} actions={{ render: (row: any) => [ { setLoading(true); try { await updateNodeGroup({ id: row.id, ...values, } as API.UpdateNodeGroupRequest); toast.success(t("updated", "Updated successfully")); // 刷新节点组列表 const { data } = await getNodeGroupList({ page: 1, size: 1000, }); setAllNodeGroups(data.data?.list || []); ref.current?.refresh(); setLoading(false); return true; } catch { setLoading(false); return false; } }} title={t("editNodeGroup", "Edit Node Group")} trigger={ } />, { await deleteNodeGroup({ id: row.id }); toast.success(t("deleted", "Deleted successfully")); // 刷新节点组列表 const { data } = await getNodeGroupList({ page: 1, size: 1000, }); setAllNodeGroups(data.data?.list || []); ref.current?.refresh(); setLoading(false); }} title={t("confirmDelete", "Confirm Delete")} trigger={ } />, ], }} columns={[ { id: "id", accessorKey: "id", header: t("id", "ID"), cell: ({ row }: { row: any }) => ( #{row.getValue("id")} ), }, { id: "name", accessorKey: "name", header: t("name", "Name"), cell: ({ row }: { row: any }) => { const isExpiredGroup = row.original.is_expired_group; return (
{row.getValue("name")} {isExpiredGroup && ( {t("expiredGroup", "Expired")} )}
); }, }, { id: "description", accessorKey: "description", header: t("description", "Description"), cell: ({ row }: { row: any }) => row.getValue("description") || "--", }, { id: "for_calculation", accessorKey: "for_calculation", header: t("forCalculation", "For Calculation"), cell: ({ row }: { row: any }) => { const value = row.getValue("for_calculation"); return value ? ( {t("yes", "Yes")} ) : ( {t("no", "No")} ); }, }, { id: "traffic_range", header: t("trafficRange", "Traffic Range (GB)"), cell: ({ row }: { row: any }) => { const min = row.original.min_traffic_gb; const max = row.original.max_traffic_gb; if (min !== undefined && max !== undefined) { return `${min} - ${max}`; } if (min !== undefined) { return `≥ ${min}`; } if (max !== undefined) { return `≤ ${max}`; } return "--"; }, }, { id: "sort", accessorKey: "sort", header: t("sort", "Sort"), }, ]} header={{ title: t("nodeGroups", "Node Groups"), toolbar: ( { setLoading(true); try { await createNodeGroup( values as API.CreateNodeGroupRequest ); toast.success(t("created", "Created successfully")); // 刷新节点组列表 const { data } = await getNodeGroupList({ page: 1, size: 1000, }); setAllNodeGroups(data.data?.list || []); ref.current?.refresh(); setLoading(false); return true; } catch { setLoading(false); return false; } }} title={t("createNodeGroup", "Create Node Group")} trigger={} /> ), }} request={async (params) => { const { data } = await getNodeGroupList({ page: params.page || 1, size: params.size || 10, }); return { list: data.data?.list || [], total: data.data?.total || 0, }; }} />
); }