()
| 318 | } |
| 319 | |
| 320 | function renderServers(){ |
| 321 | const rows = visibleServers(); |
| 322 | document.querySelectorAll('#serversTable th[data-sort]').forEach(th => { |
| 323 | th.classList.toggle('sorted-asc', th.dataset.sort === S.filters.sort && S.filters.dir === 'asc'); |
| 324 | th.classList.toggle('sorted-desc', th.dataset.sort === S.filters.sort && S.filters.dir === 'desc'); |
| 325 | }); |
| 326 | $('serversBody').innerHTML = rows.map(s => { |
| 327 | const m = metrics(s); |
| 328 | const netNow = `${humanMinKBFromB(s.network_rx)} | ${humanMinKBFromB(s.network_tx)}`; |
| 329 | const netTotal = `${humanMinMBFromB(s.network_in)} | ${humanMinMBFromB(s.network_out)}`; |
| 330 | const alertClass = m.rowLevel ? ` alert-${m.rowLevel}` : ''; |
| 331 | return `<tr data-key="${esc(s._key)}" data-online="${m.online ? 1 : 0}" class="row-server${alertClass}${osClass(s.os)}" style="cursor:${m.online ? 'pointer' : 'default'};"> |
| 332 | <td>${protoPill(s)}</td> |
| 333 | <td>${trafficCaps(s)}</td> |
| 334 | <td>${esc(s.name || '-')}</td> |
| 335 | <td>${esc(s.type || '-')}</td> |
| 336 | <td>${esc(s.location || '-')}</td> |
| 337 | <td>${esc(s.uptime || '-')}</td> |
| 338 | <td>${s.load_1 === -1 ? '–' : num(s.load_1).toFixed(2)}</td> |
| 339 | <td>${netNow}</td> |
| 340 | <td>${netTotal}</td> |
| 341 | <td>${m.online ? gaugeHTML('cpu', s.cpu) : '-'}</td> |
| 342 | <td>${m.online ? gaugeHTML('mem', m.memPct) : '-'}</td> |
| 343 | <td>${m.online ? gaugeHTML('hdd', m.hddPct) : '-'}</td> |
| 344 | <td>${buckets(s)}</td> |
| 345 | </tr>`; |
| 346 | }).join('') || `<tr><td colspan="13" class="muted" style="text-align:center;padding:1rem;">无数据</td></tr>`; |
| 347 | document.querySelectorAll('#serversBody .row-server').forEach(row => row.addEventListener('click', () => { |
| 348 | if(row.dataset.online !== '1') return; |
| 349 | openDetail(row.dataset.key); |
| 350 | })); |
| 351 | } |
| 352 | |
| 353 | function renderServersCards(){ |
| 354 | const wrap = $('serversCards'); |
no test coverage detected