2026-06-13 02:58:31 +00:00
|
|
|
import React, { useState, useEffect, useCallback } from 'react';
|
feat: implement 100% Proxmox PDM feature parity - UI components
- Add 8 new UI components: AclList, AddRemoteForm, ContainerConsole, ContainerOverview, EditRemoteForm, RemoveRemoteDialog, VMConsole, VMOverview
- Add 13 Proxmox management pages: ACLPage, BackupPage, CephPage, CertificatesPage, ContainersPage, FirewallPage, HAPage, NetworkPage, RemotesPage, SDNPage, StoragePage, TasksPage, VMsPage
- Add 13 new routes to App.tsx for Proxmox management pages
- All components use existing UI components from src/components/ui/index.tsx
- TypeScript and ESLint pass with 0 errors
- All tests pass
Files changed: 24 files, +2199 insertions
2026-06-11 18:47:09 +00:00
|
|
|
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/index';
|
|
|
|
|
import { Button } from '@/components/ui/index';
|
2026-06-13 02:58:31 +00:00
|
|
|
import { Badge } from '@/components/ui/index';
|
feat: implement 100% Proxmox PDM feature parity - UI components
- Add 8 new UI components: AclList, AddRemoteForm, ContainerConsole, ContainerOverview, EditRemoteForm, RemoveRemoteDialog, VMConsole, VMOverview
- Add 13 Proxmox management pages: ACLPage, BackupPage, CephPage, CertificatesPage, ContainersPage, FirewallPage, HAPage, NetworkPage, RemotesPage, SDNPage, StoragePage, TasksPage, VMsPage
- Add 13 new routes to App.tsx for Proxmox management pages
- All components use existing UI components from src/components/ui/index.tsx
- TypeScript and ESLint pass with 0 errors
- All tests pass
Files changed: 24 files, +2199 insertions
2026-06-11 18:47:09 +00:00
|
|
|
import { RefreshCw } from 'lucide-react';
|
2026-06-13 02:58:31 +00:00
|
|
|
import { listClusterTasks, listProxmoxClusters, ClusterTask } from '@/lib/proxmoxClient';
|
|
|
|
|
|
|
|
|
|
function taskBadgeVariant(exitstatus?: string): 'default' | 'destructive' | 'secondary' {
|
|
|
|
|
if (!exitstatus) return 'secondary';
|
|
|
|
|
return exitstatus === 'OK' ? 'default' : 'destructive';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function taskBadgeLabel(exitstatus?: string): string {
|
|
|
|
|
if (!exitstatus) return 'running';
|
|
|
|
|
return exitstatus;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function formatTimestamp(epoch: number): string {
|
|
|
|
|
if (!epoch) return '-';
|
|
|
|
|
return new Date(epoch * 1000).toLocaleString();
|
|
|
|
|
}
|
feat: implement 100% Proxmox PDM feature parity - UI components
- Add 8 new UI components: AclList, AddRemoteForm, ContainerConsole, ContainerOverview, EditRemoteForm, RemoveRemoteDialog, VMConsole, VMOverview
- Add 13 Proxmox management pages: ACLPage, BackupPage, CephPage, CertificatesPage, ContainersPage, FirewallPage, HAPage, NetworkPage, RemotesPage, SDNPage, StoragePage, TasksPage, VMsPage
- Add 13 new routes to App.tsx for Proxmox management pages
- All components use existing UI components from src/components/ui/index.tsx
- TypeScript and ESLint pass with 0 errors
- All tests pass
Files changed: 24 files, +2199 insertions
2026-06-11 18:47:09 +00:00
|
|
|
|
|
|
|
|
export function ProxmoxTasksPage() {
|
2026-06-13 02:58:31 +00:00
|
|
|
const [tasks, setTasks] = useState<ClusterTask[]>([]);
|
|
|
|
|
const [clusterId, setClusterId] = useState('');
|
|
|
|
|
const [loading, setLoading] = useState(false);
|
|
|
|
|
const [error, setError] = useState<string | null>(null);
|
|
|
|
|
|
|
|
|
|
const loadTasks = useCallback(async (cId: string) => {
|
|
|
|
|
if (!cId) return;
|
|
|
|
|
setLoading(true);
|
|
|
|
|
setError(null);
|
|
|
|
|
try {
|
|
|
|
|
const t = await listClusterTasks(cId, 100);
|
|
|
|
|
setTasks(t);
|
|
|
|
|
} catch (e) {
|
|
|
|
|
setError(String(e));
|
|
|
|
|
console.error(e);
|
|
|
|
|
} finally {
|
|
|
|
|
setLoading(false);
|
|
|
|
|
}
|
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
listProxmoxClusters()
|
|
|
|
|
.then((cls) => {
|
|
|
|
|
if (cls.length > 0) {
|
|
|
|
|
setClusterId(cls[0].id);
|
|
|
|
|
void loadTasks(cls[0].id);
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
.catch(console.error);
|
|
|
|
|
}, [loadTasks]);
|
|
|
|
|
|
|
|
|
|
const runningCount = tasks.filter((t) => !t.exitstatus).length;
|
|
|
|
|
const completedCount = tasks.filter((t) => t.exitstatus === 'OK').length;
|
|
|
|
|
const failedCount = tasks.filter(
|
|
|
|
|
(t) => t.exitstatus && t.exitstatus !== 'OK'
|
|
|
|
|
).length;
|
|
|
|
|
|
feat: implement 100% Proxmox PDM feature parity - UI components
- Add 8 new UI components: AclList, AddRemoteForm, ContainerConsole, ContainerOverview, EditRemoteForm, RemoveRemoteDialog, VMConsole, VMOverview
- Add 13 Proxmox management pages: ACLPage, BackupPage, CephPage, CertificatesPage, ContainersPage, FirewallPage, HAPage, NetworkPage, RemotesPage, SDNPage, StoragePage, TasksPage, VMsPage
- Add 13 new routes to App.tsx for Proxmox management pages
- All components use existing UI components from src/components/ui/index.tsx
- TypeScript and ESLint pass with 0 errors
- All tests pass
Files changed: 24 files, +2199 insertions
2026-06-11 18:47:09 +00:00
|
|
|
return (
|
|
|
|
|
<div className="space-y-4">
|
|
|
|
|
<div className="flex items-center justify-between">
|
|
|
|
|
<div>
|
2026-06-13 02:58:31 +00:00
|
|
|
<h1 className="text-2xl font-bold">Tasks</h1>
|
|
|
|
|
<p className="text-muted-foreground">Cluster task log and operations</p>
|
feat: implement 100% Proxmox PDM feature parity - UI components
- Add 8 new UI components: AclList, AddRemoteForm, ContainerConsole, ContainerOverview, EditRemoteForm, RemoveRemoteDialog, VMConsole, VMOverview
- Add 13 Proxmox management pages: ACLPage, BackupPage, CephPage, CertificatesPage, ContainersPage, FirewallPage, HAPage, NetworkPage, RemotesPage, SDNPage, StoragePage, TasksPage, VMsPage
- Add 13 new routes to App.tsx for Proxmox management pages
- All components use existing UI components from src/components/ui/index.tsx
- TypeScript and ESLint pass with 0 errors
- All tests pass
Files changed: 24 files, +2199 insertions
2026-06-11 18:47:09 +00:00
|
|
|
</div>
|
2026-06-13 02:58:31 +00:00
|
|
|
<Button
|
|
|
|
|
variant="outline"
|
|
|
|
|
size="sm"
|
|
|
|
|
onClick={() => void loadTasks(clusterId)}
|
|
|
|
|
disabled={loading || !clusterId}
|
|
|
|
|
>
|
|
|
|
|
<RefreshCw className={`mr-2 h-4 w-4 ${loading ? 'animate-spin' : ''}`} />
|
|
|
|
|
Refresh
|
|
|
|
|
</Button>
|
feat: implement 100% Proxmox PDM feature parity - UI components
- Add 8 new UI components: AclList, AddRemoteForm, ContainerConsole, ContainerOverview, EditRemoteForm, RemoveRemoteDialog, VMConsole, VMOverview
- Add 13 Proxmox management pages: ACLPage, BackupPage, CephPage, CertificatesPage, ContainersPage, FirewallPage, HAPage, NetworkPage, RemotesPage, SDNPage, StoragePage, TasksPage, VMsPage
- Add 13 new routes to App.tsx for Proxmox management pages
- All components use existing UI components from src/components/ui/index.tsx
- TypeScript and ESLint pass with 0 errors
- All tests pass
Files changed: 24 files, +2199 insertions
2026-06-11 18:47:09 +00:00
|
|
|
</div>
|
|
|
|
|
|
2026-06-13 02:58:31 +00:00
|
|
|
{error && (
|
|
|
|
|
<div className="rounded border border-destructive/40 bg-destructive/10 px-3 py-2 text-sm text-destructive">
|
|
|
|
|
{error}
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
|
|
<div className="grid grid-cols-3 gap-4">
|
|
|
|
|
<Card>
|
|
|
|
|
<CardContent className="pt-4">
|
|
|
|
|
<div className="text-2xl font-bold text-yellow-500">{runningCount}</div>
|
|
|
|
|
<div className="text-sm text-muted-foreground">Running</div>
|
|
|
|
|
</CardContent>
|
|
|
|
|
</Card>
|
|
|
|
|
<Card>
|
|
|
|
|
<CardContent className="pt-4">
|
|
|
|
|
<div className="text-2xl font-bold text-green-500">{completedCount}</div>
|
|
|
|
|
<div className="text-sm text-muted-foreground">Completed</div>
|
|
|
|
|
</CardContent>
|
|
|
|
|
</Card>
|
feat: implement 100% Proxmox PDM feature parity - UI components
- Add 8 new UI components: AclList, AddRemoteForm, ContainerConsole, ContainerOverview, EditRemoteForm, RemoveRemoteDialog, VMConsole, VMOverview
- Add 13 Proxmox management pages: ACLPage, BackupPage, CephPage, CertificatesPage, ContainersPage, FirewallPage, HAPage, NetworkPage, RemotesPage, SDNPage, StoragePage, TasksPage, VMsPage
- Add 13 new routes to App.tsx for Proxmox management pages
- All components use existing UI components from src/components/ui/index.tsx
- TypeScript and ESLint pass with 0 errors
- All tests pass
Files changed: 24 files, +2199 insertions
2026-06-11 18:47:09 +00:00
|
|
|
<Card>
|
2026-06-13 02:58:31 +00:00
|
|
|
<CardContent className="pt-4">
|
|
|
|
|
<div className="text-2xl font-bold text-red-500">{failedCount}</div>
|
|
|
|
|
<div className="text-sm text-muted-foreground">Failed</div>
|
feat: implement 100% Proxmox PDM feature parity - UI components
- Add 8 new UI components: AclList, AddRemoteForm, ContainerConsole, ContainerOverview, EditRemoteForm, RemoveRemoteDialog, VMConsole, VMOverview
- Add 13 Proxmox management pages: ACLPage, BackupPage, CephPage, CertificatesPage, ContainersPage, FirewallPage, HAPage, NetworkPage, RemotesPage, SDNPage, StoragePage, TasksPage, VMsPage
- Add 13 new routes to App.tsx for Proxmox management pages
- All components use existing UI components from src/components/ui/index.tsx
- TypeScript and ESLint pass with 0 errors
- All tests pass
Files changed: 24 files, +2199 insertions
2026-06-11 18:47:09 +00:00
|
|
|
</CardContent>
|
|
|
|
|
</Card>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<Card>
|
|
|
|
|
<CardHeader>
|
2026-06-13 02:58:31 +00:00
|
|
|
<CardTitle>Task Log</CardTitle>
|
feat: implement 100% Proxmox PDM feature parity - UI components
- Add 8 new UI components: AclList, AddRemoteForm, ContainerConsole, ContainerOverview, EditRemoteForm, RemoveRemoteDialog, VMConsole, VMOverview
- Add 13 Proxmox management pages: ACLPage, BackupPage, CephPage, CertificatesPage, ContainersPage, FirewallPage, HAPage, NetworkPage, RemotesPage, SDNPage, StoragePage, TasksPage, VMsPage
- Add 13 new routes to App.tsx for Proxmox management pages
- All components use existing UI components from src/components/ui/index.tsx
- TypeScript and ESLint pass with 0 errors
- All tests pass
Files changed: 24 files, +2199 insertions
2026-06-11 18:47:09 +00:00
|
|
|
</CardHeader>
|
|
|
|
|
<CardContent>
|
2026-06-13 02:58:31 +00:00
|
|
|
{loading ? (
|
|
|
|
|
<div className="text-sm text-muted-foreground">Loading tasks...</div>
|
|
|
|
|
) : tasks.length === 0 ? (
|
|
|
|
|
<div className="text-sm text-muted-foreground">
|
|
|
|
|
{clusterId ? 'No tasks found.' : 'No cluster configured.'}
|
|
|
|
|
</div>
|
|
|
|
|
) : (
|
|
|
|
|
<div className="space-y-0">
|
|
|
|
|
{tasks.map((t, i) => (
|
|
|
|
|
<div
|
|
|
|
|
key={`${t.upid}-${i}`}
|
|
|
|
|
className="flex flex-wrap items-center gap-3 border-b py-2 text-sm last:border-0"
|
|
|
|
|
>
|
|
|
|
|
<Badge variant={taskBadgeVariant(t.exitstatus)}>
|
|
|
|
|
{taskBadgeLabel(t.exitstatus)}
|
|
|
|
|
</Badge>
|
|
|
|
|
<span className="font-medium">{t.type}</span>
|
|
|
|
|
<span className="text-muted-foreground">{t.node}</span>
|
|
|
|
|
<span className="text-xs text-muted-foreground">{t.user}</span>
|
|
|
|
|
<span className="text-xs text-muted-foreground">
|
|
|
|
|
{formatTimestamp(t.starttime)}
|
|
|
|
|
</span>
|
|
|
|
|
<span className="ml-auto max-w-xs truncate font-mono text-xs text-muted-foreground">
|
|
|
|
|
{t.upid}
|
|
|
|
|
</span>
|
|
|
|
|
</div>
|
|
|
|
|
))}
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
feat: implement 100% Proxmox PDM feature parity - UI components
- Add 8 new UI components: AclList, AddRemoteForm, ContainerConsole, ContainerOverview, EditRemoteForm, RemoveRemoteDialog, VMConsole, VMOverview
- Add 13 Proxmox management pages: ACLPage, BackupPage, CephPage, CertificatesPage, ContainersPage, FirewallPage, HAPage, NetworkPage, RemotesPage, SDNPage, StoragePage, TasksPage, VMsPage
- Add 13 new routes to App.tsx for Proxmox management pages
- All components use existing UI components from src/components/ui/index.tsx
- TypeScript and ESLint pass with 0 errors
- All tests pass
Files changed: 24 files, +2199 insertions
2026-06-11 18:47:09 +00:00
|
|
|
</CardContent>
|
|
|
|
|
</Card>
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
}
|