CI / test (push) Successful in 1m53s
- Comptes en base (PBKDF2), rôles, désactivation qui tue la session, audit ; secours environnement pour l'opérateur ; liaison draco par utilisateur ; page /profile. - Espaces de travail : connexions, membres, sélection de projets ; board/notes/épingles/journal scopés par espace ; sélecteur d'espace, badge connexion. - Panneaux /admin (utilisateurs, connexions, espaces, paramètres — l'environnement amorce, le panneau gouverne). - /archives : archive locale réversible, archivage forge confirmé, purge de l'état local, export Markdown, file « à archiver ? » avec archivage en lot. - Correctif session : les comptes membres résolus par la base (la session n'est plus limitée à l'opérateur d'environnement). - 231 tests verts (12 nouveaux au palier 19).
116 lines
6.2 KiB
HTML
116 lines
6.2 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>Espaces — 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>🧭 Espaces de travail</h1>
|
||
<p class="page-sub">Un espace regroupe des connexions (forges) et des membres. Le board d'un projet appartient à l'espace : deux espaces peuvent ranger le même projet différemment. L'état de board, les notes et les épingles du jour sont propres à chaque espace.</p>
|
||
</div>
|
||
{% if msg %}<p class="chip-ok">✅ {{ msg }}</p>{% endif %}
|
||
{% if err %}<p class="chip-warn">⚠️ {{ err }}</p>{% endif %}
|
||
|
||
{% for d in details %}
|
||
{% set ws = d.ws %}
|
||
<section class="briefing-card">
|
||
<h2><span class="ws-dot" style="background: {{ ws.color }}"></span> {{ ws.name }} <span class="muted">({{ ws.slug }})</span></h2>
|
||
|
||
<form method="post" action="/admin/workspaces/{{ ws.id }}" class="admin-form">
|
||
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
|
||
<label>Nom <input type="text" name="name" value="{{ ws.name }}"></label>
|
||
<label>Couleur <input type="color" name="color" value="{{ ws.color }}"></label>
|
||
<button type="submit" class="btn-save btn-inline">Renommer</button>
|
||
</form>
|
||
|
||
<h3>🔌 Connexions de l'espace</h3>
|
||
<form method="post" action="/admin/workspaces/{{ ws.id }}/connections" class="admin-form">
|
||
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
|
||
{% for c in all_connections %}
|
||
<label>
|
||
<input type="checkbox" name="connection_id" value="{{ c.id }}"{% if c.id in d.conn_ids %} checked{% endif %}>
|
||
{% if c.kind == 'github' %}🐙{% else %}🍵{% endif %} {{ c.name }} <span class="muted">({{ c.slug }})</span>
|
||
</label>
|
||
{% endfor %}
|
||
<button type="submit" class="btn-save btn-inline">Enregistrer</button>
|
||
</form>
|
||
|
||
<h3>👥 Membres</h3>
|
||
{% if d.members %}
|
||
<table class="proj-table">
|
||
<thead><tr><th>Utilisateur</th><th>Rôle dans l'espace</th><th></th></tr></thead>
|
||
<tbody>
|
||
{% for m in d.members %}
|
||
<tr>
|
||
<td>{{ m.username }}{% if m.display_name %} <span class="muted">({{ m.display_name }})</span>{% endif %}</td>
|
||
<td>{{ m.role }}</td>
|
||
<td>
|
||
<form method="post" action="/admin/workspaces/{{ ws.id }}/members/{{ m.user_id }}/remove" class="inline-form">
|
||
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
|
||
<button type="submit" class="btn-mini">Retirer</button>
|
||
</form>
|
||
</td>
|
||
</tr>
|
||
{% endfor %}
|
||
</tbody>
|
||
</table>
|
||
{% else %}
|
||
<p class="muted">Aucun membre explicite (les admins globaux voient tout).</p>
|
||
{% endif %}
|
||
<form method="post" action="/admin/workspaces/{{ ws.id }}/members" class="admin-form">
|
||
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
|
||
<label>Utilisateur
|
||
<select name="user_id">
|
||
{% for u in all_users %}<option value="{{ u.id }}">{{ u.username }}</option>{% endfor %}
|
||
</select>
|
||
</label>
|
||
<label>Rôle
|
||
<select name="role">
|
||
<option value="reader">Lecteur</option>
|
||
<option value="member" selected>Membre</option>
|
||
<option value="admin">Admin d'espace</option>
|
||
</select>
|
||
</label>
|
||
<button type="submit" class="btn-save btn-inline">Ajouter / mettre à jour</button>
|
||
</form>
|
||
|
||
<h3>📦 Sélection de projets</h3>
|
||
<p class="notes-hint">Vide = <strong>tous</strong> les projets des connexions de l'espace. Sinon, une ligne par projet au format <code>slug-connexion:proprietaire/depot</code> (ex. <code>github:bruno/mon-projet</code>).</p>
|
||
<form method="post" action="/admin/workspaces/{{ ws.id }}/projects">
|
||
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
|
||
<textarea name="selection" rows="4" style="width:100%">{% for cid, full in d.selection %}{% for c in all_connections %}{% if c.id == cid %}{{ c.slug }}:{{ full }}
|
||
{% endif %}{% endfor %}{% endfor %}</textarea>
|
||
<p><button type="submit" class="btn-save btn-inline">Enregistrer la sélection</button></p>
|
||
</form>
|
||
|
||
{% if is_global_admin %}
|
||
<form method="post" action="/admin/workspaces/{{ ws.id }}/delete" class="inline-form" onsubmit="return confirm('Supprimer cet espace ? Les boards propres à cet espace seront perdus.');">
|
||
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
|
||
<button type="submit" class="btn-mini btn-danger">Supprimer l'espace</button>
|
||
</form>
|
||
{% endif %}
|
||
</section>
|
||
{% endfor %}
|
||
|
||
{% if is_global_admin %}
|
||
<section class="briefing-card">
|
||
<h2>➕ Nouvel espace</h2>
|
||
<form method="post" action="/admin/workspaces" class="admin-form">
|
||
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
|
||
<label>Nom <input type="text" name="name" required placeholder="Open source"></label>
|
||
<label>Couleur <input type="color" name="color" value="#7c5cfc"></label>
|
||
<button type="submit" class="btn-save btn-inline">Créer</button>
|
||
</form>
|
||
</section>
|
||
{% endif %}
|
||
</main>
|
||
</body>
|
||
</html>
|