CI / test (push) Successful in 2m17s
- Table board_columns par espace (clé immuable, nom/couleur/
ordre libres, étiquette mappée + alias, drapeau Focus) ;
définitions semées paresseusement depuis les valeurs
historiques — sans personnalisation, comportement identique.
- Service app/board_columns.py : résolution, mapping
étiquette→colonne (alias compris, ex. kanban_a_faire de
Flowdeck), colonnes Focus/Wallboard.
- Board, API, adoption, miroirs d'étiquettes, déplacements,
capture, santé, focus, wall, dashboard branchés sur les
colonnes de l'espace ; validations dynamiques dans models
(move_issue, set_column_order) et rules.
- Administration → Colonnes : ajouter (avant Terminé),
renommer, réordonner, mapper, supprimer avec migration des
cartes vers une colonne choisie, réinitialiser ; bouton
🧱 Colonnes sur le board ; journal d'audit.
- Backlog et Terminé : colonnes système non supprimables.
- 254 tests verts (7 nouveaux, palier 20) ; smoke réel contre
le vrai Gitea : création, affichage au board, suppression.
100 lines
6.6 KiB
HTML
100 lines
6.6 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>Colonnes — Administration — Kanbante</title>
|
||
<link rel="stylesheet" href="/static/css/style.css?v={{ version }}">
|
||
</head>
|
||
<body>
|
||
{% include "_header.html" %}
|
||
|
||
<main class="focus-main">
|
||
<div class="page-head">
|
||
<h1>🧱 Colonnes du board</h1>
|
||
<p class="page-sub">Espace : <strong>{{ workspace.name }}</strong> (change d'espace par le sélecteur en haut pour régler un autre board). Les colonnes sont propres à chaque espace : nom, couleur, ordre et <strong>mapping étiquette ↔ colonne</strong>. La <strong>clé</strong> d'une colonne ne change jamais (les cartes y sont rattachées) ; le <strong>nom affiché</strong>, lui, est libre.</p>
|
||
</div>
|
||
{% if msg %}<p class="chip-ok">✅ {{ msg }}</p>{% endif %}
|
||
{% if err %}<p class="chip-warn">⚠️ {{ err }}</p>{% endif %}
|
||
|
||
<section class="briefing-card">
|
||
<h2>Comment marche le mapping</h2>
|
||
<p class="notes-hint">
|
||
<strong>Miroir</strong> : quand une carte entre dans une colonne, son <em>étiquette mappée</em> est posée sur l'issue de la forge (et les étiquettes mappées des autres colonnes sont retirées).<br>
|
||
<strong>Adoption</strong> : si une issue porte <em>exactement une</em> étiquette reconnue (étiquette mappée ou alias d'une colonne), le board adopte cette colonne — c'est ce qui permet à d'autres outils de piloter le board par étiquettes.<br>
|
||
<strong>Alias</strong> : étiquettes supplémentaires reconnues pour cette colonne, séparées par des virgules — par exemple les étiquettes Flowdeck <code>kanban_a_faire</code> sur la colonne À faire.<br>
|
||
<strong>Focus</strong> : les colonnes cochées « Focus » alimentent la vue Focus du jour et le wallboard.
|
||
</p>
|
||
</section>
|
||
|
||
{% for c in columns %}
|
||
<section class="briefing-card">
|
||
<h2>
|
||
<span class="ws-dot" style="background: {{ c.color }}"></span>
|
||
{{ c.name }}
|
||
<span class="muted"><code>{{ c.key }}</code> · {{ counts[c.key] }} carte(s) dans cet espace</span>
|
||
{% if c.kind == 'backlog' %}<span class="chip">système — défaut des cartes neuves</span>{% endif %}
|
||
{% if c.kind == 'done' %}<span class="chip">système — issues fermées</span>{% endif %}
|
||
</h2>
|
||
<form method="post" action="/admin/columns/{{ c.key }}" class="admin-form">
|
||
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
|
||
<label>Nom affiché <input type="text" name="name" value="{{ c.name }}"></label>
|
||
<label>Couleur <input type="color" name="color" value="{{ c.color }}"></label>
|
||
{% if c.kind == 'flow' %}
|
||
<label>Étiquette mappée <input type="text" name="label" value="{{ c.label }}" placeholder="kanban:{{ c.key }}"></label>
|
||
<label>Alias (virgules) <input type="text" name="aliases" value="{{ c.aliases }}" placeholder="kanban_a_faire, a-faire"></label>
|
||
<label><input type="checkbox" name="in_focus" value="1"{% if c.in_focus %} checked{% endif %}> Dans Focus / Wallboard</label>
|
||
{% endif %}
|
||
<button type="submit" class="btn-save btn-inline">Enregistrer</button>
|
||
</form>
|
||
<p class="admin-actions">
|
||
<form method="post" action="/admin/columns/{{ c.key }}/move" class="inline-form">
|
||
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
|
||
<input type="hidden" name="direction" value="up">
|
||
<button type="submit" class="btn-mini" title="Monter">⬆️</button>
|
||
</form>
|
||
<form method="post" action="/admin/columns/{{ c.key }}/move" class="inline-form">
|
||
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
|
||
<input type="hidden" name="direction" value="down">
|
||
<button type="submit" class="btn-mini" title="Descendre">⬇️</button>
|
||
</form>
|
||
{% if c.kind == 'flow' %}
|
||
<form method="post" action="/admin/columns/{{ c.key }}/delete" class="inline-form" onsubmit="return confirm('Supprimer cette colonne ? Ses cartes iront dans la colonne choisie.');">
|
||
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
|
||
<label>Déplacer ses cartes vers
|
||
<select name="target">
|
||
{% for other in columns %}{% if other.key != c.key %}<option value="{{ other.key }}">{{ other.name }}</option>{% endif %}{% endfor %}
|
||
</select>
|
||
</label>
|
||
<button type="submit" class="btn-mini btn-danger">Supprimer la colonne</button>
|
||
</form>
|
||
{% endif %}
|
||
</p>
|
||
</section>
|
||
{% endfor %}
|
||
|
||
<section class="briefing-card">
|
||
<h2>➕ Nouvelle colonne</h2>
|
||
<form method="post" action="/admin/columns" class="admin-form">
|
||
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
|
||
<label>Nom affiché <input type="text" name="name" required placeholder="🛠️ En développement"></label>
|
||
<label>Couleur <input type="color" name="color" value="#7c5cfc"></label>
|
||
<label>Étiquette mappée <input type="text" name="label" placeholder="(défaut : kanban:<clé>)"></label>
|
||
<label>Alias (virgules) <input type="text" name="aliases" placeholder=""></label>
|
||
<button type="submit" class="btn-save btn-inline">Ajouter (avant Terminé)</button>
|
||
</form>
|
||
</section>
|
||
|
||
<section class="briefing-card">
|
||
<h2>↩️ Réinitialiser</h2>
|
||
<p class="notes-hint">Revenir aux six colonnes historiques de cet espace. Les cartes placées dans des colonnes personnalisées retomberont au Backlog à l'affichage.</p>
|
||
<form method="post" action="/admin/columns/reset" class="inline-form" onsubmit="return confirm('Réinitialiser les colonnes de cet espace aux valeurs par défaut ?');">
|
||
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
|
||
<button type="submit" class="btn-mini btn-danger">Réinitialiser les colonnes</button>
|
||
</form>
|
||
</section>
|
||
</main>
|
||
</body>
|
||
</html>
|