Spaces:
Running
Running
Download script.js from mfsobrin/workguard-sentinel: direct link, hf CLI and curl.
- Browser
- Download file 5.66 kB
-
https://huggingface.co/spaces/mfsobrin/workguard-sentinel/resolve/main/script.js
- Command line
-
hf download hf://spaces/mfsobrin/workguard-sentinel/script.js
-
curl -L -o script.js https://huggingface.co/spaces/mfsobrin/workguard-sentinel/resolve/main/script.js
5.66 kB
| // Realistic device simulation data with enhanced compliance checks | |
| const sampleData = { | |
| stats: { | |
| totalDevices: 30, | |
| compliantDevices: 22, | |
| nonCompliantDevices: 8, | |
| missingComponents: { | |
| ad: 3, | |
| antivirus: 5, | |
| tacticalRmm: 4, | |
| glpiAgent: 2, // Corrected from gpiAgent to glpiAgent | |
| encryption: 6, | |
| backup: 3, | |
| patches: 7 | |
| } | |
| }, | |
| devices: Array.from({length: 30}, (_, i) => { | |
| // Realistic compliance patterns | |
| const isCritical = i % 5 === 0; // 20% critical devices | |
| const isOld = i % 7 === 0; // ~14% older devices | |
| const isLaptop = i % 3 === 0; // 33% laptops | |
| const isRemote = i % 4 === 0; // 25% remote workers | |
| // Base compliance - critical devices are always compliant | |
| let isCompliant = isCritical || Math.random() > 0.25; | |
| // Older devices are less likely to be compliant | |
| if (isOld && Math.random() > 0.3) isCompliant = false; | |
| // Remote devices have specific compliance issues | |
| const remoteIssues = isRemote && Math.random() > 0.6; | |
| return { | |
| id: `DEV-${1000 + i}`, | |
| name: `${isLaptop ? 'LT' : 'DT'}-${String(i + 1).padStart(3, '0')}`, | |
| type: isLaptop ? 'Laptop' : 'Desktop', | |
| user: generateRealisticUsername(i), | |
| department: ['Finance', 'IT', 'HR', 'Marketing', 'Operations', 'Engineering'][i % 6], | |
| os: getRandomOS(i), | |
| ip: generateRandomIP(i), | |
| status: isCompliant ? 'compliant' : 'non-compliant', | |
| lastSeen: generateLastSeenDate(i, isCompliant), | |
| ad: isCompliant && !(remoteIssues && Math.random() > 0.7), | |
| antivirus: isCompliant && !(isOld && Math.random() > 0.4), | |
| tacticalRmm: isCompliant && Math.random() > 0.1, // 90% compliance for Tactical RMM | |
| glpiAgent: isCompliant && Math.random() > 0.2, // 80% compliance for GLPI | |
| antivirus: isCompliant && Math.random() > 0.05, // 95% compliance for Antivirus | |
| ad: isCompliant && Math.random() > 0.03, // 97% compliance for AD | |
| encryption: isCompliant && !(isLaptop && Math.random() > 0.2), | |
| backup: isCompliant && !(isOld && Math.random() > 0.5), | |
| patches: isCompliant ? Math.floor(Math.random() * 3) : Math.floor(Math.random() * 8) + 3, | |
| issues: isCompliant ? 0 : Math.floor(Math.random() * 3) + 1 | |
| }; | |
| }) | |
| }; | |
| // Helper functions for realistic data generation | |
| function generateRealisticUsername(index) { | |
| const firstNames = ['John', 'Jane', 'Michael', 'Sarah', 'David', 'Emily', 'Robert', 'Jennifer']; | |
| const lastNames = ['Smith', 'Johnson', 'Williams', 'Brown', 'Jones', 'Miller', 'Davis', 'Wilson']; | |
| const firstName = firstNames[index % firstNames.length]; | |
| const lastName = lastNames[Math.floor(index / firstNames.length) % lastNames.length]; | |
| return `${firstName.toLowerCase()}.${lastName.toLowerCase()}`; | |
| } | |
| function generateRandomIP(index) { | |
| return `192.168.${Math.floor(index / 16)}.${1 + (index % 254)}`; | |
| } | |
| function getRandomOS(index) { | |
| const osList = [ | |
| 'Windows 10 Enterprise', | |
| 'Windows 11 Enterprise', | |
| 'Windows 10 Pro', | |
| 'Windows 11 Pro', | |
| 'Windows Server 2019', | |
| 'Windows Server 2022' | |
| ]; | |
| return osList[index % osList.length]; | |
| } | |
| function generateLastSeenDate(index, isCompliant) { | |
| // Compliant devices seen more recently | |
| const maxDays = isCompliant ? 3 : 14; | |
| const offset = Math.random() * maxDays * 24 * 60 * 60 * 1000; | |
| return new Date(Date.now() - offset).toISOString(); | |
| } | |
| // Auto-refresh function | |
| function setupAutoRefresh() { | |
| setInterval(() => { | |
| console.log("Refreshing data..."); | |
| // In a real app, this would fetch fresh data from the API | |
| // For now, we'll just reinitialize the charts | |
| initCharts(); | |
| }, 5 * 60 * 1000); // 5 minutes | |
| } | |
| // Initialize everything when DOM is loaded | |
| document.addEventListener('DOMContentLoaded', () => { | |
| setupAutoRefresh(); | |
| updateLastUpdatedTime(); | |
| // Add click event to device rows | |
| document.addEventListener('click', (e) => { | |
| const row = e.target.closest('.device-row'); | |
| if (row) { | |
| const deviceId = row.dataset.id; | |
| console.log(`Device ${deviceId} clicked`); | |
| // In a real app, this would open a device detail view | |
| row.classList.add('bg-blue-900/10'); | |
| setTimeout(() => row.classList.remove('bg-blue-900/10'), 200); | |
| } | |
| }); | |
| // Update last updated time every minute | |
| setInterval(updateLastUpdatedTime, 60000); | |
| }); | |
| function updateLastUpdatedTime() { | |
| const now = new Date(); | |
| const timeString = now.toLocaleTimeString([], {hour: '2-digit', minute:'2-digit'}); | |
| document.getElementById('last-updated').textContent = `Today at ${timeString}`; | |
| } | |
| // Set up event listeners for filter controls | |
| document.querySelectorAll('.filter-select').forEach(select => { | |
| select.addEventListener('change', () => { | |
| console.log("Filter changed - would apply filters in real app"); | |
| }); | |
| }); | |
| // Export buttons | |
| document.getElementById('export-csv').addEventListener('click', () => { | |
| console.log("Exporting to CSV..."); | |
| // In a real app, this would generate and download a CSV file | |
| }); | |
| document.getElementById('export-pdf').addEventListener('click', () => { | |
| console.log("Exporting to PDF..."); | |
| // In a real app, this would generate and download a PDF report | |
| }); | |
| }); |