fix(dashboard): render disk chart; show server name as node label
All checks were successful
Deploy to Production / Trigger production update (push) Successful in 7s
All checks were successful
Deploy to Production / Trigger production update (push) Successful in 7s
- Dashboard "ТОП статистика по диску" was stuck on "Загрузка...": the
node name in the dashboard_metrics WS payload is `name`, not `node`, so
the RRD query stayed disabled. Use name fallback and unwrap the
{data:[...]} response shape.
- Instances list + detail page: show the panel-side server name (from the
add-server form) in the "Узел" column/label instead of the Proxmox node
hostname. Real node is still used for all API calls.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -226,16 +226,24 @@ function ClusterNodesSection({ serverList, nodeStats }: { serverList: Rec[]; nod
|
||||
.sort((a, b) => (Number(b.disk_pct) || 0) - (Number(a.disk_pct) || 0))
|
||||
.slice(0, 5)
|
||||
|
||||
// Fetch RRD for each of those nodes in parallel
|
||||
// Fetch RRD for each of those nodes in parallel.
|
||||
// Node name comes from the `dashboard_metrics` WS payload, where the field is
|
||||
// `name` (not `node`); fall back to `node` for the REST `resources/all` shape.
|
||||
const rrdResults = useQueries({
|
||||
queries: chartNodes.map(n => ({
|
||||
queryKey: ['node-rrd', Number(n.server_id) || 0, String(n.node || ''), timeframe],
|
||||
queryFn: () =>
|
||||
apiClient.get<Rec[]>(
|
||||
`/proxmox/api/${n.server_id}/node/rrddata?node=${n.node}&timeframe=${timeframe}`
|
||||
),
|
||||
enabled: !!n.server_id && !!n.node,
|
||||
})),
|
||||
queries: chartNodes.map(n => {
|
||||
const nodeName = String(n.node || n.name || '')
|
||||
return {
|
||||
queryKey: ['node-rrd', Number(n.server_id) || 0, nodeName, timeframe],
|
||||
queryFn: () =>
|
||||
apiClient
|
||||
.get<{ data?: Rec[] } | Rec[]>(
|
||||
`/proxmox/api/${n.server_id}/node/rrddata?node=${encodeURIComponent(nodeName)}&timeframe=${timeframe}`
|
||||
)
|
||||
// Endpoint wraps the series in `{ data: [...] }`; tolerate both shapes.
|
||||
.then(r => (Array.isArray(r) ? r : (r?.data ?? []))),
|
||||
enabled: !!n.server_id && !!nodeName,
|
||||
}
|
||||
}),
|
||||
})
|
||||
|
||||
// Align series by index (all PVE nodes produce same-length RRD arrays)
|
||||
|
||||
@@ -30,6 +30,7 @@ import {
|
||||
} from '@/components/ui/dropdown-menu';
|
||||
import { StatusDot } from '@/components/shared/status-dot';
|
||||
import { useVirtualMachines, usePowerAction, useVMInterfaces } from '@/hooks/use-instances';
|
||||
import { useServers } from '@/hooks/use-nodes';
|
||||
import InstanceActionDialogs, { PowerConfirmDialog, type InstanceAction, type PowerAction } from './InstanceActionDialogs';
|
||||
import { vmTypeLabel } from '@/lib/format';
|
||||
import { toast } from 'sonner';
|
||||
@@ -57,6 +58,12 @@ export default function InstanceDetailPage() {
|
||||
const { data: allVMs, isLoading } = useVirtualMachines();
|
||||
const vm = allVMs?.find((v) => v.server_id === sid && v.vmid === vid);
|
||||
|
||||
// Show the panel-side server name (from the add-server form) instead of the
|
||||
// Proxmox node hostname, matching the instances list. `node` is still used for
|
||||
// all API calls below — only the displayed label changes.
|
||||
const { data: servers = [] } = useServers();
|
||||
const nodeLabel = servers.find((s) => s.id === sid)?.name || node;
|
||||
|
||||
const power = usePowerAction(sid, vid, type, node);
|
||||
const isRunning = vm?.status === 'running';
|
||||
|
||||
@@ -131,7 +138,7 @@ export default function InstanceDetailPage() {
|
||||
<StatusDot status={vm?.status || 'unknown'} pulse />
|
||||
{vm?.status || 'unknown'}
|
||||
</span>
|
||||
<span>Node: {node}</span>
|
||||
<span>{t('common.node', 'Node')}: {nodeLabel}</span>
|
||||
{displayIP && <span className="font-mono">{displayIP}</span>}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user