- Safe Patching: bouton supprimer campagne (admin only) - Safe Patching: boutons nouvelle campagne et planning en haut - Safe Patching: message suppression dans les notifications - Planning: formulaire ajouter deplace apres le Gantt (compact) - Planning: accents retires des messages flash - Specifics: formulaire ajouter deplace en haut avant le tableau - Specifics: colonne Wave retiree, colonnes Stop/Start renommees Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
85 lines
4.6 KiB
HTML
85 lines
4.6 KiB
HTML
{% extends 'base.html' %}
|
|
{% block title %}Safe Patching{% endblock %}
|
|
{% block content %}
|
|
<div class="flex justify-between items-center mb-4">
|
|
<div>
|
|
<h2 class="text-xl font-bold text-cyber-accent">Safe Patching — Quick Win</h2>
|
|
<p class="text-xs text-gray-500 mt-1">Patching sans interruption de service : exclut tout ce qui nécessite un reboot ou un restart.</p>
|
|
</div>
|
|
<div class="flex gap-2">
|
|
{% if can_create %}
|
|
<button onclick="document.getElementById('create-form').style.display = document.getElementById('create-form').style.display === 'none' ? 'block' : 'none'" class="btn-primary px-4 py-2 text-sm">Nouvelle campagne</button>
|
|
{% endif %}
|
|
<a href="/planning" class="btn-sm bg-cyber-border text-cyber-accent px-4 py-2">Planning</a>
|
|
</div>
|
|
</div>
|
|
|
|
{% if msg %}
|
|
<div class="mb-3 p-2 rounded text-sm bg-red-900/30 text-cyber-red">
|
|
{% if msg == 'error' %}Erreur à la création (semaine déjà existante ?).{% elif msg == 'deleted' %}Campagne supprimée.{% endif %}
|
|
</div>
|
|
{% endif %}
|
|
|
|
<!-- Campagnes Quick Win existantes -->
|
|
{% if campaigns %}
|
|
<div class="space-y-2 mb-6">
|
|
{% for c in campaigns %}
|
|
<a href="/safe-patching/{{ c.id }}" class="card p-4 flex items-center justify-between hover:border-cyber-accent/50 block">
|
|
<div class="flex items-center gap-4">
|
|
<span class="font-bold text-cyber-accent">{{ c.week_code }}</span>
|
|
<span class="text-sm text-gray-400">{{ c.label }}</span>
|
|
<span class="badge badge-yellow">quickwin</span>
|
|
<span class="badge {% if c.status == 'draft' %}badge-gray{% elif c.status == 'in_progress' %}badge-yellow{% elif c.status == 'completed' %}badge-green{% else %}badge-red{% endif %}">{{ c.status }}</span>
|
|
</div>
|
|
<div class="flex gap-2 text-xs">
|
|
<span class="px-2 py-0.5 rounded bg-gray-800 text-gray-400">{{ c.session_count }} srv</span>
|
|
<span class="px-2 py-0.5 rounded bg-green-900/30 text-cyber-green">{{ c.patched_count }} ok</span>
|
|
</div>
|
|
</a>
|
|
{% endfor %}
|
|
</div>
|
|
{% endif %}
|
|
|
|
<!-- Formulaire création -->
|
|
{% if can_create %}
|
|
<div id="create-form" class="card p-5 mb-4" style="display:none">
|
|
<h3 class="text-sm font-bold text-cyber-accent mb-3">Nouvelle campagne Quick Win</h3>
|
|
<form method="POST" action="/safe-patching/create" class="space-y-3">
|
|
<div class="grid grid-cols-3 gap-3">
|
|
<div>
|
|
<label class="text-xs text-gray-500">Label</label>
|
|
<input type="text" name="label" id="qw-label" value="Quick Win S{{ '%02d' % current_week }} {{ current_year }}" class="w-full">
|
|
</div>
|
|
<div>
|
|
<label class="text-xs text-gray-500">Semaine</label>
|
|
<input type="number" name="week_number" id="qw-week" value="{{ current_week }}" min="1" max="53" class="w-full" required
|
|
onchange="document.getElementById('qw-label').value = 'Quick Win S' + String(this.value).padStart(2,'0') + ' ' + document.getElementById('qw-year').value">
|
|
</div>
|
|
<div>
|
|
<label class="text-xs text-gray-500">Année</label>
|
|
<input type="number" name="year" id="qw-year" value="{{ current_year }}" class="w-full" required
|
|
onchange="document.getElementById('qw-label').value = 'Quick Win S' + String(document.getElementById('qw-week').value).padStart(2,'0') + ' ' + this.value">
|
|
</div>
|
|
</div>
|
|
<div class="grid grid-cols-2 gap-3">
|
|
<div>
|
|
<label class="text-xs text-gray-500">Opérateur lead</label>
|
|
<select name="lead_id" class="w-full" required>
|
|
{% for o in operators %}<option value="{{ o.id }}">{{ o.display_name }}</option>{% endfor %}
|
|
</select>
|
|
</div>
|
|
<div>
|
|
<label class="text-xs text-gray-500">Assistant (optionnel)</label>
|
|
<select name="assistant_id" class="w-full">
|
|
<option value="">— Pas d'assistant —</option>
|
|
{% for o in operators %}<option value="{{ o.id }}">{{ o.display_name }}</option>{% endfor %}
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<p class="text-xs text-gray-600">Tous les serveurs Linux en production (secops) seront inclus. Hors-prod patché en premier (J), prod le lendemain (J+1).</p>
|
|
<button type="submit" class="btn-primary px-6 py-2 text-sm">Créer la campagne Quick Win</button>
|
|
</form>
|
|
</div>
|
|
{% endif %}
|
|
{% endblock %}
|