From 9d4b68e7fca6cc0f9346079ff596afe6e1d52b02 Mon Sep 17 00:00:00 2001 From: Patrick Balsiger Date: Sat, 20 Sep 2025 22:13:39 +0200 Subject: [PATCH] feat: add labels to nodes in monitoring --- .../components/MonitoringViewComponent.js | 40 +++++++++++-- public/styles/main.css | 60 +++++++++++++++++++ 2 files changed, 95 insertions(+), 5 deletions(-) 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;