()
| 559 | }); |
| 560 | } |
| 561 | function bindFilters(){ |
| 562 | $('serverSearch').addEventListener('input', e => { S.filters.query = e.target.value; renderServers(); renderServersCards(); }); |
| 563 | $('statusFilter').addEventListener('click', e => { |
| 564 | if(e.target.tagName !== 'BUTTON') return; |
| 565 | S.filters.status = e.target.dataset.filter; |
| 566 | document.querySelectorAll('#statusFilter button').forEach(btn => btn.classList.toggle('active', btn === e.target)); |
| 567 | renderServers(); renderServersCards(); |
| 568 | }); |
| 569 | $('osFilter').addEventListener('change', e => { S.filters.os = e.target.value; renderServers(); renderServersCards(); }); |
| 570 | $('osFilter').addEventListener('blur', renderOsOptions); |
| 571 | $('sortSelect').addEventListener('change', e => { S.filters.sort = e.target.value; renderServers(); renderServersCards(); }); |
| 572 | $('sortDirection').addEventListener('click', () => { |
| 573 | S.filters.dir = S.filters.dir === 'desc' ? 'asc' : 'desc'; |
| 574 | $('sortDirection').textContent = S.filters.dir === 'desc' ? '降序' : '升序'; |
| 575 | renderServers(); renderServersCards(); |
| 576 | }); |
| 577 | document.querySelectorAll('#serversTable th[data-sort]').forEach(th => th.addEventListener('click', () => { |
| 578 | if(S.filters.sort === th.dataset.sort) S.filters.dir = S.filters.dir === 'desc' ? 'asc' : 'desc'; |
| 579 | else S.filters.sort = th.dataset.sort; |
| 580 | $('sortSelect').value = S.filters.sort; |
| 581 | $('sortDirection').textContent = S.filters.dir === 'desc' ? '降序' : '升序'; |
| 582 | renderServers(); renderServersCards(); |
| 583 | })); |
| 584 | } |
| 585 | |
| 586 | function adminHeaders(){ |
| 587 | return { 'Content-Type': 'application/json', 'Authorization': `Bearer ${S.admin.token}` }; |
no test coverage detected