|
5 | 5 | const tableContainer = document.getElementById('activityContainer'); |
6 | 6 | const currentUserName = tableContainer.getAttribute('data-currentUserName'); |
7 | 7 | const currentServiceId = tableContainer.getAttribute('data-currentServiceId'); |
| 8 | + let pollInterval; |
| 9 | + let isPolling = false; |
| 10 | + const POLL_INTERVAL_MS = 25000; |
8 | 11 | const COLORS = { |
9 | 12 | delivered: '#0076d6', |
10 | 13 | failed: '#fa9441', |
|
153 | 156 | .on('mouseout', function() { |
154 | 157 | tooltip.style('display', 'none'); |
155 | 158 | }) |
156 | | - .transition() |
157 | | - .duration(1000) |
158 | 159 | .attr('y', d => y(d[1])) |
159 | 160 | .attr('height', d => { |
160 | 161 | const calculatedHeight = y(d[0]) - y(d[1]); |
|
209 | 210 | table.append(tbody); |
210 | 211 | }; |
211 | 212 |
|
212 | | - const fetchData = function(type) { |
| 213 | + const fetchData = async function(type) { |
| 214 | + if (isPolling) { |
| 215 | + return; |
| 216 | + } |
| 217 | + |
| 218 | + if (document.hidden) { |
| 219 | + return; |
| 220 | + } |
213 | 221 |
|
214 | 222 | var ctx = document.getElementById('weeklyChart'); |
215 | 223 | if (!ctx) { |
216 | 224 | return; |
217 | 225 | } |
218 | 226 |
|
| 227 | + isPolling = true; |
| 228 | + |
219 | 229 | var userTimezone = Intl.DateTimeFormat().resolvedOptions().timeZone; |
220 | 230 |
|
221 | 231 | var url = type === 'service' |
222 | 232 | ? `/services/${currentServiceId}/daily-stats.json?timezone=${encodeURIComponent(userTimezone)}` |
223 | 233 | : `/services/${currentServiceId}/daily-stats-by-user.json?timezone=${encodeURIComponent(userTimezone)}`; |
224 | 234 |
|
| 235 | + try { |
| 236 | + const response = await fetch(url); |
| 237 | + if (!response.ok) { |
| 238 | + throw new Error('Network response was not ok'); |
| 239 | + } |
225 | 240 |
|
226 | | - return fetch(url) |
227 | | - .then(response => { |
228 | | - if (!response.ok) { |
229 | | - throw new Error('Network response was not ok'); |
230 | | - } |
231 | | - return response.json(); |
232 | | - }) |
233 | | - .then(data => { |
| 241 | + const data = await response.json(); |
234 | 242 | labels = []; |
235 | 243 | deliveredData = []; |
236 | 244 | failedData = []; |
|
277 | 285 | } |
278 | 286 |
|
279 | 287 | return data; |
280 | | - }) |
281 | | - .catch(error => console.error('Error fetching daily stats:', error)); |
282 | | - }; |
283 | | - setInterval(() => fetchData(currentType), 25000); |
| 288 | + } catch (error) { |
| 289 | + console.error('Error fetching daily stats:', error); |
| 290 | + } finally { |
| 291 | + isPolling = false; |
| 292 | + } |
| 293 | + }; |
| 294 | + |
| 295 | + function startPolling() { |
| 296 | + fetchData(currentType); |
| 297 | + |
| 298 | + pollInterval = setInterval(() => { |
| 299 | + fetchData(currentType); |
| 300 | + }, POLL_INTERVAL_MS); |
| 301 | + } |
| 302 | + |
| 303 | + function stopPolling() { |
| 304 | + if (pollInterval) { |
| 305 | + clearInterval(pollInterval); |
| 306 | + pollInterval = null; |
| 307 | + } |
| 308 | + } |
| 309 | + |
| 310 | + document.addEventListener('visibilitychange', () => { |
| 311 | + if (document.hidden) { |
| 312 | + stopPolling(); |
| 313 | + } else { |
| 314 | + stopPolling(); |
| 315 | + startPolling(); |
| 316 | + } |
| 317 | + }); |
| 318 | + |
| 319 | + if (typeof jest === 'undefined') { |
| 320 | + startPolling(); |
| 321 | + } |
| 322 | + |
284 | 323 | const handleDropdownChange = function(event) { |
285 | 324 | const selectedValue = event.target.value; |
286 | 325 | currentType = selectedValue; |
|
0 commit comments