patchcenter/app/templates/partials/contact_detail.html
Khalid MOUTAOUAKIL 8e62b1fb11 Qualys complet, contacts, audit refactoré, bulk serveurs
Qualys:
- Recherche API temps réel + cache 24h base locale
- Tags: liste DYN/STAT, mapping V3 (DOM-*, TYP-*, APP-*), nb assets cliquable
- CRUD tags: créer STAT, supprimer, resync API
- Détail asset: infos + décodage nomenclature V3 + tags assignés
- Ajout/retrait tag unitaire avec autocomplete filtrable
- Bulk add/remove tag en masse avec dropdown filtrable
- Tags retirer: charge dynamiquement les STAT assignés aux assets sélectionnés
- Resync assets sélectionnés + retour même recherche

Contacts:
- 50 contacts importés avec 93 scopes (domaine/app/serveur/zone par env)
- 13 rôles (responsable_domaine, ra_prod, ra_recette, referent_technique...)
- Recherche par nom/email/serveur (affiche contacts liés)
- CRUD complet: éditer, scopes, activer/désactiver, supprimer
- Serveurs liés calculés dynamiquement depuis les scopes

Audit:
- Restructuré: Audit général + sous-menu Spécifique
- Dernier audit global affiché avec date
- Lancer audit général avec exclusions (domaines/zones) et parallélisme
- KPIs Qualys KO et S1 KO cliquables
- Export CSV

Serveurs:
- Actions groupées bulk (domaine, env, tier, état, owner, licence)
- Dashboard: KPI EOL ajouté
- Filtre état: EOL + en décommissionnement ajoutés
- 138 serveurs EOL importés depuis Qualys (owner=na, hors périmètre)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-05 00:47:26 +02:00

86 lines
4.5 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<div>
<div class="flex justify-between items-center mb-4">
<h3 class="text-lg font-bold text-cyber-accent">{{ c.name }}</h3>
<button onclick="document.getElementById('contact-detail').style.display='none'" class="text-gray-500 hover:text-white text-xl">&times;</button>
</div>
<!-- Édition -->
<form method="POST" action="/contacts/{{ c.id }}/edit" class="flex gap-3 items-end mb-4">
<div>
<label class="text-xs text-gray-500">Nom</label>
<input type="text" name="name" value="{{ c.name }}" class="text-xs py-1 px-2 w-44">
</div>
<div>
<label class="text-xs text-gray-500">Email</label>
<input type="email" name="email" value="{{ c.email }}" class="text-xs py-1 px-2 w-52">
</div>
<div>
<label class="text-xs text-gray-500">Rôle</label>
<select name="contact_role" class="text-xs py-1 px-2">
{% for code, label in roles %}<option value="{{ code }}" {% if c.role == code %}selected{% endif %}>{{ label }}</option>{% endfor %}
</select>
</div>
<button type="submit" class="btn-sm bg-cyber-accent text-black">Modifier</button>
<form method="POST" action="/contacts/{{ c.id }}/toggle" style="display:inline">
<button type="submit" class="btn-sm {% if c.is_active %}bg-red-900/30 text-cyber-red{% else %}bg-green-900/30 text-cyber-green{% endif %}">
{{ 'Désactiver' if c.is_active else 'Activer' }}
</button>
</form>
</form>
<!-- Scopes existants -->
<h4 class="text-xs text-cyber-accent font-bold uppercase mb-2 border-b border-cyber-border pb-1">Périmètre de responsabilité</h4>
<div class="space-y-1 mb-3">
{% for s in scopes %}
<div class="flex items-center gap-2 text-xs">
<span class="badge {% if s.scope_type == 'domain' %}badge-blue{% elif s.scope_type == 'application' %}badge-yellow{% elif s.scope_type == 'server' %}badge-red{% else %}badge-gray{% endif %}">{{ s.scope_type }}</span>
<span class="font-mono text-cyber-accent">{{ s.scope_value }}</span>
{% if s.env_scope != 'all' %}<span class="badge badge-green">{{ s.env_scope }}</span>{% endif %}
<form method="POST" action="/contacts/scope/{{ s.id }}/delete" style="display:inline">
<button class="text-gray-600 hover:text-cyber-red text-xs" onclick="return confirm('Supprimer ?')">×</button>
</form>
</div>
{% endfor %}
{% if not scopes %}<p class="text-xs text-gray-500">Aucun scope défini</p>{% endif %}
</div>
<!-- Ajouter scope -->
<form method="POST" action="/contacts/{{ c.id }}/scope/add" class="flex gap-2 items-end mb-4">
<div>
<label class="text-xs text-gray-500">Type</label>
<select name="scope_type" class="text-xs py-1 px-2">
{% for code, label in scope_types %}<option value="{{ code }}">{{ label }}</option>{% endfor %}
</select>
</div>
<div>
<label class="text-xs text-gray-500">Valeur</label>
<input type="text" name="scope_value" class="text-xs py-1 px-2 w-36" required list="scope-values" placeholder="EMV, COMMVAULT...">
<datalist id="scope-values">
{% for d in domains %}<option value="{{ d.code }}">{{ d.name }}</option>{% endfor %}
{% for a in app_types %}<option value="{{ a }}">{{ a }}</option>{% endfor %}
</datalist>
</div>
<div>
<label class="text-xs text-gray-500">Env</label>
<select name="env_scope" class="text-xs py-1 px-2">
{% for es in env_scopes %}<option value="{{ es }}">{{ es }}</option>{% endfor %}
</select>
</div>
<button type="submit" class="btn-sm bg-cyber-accent text-black">Ajouter</button>
</form>
<!-- Serveurs liés -->
{% if servers %}
<h4 class="text-xs text-cyber-accent font-bold uppercase mb-2 border-b border-cyber-border pb-1">Serveurs concernés ({{ servers|length }})</h4>
<div class="grid grid-cols-3 gap-1 text-xs">
{% for s in servers %}
<div class="flex items-center gap-1">
<span class="font-mono text-cyber-accent">{{ s.hostname }}</span>
<span class="text-gray-500">{{ s.domaine or '' }}</span>
<span class="badge {% if s.environnement == 'Production' %}badge-green{% else %}badge-yellow{% endif %} text-[9px]">{{ (s.environnement or '')[:4] }}</span>
</div>
{% endfor %}
</div>
{% endif %}
</div>