diff --git a/public/scripts/components/MonitoringViewComponent.js b/public/scripts/components/MonitoringViewComponent.js
index 1590636..32b2c4a 100644
--- a/public/scripts/components/MonitoringViewComponent.js
+++ b/public/scripts/components/MonitoringViewComponent.js
@@ -361,7 +361,7 @@ class MonitoringViewComponent extends Component {
}
renderNodeCard(nodeData) {
- const { ip, hostname, resources, hasResources, error, resourceSource } = nodeData;
+ const { ip, hostname, resources, hasResources, error, resourceSource, labels } = nodeData;
if (!hasResources) {
@@ -374,8 +374,21 @@ class MonitoringViewComponent extends Component {
❌ No Resources
+
+ ${labels && Object.keys(labels).length > 0 ? `
+
+
+ ${Object.entries(labels).map(([key, value]) =>
+ `${key}: ${value}`
+ ).join('')}
+
+
+
+ ` : ''}
+
- ${error || 'Monitoring endpoint not available'}
+
⚠️ Error
+
${error || 'Monitoring endpoint not available'}
${nodeData.lastSeen ? `
@@ -446,6 +459,17 @@ class MonitoringViewComponent extends Component {
${resourceSourceText}
+ ${labels && Object.keys(labels).length > 0 ? `
+
+
+ ${Object.entries(labels).map(([key, value]) =>
+ `${key}: ${value}`
+ ).join('')}
+
+
+
+ ` : ''}
+
${system.uptime_formatted ? `
⏱️ Uptime
@@ -469,7 +493,9 @@ class MonitoringViewComponent extends Component {
⚡ CPU
-
${Math.round(cpuUsed)}MHz / ${Math.round(cpuTotal)}MHz
+
+ Used: ${Math.round(cpuUsed)}MHz / Total: ${Math.round(cpuTotal)}MHz
+
@@ -480,7 +506,9 @@ class MonitoringViewComponent extends Component {
🧠 Memory
-
${this.viewModel.formatResourceValue(memoryUsed, 'memory')} / ${this.viewModel.formatResourceValue(memoryTotal, 'memory')}
+
+ Used: ${this.viewModel.formatResourceValue(memoryUsed, 'memory')} / Total: ${this.viewModel.formatResourceValue(memoryTotal, 'memory')}
+
@@ -491,7 +519,9 @@ class MonitoringViewComponent extends Component {
💾 Storage
-
${this.viewModel.formatResourceValue(storageUsed, 'storage')} / ${this.viewModel.formatResourceValue(storageTotal, 'storage')}
+
+ Used: ${this.viewModel.formatResourceValue(storageUsed, 'storage')} / Total: ${this.viewModel.formatResourceValue(storageTotal, 'storage')}
+
diff --git a/public/styles/main.css b/public/styles/main.css
index ecfe8e0..07cf3a7 100644
--- a/public/styles/main.css
+++ b/public/styles/main.css
@@ -4248,10 +4248,49 @@ html {
font-family: 'Courier New', monospace;
}
+.ip-label {
+ color: var(--text-tertiary);
+ font-size: 0.75rem;
+ font-weight: 500;
+ opacity: 0.8;
+ margin-right: 0.25rem;
+}
+
.node-status {
margin-bottom: 0.75rem;
}
+.node-labels {
+ margin-bottom: 0.75rem;
+}
+
+.labels-container {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 0.35rem;
+ margin-bottom: 0.5rem;
+}
+
+.labels-divider {
+ height: 1px;
+ background: var(--border-primary);
+ margin: 0.5rem 0;
+ opacity: 0.3;
+}
+
+.label-chip {
+ display: inline-flex;
+ align-items: center;
+ font-size: 0.75rem;
+ padding: 0.25rem 0.5rem;
+ border-radius: 9999px;
+ background: rgba(30, 58, 138, 0.35);
+ border: 1px solid rgba(59, 130, 246, 0.4);
+ color: #dbeafe;
+ white-space: nowrap;
+ font-family: inherit;
+}
+
.node-uptime {
display: flex;
justify-content: space-between;
@@ -4385,6 +4424,27 @@ html {
font-weight: 600;
}
+.value-label {
+ color: var(--text-secondary);
+ font-size: 0.8rem;
+ font-weight: 500;
+ opacity: 0.8;
+}
+
+.error-label {
+ color: var(--text-secondary);
+ font-size: 0.8rem;
+ font-weight: 500;
+ opacity: 0.8;
+ margin-bottom: 0.25rem;
+}
+
+.error-message {
+ color: var(--text-primary);
+ font-size: 0.875rem;
+ font-style: italic;
+}
+
.resource-utilization {
display: flex;
align-items: center;