feat: Agent一键安装(loading/成功/失败状态无弹框) + 批量安装API
This commit is contained in:
1 parent
48b2d2281b
commit
2fc2a2ae07
5 files changed
+213
-5
No files matched your search
@@ -73,8 +73,75 @@ export function ServerManager() {
|
||||
|
||||
// Agent 安装向导状态
|
||||
const [agentWizardOpen, setAgentWizardOpen] = useState(false);
|
||||
const openInstallAgent = (server: any) => {
|
||||
setAgentWizardOpen(true);
|
||||
// Agent 安装状态: { [serverId]: 'installing' | 'success' | 'failed' }
|
||||
const [installingIds, setInstallingIds] = useState<Set<number>>(new Set());
|
||||
const [installResults, setInstallResults] = useState<Map<number, { success: boolean; message: string }>>(new Map());
|
||||
|
||||
const openInstallAgent = async (server: any) => {
|
||||
const token = useUserStore.getState().token;
|
||||
if (!token) { toast.error('请先登录'); return; }
|
||||
|
||||
setInstallingIds(prev => new Set(prev).add(server.id));
|
||||
try {
|
||||
const res: any = await serverApi.installAgent(server.id, token);
|
||||
const installed = res?.installed || false;
|
||||
setInstallResults(prev => {
|
||||
const next = new Map(prev);
|
||||
next.set(server.id, {
|
||||
success: installed,
|
||||
message: installed ? '安装成功 ✓' : '命令已执行,Agent 未检测到运行'
|
||||
});
|
||||
return next;
|
||||
});
|
||||
if (installed) toast.success(`${server.hostname} Agent 安装成功`);
|
||||
else toast.warning(`${server.hostname}: Agent 安装命令已执行`);
|
||||
} catch (e: any) {
|
||||
setInstallResults(prev => {
|
||||
const next = new Map(prev);
|
||||
next.set(server.id, { success: false, message: e?.message || '安装失败' });
|
||||
return next;
|
||||
});
|
||||
toast.error(`${server.hostname} 安装失败: ${e?.message || '未知错误'}`);
|
||||
} finally {
|
||||
setInstallingIds(prev => {
|
||||
const next = new Set(prev);
|
||||
next.delete(server.id);
|
||||
return next;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const handleBatchInstallAgents = async () => {
|
||||
const token = useUserStore.getState().token;
|
||||
if (!token) { toast.error('请先登录'); return; }
|
||||
const ids = selectedServers.map(id => Number(id));
|
||||
|
||||
setInstallingIds(prev => {
|
||||
const next = new Set(prev);
|
||||
ids.forEach(id => next.add(id));
|
||||
return next;
|
||||
});
|
||||
|
||||
try {
|
||||
const res: any = await serverApi.batchInstallAgent(ids, token);
|
||||
const results = res?.results || [];
|
||||
setInstallResults(prev => {
|
||||
const next = new Map(prev);
|
||||
results.forEach((r: any) => {
|
||||
next.set(r.server_id, { success: r.installed, message: r.message });
|
||||
});
|
||||
return next;
|
||||
});
|
||||
toast.success(`批量安装完成: ${res?.success || 0}/${ids.length} 成功`);
|
||||
} catch (e: any) {
|
||||
toast.error(`批量安装失败: ${e?.message || '未知错误'}`);
|
||||
} finally {
|
||||
setInstallingIds(prev => {
|
||||
const next = new Set(prev);
|
||||
ids.forEach(id => next.delete(id));
|
||||
return next;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const openTerminal = (server: any) => {
|
||||
@@ -360,6 +427,15 @@ export function ServerManager() {
|
||||
{selectedServers.length > 0 && (
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="text-sm text-[var(--dg-text-secondary)]">已选择 {selectedServers.length} 项</span>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={handleBatchInstallAgents}
|
||||
className="border-[var(--dg-cyan)]/30 text-[var(--dg-cyan)] hover:bg-[var(--dg-cyan)]/10"
|
||||
>
|
||||
<Cpu className="h-4 w-4 mr-2" />
|
||||
批量安装Agent
|
||||
</Button>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
@@ -421,6 +497,8 @@ export function ServerManager() {
|
||||
onOpenEdit={openEditForm}
|
||||
onDelete={handleDelete}
|
||||
onInstallAgent={openInstallAgent}
|
||||
installing={installingIds.has(server.id)}
|
||||
installResult={installResults.get(server.id) || null}
|
||||
/>
|
||||
))
|
||||
)}
|
||||
|
||||
Reference in new issue
Block a user