import React, { useState, useEffect, useCallback } from 'react'; import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/index'; import { Button } from '@/components/ui/index'; import { Plus, Trash2, Eye } from 'lucide-react'; import { listClusterViews, createClusterView, deleteClusterView, listProxmoxClusters, ClusterView, } from '@/lib/proxmoxClient'; export function ProxmoxViewsPage() { const [views, setViews] = useState([]); const [clusterId, setClusterId] = useState(''); const [showCreate, setShowCreate] = useState(false); const [newViewName, setNewViewName] = useState(''); const [error, setError] = useState(null); const [deleting, setDeleting] = useState(null); const loadViews = useCallback(async (cId: string) => { if (!cId) return; setError(null); try { const v = await listClusterViews(cId); setViews(v); } catch (e) { setError(String(e)); } }, []); useEffect(() => { listProxmoxClusters() .then((cls) => { if (cls.length > 0) { setClusterId(cls[0].id); void loadViews(cls[0].id); } }) .catch(console.error); }, [loadViews]); const handleCreate = async () => { const trimmed = newViewName.trim(); if (!trimmed || !clusterId) return; setError(null); try { // Generate a simple ID from the name (lowercase, hyphenated) const viewId = trimmed.toLowerCase().replace(/\s+/g, '-').replace(/[^a-z0-9-]/g, ''); await createClusterView(clusterId, viewId, trimmed); setNewViewName(''); setShowCreate(false); void loadViews(clusterId); } catch (e) { setError(String(e)); } }; const handleDelete = async (viewId: string) => { if (!clusterId) return; setDeleting(viewId); setError(null); try { await deleteClusterView(clusterId, viewId); void loadViews(clusterId); } catch (e) { setError(String(e)); } finally { setDeleting(null); } }; return (

Views

Custom resource views and dashboards

{error && (
{error}
)} {showCreate && ( Create View setNewViewName(e.target.value)} onKeyDown={(e) => { if (e.key === 'Enter') void handleCreate(); if (e.key === 'Escape') setShowCreate(false); }} autoFocus /> )} {views.length === 0 && !showCreate ? ( {clusterId ? 'No custom views configured.' : 'No cluster configured.'} ) : (
{views.map((v) => (
{v.name} {v.description && (

{v.description}

)}
))}
)}
); }