feat: add labels to nodes in monitoring

This commit is contained in:
2025-09-20 22:13:39 +02:00
parent 491ddb86b8
commit 9d4b68e7fc
2 changed files with 95 additions and 5 deletions

View File

@@ -361,7 +361,7 @@ class MonitoringViewComponent extends Component {
} }
renderNodeCard(nodeData) { renderNodeCard(nodeData) {
const { ip, hostname, resources, hasResources, error, resourceSource } = nodeData; const { ip, hostname, resources, hasResources, error, resourceSource, labels } = nodeData;
if (!hasResources) { if (!hasResources) {
@@ -374,8 +374,21 @@ class MonitoringViewComponent extends Component {
<div class="node-status"> <div class="node-status">
<span class="status-badge error">❌ No Resources</span> <span class="status-badge error">❌ No Resources</span>
</div> </div>
${labels && Object.keys(labels).length > 0 ? `
<div class="node-labels">
<div class="labels-container">
${Object.entries(labels).map(([key, value]) =>
`<span class="label-chip">${key}: ${value}</span>`
).join('')}
</div>
<div class="labels-divider"></div>
</div>
` : ''}
<div class="node-error"> <div class="node-error">
${error || 'Monitoring endpoint not available'} <div class="error-label">⚠️ Error</div>
<div class="error-message">${error || 'Monitoring endpoint not available'}</div>
</div> </div>
${nodeData.lastSeen ? ` ${nodeData.lastSeen ? `
<div class="node-uptime"> <div class="node-uptime">
@@ -446,6 +459,17 @@ class MonitoringViewComponent extends Component {
<span class="status-badge ${resourceSource === 'monitoring' ? 'success' : 'warning'}">${resourceSourceText}</span> <span class="status-badge ${resourceSource === 'monitoring' ? 'success' : 'warning'}">${resourceSourceText}</span>
</div> </div>
${labels && Object.keys(labels).length > 0 ? `
<div class="node-labels">
<div class="labels-container">
${Object.entries(labels).map(([key, value]) =>
`<span class="label-chip">${key}: ${value}</span>`
).join('')}
</div>
<div class="labels-divider"></div>
</div>
` : ''}
${system.uptime_formatted ? ` ${system.uptime_formatted ? `
<div class="node-uptime"> <div class="node-uptime">
<div class="uptime-label">⏱️ Uptime</div> <div class="uptime-label">⏱️ Uptime</div>
@@ -469,7 +493,9 @@ class MonitoringViewComponent extends Component {
<div class="node-resources"> <div class="node-resources">
<div class="resource-item"> <div class="resource-item">
<div class="resource-label">⚡ CPU</div> <div class="resource-label">⚡ CPU</div>
<div class="resource-value">${Math.round(cpuUsed)}MHz / ${Math.round(cpuTotal)}MHz</div> <div class="resource-value">
<span class="value-label">Used:</span> ${Math.round(cpuUsed)}MHz / <span class="value-label">Total:</span> ${Math.round(cpuTotal)}MHz
</div>
<div class="resource-utilization"> <div class="resource-utilization">
<div class="utilization-bar"> <div class="utilization-bar">
<div class="utilization-fill ${this.getUtilizationColorClass(cpuUtilization)}" style="width: ${cpuUtilization}%"></div> <div class="utilization-fill ${this.getUtilizationColorClass(cpuUtilization)}" style="width: ${cpuUtilization}%"></div>
@@ -480,7 +506,9 @@ class MonitoringViewComponent extends Component {
<div class="resource-item"> <div class="resource-item">
<div class="resource-label">🧠 Memory</div> <div class="resource-label">🧠 Memory</div>
<div class="resource-value">${this.viewModel.formatResourceValue(memoryUsed, 'memory')} / ${this.viewModel.formatResourceValue(memoryTotal, 'memory')}</div> <div class="resource-value">
<span class="value-label">Used:</span> ${this.viewModel.formatResourceValue(memoryUsed, 'memory')} / <span class="value-label">Total:</span> ${this.viewModel.formatResourceValue(memoryTotal, 'memory')}
</div>
<div class="resource-utilization"> <div class="resource-utilization">
<div class="utilization-bar"> <div class="utilization-bar">
<div class="utilization-fill ${this.getUtilizationColorClass(memoryUtilization)}" style="width: ${memoryUtilization}%"></div> <div class="utilization-fill ${this.getUtilizationColorClass(memoryUtilization)}" style="width: ${memoryUtilization}%"></div>
@@ -491,7 +519,9 @@ class MonitoringViewComponent extends Component {
<div class="resource-item"> <div class="resource-item">
<div class="resource-label">💾 Storage</div> <div class="resource-label">💾 Storage</div>
<div class="resource-value">${this.viewModel.formatResourceValue(storageUsed, 'storage')} / ${this.viewModel.formatResourceValue(storageTotal, 'storage')}</div> <div class="resource-value">
<span class="value-label">Used:</span> ${this.viewModel.formatResourceValue(storageUsed, 'storage')} / <span class="value-label">Total:</span> ${this.viewModel.formatResourceValue(storageTotal, 'storage')}
</div>
<div class="resource-utilization"> <div class="resource-utilization">
<div class="utilization-bar"> <div class="utilization-bar">
<div class="utilization-fill ${this.getUtilizationColorClass(storageUtilization)}" style="width: ${storageUtilization}%"></div> <div class="utilization-fill ${this.getUtilizationColorClass(storageUtilization)}" style="width: ${storageUtilization}%"></div>

View File

@@ -4248,10 +4248,49 @@ html {
font-family: 'Courier New', monospace; 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 { .node-status {
margin-bottom: 0.75rem; 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 { .node-uptime {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
@@ -4385,6 +4424,27 @@ html {
font-weight: 600; 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 { .resource-utilization {
display: flex; display: flex;
align-items: center; align-items: center;