2026-06-21 04:36:58 +00:00
|
|
|
import React, { useState, useEffect, useCallback, useRef } from 'react';
|
2026-06-11 14:38:36 +00:00
|
|
|
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/index';
|
|
|
|
|
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/index';
|
|
|
|
|
import { Button } from '@/components/ui/index';
|
|
|
|
|
import { Checkbox } from '@/components/ui/index';
|
2026-06-21 04:36:58 +00:00
|
|
|
import { MoreHorizontal, Play, Square, RotateCcw, Power, PlayCircle, Pause, X, MoveRight, Copy } from 'lucide-react';
|
|
|
|
|
import { invoke } from '@tauri-apps/api/core';
|
2026-06-21 14:38:10 +00:00
|
|
|
import { confirm } from '@tauri-apps/plugin-dialog';
|
2026-06-21 04:36:58 +00:00
|
|
|
import { toast } from 'sonner';
|
2026-06-21 16:17:31 +00:00
|
|
|
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter } from '@/components/ui/index';
|
|
|
|
|
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/index';
|
|
|
|
|
import { Label } from '@/components/ui/index';
|
|
|
|
|
import { Checkbox as UICheckbox } from '@/components/ui/index';
|
|
|
|
|
import { Input } from '@/components/ui/index';
|
|
|
|
|
import { AlertCircle } from 'lucide-react';
|
|
|
|
|
import { Alert, AlertDescription } from '@/components/ui/index';
|
fix(proxmox): resolve 7 dashboard and AI chat issues
1. VM Actions: pass clusterId/clusters props from VMsPage to VMList;
rename node→node_id in 14 Rust Tauri command handlers to match
Tauri 2.x camelCase→snake_case mapping; wire action menu items
through handleAction so menu closes on click.
2. Migration: add Target Remote dropdown in MigrationDialog showing
available clusters for cross-datacenter migration; targetCluster
passed through to migrate_vm invoke.
3. Storage: switch list_proxmox_datastores to cluster/resources?type=storage
(single API call, cluster-wide); normalize plugintype→type,
disk/maxdisk→used/size, compute available via saturating_sub.
4. Network: replace free-text Interface Type Input with a Select
dropdown listing all PVE network interface types.
5. Firewall New Rule: add onNewRule prop to FirewallRuleList, wire
button; add full dialog in FirewallPage with action/protocol/
source/dest/port fields that calls add_firewall_rule; rewrite
Rust command to accept rule as serde_json::Value instead of
flat params (matches frontend invoke signature).
6. Backup: normalize raw PVE cluster/backup fields (id, storage,
node, schedule, enabled, next-run timestamp) to BackupJobInfo
shape; update BackupJobList columns to show storage, vmid, mode.
7. AI chat: merge all system prompt sections into a single system
message (fixes Qwen 3.5 / LiteLLM rejection of multiple system
messages); push assistant message with tool_calls before tool
result messages to satisfy OpenAI API contract.
2026-06-21 20:08:56 +00:00
|
|
|
import type { ClusterInfo } from '@/lib/domain';
|
2026-06-11 14:38:36 +00:00
|
|
|
|
|
|
|
|
interface VMInfo {
|
|
|
|
|
id: string;
|
|
|
|
|
vmid: number;
|
|
|
|
|
name: string;
|
|
|
|
|
node: string;
|
|
|
|
|
status: 'running' | 'stopped' | 'paused';
|
|
|
|
|
cpu: number;
|
|
|
|
|
memory: number;
|
|
|
|
|
memoryTotal: number;
|
|
|
|
|
disk: number;
|
|
|
|
|
diskTotal: number;
|
2026-06-21 04:36:58 +00:00
|
|
|
uptime?: number;
|
2026-06-11 14:38:36 +00:00
|
|
|
tags?: string[];
|
|
|
|
|
}
|
|
|
|
|
|
2026-06-21 16:17:31 +00:00
|
|
|
interface RawVMInfo {
|
|
|
|
|
id: number;
|
|
|
|
|
vmid?: number;
|
|
|
|
|
name?: string;
|
|
|
|
|
node?: string;
|
|
|
|
|
status?: string;
|
|
|
|
|
cpu?: number;
|
|
|
|
|
mem?: number;
|
|
|
|
|
max_mem?: number;
|
|
|
|
|
memory?: number;
|
2026-06-21 16:36:32 +00:00
|
|
|
memoryTotal?: number;
|
2026-06-21 16:17:31 +00:00
|
|
|
disk?: number;
|
|
|
|
|
max_disk?: number;
|
|
|
|
|
diskTotal?: number;
|
|
|
|
|
uptime?: number;
|
2026-06-21 16:36:32 +00:00
|
|
|
tags?: string[];
|
2026-06-21 16:17:31 +00:00
|
|
|
}
|
|
|
|
|
|
2026-06-11 14:38:36 +00:00
|
|
|
interface VMListProps {
|
2026-06-21 16:17:31 +00:00
|
|
|
vms: RawVMInfo[];
|
fix(proxmox): resolve 7 dashboard and AI chat issues
1. VM Actions: pass clusterId/clusters props from VMsPage to VMList;
rename node→node_id in 14 Rust Tauri command handlers to match
Tauri 2.x camelCase→snake_case mapping; wire action menu items
through handleAction so menu closes on click.
2. Migration: add Target Remote dropdown in MigrationDialog showing
available clusters for cross-datacenter migration; targetCluster
passed through to migrate_vm invoke.
3. Storage: switch list_proxmox_datastores to cluster/resources?type=storage
(single API call, cluster-wide); normalize plugintype→type,
disk/maxdisk→used/size, compute available via saturating_sub.
4. Network: replace free-text Interface Type Input with a Select
dropdown listing all PVE network interface types.
5. Firewall New Rule: add onNewRule prop to FirewallRuleList, wire
button; add full dialog in FirewallPage with action/protocol/
source/dest/port fields that calls add_firewall_rule; rewrite
Rust command to accept rule as serde_json::Value instead of
flat params (matches frontend invoke signature).
6. Backup: normalize raw PVE cluster/backup fields (id, storage,
node, schedule, enabled, next-run timestamp) to BackupJobInfo
shape; update BackupJobList columns to show storage, vmid, mode.
7. AI chat: merge all system prompt sections into a single system
message (fixes Qwen 3.5 / LiteLLM rejection of multiple system
messages); push assistant message with tool_calls before tool
result messages to satisfy OpenAI API contract.
2026-06-21 20:08:56 +00:00
|
|
|
clusterId: string;
|
|
|
|
|
clusters?: ClusterInfo[];
|
2026-06-11 14:38:36 +00:00
|
|
|
onRefresh?: () => void;
|
|
|
|
|
isLoading?: boolean;
|
|
|
|
|
onSnapshotAction?: (vm: VMInfo, action: 'create' | 'list' | 'rollback' | 'delete') => void;
|
|
|
|
|
onMigrate?: (vm: VMInfo) => void;
|
|
|
|
|
onClone?: (vm: VMInfo) => void;
|
|
|
|
|
onDelete?: (vm: VMInfo) => void;
|
|
|
|
|
selectedVMs?: Set<string>;
|
|
|
|
|
onToggleSelect?: (vm: VMInfo) => void;
|
|
|
|
|
}
|
|
|
|
|
|
2026-06-21 04:36:58 +00:00
|
|
|
function formatUptime(seconds: number): string {
|
|
|
|
|
if (seconds <= 0) return '-';
|
fix(proxmox): resolve 7 dashboard and AI chat issues
1. VM Actions: pass clusterId/clusters props from VMsPage to VMList;
rename node→node_id in 14 Rust Tauri command handlers to match
Tauri 2.x camelCase→snake_case mapping; wire action menu items
through handleAction so menu closes on click.
2. Migration: add Target Remote dropdown in MigrationDialog showing
available clusters for cross-datacenter migration; targetCluster
passed through to migrate_vm invoke.
3. Storage: switch list_proxmox_datastores to cluster/resources?type=storage
(single API call, cluster-wide); normalize plugintype→type,
disk/maxdisk→used/size, compute available via saturating_sub.
4. Network: replace free-text Interface Type Input with a Select
dropdown listing all PVE network interface types.
5. Firewall New Rule: add onNewRule prop to FirewallRuleList, wire
button; add full dialog in FirewallPage with action/protocol/
source/dest/port fields that calls add_firewall_rule; rewrite
Rust command to accept rule as serde_json::Value instead of
flat params (matches frontend invoke signature).
6. Backup: normalize raw PVE cluster/backup fields (id, storage,
node, schedule, enabled, next-run timestamp) to BackupJobInfo
shape; update BackupJobList columns to show storage, vmid, mode.
7. AI chat: merge all system prompt sections into a single system
message (fixes Qwen 3.5 / LiteLLM rejection of multiple system
messages); push assistant message with tool_calls before tool
result messages to satisfy OpenAI API contract.
2026-06-21 20:08:56 +00:00
|
|
|
|
2026-06-21 04:36:58 +00:00
|
|
|
const days = Math.floor(seconds / 86400);
|
|
|
|
|
const hours = Math.floor((seconds % 86400) / 3600);
|
|
|
|
|
const minutes = Math.floor((seconds % 3600) / 60);
|
fix(proxmox): resolve 7 dashboard and AI chat issues
1. VM Actions: pass clusterId/clusters props from VMsPage to VMList;
rename node→node_id in 14 Rust Tauri command handlers to match
Tauri 2.x camelCase→snake_case mapping; wire action menu items
through handleAction so menu closes on click.
2. Migration: add Target Remote dropdown in MigrationDialog showing
available clusters for cross-datacenter migration; targetCluster
passed through to migrate_vm invoke.
3. Storage: switch list_proxmox_datastores to cluster/resources?type=storage
(single API call, cluster-wide); normalize plugintype→type,
disk/maxdisk→used/size, compute available via saturating_sub.
4. Network: replace free-text Interface Type Input with a Select
dropdown listing all PVE network interface types.
5. Firewall New Rule: add onNewRule prop to FirewallRuleList, wire
button; add full dialog in FirewallPage with action/protocol/
source/dest/port fields that calls add_firewall_rule; rewrite
Rust command to accept rule as serde_json::Value instead of
flat params (matches frontend invoke signature).
6. Backup: normalize raw PVE cluster/backup fields (id, storage,
node, schedule, enabled, next-run timestamp) to BackupJobInfo
shape; update BackupJobList columns to show storage, vmid, mode.
7. AI chat: merge all system prompt sections into a single system
message (fixes Qwen 3.5 / LiteLLM rejection of multiple system
messages); push assistant message with tool_calls before tool
result messages to satisfy OpenAI API contract.
2026-06-21 20:08:56 +00:00
|
|
|
|
2026-06-21 04:36:58 +00:00
|
|
|
const parts: string[] = [];
|
|
|
|
|
if (days > 0) parts.push(`${days}d`);
|
|
|
|
|
if (hours > 0) parts.push(`${hours}h`);
|
|
|
|
|
if (minutes > 0 || parts.length === 0) parts.push(`${minutes}m`);
|
fix(proxmox): resolve 7 dashboard and AI chat issues
1. VM Actions: pass clusterId/clusters props from VMsPage to VMList;
rename node→node_id in 14 Rust Tauri command handlers to match
Tauri 2.x camelCase→snake_case mapping; wire action menu items
through handleAction so menu closes on click.
2. Migration: add Target Remote dropdown in MigrationDialog showing
available clusters for cross-datacenter migration; targetCluster
passed through to migrate_vm invoke.
3. Storage: switch list_proxmox_datastores to cluster/resources?type=storage
(single API call, cluster-wide); normalize plugintype→type,
disk/maxdisk→used/size, compute available via saturating_sub.
4. Network: replace free-text Interface Type Input with a Select
dropdown listing all PVE network interface types.
5. Firewall New Rule: add onNewRule prop to FirewallRuleList, wire
button; add full dialog in FirewallPage with action/protocol/
source/dest/port fields that calls add_firewall_rule; rewrite
Rust command to accept rule as serde_json::Value instead of
flat params (matches frontend invoke signature).
6. Backup: normalize raw PVE cluster/backup fields (id, storage,
node, schedule, enabled, next-run timestamp) to BackupJobInfo
shape; update BackupJobList columns to show storage, vmid, mode.
7. AI chat: merge all system prompt sections into a single system
message (fixes Qwen 3.5 / LiteLLM rejection of multiple system
messages); push assistant message with tool_calls before tool
result messages to satisfy OpenAI API contract.
2026-06-21 20:08:56 +00:00
|
|
|
|
2026-06-21 04:36:58 +00:00
|
|
|
return parts.join(' ');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function formatBytes(bytes: number): string {
|
|
|
|
|
if (bytes === 0) return '0 B';
|
|
|
|
|
const k = 1024;
|
|
|
|
|
const sizes = ['B', 'KB', 'MB', 'GB', 'TB'];
|
|
|
|
|
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
|
|
|
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
|
|
|
|
|
}
|
|
|
|
|
|
2026-06-11 14:38:36 +00:00
|
|
|
export function VMList({
|
2026-06-21 16:17:31 +00:00
|
|
|
vms: rawVms,
|
fix(proxmox): resolve 7 dashboard and AI chat issues
1. VM Actions: pass clusterId/clusters props from VMsPage to VMList;
rename node→node_id in 14 Rust Tauri command handlers to match
Tauri 2.x camelCase→snake_case mapping; wire action menu items
through handleAction so menu closes on click.
2. Migration: add Target Remote dropdown in MigrationDialog showing
available clusters for cross-datacenter migration; targetCluster
passed through to migrate_vm invoke.
3. Storage: switch list_proxmox_datastores to cluster/resources?type=storage
(single API call, cluster-wide); normalize plugintype→type,
disk/maxdisk→used/size, compute available via saturating_sub.
4. Network: replace free-text Interface Type Input with a Select
dropdown listing all PVE network interface types.
5. Firewall New Rule: add onNewRule prop to FirewallRuleList, wire
button; add full dialog in FirewallPage with action/protocol/
source/dest/port fields that calls add_firewall_rule; rewrite
Rust command to accept rule as serde_json::Value instead of
flat params (matches frontend invoke signature).
6. Backup: normalize raw PVE cluster/backup fields (id, storage,
node, schedule, enabled, next-run timestamp) to BackupJobInfo
shape; update BackupJobList columns to show storage, vmid, mode.
7. AI chat: merge all system prompt sections into a single system
message (fixes Qwen 3.5 / LiteLLM rejection of multiple system
messages); push assistant message with tool_calls before tool
result messages to satisfy OpenAI API contract.
2026-06-21 20:08:56 +00:00
|
|
|
clusterId,
|
|
|
|
|
clusters = [],
|
2026-06-11 14:38:36 +00:00
|
|
|
onRefresh,
|
|
|
|
|
isLoading,
|
fix(proxmox): resolve 7 dashboard and AI chat issues
1. VM Actions: pass clusterId/clusters props from VMsPage to VMList;
rename node→node_id in 14 Rust Tauri command handlers to match
Tauri 2.x camelCase→snake_case mapping; wire action menu items
through handleAction so menu closes on click.
2. Migration: add Target Remote dropdown in MigrationDialog showing
available clusters for cross-datacenter migration; targetCluster
passed through to migrate_vm invoke.
3. Storage: switch list_proxmox_datastores to cluster/resources?type=storage
(single API call, cluster-wide); normalize plugintype→type,
disk/maxdisk→used/size, compute available via saturating_sub.
4. Network: replace free-text Interface Type Input with a Select
dropdown listing all PVE network interface types.
5. Firewall New Rule: add onNewRule prop to FirewallRuleList, wire
button; add full dialog in FirewallPage with action/protocol/
source/dest/port fields that calls add_firewall_rule; rewrite
Rust command to accept rule as serde_json::Value instead of
flat params (matches frontend invoke signature).
6. Backup: normalize raw PVE cluster/backup fields (id, storage,
node, schedule, enabled, next-run timestamp) to BackupJobInfo
shape; update BackupJobList columns to show storage, vmid, mode.
7. AI chat: merge all system prompt sections into a single system
message (fixes Qwen 3.5 / LiteLLM rejection of multiple system
messages); push assistant message with tool_calls before tool
result messages to satisfy OpenAI API contract.
2026-06-21 20:08:56 +00:00
|
|
|
onSnapshotAction: _onSnapshotAction,
|
|
|
|
|
onMigrate: _onMigrate,
|
|
|
|
|
onClone: _onClone,
|
|
|
|
|
onDelete: _onDelete,
|
2026-06-11 14:38:36 +00:00
|
|
|
selectedVMs = new Set<string>(),
|
|
|
|
|
onToggleSelect,
|
|
|
|
|
}: VMListProps) {
|
2026-06-21 16:17:31 +00:00
|
|
|
const [migrationVM, setMigrationVM] = useState<VMInfo | null>(null);
|
|
|
|
|
const [targetNode, setTargetNode] = useState<string>('');
|
fix(proxmox): resolve 7 dashboard and AI chat issues
1. VM Actions: pass clusterId/clusters props from VMsPage to VMList;
rename node→node_id in 14 Rust Tauri command handlers to match
Tauri 2.x camelCase→snake_case mapping; wire action menu items
through handleAction so menu closes on click.
2. Migration: add Target Remote dropdown in MigrationDialog showing
available clusters for cross-datacenter migration; targetCluster
passed through to migrate_vm invoke.
3. Storage: switch list_proxmox_datastores to cluster/resources?type=storage
(single API call, cluster-wide); normalize plugintype→type,
disk/maxdisk→used/size, compute available via saturating_sub.
4. Network: replace free-text Interface Type Input with a Select
dropdown listing all PVE network interface types.
5. Firewall New Rule: add onNewRule prop to FirewallRuleList, wire
button; add full dialog in FirewallPage with action/protocol/
source/dest/port fields that calls add_firewall_rule; rewrite
Rust command to accept rule as serde_json::Value instead of
flat params (matches frontend invoke signature).
6. Backup: normalize raw PVE cluster/backup fields (id, storage,
node, schedule, enabled, next-run timestamp) to BackupJobInfo
shape; update BackupJobList columns to show storage, vmid, mode.
7. AI chat: merge all system prompt sections into a single system
message (fixes Qwen 3.5 / LiteLLM rejection of multiple system
messages); push assistant message with tool_calls before tool
result messages to satisfy OpenAI API contract.
2026-06-21 20:08:56 +00:00
|
|
|
const [targetCluster, setTargetCluster] = useState<string>('');
|
2026-06-21 16:17:31 +00:00
|
|
|
const [onlineMigration, setOnlineMigration] = useState(true);
|
|
|
|
|
const [maxDowntime, setMaxDowntime] = useState(30);
|
|
|
|
|
|
|
|
|
|
const vms: VMInfo[] = React.useMemo(() => {
|
|
|
|
|
return rawVms.map((vm) => ({
|
|
|
|
|
id: String(vm.id || vm.vmid),
|
|
|
|
|
vmid: vm.vmid || vm.id,
|
|
|
|
|
name: vm.name || `VM-${vm.vmid || vm.id}`,
|
|
|
|
|
node: vm.node || '',
|
|
|
|
|
status: (vm.status || 'stopped') as 'running' | 'stopped' | 'paused',
|
|
|
|
|
cpu: vm.cpu || 0,
|
|
|
|
|
memory: vm.mem || vm.memory || 0,
|
|
|
|
|
memoryTotal: vm.max_mem || vm.memoryTotal || 0,
|
|
|
|
|
disk: vm.disk || 0,
|
|
|
|
|
diskTotal: vm.max_disk || vm.diskTotal || 0,
|
|
|
|
|
uptime: vm.uptime,
|
|
|
|
|
tags: vm.tags,
|
|
|
|
|
}));
|
|
|
|
|
}, [rawVms]);
|
2026-06-21 04:36:58 +00:00
|
|
|
|
|
|
|
|
const handleVMAction = useCallback(async (vm: VMInfo, action: string) => {
|
fix(proxmox): resolve 7 dashboard and AI chat issues
1. VM Actions: pass clusterId/clusters props from VMsPage to VMList;
rename node→node_id in 14 Rust Tauri command handlers to match
Tauri 2.x camelCase→snake_case mapping; wire action menu items
through handleAction so menu closes on click.
2. Migration: add Target Remote dropdown in MigrationDialog showing
available clusters for cross-datacenter migration; targetCluster
passed through to migrate_vm invoke.
3. Storage: switch list_proxmox_datastores to cluster/resources?type=storage
(single API call, cluster-wide); normalize plugintype→type,
disk/maxdisk→used/size, compute available via saturating_sub.
4. Network: replace free-text Interface Type Input with a Select
dropdown listing all PVE network interface types.
5. Firewall New Rule: add onNewRule prop to FirewallRuleList, wire
button; add full dialog in FirewallPage with action/protocol/
source/dest/port fields that calls add_firewall_rule; rewrite
Rust command to accept rule as serde_json::Value instead of
flat params (matches frontend invoke signature).
6. Backup: normalize raw PVE cluster/backup fields (id, storage,
node, schedule, enabled, next-run timestamp) to BackupJobInfo
shape; update BackupJobList columns to show storage, vmid, mode.
7. AI chat: merge all system prompt sections into a single system
message (fixes Qwen 3.5 / LiteLLM rejection of multiple system
messages); push assistant message with tool_calls before tool
result messages to satisfy OpenAI API contract.
2026-06-21 20:08:56 +00:00
|
|
|
if (!clusterId) {
|
|
|
|
|
toast.error('No cluster selected');
|
|
|
|
|
return;
|
|
|
|
|
}
|
2026-06-21 04:36:58 +00:00
|
|
|
try {
|
|
|
|
|
switch (action) {
|
|
|
|
|
case 'start':
|
|
|
|
|
await invoke('start_proxmox_vm', {
|
|
|
|
|
clusterId,
|
|
|
|
|
nodeId: vm.node,
|
|
|
|
|
vmId: vm.vmid,
|
|
|
|
|
});
|
|
|
|
|
toast.success(`VM ${vm.name} started`);
|
|
|
|
|
onRefresh?.();
|
|
|
|
|
break;
|
|
|
|
|
case 'stop':
|
|
|
|
|
await invoke('stop_proxmox_vm', {
|
|
|
|
|
clusterId,
|
|
|
|
|
nodeId: vm.node,
|
|
|
|
|
vmId: vm.vmid,
|
|
|
|
|
});
|
|
|
|
|
toast.success(`VM ${vm.name} stopped`);
|
|
|
|
|
onRefresh?.();
|
|
|
|
|
break;
|
|
|
|
|
case 'reboot':
|
|
|
|
|
await invoke('reboot_proxmox_vm', {
|
|
|
|
|
clusterId,
|
|
|
|
|
nodeId: vm.node,
|
|
|
|
|
vmId: vm.vmid,
|
|
|
|
|
});
|
|
|
|
|
toast.success(`VM ${vm.name} rebooting`);
|
|
|
|
|
onRefresh?.();
|
|
|
|
|
break;
|
|
|
|
|
case 'shutdown':
|
|
|
|
|
await invoke('shutdown_proxmox_vm', {
|
|
|
|
|
clusterId,
|
|
|
|
|
nodeId: vm.node,
|
|
|
|
|
vmId: vm.vmid,
|
|
|
|
|
});
|
|
|
|
|
toast.success(`VM ${vm.name} shutting down`);
|
|
|
|
|
onRefresh?.();
|
|
|
|
|
break;
|
|
|
|
|
case 'resume':
|
|
|
|
|
await invoke('resume_proxmox_vm', {
|
|
|
|
|
clusterId,
|
|
|
|
|
nodeId: vm.node,
|
|
|
|
|
vmId: vm.vmid,
|
|
|
|
|
});
|
|
|
|
|
toast.success(`VM ${vm.name} resumed`);
|
|
|
|
|
onRefresh?.();
|
|
|
|
|
break;
|
|
|
|
|
case 'suspend':
|
|
|
|
|
await invoke('suspend_proxmox_vm', {
|
|
|
|
|
clusterId,
|
|
|
|
|
nodeId: vm.node,
|
|
|
|
|
vmId: vm.vmid,
|
|
|
|
|
});
|
|
|
|
|
toast.success(`VM ${vm.name} suspended`);
|
|
|
|
|
onRefresh?.();
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
toast.error(`Unknown action: ${action}`);
|
|
|
|
|
}
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error(`Failed to ${action} VM ${vm.name}:`, error);
|
|
|
|
|
toast.error(`Failed to ${action} VM ${vm.name}: ${error}`);
|
|
|
|
|
}
|
|
|
|
|
}, [clusterId, onRefresh]);
|
|
|
|
|
|
|
|
|
|
const handleSnapshotAction = useCallback((vm: VMInfo, action: 'create' | 'list' | 'rollback' | 'delete') => {
|
|
|
|
|
toast.info(`Snapshot ${action} for ${vm.name} - not yet implemented`);
|
|
|
|
|
}, []);
|
|
|
|
|
|
2026-06-21 16:17:31 +00:00
|
|
|
const handleMigrate = useCallback((vm: VMInfo) => {
|
|
|
|
|
setMigrationVM(vm);
|
|
|
|
|
const availableNodes = vms
|
|
|
|
|
.map((v) => v.node)
|
|
|
|
|
.filter((node, index, self) => self.indexOf(node) === index && node !== vm.node);
|
|
|
|
|
setTargetNode(availableNodes[0] || '');
|
fix(proxmox): resolve 7 dashboard and AI chat issues
1. VM Actions: pass clusterId/clusters props from VMsPage to VMList;
rename node→node_id in 14 Rust Tauri command handlers to match
Tauri 2.x camelCase→snake_case mapping; wire action menu items
through handleAction so menu closes on click.
2. Migration: add Target Remote dropdown in MigrationDialog showing
available clusters for cross-datacenter migration; targetCluster
passed through to migrate_vm invoke.
3. Storage: switch list_proxmox_datastores to cluster/resources?type=storage
(single API call, cluster-wide); normalize plugintype→type,
disk/maxdisk→used/size, compute available via saturating_sub.
4. Network: replace free-text Interface Type Input with a Select
dropdown listing all PVE network interface types.
5. Firewall New Rule: add onNewRule prop to FirewallRuleList, wire
button; add full dialog in FirewallPage with action/protocol/
source/dest/port fields that calls add_firewall_rule; rewrite
Rust command to accept rule as serde_json::Value instead of
flat params (matches frontend invoke signature).
6. Backup: normalize raw PVE cluster/backup fields (id, storage,
node, schedule, enabled, next-run timestamp) to BackupJobInfo
shape; update BackupJobList columns to show storage, vmid, mode.
7. AI chat: merge all system prompt sections into a single system
message (fixes Qwen 3.5 / LiteLLM rejection of multiple system
messages); push assistant message with tool_calls before tool
result messages to satisfy OpenAI API contract.
2026-06-21 20:08:56 +00:00
|
|
|
setTargetCluster(clusterId);
|
|
|
|
|
}, [vms, clusterId]);
|
2026-06-21 04:36:58 +00:00
|
|
|
|
2026-06-21 16:17:31 +00:00
|
|
|
const submitMigration = useCallback(async () => {
|
|
|
|
|
if (!migrationVM || !targetNode) {
|
|
|
|
|
toast.error('Please select a target node');
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
fix(proxmox): resolve 7 dashboard and AI chat issues
1. VM Actions: pass clusterId/clusters props from VMsPage to VMList;
rename node→node_id in 14 Rust Tauri command handlers to match
Tauri 2.x camelCase→snake_case mapping; wire action menu items
through handleAction so menu closes on click.
2. Migration: add Target Remote dropdown in MigrationDialog showing
available clusters for cross-datacenter migration; targetCluster
passed through to migrate_vm invoke.
3. Storage: switch list_proxmox_datastores to cluster/resources?type=storage
(single API call, cluster-wide); normalize plugintype→type,
disk/maxdisk→used/size, compute available via saturating_sub.
4. Network: replace free-text Interface Type Input with a Select
dropdown listing all PVE network interface types.
5. Firewall New Rule: add onNewRule prop to FirewallRuleList, wire
button; add full dialog in FirewallPage with action/protocol/
source/dest/port fields that calls add_firewall_rule; rewrite
Rust command to accept rule as serde_json::Value instead of
flat params (matches frontend invoke signature).
6. Backup: normalize raw PVE cluster/backup fields (id, storage,
node, schedule, enabled, next-run timestamp) to BackupJobInfo
shape; update BackupJobList columns to show storage, vmid, mode.
7. AI chat: merge all system prompt sections into a single system
message (fixes Qwen 3.5 / LiteLLM rejection of multiple system
messages); push assistant message with tool_calls before tool
result messages to satisfy OpenAI API contract.
2026-06-21 20:08:56 +00:00
|
|
|
const sourceCluster = clusterId;
|
|
|
|
|
const destCluster = targetCluster || clusterId;
|
|
|
|
|
|
2026-06-21 16:17:31 +00:00
|
|
|
try {
|
2026-06-21 04:36:58 +00:00
|
|
|
await invoke('migrate_vm', {
|
fix(proxmox): resolve 7 dashboard and AI chat issues
1. VM Actions: pass clusterId/clusters props from VMsPage to VMList;
rename node→node_id in 14 Rust Tauri command handlers to match
Tauri 2.x camelCase→snake_case mapping; wire action menu items
through handleAction so menu closes on click.
2. Migration: add Target Remote dropdown in MigrationDialog showing
available clusters for cross-datacenter migration; targetCluster
passed through to migrate_vm invoke.
3. Storage: switch list_proxmox_datastores to cluster/resources?type=storage
(single API call, cluster-wide); normalize plugintype→type,
disk/maxdisk→used/size, compute available via saturating_sub.
4. Network: replace free-text Interface Type Input with a Select
dropdown listing all PVE network interface types.
5. Firewall New Rule: add onNewRule prop to FirewallRuleList, wire
button; add full dialog in FirewallPage with action/protocol/
source/dest/port fields that calls add_firewall_rule; rewrite
Rust command to accept rule as serde_json::Value instead of
flat params (matches frontend invoke signature).
6. Backup: normalize raw PVE cluster/backup fields (id, storage,
node, schedule, enabled, next-run timestamp) to BackupJobInfo
shape; update BackupJobList columns to show storage, vmid, mode.
7. AI chat: merge all system prompt sections into a single system
message (fixes Qwen 3.5 / LiteLLM rejection of multiple system
messages); push assistant message with tool_calls before tool
result messages to satisfy OpenAI API contract.
2026-06-21 20:08:56 +00:00
|
|
|
clusterId: sourceCluster,
|
2026-06-21 16:17:31 +00:00
|
|
|
nodeId: migrationVM.node,
|
|
|
|
|
vmId: migrationVM.vmid,
|
2026-06-21 04:36:58 +00:00
|
|
|
targetNode,
|
fix(proxmox): resolve 7 dashboard and AI chat issues
1. VM Actions: pass clusterId/clusters props from VMsPage to VMList;
rename node→node_id in 14 Rust Tauri command handlers to match
Tauri 2.x camelCase→snake_case mapping; wire action menu items
through handleAction so menu closes on click.
2. Migration: add Target Remote dropdown in MigrationDialog showing
available clusters for cross-datacenter migration; targetCluster
passed through to migrate_vm invoke.
3. Storage: switch list_proxmox_datastores to cluster/resources?type=storage
(single API call, cluster-wide); normalize plugintype→type,
disk/maxdisk→used/size, compute available via saturating_sub.
4. Network: replace free-text Interface Type Input with a Select
dropdown listing all PVE network interface types.
5. Firewall New Rule: add onNewRule prop to FirewallRuleList, wire
button; add full dialog in FirewallPage with action/protocol/
source/dest/port fields that calls add_firewall_rule; rewrite
Rust command to accept rule as serde_json::Value instead of
flat params (matches frontend invoke signature).
6. Backup: normalize raw PVE cluster/backup fields (id, storage,
node, schedule, enabled, next-run timestamp) to BackupJobInfo
shape; update BackupJobList columns to show storage, vmid, mode.
7. AI chat: merge all system prompt sections into a single system
message (fixes Qwen 3.5 / LiteLLM rejection of multiple system
messages); push assistant message with tool_calls before tool
result messages to satisfy OpenAI API contract.
2026-06-21 20:08:56 +00:00
|
|
|
targetCluster: destCluster,
|
2026-06-21 04:36:58 +00:00
|
|
|
});
|
fix(proxmox): resolve 7 dashboard and AI chat issues
1. VM Actions: pass clusterId/clusters props from VMsPage to VMList;
rename node→node_id in 14 Rust Tauri command handlers to match
Tauri 2.x camelCase→snake_case mapping; wire action menu items
through handleAction so menu closes on click.
2. Migration: add Target Remote dropdown in MigrationDialog showing
available clusters for cross-datacenter migration; targetCluster
passed through to migrate_vm invoke.
3. Storage: switch list_proxmox_datastores to cluster/resources?type=storage
(single API call, cluster-wide); normalize plugintype→type,
disk/maxdisk→used/size, compute available via saturating_sub.
4. Network: replace free-text Interface Type Input with a Select
dropdown listing all PVE network interface types.
5. Firewall New Rule: add onNewRule prop to FirewallRuleList, wire
button; add full dialog in FirewallPage with action/protocol/
source/dest/port fields that calls add_firewall_rule; rewrite
Rust command to accept rule as serde_json::Value instead of
flat params (matches frontend invoke signature).
6. Backup: normalize raw PVE cluster/backup fields (id, storage,
node, schedule, enabled, next-run timestamp) to BackupJobInfo
shape; update BackupJobList columns to show storage, vmid, mode.
7. AI chat: merge all system prompt sections into a single system
message (fixes Qwen 3.5 / LiteLLM rejection of multiple system
messages); push assistant message with tool_calls before tool
result messages to satisfy OpenAI API contract.
2026-06-21 20:08:56 +00:00
|
|
|
|
|
|
|
|
toast.success(`VM ${migrationVM.name} migration started to ${targetNode}${destCluster !== sourceCluster ? ` (cluster: ${destCluster})` : ''}`);
|
2026-06-21 16:17:31 +00:00
|
|
|
setMigrationVM(null);
|
|
|
|
|
setTargetNode('');
|
fix(proxmox): resolve 7 dashboard and AI chat issues
1. VM Actions: pass clusterId/clusters props from VMsPage to VMList;
rename node→node_id in 14 Rust Tauri command handlers to match
Tauri 2.x camelCase→snake_case mapping; wire action menu items
through handleAction so menu closes on click.
2. Migration: add Target Remote dropdown in MigrationDialog showing
available clusters for cross-datacenter migration; targetCluster
passed through to migrate_vm invoke.
3. Storage: switch list_proxmox_datastores to cluster/resources?type=storage
(single API call, cluster-wide); normalize plugintype→type,
disk/maxdisk→used/size, compute available via saturating_sub.
4. Network: replace free-text Interface Type Input with a Select
dropdown listing all PVE network interface types.
5. Firewall New Rule: add onNewRule prop to FirewallRuleList, wire
button; add full dialog in FirewallPage with action/protocol/
source/dest/port fields that calls add_firewall_rule; rewrite
Rust command to accept rule as serde_json::Value instead of
flat params (matches frontend invoke signature).
6. Backup: normalize raw PVE cluster/backup fields (id, storage,
node, schedule, enabled, next-run timestamp) to BackupJobInfo
shape; update BackupJobList columns to show storage, vmid, mode.
7. AI chat: merge all system prompt sections into a single system
message (fixes Qwen 3.5 / LiteLLM rejection of multiple system
messages); push assistant message with tool_calls before tool
result messages to satisfy OpenAI API contract.
2026-06-21 20:08:56 +00:00
|
|
|
setTargetCluster('');
|
2026-06-21 04:36:58 +00:00
|
|
|
onRefresh?.();
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error('Failed to migrate VM:', error);
|
2026-06-21 16:17:31 +00:00
|
|
|
toast.error(`Failed to migrate VM ${migrationVM.name}: ${error}`);
|
2026-06-21 04:36:58 +00:00
|
|
|
}
|
fix(proxmox): resolve 7 dashboard and AI chat issues
1. VM Actions: pass clusterId/clusters props from VMsPage to VMList;
rename node→node_id in 14 Rust Tauri command handlers to match
Tauri 2.x camelCase→snake_case mapping; wire action menu items
through handleAction so menu closes on click.
2. Migration: add Target Remote dropdown in MigrationDialog showing
available clusters for cross-datacenter migration; targetCluster
passed through to migrate_vm invoke.
3. Storage: switch list_proxmox_datastores to cluster/resources?type=storage
(single API call, cluster-wide); normalize plugintype→type,
disk/maxdisk→used/size, compute available via saturating_sub.
4. Network: replace free-text Interface Type Input with a Select
dropdown listing all PVE network interface types.
5. Firewall New Rule: add onNewRule prop to FirewallRuleList, wire
button; add full dialog in FirewallPage with action/protocol/
source/dest/port fields that calls add_firewall_rule; rewrite
Rust command to accept rule as serde_json::Value instead of
flat params (matches frontend invoke signature).
6. Backup: normalize raw PVE cluster/backup fields (id, storage,
node, schedule, enabled, next-run timestamp) to BackupJobInfo
shape; update BackupJobList columns to show storage, vmid, mode.
7. AI chat: merge all system prompt sections into a single system
message (fixes Qwen 3.5 / LiteLLM rejection of multiple system
messages); push assistant message with tool_calls before tool
result messages to satisfy OpenAI API contract.
2026-06-21 20:08:56 +00:00
|
|
|
}, [migrationVM, targetNode, targetCluster, clusterId, onRefresh]);
|
2026-06-21 04:36:58 +00:00
|
|
|
|
|
|
|
|
const handleClone = useCallback(async (vm: VMInfo) => {
|
fix(proxmox): resolve 7 dashboard and AI chat issues
1. VM Actions: pass clusterId/clusters props from VMsPage to VMList;
rename node→node_id in 14 Rust Tauri command handlers to match
Tauri 2.x camelCase→snake_case mapping; wire action menu items
through handleAction so menu closes on click.
2. Migration: add Target Remote dropdown in MigrationDialog showing
available clusters for cross-datacenter migration; targetCluster
passed through to migrate_vm invoke.
3. Storage: switch list_proxmox_datastores to cluster/resources?type=storage
(single API call, cluster-wide); normalize plugintype→type,
disk/maxdisk→used/size, compute available via saturating_sub.
4. Network: replace free-text Interface Type Input with a Select
dropdown listing all PVE network interface types.
5. Firewall New Rule: add onNewRule prop to FirewallRuleList, wire
button; add full dialog in FirewallPage with action/protocol/
source/dest/port fields that calls add_firewall_rule; rewrite
Rust command to accept rule as serde_json::Value instead of
flat params (matches frontend invoke signature).
6. Backup: normalize raw PVE cluster/backup fields (id, storage,
node, schedule, enabled, next-run timestamp) to BackupJobInfo
shape; update BackupJobList columns to show storage, vmid, mode.
7. AI chat: merge all system prompt sections into a single system
message (fixes Qwen 3.5 / LiteLLM rejection of multiple system
messages); push assistant message with tool_calls before tool
result messages to satisfy OpenAI API contract.
2026-06-21 20:08:56 +00:00
|
|
|
if (!clusterId) {
|
|
|
|
|
toast.error('No cluster selected');
|
|
|
|
|
return;
|
|
|
|
|
}
|
2026-06-21 04:36:58 +00:00
|
|
|
try {
|
2026-06-21 16:17:31 +00:00
|
|
|
const nextVmid = Math.max(...vms.map((v) => v.vmid), 100) + 1;
|
|
|
|
|
const newVmidStr = window.prompt(`Enter new VM ID for ${vm.name}:`, `${nextVmid}`);
|
2026-06-21 14:38:10 +00:00
|
|
|
if (!newVmidStr) {
|
|
|
|
|
toast.info('Clone cancelled');
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
const newVmid = parseInt(newVmidStr);
|
2026-06-21 16:17:31 +00:00
|
|
|
if (isNaN(newVmid) || newVmid < 100) {
|
|
|
|
|
toast.error('Invalid VM ID. Must be >= 100');
|
|
|
|
|
return;
|
|
|
|
|
}
|
2026-06-21 14:38:10 +00:00
|
|
|
const newName = window.prompt(`Enter name for cloned VM:`, `${vm.name}-clone`);
|
|
|
|
|
if (!newName) {
|
|
|
|
|
toast.info('Clone cancelled');
|
|
|
|
|
return;
|
|
|
|
|
}
|
fix(proxmox): resolve 7 dashboard and AI chat issues
1. VM Actions: pass clusterId/clusters props from VMsPage to VMList;
rename node→node_id in 14 Rust Tauri command handlers to match
Tauri 2.x camelCase→snake_case mapping; wire action menu items
through handleAction so menu closes on click.
2. Migration: add Target Remote dropdown in MigrationDialog showing
available clusters for cross-datacenter migration; targetCluster
passed through to migrate_vm invoke.
3. Storage: switch list_proxmox_datastores to cluster/resources?type=storage
(single API call, cluster-wide); normalize plugintype→type,
disk/maxdisk→used/size, compute available via saturating_sub.
4. Network: replace free-text Interface Type Input with a Select
dropdown listing all PVE network interface types.
5. Firewall New Rule: add onNewRule prop to FirewallRuleList, wire
button; add full dialog in FirewallPage with action/protocol/
source/dest/port fields that calls add_firewall_rule; rewrite
Rust command to accept rule as serde_json::Value instead of
flat params (matches frontend invoke signature).
6. Backup: normalize raw PVE cluster/backup fields (id, storage,
node, schedule, enabled, next-run timestamp) to BackupJobInfo
shape; update BackupJobList columns to show storage, vmid, mode.
7. AI chat: merge all system prompt sections into a single system
message (fixes Qwen 3.5 / LiteLLM rejection of multiple system
messages); push assistant message with tool_calls before tool
result messages to satisfy OpenAI API contract.
2026-06-21 20:08:56 +00:00
|
|
|
|
2026-06-21 04:36:58 +00:00
|
|
|
await invoke('clone_vm', {
|
|
|
|
|
clusterId,
|
|
|
|
|
nodeId: vm.node,
|
|
|
|
|
vmId: vm.vmid,
|
|
|
|
|
newVmid,
|
2026-06-21 16:17:31 +00:00
|
|
|
name: newName,
|
2026-06-21 04:36:58 +00:00
|
|
|
});
|
fix(proxmox): resolve 7 dashboard and AI chat issues
1. VM Actions: pass clusterId/clusters props from VMsPage to VMList;
rename node→node_id in 14 Rust Tauri command handlers to match
Tauri 2.x camelCase→snake_case mapping; wire action menu items
through handleAction so menu closes on click.
2. Migration: add Target Remote dropdown in MigrationDialog showing
available clusters for cross-datacenter migration; targetCluster
passed through to migrate_vm invoke.
3. Storage: switch list_proxmox_datastores to cluster/resources?type=storage
(single API call, cluster-wide); normalize plugintype→type,
disk/maxdisk→used/size, compute available via saturating_sub.
4. Network: replace free-text Interface Type Input with a Select
dropdown listing all PVE network interface types.
5. Firewall New Rule: add onNewRule prop to FirewallRuleList, wire
button; add full dialog in FirewallPage with action/protocol/
source/dest/port fields that calls add_firewall_rule; rewrite
Rust command to accept rule as serde_json::Value instead of
flat params (matches frontend invoke signature).
6. Backup: normalize raw PVE cluster/backup fields (id, storage,
node, schedule, enabled, next-run timestamp) to BackupJobInfo
shape; update BackupJobList columns to show storage, vmid, mode.
7. AI chat: merge all system prompt sections into a single system
message (fixes Qwen 3.5 / LiteLLM rejection of multiple system
messages); push assistant message with tool_calls before tool
result messages to satisfy OpenAI API contract.
2026-06-21 20:08:56 +00:00
|
|
|
|
2026-06-21 16:17:31 +00:00
|
|
|
toast.success(`VM ${vm.name} cloned successfully to VM ${newVmid}`);
|
2026-06-21 04:36:58 +00:00
|
|
|
onRefresh?.();
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error('Failed to clone VM:', error);
|
|
|
|
|
toast.error(`Failed to clone VM ${vm.name}: ${error}`);
|
|
|
|
|
}
|
2026-06-21 16:17:31 +00:00
|
|
|
}, [clusterId, vms, onRefresh]);
|
2026-06-21 04:36:58 +00:00
|
|
|
|
|
|
|
|
const handleDelete = useCallback(async (vm: VMInfo) => {
|
fix(proxmox): resolve 7 dashboard and AI chat issues
1. VM Actions: pass clusterId/clusters props from VMsPage to VMList;
rename node→node_id in 14 Rust Tauri command handlers to match
Tauri 2.x camelCase→snake_case mapping; wire action menu items
through handleAction so menu closes on click.
2. Migration: add Target Remote dropdown in MigrationDialog showing
available clusters for cross-datacenter migration; targetCluster
passed through to migrate_vm invoke.
3. Storage: switch list_proxmox_datastores to cluster/resources?type=storage
(single API call, cluster-wide); normalize plugintype→type,
disk/maxdisk→used/size, compute available via saturating_sub.
4. Network: replace free-text Interface Type Input with a Select
dropdown listing all PVE network interface types.
5. Firewall New Rule: add onNewRule prop to FirewallRuleList, wire
button; add full dialog in FirewallPage with action/protocol/
source/dest/port fields that calls add_firewall_rule; rewrite
Rust command to accept rule as serde_json::Value instead of
flat params (matches frontend invoke signature).
6. Backup: normalize raw PVE cluster/backup fields (id, storage,
node, schedule, enabled, next-run timestamp) to BackupJobInfo
shape; update BackupJobList columns to show storage, vmid, mode.
7. AI chat: merge all system prompt sections into a single system
message (fixes Qwen 3.5 / LiteLLM rejection of multiple system
messages); push assistant message with tool_calls before tool
result messages to satisfy OpenAI API contract.
2026-06-21 20:08:56 +00:00
|
|
|
if (!clusterId) {
|
|
|
|
|
toast.error('No cluster selected');
|
|
|
|
|
return;
|
|
|
|
|
}
|
2026-06-21 16:17:31 +00:00
|
|
|
const confirmed = await confirm(`Are you sure you want to delete VM ${vm.name} (VMID: ${vm.vmid})? This action cannot be undone!`, {
|
|
|
|
|
title: 'Delete VM',
|
|
|
|
|
kind: 'warning',
|
|
|
|
|
});
|
fix(proxmox): resolve 7 dashboard and AI chat issues
1. VM Actions: pass clusterId/clusters props from VMsPage to VMList;
rename node→node_id in 14 Rust Tauri command handlers to match
Tauri 2.x camelCase→snake_case mapping; wire action menu items
through handleAction so menu closes on click.
2. Migration: add Target Remote dropdown in MigrationDialog showing
available clusters for cross-datacenter migration; targetCluster
passed through to migrate_vm invoke.
3. Storage: switch list_proxmox_datastores to cluster/resources?type=storage
(single API call, cluster-wide); normalize plugintype→type,
disk/maxdisk→used/size, compute available via saturating_sub.
4. Network: replace free-text Interface Type Input with a Select
dropdown listing all PVE network interface types.
5. Firewall New Rule: add onNewRule prop to FirewallRuleList, wire
button; add full dialog in FirewallPage with action/protocol/
source/dest/port fields that calls add_firewall_rule; rewrite
Rust command to accept rule as serde_json::Value instead of
flat params (matches frontend invoke signature).
6. Backup: normalize raw PVE cluster/backup fields (id, storage,
node, schedule, enabled, next-run timestamp) to BackupJobInfo
shape; update BackupJobList columns to show storage, vmid, mode.
7. AI chat: merge all system prompt sections into a single system
message (fixes Qwen 3.5 / LiteLLM rejection of multiple system
messages); push assistant message with tool_calls before tool
result messages to satisfy OpenAI API contract.
2026-06-21 20:08:56 +00:00
|
|
|
|
2026-06-21 16:17:31 +00:00
|
|
|
if (!confirmed) {
|
2026-06-21 04:36:58 +00:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
await invoke('delete_vm', {
|
|
|
|
|
clusterId,
|
|
|
|
|
nodeId: vm.node,
|
|
|
|
|
vmId: vm.vmid,
|
|
|
|
|
});
|
fix(proxmox): resolve 7 dashboard and AI chat issues
1. VM Actions: pass clusterId/clusters props from VMsPage to VMList;
rename node→node_id in 14 Rust Tauri command handlers to match
Tauri 2.x camelCase→snake_case mapping; wire action menu items
through handleAction so menu closes on click.
2. Migration: add Target Remote dropdown in MigrationDialog showing
available clusters for cross-datacenter migration; targetCluster
passed through to migrate_vm invoke.
3. Storage: switch list_proxmox_datastores to cluster/resources?type=storage
(single API call, cluster-wide); normalize plugintype→type,
disk/maxdisk→used/size, compute available via saturating_sub.
4. Network: replace free-text Interface Type Input with a Select
dropdown listing all PVE network interface types.
5. Firewall New Rule: add onNewRule prop to FirewallRuleList, wire
button; add full dialog in FirewallPage with action/protocol/
source/dest/port fields that calls add_firewall_rule; rewrite
Rust command to accept rule as serde_json::Value instead of
flat params (matches frontend invoke signature).
6. Backup: normalize raw PVE cluster/backup fields (id, storage,
node, schedule, enabled, next-run timestamp) to BackupJobInfo
shape; update BackupJobList columns to show storage, vmid, mode.
7. AI chat: merge all system prompt sections into a single system
message (fixes Qwen 3.5 / LiteLLM rejection of multiple system
messages); push assistant message with tool_calls before tool
result messages to satisfy OpenAI API contract.
2026-06-21 20:08:56 +00:00
|
|
|
|
2026-06-21 16:17:31 +00:00
|
|
|
toast.success(`VM ${vm.name} deleted successfully`);
|
2026-06-21 04:36:58 +00:00
|
|
|
onRefresh?.();
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error('Failed to delete VM:', error);
|
|
|
|
|
toast.error(`Failed to delete VM ${vm.name}: ${error}`);
|
|
|
|
|
}
|
|
|
|
|
}, [clusterId, onRefresh]);
|
|
|
|
|
|
2026-06-11 14:38:36 +00:00
|
|
|
return (
|
|
|
|
|
<Card>
|
|
|
|
|
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
|
|
|
|
|
<CardTitle>Virtual Machines</CardTitle>
|
|
|
|
|
<div className="flex space-x-2">
|
|
|
|
|
<Button variant="outline" size="sm" onClick={onRefresh} disabled={isLoading}>
|
|
|
|
|
Refresh
|
|
|
|
|
</Button>
|
|
|
|
|
</div>
|
|
|
|
|
</CardHeader>
|
|
|
|
|
<CardContent>
|
|
|
|
|
<div className="overflow-auto">
|
|
|
|
|
<Table>
|
|
|
|
|
<TableHeader>
|
|
|
|
|
<TableRow>
|
|
|
|
|
<TableHead className="w-[40px]">
|
|
|
|
|
<Checkbox
|
fix(proxmox): resolve 7 dashboard and AI chat issues
1. VM Actions: pass clusterId/clusters props from VMsPage to VMList;
rename node→node_id in 14 Rust Tauri command handlers to match
Tauri 2.x camelCase→snake_case mapping; wire action menu items
through handleAction so menu closes on click.
2. Migration: add Target Remote dropdown in MigrationDialog showing
available clusters for cross-datacenter migration; targetCluster
passed through to migrate_vm invoke.
3. Storage: switch list_proxmox_datastores to cluster/resources?type=storage
(single API call, cluster-wide); normalize plugintype→type,
disk/maxdisk→used/size, compute available via saturating_sub.
4. Network: replace free-text Interface Type Input with a Select
dropdown listing all PVE network interface types.
5. Firewall New Rule: add onNewRule prop to FirewallRuleList, wire
button; add full dialog in FirewallPage with action/protocol/
source/dest/port fields that calls add_firewall_rule; rewrite
Rust command to accept rule as serde_json::Value instead of
flat params (matches frontend invoke signature).
6. Backup: normalize raw PVE cluster/backup fields (id, storage,
node, schedule, enabled, next-run timestamp) to BackupJobInfo
shape; update BackupJobList columns to show storage, vmid, mode.
7. AI chat: merge all system prompt sections into a single system
message (fixes Qwen 3.5 / LiteLLM rejection of multiple system
messages); push assistant message with tool_calls before tool
result messages to satisfy OpenAI API contract.
2026-06-21 20:08:56 +00:00
|
|
|
checked={vms.length > 0 && vms.every((vm) => selectedVMs.has(vm.id))}
|
2026-06-11 14:38:36 +00:00
|
|
|
onCheckedChange={(checked) => {
|
|
|
|
|
if (checked) {
|
|
|
|
|
vms.forEach((vm) => selectedVMs.add(vm.id));
|
|
|
|
|
} else {
|
|
|
|
|
vms.forEach((vm) => selectedVMs.delete(vm.id));
|
|
|
|
|
}
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
</TableHead>
|
|
|
|
|
<TableHead>Name</TableHead>
|
|
|
|
|
<TableHead>VM ID</TableHead>
|
|
|
|
|
<TableHead>Node</TableHead>
|
|
|
|
|
<TableHead>Status</TableHead>
|
|
|
|
|
<TableHead>CPU</TableHead>
|
|
|
|
|
<TableHead>Memory</TableHead>
|
|
|
|
|
<TableHead>Disk</TableHead>
|
|
|
|
|
<TableHead>Uptime</TableHead>
|
|
|
|
|
<TableHead className="text-right">Actions</TableHead>
|
|
|
|
|
</TableRow>
|
|
|
|
|
</TableHeader>
|
|
|
|
|
<TableBody>
|
2026-06-21 04:36:58 +00:00
|
|
|
{vms.map((vm) => {
|
|
|
|
|
const cpuPercent = vm.cpu > 0 ? Math.min(vm.cpu * 100, 100) : 0;
|
|
|
|
|
const memoryPercent = vm.memoryTotal > 0 ? (vm.memory / vm.memoryTotal) * 100 : 0;
|
|
|
|
|
const diskPercent = vm.diskTotal > 0 ? (vm.disk / vm.diskTotal) * 100 : 0;
|
fix(proxmox): resolve 7 dashboard and AI chat issues
1. VM Actions: pass clusterId/clusters props from VMsPage to VMList;
rename node→node_id in 14 Rust Tauri command handlers to match
Tauri 2.x camelCase→snake_case mapping; wire action menu items
through handleAction so menu closes on click.
2. Migration: add Target Remote dropdown in MigrationDialog showing
available clusters for cross-datacenter migration; targetCluster
passed through to migrate_vm invoke.
3. Storage: switch list_proxmox_datastores to cluster/resources?type=storage
(single API call, cluster-wide); normalize plugintype→type,
disk/maxdisk→used/size, compute available via saturating_sub.
4. Network: replace free-text Interface Type Input with a Select
dropdown listing all PVE network interface types.
5. Firewall New Rule: add onNewRule prop to FirewallRuleList, wire
button; add full dialog in FirewallPage with action/protocol/
source/dest/port fields that calls add_firewall_rule; rewrite
Rust command to accept rule as serde_json::Value instead of
flat params (matches frontend invoke signature).
6. Backup: normalize raw PVE cluster/backup fields (id, storage,
node, schedule, enabled, next-run timestamp) to BackupJobInfo
shape; update BackupJobList columns to show storage, vmid, mode.
7. AI chat: merge all system prompt sections into a single system
message (fixes Qwen 3.5 / LiteLLM rejection of multiple system
messages); push assistant message with tool_calls before tool
result messages to satisfy OpenAI API contract.
2026-06-21 20:08:56 +00:00
|
|
|
|
2026-06-21 04:36:58 +00:00
|
|
|
return (
|
|
|
|
|
<TableRow key={vm.id}>
|
|
|
|
|
<TableCell>
|
|
|
|
|
<Checkbox
|
|
|
|
|
checked={selectedVMs.has(vm.id)}
|
|
|
|
|
onCheckedChange={() => onToggleSelect?.(vm)}
|
|
|
|
|
/>
|
|
|
|
|
</TableCell>
|
|
|
|
|
<TableCell className="font-medium">{vm.name}</TableCell>
|
|
|
|
|
<TableCell>{vm.vmid}</TableCell>
|
|
|
|
|
<TableCell>{vm.node}</TableCell>
|
|
|
|
|
<TableCell>
|
|
|
|
|
<span className={`inline-flex items-center rounded-full px-2 py-1 text-xs font-medium ${
|
|
|
|
|
vm.status === 'running' ? 'bg-green-100 text-green-800' :
|
|
|
|
|
vm.status === 'stopped' ? 'bg-red-100 text-red-800' :
|
|
|
|
|
'bg-yellow-100 text-yellow-800'
|
|
|
|
|
}`}>
|
|
|
|
|
{vm.status}
|
|
|
|
|
</span>
|
|
|
|
|
</TableCell>
|
|
|
|
|
<TableCell>{cpuPercent.toFixed(2)}%</TableCell>
|
|
|
|
|
<TableCell>
|
|
|
|
|
{vm.memoryTotal > 0 ? (
|
|
|
|
|
<div className="flex items-center gap-2">
|
|
|
|
|
<div className="flex-1 h-2 bg-gray-200 rounded-full overflow-hidden">
|
|
|
|
|
<div
|
|
|
|
|
className="h-full bg-blue-500"
|
|
|
|
|
style={{ width: `${memoryPercent}%` }}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
<span className="text-xs text-muted-foreground">
|
|
|
|
|
{formatBytes(vm.memory)} / {formatBytes(vm.memoryTotal)}
|
|
|
|
|
</span>
|
|
|
|
|
</div>
|
|
|
|
|
) : (
|
|
|
|
|
<span className="text-muted-foreground">-</span>
|
|
|
|
|
)}
|
|
|
|
|
</TableCell>
|
|
|
|
|
<TableCell>
|
|
|
|
|
{vm.diskTotal > 0 ? (
|
|
|
|
|
<div className="flex items-center gap-2">
|
|
|
|
|
<div className="flex-1 h-2 bg-gray-200 rounded-full overflow-hidden">
|
|
|
|
|
<div
|
|
|
|
|
className="h-full bg-green-500"
|
|
|
|
|
style={{ width: `${diskPercent}%` }}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
<span className="text-xs text-muted-foreground">
|
|
|
|
|
{formatBytes(vm.disk)} / {formatBytes(vm.diskTotal)}
|
|
|
|
|
</span>
|
|
|
|
|
</div>
|
|
|
|
|
) : (
|
|
|
|
|
<span className="text-muted-foreground">-</span>
|
|
|
|
|
)}
|
|
|
|
|
</TableCell>
|
|
|
|
|
<TableCell>{formatUptime(vm.uptime || 0)}</TableCell>
|
|
|
|
|
<TableCell className="text-right">
|
2026-06-11 14:38:36 +00:00
|
|
|
<VMActionMenu
|
|
|
|
|
vm={vm}
|
2026-06-21 04:36:58 +00:00
|
|
|
onVMAction={handleVMAction}
|
|
|
|
|
onSnapshotAction={handleSnapshotAction}
|
|
|
|
|
onMigrate={handleMigrate}
|
|
|
|
|
onClone={handleClone}
|
|
|
|
|
onDelete={handleDelete}
|
2026-06-11 14:38:36 +00:00
|
|
|
/>
|
2026-06-21 04:36:58 +00:00
|
|
|
</TableCell>
|
|
|
|
|
</TableRow>
|
|
|
|
|
);
|
|
|
|
|
})}
|
2026-06-11 14:38:36 +00:00
|
|
|
</TableBody>
|
|
|
|
|
</Table>
|
|
|
|
|
</div>
|
|
|
|
|
</CardContent>
|
2026-06-21 16:17:31 +00:00
|
|
|
|
|
|
|
|
<MigrationDialog
|
|
|
|
|
vm={migrationVM}
|
|
|
|
|
isOpen={!!migrationVM}
|
fix(proxmox): resolve 7 dashboard and AI chat issues
1. VM Actions: pass clusterId/clusters props from VMsPage to VMList;
rename node→node_id in 14 Rust Tauri command handlers to match
Tauri 2.x camelCase→snake_case mapping; wire action menu items
through handleAction so menu closes on click.
2. Migration: add Target Remote dropdown in MigrationDialog showing
available clusters for cross-datacenter migration; targetCluster
passed through to migrate_vm invoke.
3. Storage: switch list_proxmox_datastores to cluster/resources?type=storage
(single API call, cluster-wide); normalize plugintype→type,
disk/maxdisk→used/size, compute available via saturating_sub.
4. Network: replace free-text Interface Type Input with a Select
dropdown listing all PVE network interface types.
5. Firewall New Rule: add onNewRule prop to FirewallRuleList, wire
button; add full dialog in FirewallPage with action/protocol/
source/dest/port fields that calls add_firewall_rule; rewrite
Rust command to accept rule as serde_json::Value instead of
flat params (matches frontend invoke signature).
6. Backup: normalize raw PVE cluster/backup fields (id, storage,
node, schedule, enabled, next-run timestamp) to BackupJobInfo
shape; update BackupJobList columns to show storage, vmid, mode.
7. AI chat: merge all system prompt sections into a single system
message (fixes Qwen 3.5 / LiteLLM rejection of multiple system
messages); push assistant message with tool_calls before tool
result messages to satisfy OpenAI API contract.
2026-06-21 20:08:56 +00:00
|
|
|
onClose={() => { setMigrationVM(null); setTargetNode(''); setTargetCluster(''); }}
|
2026-06-21 16:17:31 +00:00
|
|
|
onSubmit={submitMigration}
|
|
|
|
|
availableNodes={vms}
|
fix(proxmox): resolve 7 dashboard and AI chat issues
1. VM Actions: pass clusterId/clusters props from VMsPage to VMList;
rename node→node_id in 14 Rust Tauri command handlers to match
Tauri 2.x camelCase→snake_case mapping; wire action menu items
through handleAction so menu closes on click.
2. Migration: add Target Remote dropdown in MigrationDialog showing
available clusters for cross-datacenter migration; targetCluster
passed through to migrate_vm invoke.
3. Storage: switch list_proxmox_datastores to cluster/resources?type=storage
(single API call, cluster-wide); normalize plugintype→type,
disk/maxdisk→used/size, compute available via saturating_sub.
4. Network: replace free-text Interface Type Input with a Select
dropdown listing all PVE network interface types.
5. Firewall New Rule: add onNewRule prop to FirewallRuleList, wire
button; add full dialog in FirewallPage with action/protocol/
source/dest/port fields that calls add_firewall_rule; rewrite
Rust command to accept rule as serde_json::Value instead of
flat params (matches frontend invoke signature).
6. Backup: normalize raw PVE cluster/backup fields (id, storage,
node, schedule, enabled, next-run timestamp) to BackupJobInfo
shape; update BackupJobList columns to show storage, vmid, mode.
7. AI chat: merge all system prompt sections into a single system
message (fixes Qwen 3.5 / LiteLLM rejection of multiple system
messages); push assistant message with tool_calls before tool
result messages to satisfy OpenAI API contract.
2026-06-21 20:08:56 +00:00
|
|
|
clusters={clusters}
|
|
|
|
|
currentClusterId={clusterId}
|
2026-06-21 16:17:31 +00:00
|
|
|
targetNode={targetNode}
|
|
|
|
|
onTargetNodeChange={setTargetNode}
|
fix(proxmox): resolve 7 dashboard and AI chat issues
1. VM Actions: pass clusterId/clusters props from VMsPage to VMList;
rename node→node_id in 14 Rust Tauri command handlers to match
Tauri 2.x camelCase→snake_case mapping; wire action menu items
through handleAction so menu closes on click.
2. Migration: add Target Remote dropdown in MigrationDialog showing
available clusters for cross-datacenter migration; targetCluster
passed through to migrate_vm invoke.
3. Storage: switch list_proxmox_datastores to cluster/resources?type=storage
(single API call, cluster-wide); normalize plugintype→type,
disk/maxdisk→used/size, compute available via saturating_sub.
4. Network: replace free-text Interface Type Input with a Select
dropdown listing all PVE network interface types.
5. Firewall New Rule: add onNewRule prop to FirewallRuleList, wire
button; add full dialog in FirewallPage with action/protocol/
source/dest/port fields that calls add_firewall_rule; rewrite
Rust command to accept rule as serde_json::Value instead of
flat params (matches frontend invoke signature).
6. Backup: normalize raw PVE cluster/backup fields (id, storage,
node, schedule, enabled, next-run timestamp) to BackupJobInfo
shape; update BackupJobList columns to show storage, vmid, mode.
7. AI chat: merge all system prompt sections into a single system
message (fixes Qwen 3.5 / LiteLLM rejection of multiple system
messages); push assistant message with tool_calls before tool
result messages to satisfy OpenAI API contract.
2026-06-21 20:08:56 +00:00
|
|
|
targetCluster={targetCluster}
|
|
|
|
|
onTargetClusterChange={setTargetCluster}
|
2026-06-21 16:17:31 +00:00
|
|
|
online={onlineMigration}
|
|
|
|
|
onOnlineChange={setOnlineMigration}
|
|
|
|
|
maxDowntime={maxDowntime}
|
|
|
|
|
onMaxDowntimeChange={setMaxDowntime}
|
|
|
|
|
/>
|
2026-06-11 14:38:36 +00:00
|
|
|
</Card>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
interface VMActionMenuProps {
|
|
|
|
|
vm: VMInfo;
|
2026-06-21 04:36:58 +00:00
|
|
|
onVMAction: (vm: VMInfo, action: 'start' | 'stop' | 'reboot' | 'shutdown' | 'resume' | 'suspend') => void;
|
|
|
|
|
onSnapshotAction: (vm: VMInfo, action: 'create' | 'list' | 'rollback' | 'delete') => void;
|
|
|
|
|
onMigrate: (vm: VMInfo) => void;
|
|
|
|
|
onClone: (vm: VMInfo) => void;
|
|
|
|
|
onDelete: (vm: VMInfo) => void;
|
2026-06-11 14:38:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function VMActionMenu({
|
|
|
|
|
vm,
|
|
|
|
|
onVMAction,
|
|
|
|
|
onSnapshotAction,
|
|
|
|
|
onMigrate,
|
|
|
|
|
onClone,
|
|
|
|
|
onDelete,
|
|
|
|
|
}: VMActionMenuProps) {
|
2026-06-21 04:36:58 +00:00
|
|
|
const [isOpen, setIsOpen] = useState(false);
|
|
|
|
|
const menuRef = useRef<HTMLDivElement>(null);
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
function handleClickOutside(event: MouseEvent) {
|
|
|
|
|
if (menuRef.current && !menuRef.current.contains(event.target as Node)) {
|
|
|
|
|
setIsOpen(false);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (isOpen) {
|
|
|
|
|
document.addEventListener('mousedown', handleClickOutside);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return () => {
|
|
|
|
|
document.removeEventListener('mousedown', handleClickOutside);
|
|
|
|
|
};
|
|
|
|
|
}, [isOpen]);
|
|
|
|
|
|
|
|
|
|
const toggleMenu = (e: React.MouseEvent) => {
|
|
|
|
|
e.stopPropagation();
|
|
|
|
|
setIsOpen(!isOpen);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const handleAction = (action: () => void) => (e: React.MouseEvent) => {
|
|
|
|
|
e.stopPropagation();
|
|
|
|
|
setIsOpen(false);
|
fix(proxmox): resolve 7 dashboard and AI chat issues
1. VM Actions: pass clusterId/clusters props from VMsPage to VMList;
rename node→node_id in 14 Rust Tauri command handlers to match
Tauri 2.x camelCase→snake_case mapping; wire action menu items
through handleAction so menu closes on click.
2. Migration: add Target Remote dropdown in MigrationDialog showing
available clusters for cross-datacenter migration; targetCluster
passed through to migrate_vm invoke.
3. Storage: switch list_proxmox_datastores to cluster/resources?type=storage
(single API call, cluster-wide); normalize plugintype→type,
disk/maxdisk→used/size, compute available via saturating_sub.
4. Network: replace free-text Interface Type Input with a Select
dropdown listing all PVE network interface types.
5. Firewall New Rule: add onNewRule prop to FirewallRuleList, wire
button; add full dialog in FirewallPage with action/protocol/
source/dest/port fields that calls add_firewall_rule; rewrite
Rust command to accept rule as serde_json::Value instead of
flat params (matches frontend invoke signature).
6. Backup: normalize raw PVE cluster/backup fields (id, storage,
node, schedule, enabled, next-run timestamp) to BackupJobInfo
shape; update BackupJobList columns to show storage, vmid, mode.
7. AI chat: merge all system prompt sections into a single system
message (fixes Qwen 3.5 / LiteLLM rejection of multiple system
messages); push assistant message with tool_calls before tool
result messages to satisfy OpenAI API contract.
2026-06-21 20:08:56 +00:00
|
|
|
action();
|
2026-06-21 04:36:58 +00:00
|
|
|
};
|
|
|
|
|
|
2026-06-11 14:38:36 +00:00
|
|
|
return (
|
2026-06-21 04:36:58 +00:00
|
|
|
<div className="relative" ref={menuRef}>
|
2026-06-11 14:38:36 +00:00
|
|
|
<Button
|
|
|
|
|
variant="ghost"
|
|
|
|
|
size="sm"
|
2026-06-21 04:36:58 +00:00
|
|
|
onClick={toggleMenu}
|
|
|
|
|
className="h-8 w-8 p-0"
|
2026-06-11 14:38:36 +00:00
|
|
|
>
|
|
|
|
|
<MoreHorizontal className="h-4 w-4" />
|
|
|
|
|
</Button>
|
|
|
|
|
{isOpen && (
|
fix(proxmox): resolve 7 dashboard and AI chat issues
1. VM Actions: pass clusterId/clusters props from VMsPage to VMList;
rename node→node_id in 14 Rust Tauri command handlers to match
Tauri 2.x camelCase→snake_case mapping; wire action menu items
through handleAction so menu closes on click.
2. Migration: add Target Remote dropdown in MigrationDialog showing
available clusters for cross-datacenter migration; targetCluster
passed through to migrate_vm invoke.
3. Storage: switch list_proxmox_datastores to cluster/resources?type=storage
(single API call, cluster-wide); normalize plugintype→type,
disk/maxdisk→used/size, compute available via saturating_sub.
4. Network: replace free-text Interface Type Input with a Select
dropdown listing all PVE network interface types.
5. Firewall New Rule: add onNewRule prop to FirewallRuleList, wire
button; add full dialog in FirewallPage with action/protocol/
source/dest/port fields that calls add_firewall_rule; rewrite
Rust command to accept rule as serde_json::Value instead of
flat params (matches frontend invoke signature).
6. Backup: normalize raw PVE cluster/backup fields (id, storage,
node, schedule, enabled, next-run timestamp) to BackupJobInfo
shape; update BackupJobList columns to show storage, vmid, mode.
7. AI chat: merge all system prompt sections into a single system
message (fixes Qwen 3.5 / LiteLLM rejection of multiple system
messages); push assistant message with tool_calls before tool
result messages to satisfy OpenAI API contract.
2026-06-21 20:08:56 +00:00
|
|
|
<div className="absolute right-0 top-full z-50 mt-2 w-48 rounded-md border bg-background shadow-md">
|
2026-06-21 04:36:58 +00:00
|
|
|
<div className="space-y-1 p-1">
|
|
|
|
|
{vm.status === 'stopped' && (
|
2026-06-11 14:38:36 +00:00
|
|
|
<button
|
|
|
|
|
className="flex w-full items-center rounded-md px-2 py-1.5 text-sm hover:bg-accent"
|
fix(proxmox): resolve 7 dashboard and AI chat issues
1. VM Actions: pass clusterId/clusters props from VMsPage to VMList;
rename node→node_id in 14 Rust Tauri command handlers to match
Tauri 2.x camelCase→snake_case mapping; wire action menu items
through handleAction so menu closes on click.
2. Migration: add Target Remote dropdown in MigrationDialog showing
available clusters for cross-datacenter migration; targetCluster
passed through to migrate_vm invoke.
3. Storage: switch list_proxmox_datastores to cluster/resources?type=storage
(single API call, cluster-wide); normalize plugintype→type,
disk/maxdisk→used/size, compute available via saturating_sub.
4. Network: replace free-text Interface Type Input with a Select
dropdown listing all PVE network interface types.
5. Firewall New Rule: add onNewRule prop to FirewallRuleList, wire
button; add full dialog in FirewallPage with action/protocol/
source/dest/port fields that calls add_firewall_rule; rewrite
Rust command to accept rule as serde_json::Value instead of
flat params (matches frontend invoke signature).
6. Backup: normalize raw PVE cluster/backup fields (id, storage,
node, schedule, enabled, next-run timestamp) to BackupJobInfo
shape; update BackupJobList columns to show storage, vmid, mode.
7. AI chat: merge all system prompt sections into a single system
message (fixes Qwen 3.5 / LiteLLM rejection of multiple system
messages); push assistant message with tool_calls before tool
result messages to satisfy OpenAI API contract.
2026-06-21 20:08:56 +00:00
|
|
|
onClick={handleAction(() => onVMAction(vm, 'start'))}
|
2026-06-11 14:38:36 +00:00
|
|
|
>
|
2026-06-21 04:36:58 +00:00
|
|
|
<Play className="mr-2 h-4 w-4" />
|
|
|
|
|
Start
|
2026-06-11 14:38:36 +00:00
|
|
|
</button>
|
|
|
|
|
)}
|
|
|
|
|
{vm.status === 'running' && (
|
2026-06-21 04:36:58 +00:00
|
|
|
<>
|
|
|
|
|
<button
|
|
|
|
|
className="flex w-full items-center rounded-md px-2 py-1.5 text-sm hover:bg-accent"
|
fix(proxmox): resolve 7 dashboard and AI chat issues
1. VM Actions: pass clusterId/clusters props from VMsPage to VMList;
rename node→node_id in 14 Rust Tauri command handlers to match
Tauri 2.x camelCase→snake_case mapping; wire action menu items
through handleAction so menu closes on click.
2. Migration: add Target Remote dropdown in MigrationDialog showing
available clusters for cross-datacenter migration; targetCluster
passed through to migrate_vm invoke.
3. Storage: switch list_proxmox_datastores to cluster/resources?type=storage
(single API call, cluster-wide); normalize plugintype→type,
disk/maxdisk→used/size, compute available via saturating_sub.
4. Network: replace free-text Interface Type Input with a Select
dropdown listing all PVE network interface types.
5. Firewall New Rule: add onNewRule prop to FirewallRuleList, wire
button; add full dialog in FirewallPage with action/protocol/
source/dest/port fields that calls add_firewall_rule; rewrite
Rust command to accept rule as serde_json::Value instead of
flat params (matches frontend invoke signature).
6. Backup: normalize raw PVE cluster/backup fields (id, storage,
node, schedule, enabled, next-run timestamp) to BackupJobInfo
shape; update BackupJobList columns to show storage, vmid, mode.
7. AI chat: merge all system prompt sections into a single system
message (fixes Qwen 3.5 / LiteLLM rejection of multiple system
messages); push assistant message with tool_calls before tool
result messages to satisfy OpenAI API contract.
2026-06-21 20:08:56 +00:00
|
|
|
onClick={handleAction(() => onVMAction(vm, 'stop'))}
|
2026-06-21 04:36:58 +00:00
|
|
|
>
|
|
|
|
|
<Square className="mr-2 h-4 w-4" />
|
|
|
|
|
Stop
|
|
|
|
|
</button>
|
|
|
|
|
<button
|
|
|
|
|
className="flex w-full items-center rounded-md px-2 py-1.5 text-sm hover:bg-accent"
|
fix(proxmox): resolve 7 dashboard and AI chat issues
1. VM Actions: pass clusterId/clusters props from VMsPage to VMList;
rename node→node_id in 14 Rust Tauri command handlers to match
Tauri 2.x camelCase→snake_case mapping; wire action menu items
through handleAction so menu closes on click.
2. Migration: add Target Remote dropdown in MigrationDialog showing
available clusters for cross-datacenter migration; targetCluster
passed through to migrate_vm invoke.
3. Storage: switch list_proxmox_datastores to cluster/resources?type=storage
(single API call, cluster-wide); normalize plugintype→type,
disk/maxdisk→used/size, compute available via saturating_sub.
4. Network: replace free-text Interface Type Input with a Select
dropdown listing all PVE network interface types.
5. Firewall New Rule: add onNewRule prop to FirewallRuleList, wire
button; add full dialog in FirewallPage with action/protocol/
source/dest/port fields that calls add_firewall_rule; rewrite
Rust command to accept rule as serde_json::Value instead of
flat params (matches frontend invoke signature).
6. Backup: normalize raw PVE cluster/backup fields (id, storage,
node, schedule, enabled, next-run timestamp) to BackupJobInfo
shape; update BackupJobList columns to show storage, vmid, mode.
7. AI chat: merge all system prompt sections into a single system
message (fixes Qwen 3.5 / LiteLLM rejection of multiple system
messages); push assistant message with tool_calls before tool
result messages to satisfy OpenAI API contract.
2026-06-21 20:08:56 +00:00
|
|
|
onClick={handleAction(() => onVMAction(vm, 'reboot'))}
|
2026-06-21 04:36:58 +00:00
|
|
|
>
|
|
|
|
|
<RotateCcw className="mr-2 h-4 w-4" />
|
|
|
|
|
Reboot
|
|
|
|
|
</button>
|
|
|
|
|
<button
|
|
|
|
|
className="flex w-full items-center rounded-md px-2 py-1.5 text-sm hover:bg-accent"
|
fix(proxmox): resolve 7 dashboard and AI chat issues
1. VM Actions: pass clusterId/clusters props from VMsPage to VMList;
rename node→node_id in 14 Rust Tauri command handlers to match
Tauri 2.x camelCase→snake_case mapping; wire action menu items
through handleAction so menu closes on click.
2. Migration: add Target Remote dropdown in MigrationDialog showing
available clusters for cross-datacenter migration; targetCluster
passed through to migrate_vm invoke.
3. Storage: switch list_proxmox_datastores to cluster/resources?type=storage
(single API call, cluster-wide); normalize plugintype→type,
disk/maxdisk→used/size, compute available via saturating_sub.
4. Network: replace free-text Interface Type Input with a Select
dropdown listing all PVE network interface types.
5. Firewall New Rule: add onNewRule prop to FirewallRuleList, wire
button; add full dialog in FirewallPage with action/protocol/
source/dest/port fields that calls add_firewall_rule; rewrite
Rust command to accept rule as serde_json::Value instead of
flat params (matches frontend invoke signature).
6. Backup: normalize raw PVE cluster/backup fields (id, storage,
node, schedule, enabled, next-run timestamp) to BackupJobInfo
shape; update BackupJobList columns to show storage, vmid, mode.
7. AI chat: merge all system prompt sections into a single system
message (fixes Qwen 3.5 / LiteLLM rejection of multiple system
messages); push assistant message with tool_calls before tool
result messages to satisfy OpenAI API contract.
2026-06-21 20:08:56 +00:00
|
|
|
onClick={handleAction(() => onVMAction(vm, 'shutdown'))}
|
2026-06-21 04:36:58 +00:00
|
|
|
>
|
|
|
|
|
<Power className="mr-2 h-4 w-4" />
|
|
|
|
|
Shutdown
|
|
|
|
|
</button>
|
|
|
|
|
<button
|
|
|
|
|
className="flex w-full items-center rounded-md px-2 py-1.5 text-sm hover:bg-accent"
|
fix(proxmox): resolve 7 dashboard and AI chat issues
1. VM Actions: pass clusterId/clusters props from VMsPage to VMList;
rename node→node_id in 14 Rust Tauri command handlers to match
Tauri 2.x camelCase→snake_case mapping; wire action menu items
through handleAction so menu closes on click.
2. Migration: add Target Remote dropdown in MigrationDialog showing
available clusters for cross-datacenter migration; targetCluster
passed through to migrate_vm invoke.
3. Storage: switch list_proxmox_datastores to cluster/resources?type=storage
(single API call, cluster-wide); normalize plugintype→type,
disk/maxdisk→used/size, compute available via saturating_sub.
4. Network: replace free-text Interface Type Input with a Select
dropdown listing all PVE network interface types.
5. Firewall New Rule: add onNewRule prop to FirewallRuleList, wire
button; add full dialog in FirewallPage with action/protocol/
source/dest/port fields that calls add_firewall_rule; rewrite
Rust command to accept rule as serde_json::Value instead of
flat params (matches frontend invoke signature).
6. Backup: normalize raw PVE cluster/backup fields (id, storage,
node, schedule, enabled, next-run timestamp) to BackupJobInfo
shape; update BackupJobList columns to show storage, vmid, mode.
7. AI chat: merge all system prompt sections into a single system
message (fixes Qwen 3.5 / LiteLLM rejection of multiple system
messages); push assistant message with tool_calls before tool
result messages to satisfy OpenAI API contract.
2026-06-21 20:08:56 +00:00
|
|
|
onClick={handleAction(() => onVMAction(vm, 'suspend'))}
|
2026-06-21 04:36:58 +00:00
|
|
|
>
|
|
|
|
|
<Pause className="mr-2 h-4 w-4" />
|
|
|
|
|
Suspend
|
|
|
|
|
</button>
|
|
|
|
|
</>
|
|
|
|
|
)}
|
|
|
|
|
{vm.status === 'paused' && (
|
2026-06-11 14:38:36 +00:00
|
|
|
<button
|
|
|
|
|
className="flex w-full items-center rounded-md px-2 py-1.5 text-sm hover:bg-accent"
|
fix(proxmox): resolve 7 dashboard and AI chat issues
1. VM Actions: pass clusterId/clusters props from VMsPage to VMList;
rename node→node_id in 14 Rust Tauri command handlers to match
Tauri 2.x camelCase→snake_case mapping; wire action menu items
through handleAction so menu closes on click.
2. Migration: add Target Remote dropdown in MigrationDialog showing
available clusters for cross-datacenter migration; targetCluster
passed through to migrate_vm invoke.
3. Storage: switch list_proxmox_datastores to cluster/resources?type=storage
(single API call, cluster-wide); normalize plugintype→type,
disk/maxdisk→used/size, compute available via saturating_sub.
4. Network: replace free-text Interface Type Input with a Select
dropdown listing all PVE network interface types.
5. Firewall New Rule: add onNewRule prop to FirewallRuleList, wire
button; add full dialog in FirewallPage with action/protocol/
source/dest/port fields that calls add_firewall_rule; rewrite
Rust command to accept rule as serde_json::Value instead of
flat params (matches frontend invoke signature).
6. Backup: normalize raw PVE cluster/backup fields (id, storage,
node, schedule, enabled, next-run timestamp) to BackupJobInfo
shape; update BackupJobList columns to show storage, vmid, mode.
7. AI chat: merge all system prompt sections into a single system
message (fixes Qwen 3.5 / LiteLLM rejection of multiple system
messages); push assistant message with tool_calls before tool
result messages to satisfy OpenAI API contract.
2026-06-21 20:08:56 +00:00
|
|
|
onClick={handleAction(() => onVMAction(vm, 'resume'))}
|
2026-06-11 14:38:36 +00:00
|
|
|
>
|
2026-06-21 04:36:58 +00:00
|
|
|
<PlayCircle className="mr-2 h-4 w-4" />
|
|
|
|
|
Resume
|
2026-06-11 14:38:36 +00:00
|
|
|
</button>
|
|
|
|
|
)}
|
|
|
|
|
<div className="h-px bg-border my-1" />
|
|
|
|
|
<button
|
|
|
|
|
className="flex w-full items-center rounded-md px-2 py-1.5 text-sm hover:bg-accent"
|
fix(proxmox): resolve 7 dashboard and AI chat issues
1. VM Actions: pass clusterId/clusters props from VMsPage to VMList;
rename node→node_id in 14 Rust Tauri command handlers to match
Tauri 2.x camelCase→snake_case mapping; wire action menu items
through handleAction so menu closes on click.
2. Migration: add Target Remote dropdown in MigrationDialog showing
available clusters for cross-datacenter migration; targetCluster
passed through to migrate_vm invoke.
3. Storage: switch list_proxmox_datastores to cluster/resources?type=storage
(single API call, cluster-wide); normalize plugintype→type,
disk/maxdisk→used/size, compute available via saturating_sub.
4. Network: replace free-text Interface Type Input with a Select
dropdown listing all PVE network interface types.
5. Firewall New Rule: add onNewRule prop to FirewallRuleList, wire
button; add full dialog in FirewallPage with action/protocol/
source/dest/port fields that calls add_firewall_rule; rewrite
Rust command to accept rule as serde_json::Value instead of
flat params (matches frontend invoke signature).
6. Backup: normalize raw PVE cluster/backup fields (id, storage,
node, schedule, enabled, next-run timestamp) to BackupJobInfo
shape; update BackupJobList columns to show storage, vmid, mode.
7. AI chat: merge all system prompt sections into a single system
message (fixes Qwen 3.5 / LiteLLM rejection of multiple system
messages); push assistant message with tool_calls before tool
result messages to satisfy OpenAI API contract.
2026-06-21 20:08:56 +00:00
|
|
|
onClick={handleAction(() => onSnapshotAction(vm, 'create'))}
|
2026-06-11 14:38:36 +00:00
|
|
|
>
|
2026-06-21 04:36:58 +00:00
|
|
|
📸 Create Snapshot
|
2026-06-11 14:38:36 +00:00
|
|
|
</button>
|
|
|
|
|
<button
|
|
|
|
|
className="flex w-full items-center rounded-md px-2 py-1.5 text-sm hover:bg-accent"
|
fix(proxmox): resolve 7 dashboard and AI chat issues
1. VM Actions: pass clusterId/clusters props from VMsPage to VMList;
rename node→node_id in 14 Rust Tauri command handlers to match
Tauri 2.x camelCase→snake_case mapping; wire action menu items
through handleAction so menu closes on click.
2. Migration: add Target Remote dropdown in MigrationDialog showing
available clusters for cross-datacenter migration; targetCluster
passed through to migrate_vm invoke.
3. Storage: switch list_proxmox_datastores to cluster/resources?type=storage
(single API call, cluster-wide); normalize plugintype→type,
disk/maxdisk→used/size, compute available via saturating_sub.
4. Network: replace free-text Interface Type Input with a Select
dropdown listing all PVE network interface types.
5. Firewall New Rule: add onNewRule prop to FirewallRuleList, wire
button; add full dialog in FirewallPage with action/protocol/
source/dest/port fields that calls add_firewall_rule; rewrite
Rust command to accept rule as serde_json::Value instead of
flat params (matches frontend invoke signature).
6. Backup: normalize raw PVE cluster/backup fields (id, storage,
node, schedule, enabled, next-run timestamp) to BackupJobInfo
shape; update BackupJobList columns to show storage, vmid, mode.
7. AI chat: merge all system prompt sections into a single system
message (fixes Qwen 3.5 / LiteLLM rejection of multiple system
messages); push assistant message with tool_calls before tool
result messages to satisfy OpenAI API contract.
2026-06-21 20:08:56 +00:00
|
|
|
onClick={handleAction(() => onSnapshotAction(vm, 'list'))}
|
2026-06-11 14:38:36 +00:00
|
|
|
>
|
2026-06-21 04:36:58 +00:00
|
|
|
📋 List Snapshots
|
2026-06-11 14:38:36 +00:00
|
|
|
</button>
|
|
|
|
|
<div className="h-px bg-border my-1" />
|
|
|
|
|
<button
|
|
|
|
|
className="flex w-full items-center rounded-md px-2 py-1.5 text-sm hover:bg-accent"
|
fix(proxmox): resolve 7 dashboard and AI chat issues
1. VM Actions: pass clusterId/clusters props from VMsPage to VMList;
rename node→node_id in 14 Rust Tauri command handlers to match
Tauri 2.x camelCase→snake_case mapping; wire action menu items
through handleAction so menu closes on click.
2. Migration: add Target Remote dropdown in MigrationDialog showing
available clusters for cross-datacenter migration; targetCluster
passed through to migrate_vm invoke.
3. Storage: switch list_proxmox_datastores to cluster/resources?type=storage
(single API call, cluster-wide); normalize plugintype→type,
disk/maxdisk→used/size, compute available via saturating_sub.
4. Network: replace free-text Interface Type Input with a Select
dropdown listing all PVE network interface types.
5. Firewall New Rule: add onNewRule prop to FirewallRuleList, wire
button; add full dialog in FirewallPage with action/protocol/
source/dest/port fields that calls add_firewall_rule; rewrite
Rust command to accept rule as serde_json::Value instead of
flat params (matches frontend invoke signature).
6. Backup: normalize raw PVE cluster/backup fields (id, storage,
node, schedule, enabled, next-run timestamp) to BackupJobInfo
shape; update BackupJobList columns to show storage, vmid, mode.
7. AI chat: merge all system prompt sections into a single system
message (fixes Qwen 3.5 / LiteLLM rejection of multiple system
messages); push assistant message with tool_calls before tool
result messages to satisfy OpenAI API contract.
2026-06-21 20:08:56 +00:00
|
|
|
onClick={handleAction(() => onMigrate(vm))}
|
2026-06-11 14:38:36 +00:00
|
|
|
>
|
2026-06-21 04:36:58 +00:00
|
|
|
<MoveRight className="mr-2 h-4 w-4" />
|
2026-06-11 14:38:36 +00:00
|
|
|
Migrate
|
|
|
|
|
</button>
|
|
|
|
|
<button
|
|
|
|
|
className="flex w-full items-center rounded-md px-2 py-1.5 text-sm hover:bg-accent"
|
fix(proxmox): resolve 7 dashboard and AI chat issues
1. VM Actions: pass clusterId/clusters props from VMsPage to VMList;
rename node→node_id in 14 Rust Tauri command handlers to match
Tauri 2.x camelCase→snake_case mapping; wire action menu items
through handleAction so menu closes on click.
2. Migration: add Target Remote dropdown in MigrationDialog showing
available clusters for cross-datacenter migration; targetCluster
passed through to migrate_vm invoke.
3. Storage: switch list_proxmox_datastores to cluster/resources?type=storage
(single API call, cluster-wide); normalize plugintype→type,
disk/maxdisk→used/size, compute available via saturating_sub.
4. Network: replace free-text Interface Type Input with a Select
dropdown listing all PVE network interface types.
5. Firewall New Rule: add onNewRule prop to FirewallRuleList, wire
button; add full dialog in FirewallPage with action/protocol/
source/dest/port fields that calls add_firewall_rule; rewrite
Rust command to accept rule as serde_json::Value instead of
flat params (matches frontend invoke signature).
6. Backup: normalize raw PVE cluster/backup fields (id, storage,
node, schedule, enabled, next-run timestamp) to BackupJobInfo
shape; update BackupJobList columns to show storage, vmid, mode.
7. AI chat: merge all system prompt sections into a single system
message (fixes Qwen 3.5 / LiteLLM rejection of multiple system
messages); push assistant message with tool_calls before tool
result messages to satisfy OpenAI API contract.
2026-06-21 20:08:56 +00:00
|
|
|
onClick={handleAction(() => onClone(vm))}
|
2026-06-11 14:38:36 +00:00
|
|
|
>
|
2026-06-21 04:36:58 +00:00
|
|
|
<Copy className="mr-2 h-4 w-4" />
|
2026-06-11 14:38:36 +00:00
|
|
|
Clone
|
|
|
|
|
</button>
|
|
|
|
|
<div className="h-px bg-border my-1" />
|
|
|
|
|
<button
|
|
|
|
|
className="flex w-full items-center rounded-md px-2 py-1.5 text-sm hover:bg-red-100 hover:text-red-600"
|
fix(proxmox): resolve 7 dashboard and AI chat issues
1. VM Actions: pass clusterId/clusters props from VMsPage to VMList;
rename node→node_id in 14 Rust Tauri command handlers to match
Tauri 2.x camelCase→snake_case mapping; wire action menu items
through handleAction so menu closes on click.
2. Migration: add Target Remote dropdown in MigrationDialog showing
available clusters for cross-datacenter migration; targetCluster
passed through to migrate_vm invoke.
3. Storage: switch list_proxmox_datastores to cluster/resources?type=storage
(single API call, cluster-wide); normalize plugintype→type,
disk/maxdisk→used/size, compute available via saturating_sub.
4. Network: replace free-text Interface Type Input with a Select
dropdown listing all PVE network interface types.
5. Firewall New Rule: add onNewRule prop to FirewallRuleList, wire
button; add full dialog in FirewallPage with action/protocol/
source/dest/port fields that calls add_firewall_rule; rewrite
Rust command to accept rule as serde_json::Value instead of
flat params (matches frontend invoke signature).
6. Backup: normalize raw PVE cluster/backup fields (id, storage,
node, schedule, enabled, next-run timestamp) to BackupJobInfo
shape; update BackupJobList columns to show storage, vmid, mode.
7. AI chat: merge all system prompt sections into a single system
message (fixes Qwen 3.5 / LiteLLM rejection of multiple system
messages); push assistant message with tool_calls before tool
result messages to satisfy OpenAI API contract.
2026-06-21 20:08:56 +00:00
|
|
|
onClick={handleAction(() => onDelete(vm))}
|
2026-06-11 14:38:36 +00:00
|
|
|
>
|
|
|
|
|
<X className="mr-2 h-4 w-4" />
|
|
|
|
|
Delete
|
|
|
|
|
</button>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
}
|
2026-06-21 16:17:31 +00:00
|
|
|
|
|
|
|
|
interface MigrationDialogProps {
|
|
|
|
|
vm: VMInfo | null;
|
|
|
|
|
isOpen: boolean;
|
|
|
|
|
onClose: () => void;
|
|
|
|
|
onSubmit: () => void;
|
|
|
|
|
availableNodes: VMInfo[];
|
fix(proxmox): resolve 7 dashboard and AI chat issues
1. VM Actions: pass clusterId/clusters props from VMsPage to VMList;
rename node→node_id in 14 Rust Tauri command handlers to match
Tauri 2.x camelCase→snake_case mapping; wire action menu items
through handleAction so menu closes on click.
2. Migration: add Target Remote dropdown in MigrationDialog showing
available clusters for cross-datacenter migration; targetCluster
passed through to migrate_vm invoke.
3. Storage: switch list_proxmox_datastores to cluster/resources?type=storage
(single API call, cluster-wide); normalize plugintype→type,
disk/maxdisk→used/size, compute available via saturating_sub.
4. Network: replace free-text Interface Type Input with a Select
dropdown listing all PVE network interface types.
5. Firewall New Rule: add onNewRule prop to FirewallRuleList, wire
button; add full dialog in FirewallPage with action/protocol/
source/dest/port fields that calls add_firewall_rule; rewrite
Rust command to accept rule as serde_json::Value instead of
flat params (matches frontend invoke signature).
6. Backup: normalize raw PVE cluster/backup fields (id, storage,
node, schedule, enabled, next-run timestamp) to BackupJobInfo
shape; update BackupJobList columns to show storage, vmid, mode.
7. AI chat: merge all system prompt sections into a single system
message (fixes Qwen 3.5 / LiteLLM rejection of multiple system
messages); push assistant message with tool_calls before tool
result messages to satisfy OpenAI API contract.
2026-06-21 20:08:56 +00:00
|
|
|
clusters: ClusterInfo[];
|
|
|
|
|
currentClusterId: string;
|
2026-06-21 16:17:31 +00:00
|
|
|
targetNode: string;
|
|
|
|
|
onTargetNodeChange: (node: string) => void;
|
fix(proxmox): resolve 7 dashboard and AI chat issues
1. VM Actions: pass clusterId/clusters props from VMsPage to VMList;
rename node→node_id in 14 Rust Tauri command handlers to match
Tauri 2.x camelCase→snake_case mapping; wire action menu items
through handleAction so menu closes on click.
2. Migration: add Target Remote dropdown in MigrationDialog showing
available clusters for cross-datacenter migration; targetCluster
passed through to migrate_vm invoke.
3. Storage: switch list_proxmox_datastores to cluster/resources?type=storage
(single API call, cluster-wide); normalize plugintype→type,
disk/maxdisk→used/size, compute available via saturating_sub.
4. Network: replace free-text Interface Type Input with a Select
dropdown listing all PVE network interface types.
5. Firewall New Rule: add onNewRule prop to FirewallRuleList, wire
button; add full dialog in FirewallPage with action/protocol/
source/dest/port fields that calls add_firewall_rule; rewrite
Rust command to accept rule as serde_json::Value instead of
flat params (matches frontend invoke signature).
6. Backup: normalize raw PVE cluster/backup fields (id, storage,
node, schedule, enabled, next-run timestamp) to BackupJobInfo
shape; update BackupJobList columns to show storage, vmid, mode.
7. AI chat: merge all system prompt sections into a single system
message (fixes Qwen 3.5 / LiteLLM rejection of multiple system
messages); push assistant message with tool_calls before tool
result messages to satisfy OpenAI API contract.
2026-06-21 20:08:56 +00:00
|
|
|
targetCluster: string;
|
|
|
|
|
onTargetClusterChange: (clusterId: string) => void;
|
2026-06-21 16:17:31 +00:00
|
|
|
online: boolean;
|
|
|
|
|
onOnlineChange: (online: boolean) => void;
|
|
|
|
|
maxDowntime: number;
|
|
|
|
|
onMaxDowntimeChange: (downtime: number) => void;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function MigrationDialog({
|
|
|
|
|
vm,
|
|
|
|
|
isOpen,
|
|
|
|
|
onClose,
|
|
|
|
|
onSubmit,
|
|
|
|
|
availableNodes,
|
fix(proxmox): resolve 7 dashboard and AI chat issues
1. VM Actions: pass clusterId/clusters props from VMsPage to VMList;
rename node→node_id in 14 Rust Tauri command handlers to match
Tauri 2.x camelCase→snake_case mapping; wire action menu items
through handleAction so menu closes on click.
2. Migration: add Target Remote dropdown in MigrationDialog showing
available clusters for cross-datacenter migration; targetCluster
passed through to migrate_vm invoke.
3. Storage: switch list_proxmox_datastores to cluster/resources?type=storage
(single API call, cluster-wide); normalize plugintype→type,
disk/maxdisk→used/size, compute available via saturating_sub.
4. Network: replace free-text Interface Type Input with a Select
dropdown listing all PVE network interface types.
5. Firewall New Rule: add onNewRule prop to FirewallRuleList, wire
button; add full dialog in FirewallPage with action/protocol/
source/dest/port fields that calls add_firewall_rule; rewrite
Rust command to accept rule as serde_json::Value instead of
flat params (matches frontend invoke signature).
6. Backup: normalize raw PVE cluster/backup fields (id, storage,
node, schedule, enabled, next-run timestamp) to BackupJobInfo
shape; update BackupJobList columns to show storage, vmid, mode.
7. AI chat: merge all system prompt sections into a single system
message (fixes Qwen 3.5 / LiteLLM rejection of multiple system
messages); push assistant message with tool_calls before tool
result messages to satisfy OpenAI API contract.
2026-06-21 20:08:56 +00:00
|
|
|
clusters,
|
|
|
|
|
currentClusterId,
|
2026-06-21 16:17:31 +00:00
|
|
|
targetNode,
|
|
|
|
|
onTargetNodeChange,
|
fix(proxmox): resolve 7 dashboard and AI chat issues
1. VM Actions: pass clusterId/clusters props from VMsPage to VMList;
rename node→node_id in 14 Rust Tauri command handlers to match
Tauri 2.x camelCase→snake_case mapping; wire action menu items
through handleAction so menu closes on click.
2. Migration: add Target Remote dropdown in MigrationDialog showing
available clusters for cross-datacenter migration; targetCluster
passed through to migrate_vm invoke.
3. Storage: switch list_proxmox_datastores to cluster/resources?type=storage
(single API call, cluster-wide); normalize plugintype→type,
disk/maxdisk→used/size, compute available via saturating_sub.
4. Network: replace free-text Interface Type Input with a Select
dropdown listing all PVE network interface types.
5. Firewall New Rule: add onNewRule prop to FirewallRuleList, wire
button; add full dialog in FirewallPage with action/protocol/
source/dest/port fields that calls add_firewall_rule; rewrite
Rust command to accept rule as serde_json::Value instead of
flat params (matches frontend invoke signature).
6. Backup: normalize raw PVE cluster/backup fields (id, storage,
node, schedule, enabled, next-run timestamp) to BackupJobInfo
shape; update BackupJobList columns to show storage, vmid, mode.
7. AI chat: merge all system prompt sections into a single system
message (fixes Qwen 3.5 / LiteLLM rejection of multiple system
messages); push assistant message with tool_calls before tool
result messages to satisfy OpenAI API contract.
2026-06-21 20:08:56 +00:00
|
|
|
targetCluster,
|
|
|
|
|
onTargetClusterChange,
|
2026-06-21 16:17:31 +00:00
|
|
|
online,
|
|
|
|
|
onOnlineChange,
|
|
|
|
|
maxDowntime,
|
|
|
|
|
onMaxDowntimeChange,
|
|
|
|
|
}: MigrationDialogProps) {
|
|
|
|
|
if (!vm) return null;
|
|
|
|
|
|
fix(proxmox): resolve 7 dashboard and AI chat issues
1. VM Actions: pass clusterId/clusters props from VMsPage to VMList;
rename node→node_id in 14 Rust Tauri command handlers to match
Tauri 2.x camelCase→snake_case mapping; wire action menu items
through handleAction so menu closes on click.
2. Migration: add Target Remote dropdown in MigrationDialog showing
available clusters for cross-datacenter migration; targetCluster
passed through to migrate_vm invoke.
3. Storage: switch list_proxmox_datastores to cluster/resources?type=storage
(single API call, cluster-wide); normalize plugintype→type,
disk/maxdisk→used/size, compute available via saturating_sub.
4. Network: replace free-text Interface Type Input with a Select
dropdown listing all PVE network interface types.
5. Firewall New Rule: add onNewRule prop to FirewallRuleList, wire
button; add full dialog in FirewallPage with action/protocol/
source/dest/port fields that calls add_firewall_rule; rewrite
Rust command to accept rule as serde_json::Value instead of
flat params (matches frontend invoke signature).
6. Backup: normalize raw PVE cluster/backup fields (id, storage,
node, schedule, enabled, next-run timestamp) to BackupJobInfo
shape; update BackupJobList columns to show storage, vmid, mode.
7. AI chat: merge all system prompt sections into a single system
message (fixes Qwen 3.5 / LiteLLM rejection of multiple system
messages); push assistant message with tool_calls before tool
result messages to satisfy OpenAI API contract.
2026-06-21 20:08:56 +00:00
|
|
|
const isCrossCluster = targetCluster && targetCluster !== currentClusterId;
|
|
|
|
|
|
2026-06-21 16:17:31 +00:00
|
|
|
const availableTargets = availableNodes
|
|
|
|
|
.map((v) => v.node)
|
|
|
|
|
.filter((node, index, self) => self.indexOf(node) === index && node !== vm.node);
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<Dialog open={isOpen} onOpenChange={onClose}>
|
|
|
|
|
<DialogContent>
|
|
|
|
|
<DialogHeader>
|
|
|
|
|
<DialogTitle>Migrate {vm.name} (VM {vm.vmid})</DialogTitle>
|
|
|
|
|
</DialogHeader>
|
|
|
|
|
<div className="space-y-4 py-4">
|
|
|
|
|
<Alert variant="destructive">
|
|
|
|
|
<AlertCircle className="h-4 w-4" />
|
|
|
|
|
<AlertDescription>
|
|
|
|
|
Live migration requires the same hardware configuration on both nodes. Ensure storage is accessible from both nodes.
|
|
|
|
|
</AlertDescription>
|
|
|
|
|
</Alert>
|
fix(proxmox): resolve 7 dashboard and AI chat issues
1. VM Actions: pass clusterId/clusters props from VMsPage to VMList;
rename node→node_id in 14 Rust Tauri command handlers to match
Tauri 2.x camelCase→snake_case mapping; wire action menu items
through handleAction so menu closes on click.
2. Migration: add Target Remote dropdown in MigrationDialog showing
available clusters for cross-datacenter migration; targetCluster
passed through to migrate_vm invoke.
3. Storage: switch list_proxmox_datastores to cluster/resources?type=storage
(single API call, cluster-wide); normalize plugintype→type,
disk/maxdisk→used/size, compute available via saturating_sub.
4. Network: replace free-text Interface Type Input with a Select
dropdown listing all PVE network interface types.
5. Firewall New Rule: add onNewRule prop to FirewallRuleList, wire
button; add full dialog in FirewallPage with action/protocol/
source/dest/port fields that calls add_firewall_rule; rewrite
Rust command to accept rule as serde_json::Value instead of
flat params (matches frontend invoke signature).
6. Backup: normalize raw PVE cluster/backup fields (id, storage,
node, schedule, enabled, next-run timestamp) to BackupJobInfo
shape; update BackupJobList columns to show storage, vmid, mode.
7. AI chat: merge all system prompt sections into a single system
message (fixes Qwen 3.5 / LiteLLM rejection of multiple system
messages); push assistant message with tool_calls before tool
result messages to satisfy OpenAI API contract.
2026-06-21 20:08:56 +00:00
|
|
|
|
|
|
|
|
{clusters.length > 1 && (
|
|
|
|
|
<div className="space-y-2">
|
|
|
|
|
<Label htmlFor="targetCluster">Target Remote</Label>
|
|
|
|
|
<Select value={targetCluster || currentClusterId} onValueChange={onTargetClusterChange}>
|
|
|
|
|
<SelectTrigger>
|
|
|
|
|
<SelectValue placeholder="Select target cluster" />
|
|
|
|
|
</SelectTrigger>
|
|
|
|
|
<SelectContent>
|
|
|
|
|
{clusters.map((c) => (
|
|
|
|
|
<SelectItem key={c.id} value={c.id}>
|
|
|
|
|
{c.name}{c.id === currentClusterId ? ' (current)' : ''}
|
|
|
|
|
</SelectItem>
|
|
|
|
|
))}
|
|
|
|
|
</SelectContent>
|
|
|
|
|
</Select>
|
|
|
|
|
{isCrossCluster && (
|
|
|
|
|
<p className="text-xs text-amber-600">
|
|
|
|
|
Cross-cluster migration — VM will be moved to a different datacenter.
|
|
|
|
|
</p>
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
|
2026-06-21 16:17:31 +00:00
|
|
|
<div className="space-y-2">
|
|
|
|
|
<Label htmlFor="targetNode">Target Node</Label>
|
fix(proxmox): resolve 7 dashboard and AI chat issues
1. VM Actions: pass clusterId/clusters props from VMsPage to VMList;
rename node→node_id in 14 Rust Tauri command handlers to match
Tauri 2.x camelCase→snake_case mapping; wire action menu items
through handleAction so menu closes on click.
2. Migration: add Target Remote dropdown in MigrationDialog showing
available clusters for cross-datacenter migration; targetCluster
passed through to migrate_vm invoke.
3. Storage: switch list_proxmox_datastores to cluster/resources?type=storage
(single API call, cluster-wide); normalize plugintype→type,
disk/maxdisk→used/size, compute available via saturating_sub.
4. Network: replace free-text Interface Type Input with a Select
dropdown listing all PVE network interface types.
5. Firewall New Rule: add onNewRule prop to FirewallRuleList, wire
button; add full dialog in FirewallPage with action/protocol/
source/dest/port fields that calls add_firewall_rule; rewrite
Rust command to accept rule as serde_json::Value instead of
flat params (matches frontend invoke signature).
6. Backup: normalize raw PVE cluster/backup fields (id, storage,
node, schedule, enabled, next-run timestamp) to BackupJobInfo
shape; update BackupJobList columns to show storage, vmid, mode.
7. AI chat: merge all system prompt sections into a single system
message (fixes Qwen 3.5 / LiteLLM rejection of multiple system
messages); push assistant message with tool_calls before tool
result messages to satisfy OpenAI API contract.
2026-06-21 20:08:56 +00:00
|
|
|
{isCrossCluster ? (
|
|
|
|
|
<>
|
|
|
|
|
<Input
|
|
|
|
|
id="targetNode"
|
|
|
|
|
value={targetNode}
|
|
|
|
|
onChange={(e) => onTargetNodeChange(e.target.value)}
|
|
|
|
|
placeholder="Enter target node name"
|
|
|
|
|
/>
|
|
|
|
|
<p className="text-xs text-muted-foreground">
|
|
|
|
|
Enter the node name on the destination cluster
|
|
|
|
|
</p>
|
|
|
|
|
</>
|
|
|
|
|
) : (
|
|
|
|
|
<>
|
|
|
|
|
<Select value={targetNode} onValueChange={onTargetNodeChange}>
|
|
|
|
|
<SelectTrigger>
|
|
|
|
|
<SelectValue placeholder="Select target node" />
|
|
|
|
|
</SelectTrigger>
|
|
|
|
|
<SelectContent>
|
|
|
|
|
{availableTargets.map((node) => (
|
|
|
|
|
<SelectItem key={node} value={node}>
|
|
|
|
|
{node}
|
|
|
|
|
</SelectItem>
|
|
|
|
|
))}
|
|
|
|
|
</SelectContent>
|
|
|
|
|
</Select>
|
|
|
|
|
{availableTargets.length === 0 && (
|
|
|
|
|
<p className="text-xs text-muted-foreground">
|
|
|
|
|
No other nodes available in this cluster
|
|
|
|
|
</p>
|
|
|
|
|
)}
|
|
|
|
|
</>
|
2026-06-21 16:17:31 +00:00
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div className="space-y-2">
|
|
|
|
|
<div className="flex items-center space-x-2">
|
|
|
|
|
<UICheckbox
|
|
|
|
|
id="online"
|
|
|
|
|
checked={online}
|
|
|
|
|
onCheckedChange={(checked) => onOnlineChange(checked as boolean)}
|
|
|
|
|
/>
|
|
|
|
|
<Label htmlFor="online">Live Migration</Label>
|
|
|
|
|
</div>
|
|
|
|
|
<p className="text-xs text-muted-foreground">
|
|
|
|
|
{online ? 'Keep VM running during migration' : 'VM will be stopped during migration'}
|
|
|
|
|
</p>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
{online && (
|
|
|
|
|
<div className="space-y-2">
|
|
|
|
|
<Label htmlFor="maxDowntime">Max Downtime (ms)</Label>
|
|
|
|
|
<Input
|
|
|
|
|
id="maxDowntime"
|
|
|
|
|
type="number"
|
|
|
|
|
value={maxDowntime}
|
|
|
|
|
onChange={(e) => onMaxDowntimeChange(Number(e.target.value))}
|
|
|
|
|
min={10}
|
|
|
|
|
max={10000}
|
|
|
|
|
/>
|
|
|
|
|
<p className="text-xs text-muted-foreground">
|
|
|
|
|
Maximum allowed downtime during live migration
|
|
|
|
|
</p>
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
<DialogFooter>
|
|
|
|
|
<Button variant="outline" onClick={onClose}>
|
|
|
|
|
Cancel
|
|
|
|
|
</Button>
|
fix(proxmox): resolve 7 dashboard and AI chat issues
1. VM Actions: pass clusterId/clusters props from VMsPage to VMList;
rename node→node_id in 14 Rust Tauri command handlers to match
Tauri 2.x camelCase→snake_case mapping; wire action menu items
through handleAction so menu closes on click.
2. Migration: add Target Remote dropdown in MigrationDialog showing
available clusters for cross-datacenter migration; targetCluster
passed through to migrate_vm invoke.
3. Storage: switch list_proxmox_datastores to cluster/resources?type=storage
(single API call, cluster-wide); normalize plugintype→type,
disk/maxdisk→used/size, compute available via saturating_sub.
4. Network: replace free-text Interface Type Input with a Select
dropdown listing all PVE network interface types.
5. Firewall New Rule: add onNewRule prop to FirewallRuleList, wire
button; add full dialog in FirewallPage with action/protocol/
source/dest/port fields that calls add_firewall_rule; rewrite
Rust command to accept rule as serde_json::Value instead of
flat params (matches frontend invoke signature).
6. Backup: normalize raw PVE cluster/backup fields (id, storage,
node, schedule, enabled, next-run timestamp) to BackupJobInfo
shape; update BackupJobList columns to show storage, vmid, mode.
7. AI chat: merge all system prompt sections into a single system
message (fixes Qwen 3.5 / LiteLLM rejection of multiple system
messages); push assistant message with tool_calls before tool
result messages to satisfy OpenAI API contract.
2026-06-21 20:08:56 +00:00
|
|
|
<Button
|
|
|
|
|
onClick={onSubmit}
|
|
|
|
|
disabled={!targetNode || (!isCrossCluster && availableTargets.length === 0)}
|
|
|
|
|
>
|
2026-06-21 16:17:31 +00:00
|
|
|
Start Migration
|
|
|
|
|
</Button>
|
|
|
|
|
</DialogFooter>
|
|
|
|
|
</DialogContent>
|
|
|
|
|
</Dialog>
|
|
|
|
|
);
|
|
|
|
|
}
|