Add: Detailed namespace analysis with modal popup showing pod and container details
This commit is contained in:
@@ -224,6 +224,125 @@
|
|||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Modal Styles */
|
||||||
|
.modal {
|
||||||
|
display: none;
|
||||||
|
position: fixed;
|
||||||
|
z-index: 1000;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background-color: rgba(0,0,0,0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-content {
|
||||||
|
background-color: #fefefe;
|
||||||
|
margin: 5% auto;
|
||||||
|
padding: 20px;
|
||||||
|
border: 1px solid #888;
|
||||||
|
border-radius: 8px;
|
||||||
|
width: 80%;
|
||||||
|
max-width: 1000px;
|
||||||
|
max-height: 80vh;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.close {
|
||||||
|
color: #aaa;
|
||||||
|
float: right;
|
||||||
|
font-size: 28px;
|
||||||
|
font-weight: bold;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.close:hover {
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Namespace Details Styles */
|
||||||
|
.namespace-details {
|
||||||
|
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
.namespace-summary {
|
||||||
|
background: #f8f9fa;
|
||||||
|
padding: 15px;
|
||||||
|
border-radius: 5px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.namespace-summary ul {
|
||||||
|
margin: 10px 0;
|
||||||
|
padding-left: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pod-detail {
|
||||||
|
border: 1px solid #dee2e6;
|
||||||
|
border-radius: 5px;
|
||||||
|
margin: 15px 0;
|
||||||
|
padding: 15px;
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pod-detail h5 {
|
||||||
|
color: #495057;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
border-bottom: 1px solid #dee2e6;
|
||||||
|
padding-bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.containers-detail {
|
||||||
|
margin: 15px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container-detail {
|
||||||
|
background: #f8f9fa;
|
||||||
|
padding: 10px;
|
||||||
|
margin: 10px 0;
|
||||||
|
border-radius: 3px;
|
||||||
|
border-left: 4px solid #007bff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.validations-detail {
|
||||||
|
margin: 15px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.validation-item {
|
||||||
|
padding: 10px;
|
||||||
|
margin: 8px 0;
|
||||||
|
border-radius: 3px;
|
||||||
|
border-left: 4px solid #6c757d;
|
||||||
|
}
|
||||||
|
|
||||||
|
.validation-item.severity-error {
|
||||||
|
background: #f8d7da;
|
||||||
|
border-left-color: #dc3545;
|
||||||
|
}
|
||||||
|
|
||||||
|
.validation-item.severity-warning {
|
||||||
|
background: #fff3cd;
|
||||||
|
border-left-color: #ffc107;
|
||||||
|
}
|
||||||
|
|
||||||
|
.validation-item.severity-info {
|
||||||
|
background: #d1ecf1;
|
||||||
|
border-left-color: #17a2b8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.validation-item p {
|
||||||
|
margin: 5px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.validation-item strong {
|
||||||
|
color: #495057;
|
||||||
|
}
|
||||||
|
|
||||||
|
.validation-item em {
|
||||||
|
color: #6c757d;
|
||||||
|
font-size: 0.9em;
|
||||||
|
}
|
||||||
|
|
||||||
/* Problem Summary Table */
|
/* Problem Summary Table */
|
||||||
.problem-summary {
|
.problem-summary {
|
||||||
margin-bottom: 2rem;
|
margin-bottom: 2rem;
|
||||||
@@ -845,6 +964,126 @@
|
|||||||
return 'info';
|
return 'info';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Analyze namespace - show detailed issues
|
||||||
|
function analyzeNamespace(namespaceName) {
|
||||||
|
if (!currentData || !currentData.namespaces) return;
|
||||||
|
|
||||||
|
const namespace = currentData.namespaces.find(ns => ns.namespace === namespaceName);
|
||||||
|
if (!namespace) return;
|
||||||
|
|
||||||
|
// Create detailed view
|
||||||
|
const detailsHtml = createNamespaceDetails(namespace);
|
||||||
|
|
||||||
|
// Show modal or expandable section
|
||||||
|
showNamespaceDetails(namespaceName, detailsHtml);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create detailed HTML for namespace issues
|
||||||
|
function createNamespaceDetails(namespace) {
|
||||||
|
let html = `
|
||||||
|
<div class="namespace-details">
|
||||||
|
<h3>📋 ${namespace.namespace} - Detailed Analysis</h3>
|
||||||
|
<div class="namespace-summary">
|
||||||
|
<p><strong>Pods:</strong> ${Object.keys(namespace.pods || {}).length}</p>
|
||||||
|
<p><strong>Total Issues:</strong> ${namespace.total_validations || 0}</p>
|
||||||
|
<p><strong>Severity Breakdown:</strong></p>
|
||||||
|
<ul>
|
||||||
|
<li>Errors: ${namespace.severity_breakdown?.error || 0}</li>
|
||||||
|
<li>Warnings: ${namespace.severity_breakdown?.warning || 0}</li>
|
||||||
|
<li>Info: ${namespace.severity_breakdown?.info || 0}</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="pods-details">
|
||||||
|
<h4>🔍 Pod Analysis</h4>
|
||||||
|
`;
|
||||||
|
|
||||||
|
// Add details for each pod
|
||||||
|
Object.values(namespace.pods || {}).forEach(pod => {
|
||||||
|
html += `
|
||||||
|
<div class="pod-detail">
|
||||||
|
<h5>📦 ${pod.pod_name}</h5>
|
||||||
|
<p><strong>Status:</strong> ${pod.phase}</p>
|
||||||
|
<p><strong>Node:</strong> ${pod.node_name}</p>
|
||||||
|
<div class="containers-detail">
|
||||||
|
<h6>Containers:</h6>
|
||||||
|
`;
|
||||||
|
|
||||||
|
pod.containers.forEach(container => {
|
||||||
|
const hasRequests = Object.keys(container.resources?.requests || {}).length > 0;
|
||||||
|
const hasLimits = Object.keys(container.resources?.limits || {}).length > 0;
|
||||||
|
|
||||||
|
html += `
|
||||||
|
<div class="container-detail">
|
||||||
|
<p><strong>${container.name}</strong> (${container.image})</p>
|
||||||
|
<p>Requests: ${hasRequests ? JSON.stringify(container.resources.requests) : '❌ Not defined'}</p>
|
||||||
|
<p>Limits: ${hasLimits ? JSON.stringify(container.resources.limits) : '❌ Not defined'}</p>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
});
|
||||||
|
|
||||||
|
html += `
|
||||||
|
</div>
|
||||||
|
<div class="validations-detail">
|
||||||
|
<h6>Issues Found:</h6>
|
||||||
|
`;
|
||||||
|
|
||||||
|
pod.validations.forEach(validation => {
|
||||||
|
const severityClass = `severity-${validation.severity}`;
|
||||||
|
html += `
|
||||||
|
<div class="validation-item ${severityClass}">
|
||||||
|
<p><strong>${validation.rule_name}:</strong> ${validation.message}</p>
|
||||||
|
<p><em>Recommendation:</em> ${validation.recommendation}</p>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
});
|
||||||
|
|
||||||
|
html += `
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
});
|
||||||
|
|
||||||
|
html += `
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
return html;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show namespace details in modal
|
||||||
|
function showNamespaceDetails(namespaceName, detailsHtml) {
|
||||||
|
// Create modal if it doesn't exist
|
||||||
|
let modal = document.getElementById('namespaceModal');
|
||||||
|
if (!modal) {
|
||||||
|
modal = document.createElement('div');
|
||||||
|
modal.id = 'namespaceModal';
|
||||||
|
modal.className = 'modal';
|
||||||
|
modal.innerHTML = `
|
||||||
|
<div class="modal-content">
|
||||||
|
<span class="close">×</span>
|
||||||
|
<div id="modalBody"></div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
document.body.appendChild(modal);
|
||||||
|
|
||||||
|
// Add close functionality
|
||||||
|
modal.querySelector('.close').onclick = () => modal.style.display = 'none';
|
||||||
|
modal.onclick = (e) => {
|
||||||
|
if (e.target === modal) modal.style.display = 'none';
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Populate and show modal
|
||||||
|
document.getElementById('modalBody').innerHTML = detailsHtml;
|
||||||
|
modal.style.display = 'block';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fix namespace - placeholder for now
|
||||||
|
function fixNamespace(namespaceName) {
|
||||||
|
alert(`Fix functionality for namespace "${namespaceName}" will be implemented in Phase 2.\n\nThis will include:\n- Auto-generating resource recommendations\n- Creating YAML patches\n- Applying fixes via OpenShift API`);
|
||||||
|
}
|
||||||
|
|
||||||
// Apply filters
|
// Apply filters
|
||||||
function applyFilters() {
|
function applyFilters() {
|
||||||
if (!currentData) return;
|
if (!currentData) return;
|
||||||
|
|||||||
Reference in New Issue
Block a user