feat(qualys/search): KPI total/avec-vuln/sans-vuln + filtre vuln_filter

This commit is contained in:
Pierre & Lumière 2026-04-24 22:27:55 +00:00
parent 5d421dcd28
commit c57ef61adb
8 changed files with 32 additions and 0 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -466,11 +466,23 @@ async def qualys_search(request: Request, db=Depends(get_db),
all_tags = db.execute(text("SELECT qualys_tag_id, name FROM qualys_tags ORDER BY name")).fetchall()
# KPI : total / avec vuln / sans vuln + filtrage vuln_filter (with|zero)
vuln_filter = request.query_params.get("vuln_filter", "")
kpi_total = len(assets) if assets else 0
kpi_with_vuln = sum(1 for a in assets if vuln_map.get(str(a.ip_address), 0) > 0) if assets else 0
kpi_zero_vuln = kpi_total - kpi_with_vuln
if assets and vuln_filter == "with":
assets = [a for a in assets if vuln_map.get(str(a.ip_address), 0) > 0]
elif assets and vuln_filter == "zero":
assets = [a for a in assets if vuln_map.get(str(a.ip_address), 0) == 0]
ctx = base_context(request, db, user)
ctx.update({
"app_name": APP_NAME, "assets": assets, "search": search,
"field": field, "api_msg": api_msg,
"all_tags": all_tags, "vuln_map": vuln_map,
"kpi_total": kpi_total, "kpi_with_vuln": kpi_with_vuln, "kpi_zero_vuln": kpi_zero_vuln,
"vuln_filter": vuln_filter,
"cache_info": cache_info,
"can_edit_qualys": can_edit(perms, "qualys"),
"msg": request.query_params.get("msg"),

View File

@ -48,6 +48,26 @@
</div>
{% endif %}
{% if search and kpi_total is defined %}
<div class="grid grid-cols-3 gap-3 mb-3">
<a href="/qualys/search?field={{ field }}&search={{ search }}" class="card p-3 hover:border-cyber-accent transition {% if not vuln_filter %}border-cyber-accent{% endif %}">
<div class="text-xs text-gray-400 uppercase">Total</div>
<div class="text-2xl font-bold text-cyber-accent">{{ kpi_total }}</div>
<div class="text-xs text-gray-500">{% if vuln_filter %}Voir tous{% else %}Affichage actuel{% endif %}</div>
</a>
<a href="/qualys/search?field={{ field }}&search={{ search }}&vuln_filter=with" class="card p-3 hover:border-cyber-red transition {% if vuln_filter == 'with' %}border-cyber-red{% endif %}">
<div class="text-xs text-gray-400 uppercase">Avec vulnerabilites</div>
<div class="text-2xl font-bold text-red-400">{{ kpi_with_vuln }}</div>
<div class="text-xs text-gray-500">Cliquer pour filtrer</div>
</a>
<a href="/qualys/search?field={{ field }}&search={{ search }}&vuln_filter=zero" class="card p-3 hover:border-cyber-green transition {% if vuln_filter == 'zero' %}border-cyber-green{% endif %}">
<div class="text-xs text-gray-400 uppercase">Sans vulnerabilite</div>
<div class="text-2xl font-bold text-cyber-green">{{ kpi_zero_vuln }}</div>
<div class="text-xs text-gray-500">Cliquer pour filtrer</div>
</a>
</div>
{% endif %}
<!-- Panel détail -->
<div id="detail-loading" class="card mb-4 p-6 flex items-center justify-center gap-3" style="display:none;">
<div style="width:20px;height:20px;border:2px solid #22c55e;border-top-color:transparent;border-radius:50%;animation:spin 0.8s linear infinite;"></div>