feat(qualys/agents): tri click-to-sort sur toutes les tables (hostname, OS, check-in, etc.)

This commit is contained in:
Pierre & Lumière 2026-04-27 16:57:56 +02:00
parent f32c247bf4
commit ad630eba99

View File

@ -44,7 +44,34 @@
<button id="btn-cancel" class="btn-secondary px-3 py-1 text-xs mt-4" onclick="cancelRefresh()">Annuler</button> <button id="btn-cancel" class="btn-secondary px-3 py-1 text-xs mt-4" onclick="cancelRefresh()">Annuler</button>
</div> </div>
</div> </div>
<style>@keyframes spin{to{transform:rotate(360deg)}}</style> <style>@keyframes spin{to{transform:rotate(360deg)}}
.sortable-table th.sortable{cursor:pointer;user-select:none;position:relative;padding-right:18px}
.sortable-table th.sortable::after{content:'\2195';position:absolute;right:6px;color:#4b5563;font-size:10px}
.sortable-table th.sort-asc::after{content:'\2191';color:#00ffc8}
.sortable-table th.sort-desc::after{content:'\2193';color:#00ffc8}</style>
<script>
function sortTable(th, type){
var table = th.closest('table');
var tbody = table.querySelector('tbody');
var ths = Array.from(table.querySelectorAll('thead th'));
var col = ths.indexOf(th);
var asc = !th.classList.contains('sort-asc');
ths.forEach(function(t){ t.classList.remove('sort-asc','sort-desc'); });
th.classList.add(asc ? 'sort-asc' : 'sort-desc');
var rows = Array.from(tbody.querySelectorAll('tr'));
rows.sort(function(a,b){
var av = (a.cells[col] && a.cells[col].innerText || '').trim();
var bv = (b.cells[col] && b.cells[col].innerText || '').trim();
if(type === 'num'){
var an = parseFloat(av.replace(/[^0-9.-]/g,'')) || 0;
var bn = parseFloat(bv.replace(/[^0-9.-]/g,'')) || 0;
return asc ? an - bn : bn - an;
}
return asc ? av.localeCompare(bv,'fr',{numeric:true}) : bv.localeCompare(av,'fr',{numeric:true});
});
rows.forEach(function(r){ tbody.appendChild(r); });
}
</script>
<!-- Message résultat --> <!-- Message résultat -->
<div id="refresh-msg" style="display:none;padding:8px 16px;border-radius:6px;margin-bottom:12px;font-size:0.85rem"></div> <div id="refresh-msg" style="display:none;padding:8px 16px;border-radius:6px;margin-bottom:12px;font-size:0.85rem"></div>
@ -117,13 +144,13 @@ function refreshAgents(mode) {
<!-- Activation Keys --> <!-- Activation Keys -->
<div class="card p-4 mb-4"> <div class="card p-4 mb-4">
<h3 class="text-sm font-bold text-cyber-accent mb-3">Activation Keys</h3> <h3 class="text-sm font-bold text-cyber-accent mb-3">Activation Keys</h3>
<table class="w-full table-cyber text-xs"> <table class="w-full table-cyber text-xs sortable-table">
<thead><tr> <thead><tr>
<th class="text-left p-2">Titre</th> <th class="text-left p-2 sortable" onclick="sortTable(this)">Titre</th>
<th class="p-2">Statut</th> <th class="p-2 sortable" onclick="sortTable(this)">Statut</th>
<th class="p-2">Type</th> <th class="p-2 sortable" onclick="sortTable(this)">Type</th>
<th class="p-2">Utilisés</th> <th class="p-2 sortable" onclick="sortTable(this,'num')">Utilisés</th>
<th class="text-left p-2">Clé</th> <th class="text-left p-2 sortable" onclick="sortTable(this)">Clé</th>
</tr></thead> </tr></thead>
<tbody> <tbody>
{% for k in keys %} {% for k in keys %}
@ -144,8 +171,8 @@ function refreshAgents(mode) {
<div class="card p-4"> <div class="card p-4">
<h3 class="text-sm font-bold text-cyber-accent mb-3">Statut des agents</h3> <h3 class="text-sm font-bold text-cyber-accent mb-3">Statut des agents</h3>
{% if summary.statuses %} {% if summary.statuses %}
<table class="w-full table-cyber text-xs"> <table class="w-full table-cyber text-xs sortable-table">
<thead><tr><th class="text-left p-2">Statut</th><th class="p-2">Nombre</th></tr></thead> <thead><tr><th class="text-left p-2 sortable" onclick="sortTable(this)">Statut</th><th class="p-2 sortable" onclick="sortTable(this,'num')">Nombre</th></tr></thead>
<tbody> <tbody>
{% for s in summary.statuses %} {% for s in summary.statuses %}
<tr> <tr>
@ -163,8 +190,8 @@ function refreshAgents(mode) {
<div class="card p-4"> <div class="card p-4">
<h3 class="text-sm font-bold text-cyber-accent mb-3">Versions déployées</h3> <h3 class="text-sm font-bold text-cyber-accent mb-3">Versions déployées</h3>
{% if summary.versions %} {% if summary.versions %}
<table class="w-full table-cyber text-xs"> <table class="w-full table-cyber text-xs sortable-table">
<thead><tr><th class="text-left p-2">Version</th><th class="p-2">Nombre</th></tr></thead> <thead><tr><th class="text-left p-2 sortable" onclick="sortTable(this)">Version</th><th class="p-2 sortable" onclick="sortTable(this,'num')">Nombre</th></tr></thead>
<tbody> <tbody>
{% for v in summary.versions %} {% for v in summary.versions %}
<tr> <tr>
@ -211,15 +238,15 @@ function refreshAgents(mode) {
</select> </select>
<button @click="fHost='';fOs='';fDom='';fEnv='';fEtat=''" class="text-xs text-gray-400 hover:text-cyber-accent">Reset</button> <button @click="fHost='';fOs='';fDom='';fEnv='';fEtat=''" class="text-xs text-gray-400 hover:text-cyber-accent">Reset</button>
</div> </div>
<table class="w-full table-cyber text-xs"> <table class="w-full table-cyber text-xs sortable-table">
<thead><tr> <thead><tr>
<th class="text-left p-2">Hostname</th> <th class="text-left p-2 sortable" onclick="sortTable(this)">Hostname</th>
<th class="p-2">OS</th> <th class="p-2 sortable" onclick="sortTable(this)">OS</th>
<th class="p-2">Version OS</th> <th class="p-2 sortable" onclick="sortTable(this)">Version OS</th>
<th class="p-2">Domaine</th> <th class="p-2 sortable" onclick="sortTable(this)">Domaine</th>
<th class="p-2">Env</th> <th class="p-2 sortable" onclick="sortTable(this)">Env</th>
<th class="p-2">Zone</th> <th class="p-2 sortable" onclick="sortTable(this)">Zone</th>
<th class="p-2">État</th> <th class="p-2 sortable" onclick="sortTable(this)">État</th>
</tr></thead> </tr></thead>
<tbody id="noagent-body"> <tbody id="noagent-body">
{% for s in no_agent_servers %} {% for s in no_agent_servers %}
@ -256,13 +283,13 @@ function refreshAgents(mode) {
Causes possibles : serveur éteint, flux réseau bloqué (port 443 vers qualysagent.qualys.eu), agent crashé, ou OS non supporté (RHEL 5 EOL). Causes possibles : serveur éteint, flux réseau bloqué (port 443 vers qualysagent.qualys.eu), agent crashé, ou OS non supporté (RHEL 5 EOL).
Tous ces agents sont en version <b>6.1.0.28</b> sur <b>RHEL 5.x</b> — dernier check-in le <b>14/11/2025</b>. Tous ces agents sont en version <b>6.1.0.28</b> sur <b>RHEL 5.x</b> — dernier check-in le <b>14/11/2025</b>.
</div> </div>
<table class="w-full table-cyber text-xs"> <table class="w-full table-cyber text-xs sortable-table">
<thead><tr> <thead><tr>
<th class="text-left p-2">Hostname</th> <th class="text-left p-2 sortable" onclick="sortTable(this)">Hostname</th>
<th class="p-2">OS</th> <th class="p-2 sortable" onclick="sortTable(this)">OS</th>
<th class="p-2">Version agent</th> <th class="p-2 sortable" onclick="sortTable(this)">Version agent</th>
<th class="p-2">Dernier check-in</th> <th class="p-2 sortable" onclick="sortTable(this)">Dernier check-in</th>
<th class="p-2">État</th> <th class="p-2 sortable" onclick="sortTable(this)">État</th>
</tr></thead> </tr></thead>
<tbody> <tbody>
{% for a in inactive_agents %} {% for a in inactive_agents %}