Partiel _header.html unique pour les 19 pages (fin des copies qui dérivaient): desktop une ligne — primaires + menu Plus + Ctrl K, page active déduite du gabarit dans render(); mobile ≤900px burger + panneau ≥44px, Échap/clic extérieur; wallboard sans header et triage sur le même partiel. nav.js partagé.
75 lines
3.7 KiB
HTML
75 lines
3.7 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="fr" data-theme="dark">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<meta name="csrf-token" content="{{ csrf_token }}">
|
|
<title>Santé — {{ full_name }} — Kanbante</title>
|
|
<link rel="stylesheet" href="/static/css/style.css">
|
|
</head>
|
|
<body>
|
|
{% include "_header.html" %}
|
|
|
|
<main class="focus-main">
|
|
{% if health is none %}
|
|
<section class="briefing-card">
|
|
<h1>🩺 {{ full_name }}</h1>
|
|
<p>Projet introuvable.</p>
|
|
</section>
|
|
{% else %}
|
|
<section class="briefing-card">
|
|
<h1>🩺 {{ full_name }}</h1>
|
|
<h2>⏱️ Temps passé par colonne (journal)</h2>
|
|
{% if health.dwell %}
|
|
<table class="health-table">
|
|
<thead><tr><th>Colonne</th><th>Séjours mesurés</th><th>Médiane</th><th>Moyenne</th></tr></thead>
|
|
<tbody>
|
|
{% for row in health.dwell %}
|
|
<tr{% if health.slowest and row.column == health.slowest.column %} class="health-slowest"{% endif %}>
|
|
<td>{{ health.column_labels[row.column] }}{% if health.slowest and row.column == health.slowest.column %} 🐌{% endif %}</td>
|
|
<td>{{ row.count }}</td>
|
|
<td>{{ row.median_days }} j</td>
|
|
<td>{{ row.avg_days }} j</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
{% if health.slowest %}
|
|
<p>🐌 <strong>Goulot : {{ health.column_labels[health.slowest.column] }}</strong> — c'est là que les cartes dorment le plus longtemps (médiane {{ health.slowest.median_days }} j).</p>
|
|
{% endif %}
|
|
{% else %}
|
|
<p>Pas encore de séjours mesurables dans le journal de ce projet — il faut des déplacements journalisés pour calculer les temps de colonne.</p>
|
|
{% endif %}
|
|
</section>
|
|
|
|
<section class="briefing-card">
|
|
<h2>🧟 Cartes zombies — aucune activité depuis ≥ {{ health.zombie_days }} jours</h2>
|
|
{% if health.zombies %}
|
|
<ul class="today-list">
|
|
{% for z in health.zombies %}
|
|
<li>
|
|
<span>#{{ z.number }} — {{ z.title }} <em>({{ z.column_label }} · inactive depuis {{ z.days_inactive }} j)</em></span>
|
|
<span class="zombie-actions">
|
|
<button type="button" class="btn-sm" data-zombie="comment" data-repo="{{ full_name }}" data-number="{{ z.number }}" data-column="{{ z.column }}">💬 Toujours pertinent ?</button>
|
|
<button type="button" class="btn-sm" data-zombie="backlog" data-repo="{{ full_name }}" data-number="{{ z.number }}" data-column="{{ z.column }}">↩️ Backlog</button>
|
|
<button type="button" class="btn-sm" data-zombie="close" data-repo="{{ full_name }}" data-number="{{ z.number }}" data-column="{{ z.column }}">✅ Fermer</button>
|
|
</span>
|
|
</li>
|
|
{% endfor %}
|
|
</ul>
|
|
<p class="notes-hint">« Fermer » déplace la carte en Terminé (l'issue est fermée dans Gitea par la synchro habituelle). « Toujours pertinent ? » poste un commentaire du même texte sur l'issue.</p>
|
|
{% else %}
|
|
<p>Aucune carte zombie. Le flux est propre. ✨</p>
|
|
{% endif %}
|
|
</section>
|
|
{% endif %}
|
|
</main>
|
|
<footer>
|
|
<span>Kanbante v{{ version }} · seuil zombie : KANBANTE_ZOMBIE_DAYS</span>
|
|
</footer>
|
|
{% include "_palette.html" %}
|
|
<script src="/static/js/palette.js" defer></script>
|
|
<script src="/static/js/health.js" defer></script>
|
|
</body>
|
|
</html>
|