proxyscrape/puppet-proxy
1
1
2let autoRefreshInterval = null;
3let isAutoRefreshEnabled = false;
4
5function toggleAutoRefresh() {
6 const btn = document.getElementById('autoRefreshBtn');
7 const indicator = document.getElementById('autoRefreshIndicator');
8
9 if (isAutoRefreshEnabled) {
10 clearInterval(autoRefreshInterval);
11 isAutoRefreshEnabled = false;
12 btn.innerHTML = '<i class="bi bi-arrow-clockwise"></i> Enable Auto-Refresh';
13 btn.className = 'btn btn-success w-100';
14 indicator.style.display = 'none';
15 } else {
16 isAutoRefreshEnabled = true;
17 btn.innerHTML = '<i class="bi bi-pause-circle"></i> Disable Auto-Refresh';
18 btn.className = 'btn btn-warning w-100';
19 indicator.style.display = 'block';
20 autoRefreshInterval = setInterval(updateDashboard, 5000);
21 }
22}
23
24async function updateDashboard() {
25 try {
26 const response = await fetch('/api/stats');
27 const data = await response.json();
28
29 document.getElementById('totalRequests').textContent = data.serverStats.totalRequests;
30 document.getElementById('hitRate').textContent = data.serverStats.hitRate + '%';
31 document.getElementById('hitRateBar').style.width = data.serverStats.hitRate + '%';
32 document.getElementById('avgResponseTime').textContent = data.serverStats.averageResponseTime + 'ms';
33 document.getElementById('errorRate').textContent = data.serverStats.errorRate + '%';
34 document.getElementById('uptime').textContent = data.serverStats.uptime;
35 document.getElementById('cacheHits').textContent = data.serverStats.cacheHits;
36 document.getElementById('cacheMisses').textContent = data.serverStats.cacheMisses;
37 document.getElementById('errorCount').textContent = data.serverStats.errors;
38 document.getElementById('memoryEntries').textContent = data.cacheStats.memoryEntries;
39 document.getElementById('fileEntries').textContent = data.cacheStats.fileEntries;
40 document.getElementById('totalFileSize').textContent = data.cacheStats.totalFileSize;
41 document.getElementById('totalMemory').textContent = data.systemInfo.totalMemory;
42 document.getElementById('freeMemory').textContent = data.systemInfo.freeMemory;
43 document.getElementById('processMemory').textContent = data.systemInfo.processMemory.rss;
44 document.getElementById('heapUsed').textContent = data.systemInfo.processMemory.heapUsed;
45 const statusBadge = document.getElementById('browserStatusBadge');
46 statusBadge.textContent = data.browserStatus;
47 statusBadge.className = `status-badge ${data.browserStatus === 'Connected' ? 'badge-online' : 'badge-offline'}`;
48 updateRecentRequestsTable(data.recentRequests);
49
50 } catch (error) {
51 console.error('Failed to update dashboard:', error);
52 }
53}
54
55function updateRecentRequestsTable(requests) {
56 const tbody = document.querySelector('#recentRequestsTable tbody');
57 if (!tbody || !requests.length) return;
58
59 tbody.innerHTML = requests.map(request => `
60 <tr>
61 <td><small class="text-muted">${new Date(request.timestamp).toLocaleTimeString()}</small></td>
62 <td><div class="text-truncate" style="max-width: 200px;" title="${request.url}">${request.url}</div></td>
63 <td>
64 <span class="status-badge ${request.success ? 'badge-online' : 'badge-offline'}">
65 <i class="bi bi-${request.success ? 'check' : 'x'}"></i>
66 ${request.success ? 'Success' : 'Failed'}
67 </span>
68 </td>
69 <td><strong>${request.responseTime}ms</strong></td>
70 <td>${request.contentLength ? (request.contentLength / 1000).toFixed(1) + 'k' : 'N/A'}</td>
71 <td>
72 <span class="status-badge ${request.cached ? 'badge-cached' : 'badge-offline'}">
73 ${request.cached ? 'HIT' : 'MISS'}
74 </span>
75 </td>
76 </tr>
77 `).join('');
78}
79document.getElementById('testForm').addEventListener('submit', function () {
80 const btn = this.querySelector('button[type="submit"]');
81 const originalText = btn.innerHTML;
82 btn.innerHTML = '<span class="spinner-border spinner-border-sm me-2"></span>Testing...';
83 btn.disabled = true;
84 setTimeout(() => {
85 btn.innerHTML = originalText;
86 btn.disabled = false;
87 }, 15000);
88});
89setTimeout(() => {
90 const alerts = document.querySelectorAll('.alert-dismissible');
91 alerts.forEach(alert => {
92 const bsAlert = new bootstrap.Alert(alert);
93 bsAlert.close();
94 });
95}, 5000);
96document.querySelectorAll('form').forEach(form => {
97 form.addEventListener('submit', function () {
98 document.body.classList.add('loading');
99 });
100});
101 