diff --git a/server/dataFetcher.js b/server/dataFetcher.js
index 73e2df7b7..db259cd2e 100644
--- a/server/dataFetcher.js
+++ b/server/dataFetcher.js
@@ -275,9 +275,20 @@ async function fetchDataForPveEndpoint(endpointId, apiClientInstance, config) {
const correspondingNodeInfo = nodes[index];
if (!correspondingNodeInfo || !correspondingNodeInfo.node) return;
+ // Determine display name based on cluster configuration
+ let nodeDisplayName = correspondingNodeInfo.node;
+ if (endpointType === 'standalone' && config.name) {
+ // For standalone nodes, use the configured name
+ nodeDisplayName = config.name;
+ } else if (endpointType === 'cluster' && nodes.length > 1 && config.name) {
+ // For multi-node clusters, prefix with configured name
+ nodeDisplayName = `${config.name} - ${correspondingNodeInfo.node}`;
+ }
+
const finalNode = {
cpu: null, mem: null, disk: null, maxdisk: null, uptime: 0, loadavg: null, storage: [],
node: correspondingNodeInfo.node,
+ displayName: nodeDisplayName,
maxcpu: correspondingNodeInfo.maxcpu,
maxmem: correspondingNodeInfo.maxmem,
level: correspondingNodeInfo.level,
@@ -292,8 +303,18 @@ async function fetchDataForPveEndpoint(endpointId, apiClientInstance, config) {
if (result.status === 'fulfilled' && result.value) {
const nodeData = result.value;
// Use endpointId (the actual key) for constructing IDs and tagging
- endpointVms.push(...(nodeData.vms || []).map(vm => ({ ...vm, endpointId: endpointId, id: `${endpointId}-${vm.node}-${vm.vmid}` })));
- endpointContainers.push(...(nodeData.containers || []).map(ct => ({ ...ct, endpointId: endpointId, id: `${endpointId}-${ct.node}-${ct.vmid}` })));
+ endpointVms.push(...(nodeData.vms || []).map(vm => ({
+ ...vm,
+ endpointId: endpointId,
+ id: `${endpointId}-${vm.node}-${vm.vmid}`,
+ nodeDisplayName: nodeDisplayName // Use the calculated display name
+ })));
+ endpointContainers.push(...(nodeData.containers || []).map(ct => ({
+ ...ct,
+ endpointId: endpointId,
+ id: `${endpointId}-${ct.node}-${ct.vmid}`,
+ nodeDisplayName: nodeDisplayName // Use the calculated display name
+ })));
if (nodeData.nodeStatus && Object.keys(nodeData.nodeStatus).length > 0) {
const statusData = nodeData.nodeStatus;
diff --git a/src/public/js/ui/dashboard.js b/src/public/js/ui/dashboard.js
index 089167b9e..c05370fac 100644
--- a/src/public/js/ui/dashboard.js
+++ b/src/public/js/ui/dashboard.js
@@ -282,7 +282,7 @@ PulseApp.ui.dashboard = (() => {
uniqueId: guestUniqueId,
vmid: guest.vmid,
name: guest.name || `${guest.type === 'qemu' ? GUEST_TYPE_VM : GUEST_TYPE_CT} ${guest.vmid}`,
- node: guest.node,
+ node: guest.nodeDisplayName || guest.node, // Use display name if available
type: guest.type === 'qemu' ? GUEST_TYPE_VM : GUEST_TYPE_CT,
status: guest.status,
cpu: avgCpu,
diff --git a/src/public/js/ui/nodes.js b/src/public/js/ui/nodes.js
index 9fda2a9f2..0da3a85b4 100644
--- a/src/public/js/ui/nodes.js
+++ b/src/public/js/ui/nodes.js
@@ -64,7 +64,7 @@ PulseApp.ui.nodes = (() => {
${statusText}
-
${node.node || 'N/A'} |
+ ${node.displayName || node.node || 'N/A'} |
${cpuBarHTML} |
${memoryBarHTML} |
${diskBarHTML} |
@@ -99,7 +99,7 @@ PulseApp.ui.nodes = (() => {
card.innerHTML = `
-
${node.node || 'N/A'}
+
${node.displayName || node.node || 'N/A'}
${statusText}
@@ -237,7 +237,7 @@ PulseApp.ui.nodes = (() => {
-
${node.node || 'Unknown'}
+ ${node.displayName || node.node || 'Unknown'}
diff --git a/src/public/js/ui/settings.js b/src/public/js/ui/settings.js
index 6c551a71d..cb3540b10 100644
--- a/src/public/js/ui/settings.js
+++ b/src/public/js/ui/settings.js
@@ -814,7 +814,24 @@ PulseApp.ui.settings = (() => {
// Count only actual endpoint divs (not the empty state)
const existingEndpoints = container.querySelectorAll('.border:not(.border-dashed)');
- const index = existingEndpoints.length + 2; // Start from _2 for additional endpoints
+
+ // Find the next available index by checking existing endpoints
+ let index = 2;
+ const usedIndexes = new Set();
+ existingEndpoints.forEach(endpoint => {
+ const header = endpoint.querySelector('h4');
+ if (header) {
+ const match = header.textContent.match(/#(\d+)/);
+ if (match) {
+ usedIndexes.add(parseInt(match[1]));
+ }
+ }
+ });
+
+ // Find the first unused index starting from 2
+ while (usedIndexes.has(index)) {
+ index++;
+ }
const endpointHtml = `