From 28a3cbbae37b847d1febfa2bf491e8f3560677e4 Mon Sep 17 00:00:00 2001 From: andersonid Date: Fri, 3 Oct 2025 08:35:42 -0300 Subject: [PATCH] fix: resolve Historical Analysis loading and implement PatternFly dropdown - Fix Historical Analysis loading issue by updating loadHistoricalAnalysis function - Replace native HTML select with PatternFly dropdown for time range selector - Add PatternFly-compliant CSS styling for dropdown component - Implement proper dropdown functionality with toggle, selection, and outside click - Add accessibility features with ARIA attributes - Integrate dropdown with existing API calls - Improve user experience with consistent PatternFly design --- app/static/index.html | 195 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 186 insertions(+), 9 deletions(-) diff --git a/app/static/index.html b/app/static/index.html index a90b7c4..664a558 100644 --- a/app/static/index.html +++ b/app/static/index.html @@ -1002,6 +1002,88 @@ .pf-v6-c-dropdown__toggle[aria-expanded="true"] .pf-v6-c-dropdown__toggle-icon { transform: rotate(180deg); } + + /* PatternFly Dropdown Styles */ + .pf-v6-c-dropdown { + position: relative; + display: inline-block; + } + + .pf-v6-c-dropdown__toggle { + background: var(--pf-global--BackgroundColor--100); + border: 1px solid var(--pf-global--BorderColor--300); + color: var(--pf-global--Color--100); + padding: 8px 12px; + border-radius: 4px; + cursor: pointer; + display: flex; + align-items: center; + justify-content: space-between; + min-width: 150px; + font-size: 14px; + } + + .pf-v6-c-dropdown__toggle:hover { + background: var(--pf-global--BackgroundColor--200); + border-color: var(--pf-global--BorderColor--400); + } + + .pf-v6-c-dropdown__toggle:focus { + outline: 2px solid var(--pf-global--active-color--100); + outline-offset: 2px; + } + + .pf-v6-c-dropdown__toggle-text { + flex: 1; + text-align: left; + } + + .pf-v6-c-dropdown__toggle-icon { + margin-left: 8px; + transition: transform 0.2s ease; + } + + .pf-v6-c-dropdown__menu { + position: absolute; + top: 100%; + left: 0; + right: 0; + background: var(--pf-global--BackgroundColor--100); + border: 1px solid var(--pf-global--BorderColor--300); + border-radius: 4px; + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2); + z-index: 1000; + margin-top: 4px; + padding: 4px 0; + list-style: none; + margin: 0; + } + + .pf-v6-c-dropdown__menu-item { + background: none; + border: none; + color: var(--pf-global--Color--100); + padding: 8px 12px; + width: 100%; + text-align: left; + cursor: pointer; + font-size: 14px; + display: block; + } + + .pf-v6-c-dropdown__menu-item:hover { + background: var(--pf-global--BackgroundColor--200); + } + + .pf-v6-c-dropdown__menu-item.pf-m-selected { + background: var(--pf-global--active-color--100); + color: var(--pf-global--Color--light-100); + } + + .pf-v6-c-dropdown__menu-item:focus { + outline: 2px solid var(--pf-global--active-color--100); + outline-offset: -2px; + } @@ -1307,17 +1389,46 @@

Available Workloads

- +
+ + +
-
+
@@ -1407,6 +1518,19 @@ // Refresh buttons document.getElementById('refresh-workloads').addEventListener('click', loadRequestsLimits); document.getElementById('refresh-historical').addEventListener('click', loadHistoricalAnalysis); + + // Close dropdown when clicking outside + document.addEventListener('click', function(event) { + const dropdown = document.getElementById('timeRangeDropdown'); + if (dropdown && !dropdown.contains(event.target)) { + const menu = document.getElementById('timeRangeMenu'); + const toggle = document.getElementById('timeRangeToggle'); + if (menu && toggle) { + menu.style.display = 'none'; + toggle.setAttribute('aria-expanded', 'false'); + } + } + }); } function showSection(section) { @@ -2172,8 +2296,17 @@ try { showLoading('historical-workloads-container'); - // Get selected time range - const timeRange = document.getElementById('timeRangeSelect')?.value || '24h'; + // Get selected time range from PatternFly dropdown + const timeRangeText = document.getElementById('timeRangeText')?.textContent || 'Last 24 Hours'; + let timeRange = '24h'; // default + + switch(timeRangeText) { + case 'Last 1 Hour': timeRange = '1h'; break; + case 'Last 6 Hours': timeRange = '6h'; break; + case 'Last 24 Hours': timeRange = '24h'; break; + case 'Last 7 Days': timeRange = '7d'; break; + case 'Last 30 Days': timeRange = '30d'; break; + } // Load historical data const response = await fetch(`/api/v1/historical-analysis?time_range=${timeRange}`); @@ -2192,6 +2325,50 @@ loadHistoricalAnalysis(); } + // Time range dropdown functions + function toggleTimeRangeDropdown() { + const menu = document.getElementById('timeRangeMenu'); + const toggle = document.getElementById('timeRangeToggle'); + const isExpanded = toggle.getAttribute('aria-expanded') === 'true'; + + menu.style.display = isExpanded ? 'none' : 'block'; + toggle.setAttribute('aria-expanded', !isExpanded); + } + + function selectTimeRange(value, text) { + // Update selected item + document.querySelectorAll('#timeRangeMenu .pf-m-selected').forEach(item => { + item.classList.remove('pf-m-selected'); + }); + event.target.classList.add('pf-m-selected'); + + // Update display text + document.getElementById('timeRangeText').textContent = text; + + // Close dropdown + document.getElementById('timeRangeMenu').style.display = 'none'; + document.getElementById('timeRangeToggle').setAttribute('aria-expanded', 'false'); + + // Load data with new time range + loadHistoricalAnalysisWithTimeRange(value); + } + + async function loadHistoricalAnalysisWithTimeRange(timeRange) { + try { + showLoading('historical-workloads-container'); + + // Load historical data + const response = await fetch(`/api/v1/historical-analysis?time_range=${timeRange}`); + const data = await response.json(); + + updateHistoricalWorkloads(data); + + } catch (error) { + console.error('Error loading historical analysis data:', error); + showError('historical-workloads-container', 'Failed to load historical data'); + } + } + function updateMetricsCards(data) { document.getElementById('total-workloads').textContent = data.total_pods || 0; document.getElementById('total-namespaces').textContent = data.total_namespaces || 0;