diff --git a/app/static/index.html b/app/static/index.html index 571ac95..2e62fbb 100644 --- a/app/static/index.html +++ b/app/static/index.html @@ -224,6 +224,125 @@ 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 { margin-bottom: 2rem; @@ -845,6 +964,126 @@ 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 = ` +
+

📋 ${namespace.namespace} - Detailed Analysis

+
+

Pods: ${Object.keys(namespace.pods || {}).length}

+

Total Issues: ${namespace.total_validations || 0}

+

Severity Breakdown:

+ +
+
+

🔍 Pod Analysis

+ `; + + // Add details for each pod + Object.values(namespace.pods || {}).forEach(pod => { + html += ` +
+
📦 ${pod.pod_name}
+

Status: ${pod.phase}

+

Node: ${pod.node_name}

+
+
Containers:
+ `; + + pod.containers.forEach(container => { + const hasRequests = Object.keys(container.resources?.requests || {}).length > 0; + const hasLimits = Object.keys(container.resources?.limits || {}).length > 0; + + html += ` +
+

${container.name} (${container.image})

+

Requests: ${hasRequests ? JSON.stringify(container.resources.requests) : '❌ Not defined'}

+

Limits: ${hasLimits ? JSON.stringify(container.resources.limits) : '❌ Not defined'}

+
+ `; + }); + + html += ` +
+
+
Issues Found:
+ `; + + pod.validations.forEach(validation => { + const severityClass = `severity-${validation.severity}`; + html += ` +
+

${validation.rule_name}: ${validation.message}

+

Recommendation: ${validation.recommendation}

+
+ `; + }); + + html += ` +
+
+ `; + }); + + html += ` +
+
+ `; + + 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 = ` + + `; + 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 function applyFilters() { if (!currentData) return;