Refactor: group smart recommendations by type and remove redundant View Details button

This commit is contained in:
2025-10-02 10:15:51 -03:00
parent 91e68b79c7
commit 943fe4fcac
3 changed files with 186 additions and 77 deletions

View File

@@ -1569,6 +1569,9 @@
'low': '⚪'
}[rec.priority] || '⚪';
// Check if this is a grouped recommendation
const isGrouped = rec.workload_name === "Multiple Workloads" && rec.workload_list;
html += `
<div class="recommendation-card" data-priority="${rec.priority}" data-type="${rec.recommendation_type}"
style="border: 1px solid #ddd; border-radius: 8px; margin-bottom: 1rem; overflow: hidden; background: white;">
@@ -1576,9 +1579,13 @@
<div>
<h3 style="margin: 0 0 0.5rem 0; color: #2c3e50;">${priorityIcon} ${rec.title}</h3>
<p style="margin: 0; color: #7f8c8d; font-size: 0.9rem;">
<strong>Workload:</strong> ${rec.workload_name} |
<strong>Namespace:</strong> ${rec.namespace} |
<strong>Type:</strong> ${rec.recommendation_type.replace('_', ' ').toUpperCase()}
${isGrouped ?
`<strong>Workloads:</strong> ${rec.workload_list.length} workloads |
<strong>Type:</strong> ${rec.recommendation_type.replace('_', ' ').toUpperCase()}` :
`<strong>Workload:</strong> ${rec.workload_name} |
<strong>Namespace:</strong> ${rec.namespace} |
<strong>Type:</strong> ${rec.recommendation_type.replace('_', ' ').toUpperCase()}`
}
</p>
</div>
<div style="text-align: right;">
@@ -1591,6 +1598,15 @@
<div class="recommendation-body" style="padding: 1rem;">
<p style="margin: 0 0 1rem 0; color: #2c3e50;">${rec.description}</p>
${isGrouped && rec.workload_list ? `
<div style="margin-bottom: 1rem;">
<h4 style="color: #2c3e50; margin-bottom: 0.5rem; font-size: 1rem;">Affected Workloads:</h4>
<ul style="margin: 0; padding-left: 1.5rem; color: #555;">
${rec.workload_list.map(workload => `<li style="margin-bottom: 0.25rem;">${workload}</li>`).join('')}
</ul>
</div>
` : ''}
${rec.implementation_steps ? `
<div style="margin-bottom: 1rem;">
<h4 style="color: #2c3e50; margin-bottom: 0.5rem; font-size: 1rem;">Implementation Steps:</h4>
@@ -1610,14 +1626,10 @@
` : ''}
<div style="display: flex; gap: 0.5rem; margin-top: 1rem;">
<button onclick="showRecommendationDetails(${index})"
style="padding: 0.5rem 1rem; background: #3498db; color: white; border: none; border-radius: 4px; cursor: pointer; font-size: 0.9rem;">
📋 View Details
</button>
${rec.vpa_yaml ? `
<button onclick="showVPAYaml(${index})"
style="padding: 0.5rem 1rem; background: #9b59b6; color: white; border: none; border-radius: 4px; cursor: pointer; font-size: 0.9rem;">
📄 VPA YAML
📄 Generate VPA YAML
</button>
` : ''}
</div>
@@ -2036,62 +2048,6 @@
loadSmartRecommendations();
}
function showRecommendationDetails(index) {
const rec = window.currentRecommendations[index];
if (!rec) return;
let modalContent = `
<div class="modal-header" style="background: #f8f9fa; color: #2c3e50; padding: 2rem; position: relative; border-bottom: 1px solid #dee2e6;">
<h2 style="margin: 0; font-size: 1.5rem; font-weight: 600;">📋 Recommendation Details</h2>
<span class="close" onclick="closeModal()">&times;</span>
</div>
<div class="modal-body" style="padding: 2rem; max-height: 70vh; overflow-y: auto;">
<div style="margin-bottom: 2rem;">
<h3 style="color: #2c3e50; margin-bottom: 1rem;">${rec.title}</h3>
<div style="background: #f8f9fa; padding: 1rem; border-radius: 8px; margin-bottom: 1rem;">
<p><strong>Workload:</strong> ${rec.workload_name}</p>
<p><strong>Namespace:</strong> ${rec.namespace}</p>
<p><strong>Type:</strong> ${rec.recommendation_type.replace('_', ' ').toUpperCase()}</p>
<p><strong>Priority:</strong> <span style="background: ${getPriorityColor(rec.priority)}; color: white; padding: 0.25rem 0.5rem; border-radius: 4px; font-size: 0.8rem;">${rec.priority.toUpperCase()}</span></p>
${rec.confidence_level ? `<p><strong>Confidence:</strong> ${Math.round(rec.confidence_level * 100)}%</p>` : ''}
</div>
<h4 style="color: #2c3e50; margin-bottom: 1rem;">Description</h4>
<p style="margin-bottom: 2rem; color: #555;">${rec.description}</p>
${rec.implementation_steps ? `
<h4 style="color: #2c3e50; margin-bottom: 1rem;">Implementation Steps</h4>
<ol style="margin-bottom: 2rem; padding-left: 1.5rem; color: #555;">
${rec.implementation_steps.map(step => `<li style="margin-bottom: 0.5rem;">${step}</li>`).join('')}
</ol>
` : ''}
${rec.kubectl_commands && rec.kubectl_commands.length > 0 ? `
<h4 style="color: #2c3e50; margin-bottom: 1rem;">OpenShift Commands</h4>
<div style="background: #f8f9fa; border: 1px solid #dee2e6; border-radius: 4px; padding: 1rem; margin-bottom: 2rem; font-family: 'Courier New', monospace; font-size: 0.9rem;">
${rec.kubectl_commands.map(cmd => `<div style="margin-bottom: 0.5rem;">${cmd}</div>`).join('')}
</div>
<div style="background: #e3f2fd; border: 1px solid #2196f3; border-radius: 4px; padding: 1rem; margin-bottom: 2rem;">
<p style="margin: 0; color: #1565c0; font-size: 0.9rem;">
<strong>💡 Note:</strong> To get the VPA YAML file, click the "📄 VPA YAML" button in the recommendation card.
</p>
</div>
` : ''}
<div style="text-align: center; margin-top: 2rem;">
<button onclick="copyRecommendationCommands(${index})" style="padding: 0.75rem 1.5rem; background: #28a745; color: white; border: none; border-radius: 4px; cursor: pointer; margin-right: 1rem;">
📋 Copy Commands
</button>
<button onclick="closeModal()" style="padding: 0.75rem 1.5rem; background: #6c757d; color: white; border: none; border-radius: 4px; cursor: pointer;">
Close
</button>
</div>
</div>
</div>
`;
showModal(modalContent);
}
function showVPAYaml(index) {
const rec = window.currentRecommendations[index];
@@ -2123,13 +2079,6 @@ ${rec.vpa_yaml}
showModal(modalContent);
}
function copyRecommendationCommands(index) {
const rec = window.currentRecommendations[index];
if (!rec || !rec.kubectl_commands) return;
const commands = rec.kubectl_commands.join('\n');
copyToClipboard(commands);
}
function copyVPAYaml(index) {
const rec = window.currentRecommendations[index];