|
1 | | -let refreshInterval = 0; // Initialize with a default value |
2 | | -let refreshTimer; // Variable to hold the setInterval timer |
3 | | -let refreshTimeout; // Variable to hold the setTimeout timer |
| 1 | +let refreshInterval = 0; |
| 2 | +let refreshTimer, refreshTimeout; |
4 | 3 |
|
| 4 | +// Fetch the refresh interval from the server |
5 | 5 | function fetchRefreshInterval() { |
6 | | - fetch('/api/v1/refresh-interval') |
| 6 | + return fetch('/api/v1/refresh-interval') |
7 | 7 | .then(response => response.json()) |
8 | 8 | .then(data => { |
9 | 9 | if (data.success) { |
10 | | - refreshInterval = data.refresh_interval * 1000; // Convert to milliseconds |
11 | | - console.log('Refresh interval fetched successfully:', data.refresh_interval); |
12 | | - startRefresh(); // Start refreshing after fetching the interval |
| 10 | + refreshInterval = data.refresh_interval * 1000; // Convert to ms |
| 11 | + console.log('Refresh interval:', data.refresh_interval); |
| 12 | + return refreshInterval; |
13 | 13 | } else { |
14 | | - console.error('Failed to fetch refresh interval:', data.error); |
| 14 | + console.error('Error fetching interval:', data.error); |
15 | 15 | } |
16 | 16 | }) |
17 | | - .catch(error => console.error('Error:', error)); |
| 17 | + .catch(error => console.error('Fetch interval error:', error)); |
18 | 18 | } |
19 | 19 |
|
20 | | -// Event listener for select input change |
21 | | -document.getElementById('refresh-interval').addEventListener('change', function () { |
22 | | - // Clear the existing timeout |
23 | | - clearTimeout(refreshTimeout); |
24 | | - |
25 | | - // Update the interval based on the selected value |
26 | | - refreshInterval = parseInt(this.value) * 1000; // Convert to milliseconds |
| 20 | +// Update the refresh interval when the user changes the value |
| 21 | +function updateRefreshInterval() { |
| 22 | + const refreshInput = document.getElementById('refresh-interval'); |
| 23 | + refreshInput.addEventListener('change', function () { |
| 24 | + clearTimeout(refreshTimeout); |
| 25 | + refreshInterval = parseInt(this.value) * 1000; |
27 | 26 |
|
28 | | - // refresh the page once |
29 | | - refreshTimeout = setTimeout(() => { |
30 | | - window.location.reload(); |
31 | | - }, refreshInterval); |
| 27 | + refreshTimeout = setTimeout(() => window.location.reload(), refreshInterval); |
| 28 | + |
| 29 | + postRefreshInterval(refreshInterval / 1000); // Send in seconds |
| 30 | + updateColorBars(); // Update color bars based on data attributes |
| 31 | +}); |
| 32 | +} |
32 | 33 |
|
33 | | - // Send the updated refresh interval to the server |
| 34 | +// Post the updated refresh interval to the server |
| 35 | +function postRefreshInterval(newInterval) { |
34 | 36 | fetch('/api/v1/refresh-interval', { |
35 | 37 | method: 'POST', |
36 | | - headers: { |
37 | | - 'Content-Type': 'application/json' |
38 | | - }, |
39 | | - body: JSON.stringify({ refresh_interval: parseInt(this.value) }) // Send in seconds, not milliseconds |
| 38 | + headers: { 'Content-Type': 'application/json' }, |
| 39 | + body: JSON.stringify({ refresh_interval: newInterval }) |
40 | 40 | }) |
41 | 41 | .then(response => response.json()) |
42 | 42 | .then(data => { |
43 | 43 | if (data.success) { |
44 | | - console.log('Refresh interval updated successfully:', data.refresh_interval); |
| 44 | + console.log('Updated interval:', data.refresh_interval); |
45 | 45 | } else { |
46 | | - console.error('Failed to update refresh interval:', data.error); |
| 46 | + console.error('Failed to update interval:', data.error); |
47 | 47 | } |
48 | 48 | }) |
49 | 49 | .catch(error => console.error('Error:', error)); |
50 | | -}); |
| 50 | +} |
51 | 51 |
|
52 | | -// Function to fetch system data from the API once |
| 52 | +// Fetch system data from a given API endpoint |
53 | 53 | function fetchSystemData(apiEndpoint) { |
54 | | - if (!apiEndpoint) { |
55 | | - console.error('Missing required parameter: apiEndpoint.'); |
56 | | - return; |
57 | | - } |
58 | | - |
59 | 54 | return fetch(apiEndpoint) |
60 | | - .then(response => { |
61 | | - if (!response.ok) { |
62 | | - throw new Error(`HTTP error! Status: ${response.status}`); |
63 | | - } |
64 | | - return response.json(); |
65 | | - }) |
66 | | - .then(data => { |
67 | | - return data; |
68 | | - }) |
| 55 | + .then(response => response.json()) |
69 | 56 | .catch(error => { |
70 | | - console.error(`Error fetching data from ${apiEndpoint}:`, error); |
71 | | - return null; // Return null on error so we can handle it later |
| 57 | + console.error(`Error fetching ${apiEndpoint}:`, error); |
| 58 | + return null; |
72 | 59 | }); |
73 | 60 | } |
74 | 61 |
|
75 | | -// Function to update individual cards with the fetched data |
76 | | -function updateCard(cardSelector, dataKey, data, unit = '') { |
| 62 | +// Update card content based on the fetched data |
| 63 | +function updateCard(cardSelector, dataKey, data, unit = '', barSelector) { |
77 | 64 | const cardElement = document.querySelector(cardSelector); |
78 | | - if (!cardElement) { |
79 | | - return; // Exit early if the card element is not found |
80 | | - } |
| 65 | + if (!cardElement) return; |
| 66 | + |
| 67 | + const dataValue = data?.[dataKey]; |
| 68 | + cardElement.querySelector('.card-text').textContent = dataValue |
| 69 | + ? `${dataValue}${unit}` |
| 70 | + : 'Data not available'; |
81 | 71 |
|
82 | | - const dataValue = data[dataKey]; |
83 | | - if (dataValue === undefined) { |
84 | | - console.warn(`Data key ${dataKey} not found in the response.`); |
85 | | - cardElement.querySelector('.card-text').textContent = 'Data not available'; |
86 | | - return; |
87 | | - } |
88 | | - else if (dataValue === null) { |
89 | | - console.warn(`Data key ${dataKey} is null in the response.`); |
90 | | - cardElement.querySelector('.card-text').textContent = 'Data not available'; |
91 | | - return; |
92 | | - } |
| 72 | + // update the bar element if a selector is provided |
| 73 | + if (barSelector) { |
| 74 | + const barElement = cardElement.querySelector(barSelector); |
| 75 | + if (!barElement) return; |
| 76 | + |
| 77 | + // update the bar element based on the data value |
| 78 | + const percentage = parseFloat(dataValue); |
| 79 | + if (isNaN(percentage)) return; |
93 | 80 |
|
94 | | - cardElement.querySelector('.card-text').textContent = `${dataValue}${unit}`; |
| 81 | + barElement.style.width = `${percentage}%`; |
| 82 | + } |
95 | 83 | } |
96 | 84 |
|
97 | | -// Main function to refresh data and update all necessary cards |
| 85 | + |
| 86 | +// Refresh all card data |
98 | 87 | function refreshData() { |
99 | | - fetchSystemData('api/system-info').then(data => { |
100 | | - if (!data) { |
101 | | - return; // Don't update cards if the fetch failed |
| 88 | + fetchSystemData('/api/system-info').then(data => { |
| 89 | + if (!data) return; |
| 90 | + updateCard('.bg-disk', 'disk_percent', data, '%', '.disk-bar'); |
| 91 | + updateCard('.cpu-temp-card', 'current_temp', data, ' °C', '.temp-bar'); |
| 92 | + updateCard('.bg-memory', 'memory_percent', data, '%', '.memory-usage-bar'); |
| 93 | + updateCard('.cpu-frequency', 'cpu_frequency', data, ' MHz', '.frequency-bar'); |
| 94 | + updateCard('.cpu-usage-card', 'cpu_percent', data, '%', '.cpu-usage-bar'); |
| 95 | + updateCard('.network-received', 'network_received', data, 'MB'); |
| 96 | + updateCard('.network-sent', 'network_sent', data, 'MB'); |
| 97 | + updateCard('.battery-card', 'battery_percent', data, '%', '.battery-bar'); |
| 98 | + updateColorBars(); // Update color bars based on data attributes |
| 99 | + }); |
| 100 | +} |
| 101 | + |
| 102 | +// Update color bars based on data attributes |
| 103 | +function updateColorBars() { |
| 104 | + const bars = [ |
| 105 | + { selector: '.battery-bar', dataAttr: 'data-battery', limits: [25, 75] }, |
| 106 | + { selector: '.disk-bar', dataAttr: 'data-disk-usage', limits: [60, 80] }, |
| 107 | + { selector: '.cpu-usage-bar', dataAttr: 'data-cpu-usage', limits: [50, 80] }, |
| 108 | + { selector: '.memory-usage-bar', dataAttr: 'data-memory-usage', limits: [0.5, 0.8], maxAttr: 'data-memory-total' }, |
| 109 | + { selector: '.frequency-bar', dataAttr: 'data-cpu-frequency', limits: [0.5, 0.8], maxAttr: 'data-cpu-max-frequency' }, |
| 110 | + { selector: '.temp-bar', dataAttr: 'data-cpu-temp', limits: [0.65, 0.9], maxAttr: 'data-cpu-max-temp' } |
| 111 | + ]; |
| 112 | + |
| 113 | + bars.forEach(({ selector, dataAttr, limits, maxAttr }) => { |
| 114 | + const bar = document.querySelector(selector); |
| 115 | + const card = document.querySelector(`[${dataAttr}]`); |
| 116 | + const maxElement = maxAttr ? document.querySelector(`[${maxAttr}]`) : null; |
| 117 | + |
| 118 | + if (!bar || !card) { |
| 119 | + // console.warn(`Element not found for selector: ${selector} or data attribute: ${dataAttr}`); |
| 120 | + return; |
| 121 | + } |
| 122 | + |
| 123 | + let percentage = parseFloat(card.getAttribute(dataAttr)); |
| 124 | + |
| 125 | + if (isNaN(percentage)) { |
| 126 | + console.warn(`Invalid percentage value for ${dataAttr}`); |
| 127 | + return; |
| 128 | + } |
| 129 | + |
| 130 | + // If maxAttr is defined, use it to scale the limits |
| 131 | + if (maxElement) { |
| 132 | + const maxValue = parseFloat(maxElement.getAttribute(maxAttr)); |
| 133 | + if (isNaN(maxValue)) { |
| 134 | + // console.warn(`Invalid max value for ${maxAttr}`); |
| 135 | + return; |
| 136 | + } |
| 137 | + |
| 138 | + limits = [maxValue * limits[0], maxValue * limits[1]]; |
| 139 | + } |
| 140 | + |
| 141 | + // Apply class based on percentage within the defined limits |
| 142 | + if (percentage <= limits[0]) { |
| 143 | + bar.classList.add('low'); |
| 144 | + } else if (percentage > limits[0] && percentage <= limits[1]) { |
| 145 | + bar.classList.add('medium'); |
| 146 | + } else { |
| 147 | + bar.classList.add('high'); |
102 | 148 | } |
103 | | - updateCard('.bg-disk', 'disk_percent', data); // Disk Usage |
104 | | - updateCard('.cpu-temp-card', 'current_temp', data, ' °C'); // CPU Temperature |
105 | | - updateCard('.bg-memory', 'memory_percent', data, '%'); // Memory Usage |
106 | | - updateCard('.cpu-frequency', 'cpu_frequency', data, " MHz"); // CPU Frequency |
107 | | - updateCard('.cpu-usage-card', 'cpu_percent', data, '%'); // CPU Usage |
108 | | - updateCard('.network-received', 'network_received', data, "MB"); // Network Received |
109 | | - updateCard('.network-sent', 'network_sent', data, "MB"); // Network Sent |
110 | | - updateCard('.network-stats-card', 'network_stats', data, ""); // Network Sent |
111 | | - updateCard('.battery-card', 'battery_percent', data, "%"); // Battery |
112 | | - updateCard('.network-sent', 'network_sent', data, "MB"); // Network Sent |
113 | | - updateCard('.network-received', 'network_received', data, "MB"); // Network Received |
114 | 149 | }); |
115 | 150 | } |
116 | 151 |
|
117 | | -// Function to start refreshing data at the set interval |
| 152 | + |
| 153 | +// Start the automatic refresh process |
118 | 154 | function startRefresh() { |
119 | | - if (refreshTimer) { |
120 | | - clearInterval(refreshTimer); // Clear any existing interval |
121 | | - } |
| 155 | + clearInterval(refreshTimer); |
122 | 156 | if (refreshInterval > 0) { |
123 | | - refreshTimer = setInterval(refreshData, refreshInterval); // Set a new interval |
| 157 | + refreshTimer = setInterval(refreshData, refreshInterval); |
124 | 158 | } |
125 | 159 | } |
126 | 160 |
|
127 | | -// Fetch the refresh interval initially |
128 | | -fetchRefreshInterval(); |
| 161 | +// Initialize the system |
| 162 | +function init() { |
| 163 | + fetchRefreshInterval().then(startRefresh); // Fetch interval and start refreshing |
| 164 | + updateRefreshInterval(); // Listen for changes to the refresh interval input |
| 165 | + updateColorBars(); // Update color bars based on data attributes |
| 166 | +} |
| 167 | + |
| 168 | +document.addEventListener('DOMContentLoaded', init); |
0 commit comments