Spaces:
Running
Running
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Advanced Monitoring Dashboard</title> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> | |
| <style> | |
| .risk-level-1 { | |
| background-color: #10B981; | |
| } | |
| .risk-level-2 { | |
| background-color: #F59E0B; | |
| } | |
| .risk-level-3 { | |
| background-color: #EF4444; | |
| } | |
| .slide-down { | |
| max-height: 0; | |
| overflow: hidden; | |
| transition: max-height 0.3s ease-out; | |
| } | |
| .slide-down.active { | |
| max-height: 500px; | |
| transition: max-height 0.5s ease-in; | |
| } | |
| .spinner { | |
| animation: spin 1s linear infinite; | |
| } | |
| @keyframes spin { | |
| 0% { transform: rotate(0deg); } | |
| 100% { transform: rotate(360deg); } | |
| } | |
| .square-details { | |
| background-color: #f9fafb; | |
| border-left: 4px solid #3b82f6; | |
| } | |
| </style> | |
| </head> | |
| <body class="bg-gray-100"> | |
| <div class="container mx-auto px-4 py-8"> | |
| <div class="flex justify-between items-center mb-6"> | |
| <h1 class="text-3xl font-bold text-gray-800">Advanced Monitoring Dashboard</h1> | |
| <div class="flex space-x-3"> | |
| <button id="expandAllBtn" class="bg-blue-500 hover:bg-blue-600 text-white px-4 py-2 rounded-lg flex items-center"> | |
| <i class="fas fa-expand mr-2"></i> Expand All | |
| </button> | |
| <button id="exportBtn" class="bg-green-500 hover:bg-green-600 text-white px-4 py-2 rounded-lg flex items-center"> | |
| <i class="fas fa-file-export mr-2"></i> Export | |
| </button> | |
| <button id="rerunBtn" class="bg-purple-500 hover:bg-purple-600 text-white px-4 py-2 rounded-lg flex items-center"> | |
| <i class="fas fa-sync-alt mr-2"></i> Rerun | |
| </button> | |
| <button id="addBtn" class="bg-indigo-500 hover:bg-indigo-600 text-white px-4 py-2 rounded-lg flex items-center"> | |
| <i class="fas fa-plus mr-2"></i> Add | |
| </button> | |
| </div> | |
| </div> | |
| <div class="bg-white rounded-xl shadow-md overflow-hidden"> | |
| <div class="overflow-x-auto"> | |
| <table class="min-w-full divide-y divide-gray-200"> | |
| <thead class="bg-gray-50"> | |
| <tr> | |
| <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"> | |
| <input type="checkbox" id="selectAll" class="rounded text-blue-500"> | |
| </th> | |
| <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"> | |
| SQR MID | |
| </th> | |
| <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"> | |
| Risk Level | |
| </th> | |
| <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"> | |
| Recent Message | |
| </th> | |
| <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"> | |
| Report | |
| </th> | |
| <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"> | |
| Last Updated | |
| </th> | |
| <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"> | |
| Actions | |
| </th> | |
| </tr> | |
| </thead> | |
| <tbody class="bg-white divide-y divide-gray-200" id="monitoringTableBody"> | |
| <!-- Rows will be populated by JavaScript --> | |
| </tbody> | |
| </table> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Add Monitoring Modal --> | |
| <div id="addModal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center hidden"> | |
| <div class="bg-white rounded-xl p-6 w-full max-w-md"> | |
| <div class="flex justify-between items-center mb-4"> | |
| <h2 class="text-xl font-bold text-gray-800">Add New Monitoring</h2> | |
| <button id="closeAddModal" class="text-gray-500 hover:text-gray-700"> | |
| <i class="fas fa-times"></i> | |
| </button> | |
| </div> | |
| <div class="mb-4"> | |
| <label for="sqrMidInput" class="block text-sm font-medium text-gray-700 mb-1">SQR MID</label> | |
| <input type="text" id="sqrMidInput" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-indigo-500"> | |
| </div> | |
| <div id="previewSection" class="hidden mb-4 p-4 bg-gray-50 rounded-lg"> | |
| <div class="flex items-center mb-3"> | |
| <div class="w-16 h-16 bg-gray-200 rounded-lg mr-3 overflow-hidden"> | |
| <img id="previewImage" src="" alt="Preview" class="w-full h-full object-cover"> | |
| </div> | |
| <div> | |
| <h3 id="previewName" class="font-medium text-gray-800"></h3> | |
| <p id="previewDesc" class="text-sm text-gray-600"></p> | |
| </div> | |
| </div> | |
| <div class="text-sm"> | |
| <p class="font-medium text-gray-700 mb-1">Recent Message:</p> | |
| <p id="previewMessage" class="text-gray-600"></p> | |
| </div> | |
| </div> | |
| <div class="flex justify-end space-x-3"> | |
| <button id="cancelAddBtn" class="px-4 py-2 border border-gray-300 rounded-md text-gray-700 hover:bg-gray-50"> | |
| Close | |
| </button> | |
| <button id="confirmAddBtn" class="px-4 py-2 bg-indigo-500 text-white rounded-md hover:bg-indigo-600"> | |
| Add & Monitor | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Config Modal --> | |
| <div id="configModal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center hidden"> | |
| <div class="bg-white rounded-xl p-6 w-full max-w-md"> | |
| <div class="flex justify-between items-center mb-4"> | |
| <h2 class="text-xl font-bold text-gray-800">Edit Monitoring Config</h2> | |
| <button id="closeConfigModal" class="text-gray-500 hover:text-gray-700"> | |
| <i class="fas fa-times"></i> | |
| </button> | |
| </div> | |
| <div class="mb-4"> | |
| <label class="block text-sm font-medium text-gray-700 mb-1">Monitoring Frequency</label> | |
| <select id="monitoringInterval" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-indigo-500"> | |
| <option value="1">1 hour</option> | |
| <option value="2">2 hours</option> | |
| <option value="3">3 hours</option> | |
| <option value="4">4 hours</option> | |
| <option value="6">6 hours</option> | |
| <option value="8">8 hours</option> | |
| <option value="12">12 hours</option> | |
| <option value="24">24 hours</option> | |
| </select> | |
| </div> | |
| <div class="mb-4"> | |
| <label class="block text-sm font-medium text-gray-700 mb-1">Recent Messages Count</label> | |
| <select id="messageCount" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-indigo-500"> | |
| <option value="10">10 messages</option> | |
| <option value="20">20 messages</option> | |
| <option value="30">30 messages</option> | |
| <option value="40">40 messages</option> | |
| <option value="50">50 messages</option> | |
| </select> | |
| </div> | |
| <div class="flex justify-end space-x-3"> | |
| <button id="cancelConfigBtn" class="px-4 py-2 border border-gray-300 rounded-md text-gray-700 hover:bg-gray-50"> | |
| Cancel | |
| </button> | |
| <button id="saveConfigBtn" class="px-4 py-2 bg-indigo-500 text-white rounded-md hover:bg-indigo-600"> | |
| Save Changes | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| <script> | |
| // Enhanced sample data with square details | |
| const monitoringData = [ | |
| { | |
| sqr_mid: "MID-1001", | |
| name: "Payment Gateway", | |
| description: "Main payment processing service", | |
| image: "https://images.unsplash.com/photo-1556742049-0cfed4f6a45d?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1470&q=80", | |
| risk_level: 1, | |
| recent_messages: [ | |
| "Transaction processed successfully", | |
| "No errors detected in last scan", | |
| "System performance optimal" | |
| ], | |
| report: "All systems operational. No issues detected in the last 24 hours.", | |
| last_updated: "2023-05-15 09:23:45", | |
| status: "ready", | |
| config: { | |
| interval: 1, | |
| message_count: 10 | |
| } | |
| }, | |
| { | |
| sqr_mid: "MID-1002", | |
| name: "Inventory Service", | |
| description: "Product inventory management", | |
| image: "https://images.unsplash.com/photo-1556740738-b6a63e27c4df?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1470&q=80", | |
| risk_level: 2, | |
| recent_messages: [ | |
| "Warning: Low stock detected for SKU-4567", | |
| "Synchronization with warehouse delayed by 15 minutes", | |
| "Database backup completed" | |
| ], | |
| report: "Minor issues detected. Low stock warnings for 3 products. Synchronization delays.", | |
| last_updated: "2023-05-15 08:45:12", | |
| status: "ready", | |
| config: { | |
| interval: 2, | |
| message_count: 20 | |
| } | |
| }, | |
| { | |
| sqr_mid: "MID-1003", | |
| name: "Customer API", | |
| description: "Customer data access endpoint", | |
| image: "https://images.unsplash.com/photo-1551288049-bebda4e38f71?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1470&q=80", | |
| risk_level: 3, | |
| recent_messages: [ | |
| "ERROR: Authentication failure rate at 12%", | |
| "Response times exceeding SLA by 300ms", | |
| "Emergency maintenance scheduled" | |
| ], | |
| report: "Critical issues detected. High failure rate on authentication. Performance degraded.", | |
| last_updated: "2023-05-15 07:30:18", | |
| status: "ready", | |
| config: { | |
| interval: 4, | |
| message_count: 30 | |
| } | |
| }, | |
| { | |
| sqr_mid: "MID-1004", | |
| name: "Order Processing", | |
| description: "Order fulfillment pipeline", | |
| image: "https://images.unsplash.com/photo-1556742044-3c52d6e88c62?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1470&q=80", | |
| risk_level: 2, | |
| recent_messages: [ | |
| "Warning: Processing queue backlog of 125 orders", | |
| "Shipping API connectivity issues resolved", | |
| "Daily report generated" | |
| ], | |
| report: "Moderate issues. Order backlog detected. Shipping API had temporary outage.", | |
| last_updated: "2023-05-15 10:15:33", | |
| status: "ready", | |
| config: { | |
| interval: 8, | |
| message_count: 10 | |
| } | |
| } | |
| ]; | |
| // DOM elements | |
| const tableBody = document.getElementById('monitoringTableBody'); | |
| const addModal = document.getElementById('addModal'); | |
| const configModal = document.getElementById('configModal'); | |
| const expandAllBtn = document.getElementById('expandAllBtn'); | |
| const exportBtn = document.getElementById('exportBtn'); | |
| const rerunBtn = document.getElementById('rerunBtn'); | |
| const addBtn = document.getElementById('addBtn'); | |
| const selectAll = document.getElementById('selectAll'); | |
| const sqrMidInput = document.getElementById('sqrMidInput'); | |
| const previewSection = document.getElementById('previewSection'); | |
| const confirmAddBtn = document.getElementById('confirmAddBtn'); | |
| const cancelAddBtn = document.getElementById('cancelAddBtn'); | |
| const closeAddModal = document.getElementById('closeAddModal'); | |
| const closeConfigModal = document.getElementById('closeConfigModal'); | |
| const cancelConfigBtn = document.getElementById('cancelConfigBtn'); | |
| const saveConfigBtn = document.getElementById('saveConfigBtn'); | |
| // Current config being edited | |
| let currentConfigItem = null; | |
| // Initialize the table with enhanced square details | |
| function renderTable() { | |
| tableBody.innerHTML = ''; | |
| monitoringData.forEach(item => { | |
| const row = document.createElement('tr'); | |
| row.className = 'hover:bg-gray-50'; | |
| row.dataset.sqrMid = item.sqr_mid; | |
| // Checkbox | |
| const checkboxCell = document.createElement('td'); | |
| checkboxCell.className = 'px-6 py-4 whitespace-nowrap'; | |
| const checkbox = document.createElement('input'); | |
| checkbox.type = 'checkbox'; | |
| checkbox.className = 'row-checkbox rounded text-blue-500'; | |
| checkboxCell.appendChild(checkbox); | |
| row.appendChild(checkboxCell); | |
| // SQR MID | |
| const sqrMidCell = document.createElement('td'); | |
| sqrMidCell.className = 'px-6 py-4 whitespace-nowrap'; | |
| sqrMidCell.innerHTML = `<div class="text-sm font-medium text-gray-900">${item.sqr_mid}</div>`; | |
| row.appendChild(sqrMidCell); | |
| // Risk Level | |
| const riskCell = document.createElement('td'); | |
| riskCell.className = 'px-6 py-4 whitespace-nowrap'; | |
| riskCell.innerHTML = ` | |
| <div class="flex items-center"> | |
| <div class="h-4 w-4 rounded-full risk-level-${item.risk_level} mr-2"></div> | |
| <span class="text-sm font-medium">Level ${item.risk_level}</span> | |
| </div> | |
| `; | |
| row.appendChild(riskCell); | |
| // Recent Messages | |
| const messagesCell = document.createElement('td'); | |
| messagesCell.className = 'px-6 py-4 whitespace-nowrap'; | |
| messagesCell.innerHTML = ` | |
| <div class="flex items-center"> | |
| <div class="text-sm text-gray-500 max-w-xs truncate">${item.recent_messages[0]}</div> | |
| <button class="ml-2 text-gray-400 hover:text-gray-600 message-toggle"> | |
| <i class="fas fa-chevron-down"></i> | |
| </button> | |
| </div> | |
| <div class="slide-down mt-2"> | |
| <ul class="text-sm text-gray-500 list-disc pl-5"> | |
| ${item.recent_messages.map(msg => `<li class="mb-1">${msg}</li>`).join('')} | |
| </ul> | |
| </div> | |
| `; | |
| row.appendChild(messagesCell); | |
| // Report | |
| const reportCell = document.createElement('td'); | |
| reportCell.className = 'px-6 py-4 whitespace-nowrap'; | |
| reportCell.innerHTML = ` | |
| <div class="flex items-center"> | |
| <div class="text-sm text-gray-500 max-w-xs truncate">${item.report.substring(0, 50)}...</div> | |
| <button class="ml-2 text-gray-400 hover:text-gray-600 report-toggle"> | |
| <i class="fas fa-chevron-down"></i> | |
| </button> | |
| </div> | |
| <div class="slide-down mt-2"> | |
| <div class="text-sm text-gray-500">${item.report}</div> | |
| </div> | |
| `; | |
| row.appendChild(reportCell); | |
| // Last Updated | |
| const updatedCell = document.createElement('td'); | |
| updatedCell.className = 'px-6 py-4 whitespace-nowrap'; | |
| updatedCell.innerHTML = `<div class="text-sm text-gray-500">${item.last_updated}</div>`; | |
| row.appendChild(updatedCell); | |
| // Actions | |
| const actionsCell = document.createElement('td'); | |
| actionsCell.className = 'px-6 py-4 whitespace-nowrap text-sm font-medium'; | |
| actionsCell.innerHTML = ` | |
| <div class="flex items-center space-x-2"> | |
| <span class="status-badge inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium ${ | |
| item.status === 'ready' ? 'bg-green-100 text-green-800' : 'bg-yellow-100 text-yellow-800' | |
| }"> | |
| ${item.status === 'rerun' ? '<i class="fas fa-sync-alt spinner mr-1"></i>' : ''} | |
| ${item.status} | |
| </span> | |
| <button class="text-indigo-600 hover:text-indigo-900 config-btn"> | |
| <i class="fas fa-cog"></i> | |
| </button> | |
| <button class="text-red-600 hover:text-red-900 delete-btn"> | |
| <i class="fas fa-trash"></i> | |
| </button> | |
| </div> | |
| `; | |
| row.appendChild(actionsCell); | |
| // Square Details Row (initially hidden) | |
| const detailsRow = document.createElement('tr'); | |
| detailsRow.className = 'square-details hidden'; | |
| detailsRow.dataset.sqrMid = item.sqr_mid; | |
| detailsRow.innerHTML = ` | |
| <td colspan="8" class="px-6 py-4"> | |
| <div class="grid grid-cols-1 md:grid-cols-3 gap-4"> | |
| <div class="col-span-1"> | |
| <h3 class="font-medium text-gray-800 mb-1">Square Details</h3> | |
| <p class="text-sm text-gray-600 mb-2">${item.description}</p> | |
| <img src="${item.image}" alt="${item.name}" class="w-full h-32 object-cover rounded-lg"> | |
| </div> | |
| <div class="col-span-2"> | |
| <h3 class="font-medium text-gray-800 mb-1">Recent Messages</h3> | |
| <ul class="text-sm text-gray-500 list-disc pl-5"> | |
| ${item.recent_messages.map(msg => `<li class="mb-1">${msg}</li>`).join('')} | |
| </ul> | |
| <h3 class="font-medium text-gray-800 mt-3 mb-1">Full Report</h3> | |
| <p class="text-sm text-gray-500">${item.report}</p> | |
| </div> | |
| </div> | |
| </td> | |
| `; | |
| // Add click handler to show square details when clicking the SQR MID | |
| sqrMidCell.addEventListener('click', function(e) { | |
| if (e.target.tagName !== 'INPUT') { // Don't trigger when clicking checkbox | |
| detailsRow.classList.toggle('hidden'); | |
| } | |
| }); | |
| tableBody.appendChild(row); | |
| tableBody.appendChild(detailsRow); | |
| }); | |
| // Add event listeners to all toggle buttons | |
| document.querySelectorAll('.message-toggle').forEach(btn => { | |
| btn.addEventListener('click', function() { | |
| const slideDown = this.closest('td').querySelector('.slide-down'); | |
| slideDown.classList.toggle('active'); | |
| const icon = this.querySelector('i'); | |
| if (slideDown.classList.contains('active')) { | |
| icon.classList.replace('fa-chevron-down', 'fa-chevron-up'); | |
| } else { | |
| icon.classList.replace('fa-chevron-up', 'fa-chevron-down'); | |
| } | |
| }); | |
| }); | |
| document.querySelectorAll('.report-toggle').forEach(btn => { | |
| btn.addEventListener('click', function() { | |
| const slideDown = this.closest('td').querySelector('.slide-down'); | |
| slideDown.classList.toggle('active'); | |
| const icon = this.querySelector('i'); | |
| if (slideDown.classList.contains('active')) { | |
| icon.classList.replace('fa-chevron-down', 'fa-chevron-up'); | |
| } else { | |
| icon.classList.replace('fa-chevron-up', 'fa-chevron-down'); | |
| } | |
| }); | |
| }); | |
| // Add event listeners to config buttons | |
| document.querySelectorAll('.config-btn').forEach(btn => { | |
| btn.addEventListener('click', function() { | |
| const row = this.closest('tr'); | |
| const sqrMid = row.dataset.sqrMid; | |
| const item = monitoringData.find(item => item.sqr_mid === sqrMid); | |
| currentConfigItem = item; | |
| // Set current values in modal | |
| document.getElementById('monitoringInterval').value = item.config.interval; | |
| document.getElementById('messageCount').value = item.config.message_count; | |
| configModal.classList.remove('hidden'); | |
| }); | |
| }); | |
| // Add event listeners to delete buttons | |
| document.querySelectorAll('.delete-btn').forEach(btn => { | |
| btn.addEventListener('click', function() { | |
| const row = this.closest('tr'); | |
| const sqrMid = row.dataset.sqrMid; | |
| if (confirm(`Are you sure you want to delete monitoring for ${sqrMid}?`)) { | |
| const index = monitoringData.findIndex(item => item.sqr_mid === sqrMid); | |
| if (index !== -1) { | |
| monitoringData.splice(index, 1); | |
| renderTable(); | |
| } | |
| } | |
| }); | |
| }); | |
| } | |
| // Event listeners | |
| addBtn.addEventListener('click', () => { | |
| addModal.classList.remove('hidden'); | |
| sqrMidInput.focus(); | |
| }); | |
| closeAddModal.addEventListener('click', () => { | |
| addModal.classList.add('hidden'); | |
| previewSection.classList.add('hidden'); | |
| sqrMidInput.value = ''; | |
| }); | |
| cancelAddBtn.addEventListener('click', () => { | |
| addModal.classList.add('hidden'); | |
| previewSection.classList.add('hidden'); | |
| sqrMidInput.value = ''; | |
| }); | |
| closeConfigModal.addEventListener('click', () => { | |
| configModal.classList.add('hidden'); | |
| }); | |
| cancelConfigBtn.addEventListener('click', () => { | |
| configModal.classList.add('hidden'); | |
| }); | |
| saveConfigBtn.addEventListener('click', () => { | |
| if (currentConfigItem) { | |
| currentConfigItem.config.interval = parseInt(document.getElementById('monitoringInterval').value); | |
| currentConfigItem.config.message_count = parseInt(document.getElementById('messageCount').value); | |
| renderTable(); | |
| configModal.classList.add('hidden'); | |
| alert('Configuration saved successfully!'); | |
| } | |
| }); | |
| expandAllBtn.addEventListener('click', () => { | |
| const allSlideDowns = document.querySelectorAll('.slide-down'); | |
| const allMessageToggles = document.querySelectorAll('.message-toggle i'); | |
| const allReportToggles = document.querySelectorAll('.report-toggle i'); | |
| const anyExpanded = Array.from(allSlideDowns).some(el => el.classList.contains('active')); | |
| allSlideDowns.forEach(el => { | |
| if (anyExpanded) { | |
| el.classList.remove('active'); | |
| } else { | |
| el.classList.add('active'); | |
| } | |
| }); | |
| allMessageToggles.forEach(icon => { | |
| if (anyExpanded) { | |
| icon.classList.replace('fa-chevron-up', 'fa-chevron-down'); | |
| } else { | |
| icon.classList.replace('fa-chevron-down', 'fa-chevron-up'); | |
| } | |
| }); | |
| allReportToggles.forEach(icon => { | |
| if (anyExpanded) { | |
| icon.classList.replace('fa-chevron-up', 'fa-chevron-down'); | |
| } else { | |
| icon.classList.replace('fa-chevron-down', 'fa-chevron-up'); | |
| } | |
| }); | |
| }); | |
| exportBtn.addEventListener('click', () => { | |
| const selectedRows = Array.from(document.querySelectorAll('.row-checkbox:checked')).map(checkbox => { | |
| return checkbox.closest('tr').dataset.sqrMid; | |
| }); | |
| if (selectedRows.length === 0) { | |
| alert('Please select at least one row to export.'); | |
| return; | |
| } | |
| const dataToExport = monitoringData.filter(item => selectedRows.includes(item.sqr_mid)); | |
| // In a real app, this would generate an actual Excel file | |
| console.log('Exporting data:', dataToExport); | |
| alert(`Preparing export for ${selectedRows.length} selected items.`); | |
| }); | |
| rerunBtn.addEventListener('click', () => { | |
| const selectedRows = Array.from(document.querySelectorAll('.row-checkbox:checked')).map(checkbox => { | |
| return checkbox.closest('tr').dataset.sqrMid; | |
| }); | |
| if (selectedRows.length === 0) { | |
| alert('Please select at least one row to rerun.'); | |
| return; | |
| } | |
| // Update status to rerun and show loading spinner | |
| monitoringData.forEach(item => { | |
| if (selectedRows.includes(item.sqr_mid)) { | |
| item.status = 'rerun'; | |
| } | |
| }); | |
| renderTable(); | |
| // Simulate server response after 3 seconds | |
| setTimeout(() => { | |
| monitoringData.forEach(item => { | |
| if (selectedRows.includes(item.sqr_mid)) { | |
| item.status = 'ready'; | |
| // Simulate updated data | |
| item.last_updated = new Date().toISOString().replace('T', ' ').substring(0, 19); | |
| // Randomly change risk level for demo purposes | |
| if (Math.random() > 0.7) { | |
| item.risk_level = Math.floor(Math.random() * 3) + 1; | |
| } | |
| // Add a new recent message | |
| const messages = [ | |
| "Rerun completed successfully", | |
| "New data processed", | |
| "System check completed", | |
| "Updated metrics available" | |
| ]; | |
| item.recent_messages.unshift(messages[Math.floor(Math.random() * messages.length)]); | |
| // Update report | |
| item.report = `Rerun completed at ${new Date().toISOString().substring(11, 19)}. ` + | |
| (item.risk_level === 1 ? "No issues detected." : | |
| item.risk_level === 2 ? "Some warnings detected." : "Critical issues found."); | |
| } | |
| }); | |
| renderTable(); | |
| alert('Rerun completed for selected items!'); | |
| }, 3000); | |
| }); | |
| selectAll.addEventListener('change', function() { | |
| const checkboxes = document.querySelectorAll('.row-checkbox'); | |
| checkboxes.forEach(checkbox => { | |
| checkbox.checked = this.checked; | |
| }); | |
| }); | |
| sqrMidInput.addEventListener('input', function() { | |
| // In a real app, this would call an API to validate the SQR MID | |
| // For demo purposes, we'll just show a preview after 3 characters | |
| if (this.value.length >= 3) { | |
| // Simulate API response | |
| const mockResponses = { | |
| "MID": { | |
| name: "Payment Gateway", | |
| description: "Main payment processing service", | |
| image: "https://images.unsplash.com/photo-1556742049-0cfed4f6a45d?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1470&q=80", | |
| recent_message: "Transaction processed successfully" | |
| }, | |
| "INV": { | |
| name: "Inventory Service", | |
| description: "Product inventory management", | |
| image: "https://images.unsplash.com/photo-1556740738-b6a63e27c4df?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1470&q=80", | |
| recent_message: "Warning: Low stock detected for SKU-4567" | |
| }, | |
| "CUS": { | |
| name: "Customer API", | |
| description: "Customer data access endpoint", | |
| image: "https://images.unsplash.com/photo-1551288049-bebda4e38f71?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1470&q=80", | |
| recent_message: "ERROR: Authentication failure rate at 12%" | |
| }, | |
| "ORD": { | |
| name: "Order Processing", | |
| description: "Order fulfillment pipeline", | |
| image: "https://images.unsplash.com/photo-1556742044-3c52d6e88c62?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1470&q=80", | |
| recent_message: "Warning: Processing queue backlog of 125 orders" | |
| } | |
| }; | |
| const prefix = this.value.substring(0, 3).toUpperCase(); | |
| const mockData = mockResponses[prefix] || { | |
| name: `Service ${this.value}`, | |
| description: `Description for service ${this.value}`, | |
| image: "https://via.placeholder.com/150/008000/FFFFFF", | |
| recent_message: `Initializing monitoring for ${this.value}` | |
| }; | |
| document.getElementById('previewImage').src = mockData.image; | |
| document.getElementById('previewName').textContent = mockData.name; | |
| document.getElementById('previewDesc').textContent = mockData.description; | |
| document.getElementById('previewMessage').textContent = mockData.recent_message; | |
| previewSection.classList.remove('hidden'); | |
| } else { | |
| previewSection.classList.add('hidden'); | |
| } | |
| }); | |
| confirmAddBtn.addEventListener('click', function() { | |
| const sqrMid = sqrMidInput.value.trim(); | |
| if (!sqrMid) { | |
| alert('Please enter a valid SQR MID'); | |
| return; | |
| } | |
| // Check if already exists | |
| if (monitoringData.some(item => item.sqr_mid === sqrMid)) { | |
| alert('This SQR MID is already being monitored'); | |
| return; | |
| } | |
| // Add new monitoring item | |
| const newItem = { | |
| sqr_mid: sqrMid, | |
| name: document.getElementById('previewName').textContent || `Service ${sqrMid}`, | |
| description: document.getElementById('previewDesc').textContent || `Monitoring for ${sqrMid}`, | |
| image: document.getElementById('previewImage').src || "https://via.placeholder.com/150/008000/FFFFFF", | |
| risk_level: 1, | |
| recent_messages: [ | |
| document.getElementById('previewMessage').textContent || `Monitoring started for ${sqrMid}` | |
| ], | |
| report: `Initial monitoring report for ${sqrMid}. No issues detected.`, | |
| last_updated: new Date().toISOString().replace('T', ' ').substring(0, 19), | |
| status: "ready", | |
| config: { | |
| interval: 1, | |
| message_count: 10 | |
| } | |
| }; | |
| monitoringData.push(newItem); | |
| renderTable(); | |
| // Reset and close modal | |
| sqrMidInput.value = ''; | |
| previewSection.classList.add('hidden'); | |
| addModal.classList.add('hidden'); | |
| alert(`Successfully added monitoring for ${sqrMid}`); | |
| }); | |
| // Initial render | |
| renderTable(); | |
| </script> | |
| <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=vrvrv/monitoring-dashboard" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> | |
| </html> |