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
This commit is contained in:
2025-10-03 08:35:42 -03:00
parent 6bb678ca41
commit 28a3cbbae3

View File

@@ -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;
}
</style>
</head>
<body>
@@ -1307,17 +1389,46 @@
<div class="card-header">
<h2 class="card-title">Available Workloads</h2>
<div style="display: flex; gap: 12px; align-items: center;">
<select id="timeRangeSelect" class="openshift-select" onchange="loadHistoricalWorkloads()">
<option value="1h">Last 1 Hour</option>
<option value="24h" selected>Last 24 Hours</option>
<option value="7d">Last 7 Days</option>
<option value="30d">Last 30 Days</option>
</select>
<div class="pf-v6-c-dropdown" id="timeRangeDropdown">
<button class="pf-v6-c-dropdown__toggle" type="button" id="timeRangeToggle" aria-expanded="false" onclick="toggleTimeRangeDropdown()">
<span class="pf-v6-c-dropdown__toggle-text" id="timeRangeText">Last 24 Hours</span>
<span class="pf-v6-c-dropdown__toggle-icon">
<i class="fas fa-chevron-down"></i>
</span>
</button>
<ul class="pf-v6-c-dropdown__menu" id="timeRangeMenu" style="display: none;">
<li>
<button class="pf-v6-c-dropdown__menu-item" onclick="selectTimeRange('1h', 'Last 1 Hour')">
Last 1 Hour
</button>
</li>
<li>
<button class="pf-v6-c-dropdown__menu-item pf-m-selected" onclick="selectTimeRange('24h', 'Last 24 Hours')">
Last 24 Hours
</button>
</li>
<li>
<button class="pf-v6-c-dropdown__menu-item" onclick="selectTimeRange('6h', 'Last 6 Hours')">
Last 6 Hours
</button>
</li>
<li>
<button class="pf-v6-c-dropdown__menu-item" onclick="selectTimeRange('7d', 'Last 7 Days')">
Last 7 Days
</button>
</li>
<li>
<button class="pf-v6-c-dropdown__menu-item" onclick="selectTimeRange('30d', 'Last 30 Days')">
Last 30 Days
</button>
</li>
</ul>
</div>
<button class="openshift-button" id="refresh-historical">
<i class="fas fa-sync-alt"></i>
Refresh
</button>
</div>
</div>
</div>
<div class="table-content" id="historical-workloads-container">
<div class="loading-spinner">
@@ -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;