From ea7f92c8fc4f1ab20f3ee247ccd8e04b633c208f Mon Sep 17 00:00:00 2001 From: andersonid Date: Fri, 17 Oct 2025 15:14:31 -0300 Subject: [PATCH] Feature: Storage cylinder chart no dashboard - cilindro transparente com preenchimento verde mostrando uso de storage --- app/static/index.html | 235 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 235 insertions(+) diff --git a/app/static/index.html b/app/static/index.html index d52263e..e206bae 100644 --- a/app/static/index.html +++ b/app/static/index.html @@ -342,6 +342,114 @@ transform: translateY(-2px); box-shadow: 0 6px 12px rgba(0, 0, 0, 0.3); } + + /* Storage Cylinder Chart */ + .storage-cylinder-card { + background: linear-gradient(135deg, #2B2B2B 0%, #1E1E1E 100%); + border: 1px solid #404040; + border-radius: 8px; + padding: 20px; + text-align: center; + transition: all 0.3s ease; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + min-height: 200px; + } + + .storage-cylinder-card:hover { + transform: translateY(-2px); + box-shadow: 0 6px 12px rgba(0, 0, 0, 0.3); + } + + .storage-cylinder { + width: 80px; + height: 120px; + position: relative; + margin: 16px 0; + } + + .cylinder-container { + width: 100%; + height: 100%; + position: relative; + display: flex; + align-items: center; + justify-content: center; + } + + .cylinder-outline { + width: 60px; + height: 100px; + border: 3px solid rgba(255, 255, 255, 0.3); + border-radius: 30px; + position: relative; + background: rgba(255, 255, 255, 0.05); + overflow: hidden; + } + + .cylinder-fill { + position: absolute; + bottom: 0; + left: 0; + width: 100%; + background: linear-gradient(to top, + rgba(34, 197, 94, 0.8) 0%, + rgba(34, 197, 94, 0.6) 50%, + rgba(34, 197, 94, 0.4) 100%); + border-radius: 0 0 27px 27px; + transition: height 0.8s ease-in-out; + min-height: 2px; + } + + .cylinder-top { + position: absolute; + top: -3px; + left: -3px; + width: 66px; + height: 20px; + border: 3px solid rgba(255, 255, 255, 0.3); + border-bottom: none; + border-radius: 33px 33px 0 0; + background: rgba(255, 255, 255, 0.05); + } + + .cylinder-bottom { + position: absolute; + bottom: -3px; + left: -3px; + width: 66px; + height: 20px; + border: 3px solid rgba(255, 255, 255, 0.3); + border-top: none; + border-radius: 0 0 33px 33px; + background: rgba(255, 255, 255, 0.05); + } + + .storage-cylinder-info { + margin-top: 12px; + text-align: center; + } + + .storage-cylinder-label { + font-size: 14px; + color: var(--pf-global--Color--200); + margin-bottom: 4px; + } + + .storage-cylinder-value { + font-size: 18px; + font-weight: 600; + color: var(--pf-global--Color--100); + margin-bottom: 2px; + } + + .storage-cylinder-percentage { + font-size: 12px; + color: var(--pf-global--success-color--100); + font-weight: 500; + } /* Chart Cards */ .chart-card { @@ -1821,6 +1929,50 @@ + +
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
Storage Usage
+
-
+
0%
+
+
+
+
+ +
+
-
+
Total PVCs
+
+
+
+ +
+
-
+
Storage Warnings
+
+
+
+ +
+
-
+
Storage Classes
+
+
+

Resource Analytics

@@ -2727,6 +2879,86 @@ return 'Healthy'; } + // Dashboard Storage Functions + async function loadDashboardStorageData() { + try { + console.log('Loading dashboard storage data...'); + + // Load storage data from API + const response = await fetch('/api/v1/storage/analysis'); + if (!response.ok) { + throw new Error(`HTTP ${response.status}: ${response.statusText}`); + } + + const data = await response.json(); + + // Update dashboard storage metrics + updateDashboardStorageMetrics(data); + + console.log('Dashboard storage data loaded successfully'); + + } catch (error) { + console.error('Error loading dashboard storage data:', error); + // Don't show error for storage data, just log it + } + } + + function updateDashboardStorageMetrics(data) { + try { + // Update storage metrics cards + document.getElementById('dashboard-total-pvcs').textContent = data.total_pvcs || '0'; + document.getElementById('dashboard-storage-warnings').textContent = data.storage_warnings || '0'; + document.getElementById('dashboard-storage-classes').textContent = data.storage_classes ? data.storage_classes.length : '0'; + + // Update storage cylinder + updateStorageCylinder(data); + + } catch (error) { + console.error('Error updating dashboard storage metrics:', error); + } + } + + function updateStorageCylinder(data) { + try { + const totalStorageUsed = data.total_storage_used || 0; + const storageUtilization = data.storage_utilization_percent || 0; + + // Calculate cylinder fill percentage (use storage utilization or mock calculation) + const fillPercentage = Math.min(100, Math.max(0, storageUtilization)); + + // Update cylinder fill + const cylinderFill = document.getElementById('storage-cylinder-fill'); + if (cylinderFill) { + cylinderFill.style.height = `${fillPercentage}%`; + } + + // Update cylinder info + document.getElementById('storage-cylinder-used').textContent = formatBytes(totalStorageUsed); + document.getElementById('storage-cylinder-percentage').textContent = `${fillPercentage.toFixed(1)}%`; + + // Change color based on utilization level + const cylinderPercentage = document.getElementById('storage-cylinder-percentage'); + if (cylinderPercentage) { + if (fillPercentage >= 90) { + cylinderPercentage.style.color = 'var(--pf-global--danger-color--100)'; + cylinderFill.style.background = 'linear-gradient(to top, rgba(220, 38, 38, 0.8) 0%, rgba(220, 38, 38, 0.6) 50%, rgba(220, 38, 38, 0.4) 100%)'; + } else if (fillPercentage >= 75) { + cylinderPercentage.style.color = 'var(--pf-global--warning-color--100)'; + cylinderFill.style.background = 'linear-gradient(to top, rgba(245, 158, 11, 0.8) 0%, rgba(245, 158, 11, 0.6) 50%, rgba(245, 158, 11, 0.4) 100%)'; + } else if (fillPercentage >= 50) { + cylinderPercentage.style.color = 'var(--pf-global--info-color--100)'; + cylinderFill.style.background = 'linear-gradient(to top, rgba(59, 130, 246, 0.8) 0%, rgba(59, 130, 246, 0.6) 50%, rgba(59, 130, 246, 0.4) 100%)'; + } else { + cylinderPercentage.style.color = 'var(--pf-global--success-color--100)'; + cylinderFill.style.background = 'linear-gradient(to top, rgba(34, 197, 94, 0.8) 0%, rgba(34, 197, 94, 0.6) 50%, rgba(34, 197, 94, 0.4) 100%)'; + } + } + + } catch (error) { + console.error('Error updating storage cylinder:', error); + } + } + // Initialize the application document.addEventListener('DOMContentLoaded', function() { initializeApp(); @@ -3088,6 +3320,9 @@ // Update metrics cards with results updateMetricsCards(statusData.result); + // Load storage data for dashboard + await loadDashboardStorageData(); + // Load dashboard charts updateSmartProgress(100, 'Loading dashboard charts...'); await loadDashboardCharts();