feat: K8s 集群同步功能 + 表单简化
- 新增手动同步按钮(卡片下拉菜单「同步」) - 新建集群后自动触发同步(延迟500ms等列表刷新) - 同步后刷新集群列表,节点/Pod/Deployment 数据写入 DB - 集群表单:名称即code,正则校验英文/数字/连字符
This commit is contained in:
1 parent
e5276161ea
commit
9dbb7e9fc4
1 file changed
+41
-1
@@ -29,6 +29,7 @@ import {
|
|||||||
Container,
|
Container,
|
||||||
} from 'lucide-react';
|
} from 'lucide-react';
|
||||||
import { kubernetesApi } from '@/services/api';
|
import { kubernetesApi } from '@/services/api';
|
||||||
|
import { toast } from 'sonner';
|
||||||
import type { KubernetesCluster } from '@/types';
|
import type { KubernetesCluster } from '@/types';
|
||||||
import { KubernetesClusterDetail } from './KubernetesClusterDetail';
|
import { KubernetesClusterDetail } from './KubernetesClusterDetail';
|
||||||
import { KubernetesClusterDialog } from './KubernetesClusterDialog';
|
import { KubernetesClusterDialog } from './KubernetesClusterDialog';
|
||||||
@@ -65,6 +66,24 @@ export function KubernetesClusters() {
|
|||||||
loadData();
|
loadData();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
// 新建后自动同步
|
||||||
|
const [pendingSyncId, setPendingSyncId] = useState<number | null>(null);
|
||||||
|
|
||||||
|
const handleSaved = () => {
|
||||||
|
loadData().then(() => {
|
||||||
|
if (!editingCluster) {
|
||||||
|
// 新建集群后,等列表刷新完再取最新一条同步
|
||||||
|
setTimeout(async () => {
|
||||||
|
const res: any = await kubernetesApi.getClusters();
|
||||||
|
const list = res?.list || [];
|
||||||
|
if (list.length > 0) {
|
||||||
|
handleSync(list[list.length - 1].id, true);
|
||||||
|
}
|
||||||
|
}, 500);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
const handleDelete = async (id: string) => {
|
const handleDelete = async (id: string) => {
|
||||||
try {
|
try {
|
||||||
await kubernetesApi.deleteCluster(id);
|
await kubernetesApi.deleteCluster(id);
|
||||||
@@ -74,6 +93,17 @@ export function KubernetesClusters() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleSync = async (id: number | string, silent?: boolean) => {
|
||||||
|
try {
|
||||||
|
if (!silent) toast.info('正在同步集群资源...');
|
||||||
|
const res: any = await kubernetesApi.syncCluster(id);
|
||||||
|
if (!silent) toast.success(res?.message || '同步完成');
|
||||||
|
loadData();
|
||||||
|
} catch (e: any) {
|
||||||
|
if (!silent) toast.error(e?.message || '同步失败');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const filteredClusters = clusters.filter(
|
const filteredClusters = clusters.filter(
|
||||||
(cluster) =>
|
(cluster) =>
|
||||||
(cluster.name || '').toLowerCase().includes(searchQuery.toLowerCase()) ||
|
(cluster.name || '').toLowerCase().includes(searchQuery.toLowerCase()) ||
|
||||||
@@ -280,6 +310,16 @@ export function KubernetesClusters() {
|
|||||||
<Settings className="h-4 w-4 mr-2" />
|
<Settings className="h-4 w-4 mr-2" />
|
||||||
配置
|
配置
|
||||||
</DropdownMenuItem>
|
</DropdownMenuItem>
|
||||||
|
<DropdownMenuItem
|
||||||
|
className="text-cyan-400 focus:bg-slate-700 focus:text-cyan-300"
|
||||||
|
onClick={(e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
handleSync(cluster.id);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<RefreshCw className="h-4 w-4 mr-2" />
|
||||||
|
同步
|
||||||
|
</DropdownMenuItem>
|
||||||
<DropdownMenuItem
|
<DropdownMenuItem
|
||||||
className="text-emerald-400 focus:bg-slate-700 focus:text-emerald-300"
|
className="text-emerald-400 focus:bg-slate-700 focus:text-emerald-300"
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
@@ -377,7 +417,7 @@ export function KubernetesClusters() {
|
|||||||
open={dialogOpen}
|
open={dialogOpen}
|
||||||
onOpenChange={setDialogOpen}
|
onOpenChange={setDialogOpen}
|
||||||
editingCluster={editingCluster}
|
editingCluster={editingCluster}
|
||||||
onSaved={loadData}
|
onSaved={handleSaved}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{/* kubectl 终端 */}
|
{/* kubectl 终端 */}
|
||||||
|
|||||||
Reference in new issue
Block a user