From 0c280b3c7e4eafb5995d2b03ebb78444b3f16700 Mon Sep 17 00:00:00 2001 From: Spark Date: Sun, 11 Oct 2026 12:40:32 -0400 Subject: [PATCH] feat(capture): page /capture (formulaire, statut, exemples) + navigation --- README.md | 6 +++ app/templates/activity.html | 1 + app/templates/board.html | 1 + app/templates/briefing.html | 1 + app/templates/capture.html | 100 +++++++++++++++++++++++++++++++++++ app/templates/dashboard.html | 1 + app/templates/focus.html | 1 + app/templates/my.html | 1 + app/templates/search.html | 1 + static/css/style.css | 13 +++++ 10 files changed, 126 insertions(+) create mode 100644 app/templates/capture.html diff --git a/README.md b/README.md index cf05cc2..c4acec8 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,7 @@ - ⏳ **Vieillissement + limites WIP** — badge d'ancienneté par colonne et limites souples configurables - 🎯 **Vue Focus** — tout ce qui est En cours / en QA / En révision, tous projets confondus (`/focus`) - 🖥️ **Wallboard** — mode TV plein écran (`/wall`) : rotation automatique entre les projets actifs, cartes en vol et compteurs en très grands caractères, rafraîchi en direct ; `?repo=Proprietaire/depot` fige un seul projet +- ⚡ **Capture éclair** — page `/capture` (formulaire), endpoint `POST /api/capture` protégé par un jeton dédié, et écoute ntfy : un message publié sur le topic de capture devient une issue dans le dépôt par défaut - 🔀 **Réconciliation par étiquettes** — si l'étiquette `kanban:*` d'une issue change hors de Kanbante (dans Gitea, par un autre outil), le board adopte la colonne de l'étiquette au chargement et le journalise (source `gitea`). Une seule étiquette `kanban:*` fait foi ; aucune ou plusieurs = l'état local gagne - 🔍 **Recherche globale + Mes issues** — chercher dans toutes les issues de tous les projets (`/search`), et voir ce qui vous est assigné (`/my`) - 📊 **Briefing quotidien** — encours, vieillissement, milestones proches : page `/briefing` et envoi **ntfy** planifié @@ -112,6 +113,9 @@ sudo systemctl enable --now docker | `KANBANTE_NTFY_TOPIC` | *(vide)* | Topic ntfy du briefing (URL + topic requis pour activer l'envoi) | | `KANBANTE_NTFY_TOKEN` | *(vide)* | Jeton Bearer optionnel pour un topic protégé | | `KANBANTE_BRIEFING_TIME` | *(vide)* | Heure d'envoi quotidien du briefing, `HH:MM` heure du serveur ; vide = pas d'envoi automatique | +| `KANBANTE_CAPTURE_REPO` | *(vide)* | Dépôt par défaut de la capture éclair (`Proprietaire/depot`) | +| `KANBANTE_CAPTURE_TOKEN` | *(vide)* | Jeton dédié de `POST /api/capture` ; vide = endpoint désactivé (503) | +| `KANBANTE_CAPTURE_NTFY_TOPIC` | *(vide)* | Topic ntfy écouté : chaque message devient une issue dans `KANBANTE_CAPTURE_REPO` | ## Sécurité @@ -155,6 +159,8 @@ kanbante/ | GET | `/board/{owner}/{repo}` | Kanban board | | GET | `/focus` | En cours + QA + En révision, tous projets actifs | | GET | `/wall` | Wallboard plein écran (rotation des projets actifs ; `?repo=` pour un seul projet) | +| GET | `/capture` | Page de capture éclair (formulaire + statut + instructions) | +| POST | `/api/capture` | Capture machine-à-machine (jeton `X-Capture-Token`, JSON ou texte : 1re ligne = titre) | | GET | `/activity` | Fil d'activité (journal d'événements, tous projets) | | POST | `/api/move` | Déplacer une issue (ordre persisté, synchro Gitea) | | POST | `/api/issues` | Créer une issue Gitea depuis le board | diff --git a/app/templates/activity.html b/app/templates/activity.html index 09337b9..c212e68 100644 --- a/app/templates/activity.html +++ b/app/templates/activity.html @@ -20,6 +20,7 @@ 📰 Activité 📊 Briefing 🔍 Recherche + ⚡ Capture 🖥️ Wallboard diff --git a/app/templates/board.html b/app/templates/board.html index 1a20cbc..9836b7b 100644 --- a/app/templates/board.html +++ b/app/templates/board.html @@ -23,6 +23,7 @@ 👤 Mes issues 📰 Activité 🔍 Recherche + ⚡ Capture 🖥️ Wallboard {% if repo_info.html_url %} 🔗 Gitea ↗ diff --git a/app/templates/briefing.html b/app/templates/briefing.html index f290eb3..fcb491b 100644 --- a/app/templates/briefing.html +++ b/app/templates/briefing.html @@ -20,6 +20,7 @@ 👤 Mes issues 📰 Activité 🔍 Recherche + ⚡ Capture 🖥️ Wallboard diff --git a/app/templates/capture.html b/app/templates/capture.html new file mode 100644 index 0000000..621eb14 --- /dev/null +++ b/app/templates/capture.html @@ -0,0 +1,100 @@ + + + + + + + Capture éclair — Kanbante + + + +
+ + +
+ +
+
+

⚡ Capture éclair

+

Une idée, un bogue, une pensée — capturés en deux secondes, ils deviennent une issue dans le bon backlog.

+
+ + {% if created %} +
+

✅ Capturé !

+

Issue #{{ created.number }} créée dans + {{ created.repo_full_name }} (colonne {{ created.column }}) : + {% if created.html_url %}{{ created.title }}{% else %}{{ created.title }}{% endif %} + · ouvrir le board

+
+ {% endif %} + {% if error %} +
+

❌ Capture impossible

+

{{ error }}

+
+ {% endif %} + +
+

✍️ Saisie rapide

+
+ + + + + + +
+
+ +
+

🔌 Depuis un script ou un raccourci

+ {% if api_enabled %} +

L'endpoint POST /api/capture est actif (jeton de capture configuré). Exemples :

+
curl -X POST https://votre-kanbante/api/capture \
+  -H "X-Capture-Token: VOTRE_JETON" \
+  -H "Content-Type: application/json" \
+  -d '{"text": "Idée : trier les cartes par échéance\n\nDétails ici…"}'
+

Texte libre accepté aussi (Content-Type: text/plain) : la première ligne devient le titre. Le dépôt vient de KANBANTE_CAPTURE_REPO ou du champ repo.

+ {% else %} +

L'endpoint POST /api/capture est inactif : définis KANBANTE_CAPTURE_TOKEN (un jeton dédié, distinct de celui de Gitea) puis redémarre Kanbante.

+ {% endif %} +
+ +
+

📱 Depuis le téléphone (ntfy)

+ {% if ntfy_topic %} +

Écoute active sur le topic {{ ntfy_topic }} : chaque message publié devient une issue dans {{ capture_repo or "— (KANBANTE_CAPTURE_REPO manquant)" }}. La première ligne fait le titre. Publie depuis l'application ntfy ou :

+
curl -d "Idée : relire le rapport\n\nDétails…" {{ ntfy_url }}/{{ ntfy_topic }}
+

Les messages portant le tag kanbante sont ignorés (jamais d'auto-ingestion).

+ {% else %} +

Inactif : définis KANBANTE_CAPTURE_NTFY_TOPIC (et KANBANTE_CAPTURE_REPO) puis redémarre Kanbante. Chaque message publié sur ce topic deviendra une issue — capture depuis l'application ntfy en deux touchers.

+ {% endif %} +
+
+ + + + diff --git a/app/templates/dashboard.html b/app/templates/dashboard.html index 0f0ff39..4600e80 100644 --- a/app/templates/dashboard.html +++ b/app/templates/dashboard.html @@ -20,6 +20,7 @@ 📰 Activité 📊 Briefing 🔍 Recherche + ⚡ Capture 🖥️ Wallboard diff --git a/app/templates/focus.html b/app/templates/focus.html index 8a60743..49d9073 100644 --- a/app/templates/focus.html +++ b/app/templates/focus.html @@ -20,6 +20,7 @@ 📰 Activité 📊 Briefing 🔍 Recherche + ⚡ Capture 🖥️ Wallboard {{ groups|map(attribute='cards')|map('length')|sum }} cartes en cours diff --git a/app/templates/my.html b/app/templates/my.html index 32697a5..d760ae8 100644 --- a/app/templates/my.html +++ b/app/templates/my.html @@ -19,6 +19,7 @@ 👤 Mes issues 📰 Activité 🔍 Recherche + ⚡ Capture 🖥️ Wallboard diff --git a/app/templates/search.html b/app/templates/search.html index 36f6208..1d5b98b 100644 --- a/app/templates/search.html +++ b/app/templates/search.html @@ -19,6 +19,7 @@ 👤 Mes issues 📰 Activité 🔍 Recherche + ⚡ Capture 🖥️ Wallboard diff --git a/static/css/style.css b/static/css/style.css index 4b4a1de..67d4c65 100644 --- a/static/css/style.css +++ b/static/css/style.css @@ -967,3 +967,16 @@ footer { @media (max-width: 900px) { .wall-counts { grid-template-columns: repeat(3, 1fr); } } + +/* ── Capture éclair (0.7.0) ── */ +.capture-form { display: flex; flex-direction: column; gap: 12px; } +.capture-form label { display: flex; flex-direction: column; gap: 6px; font-weight: 600; } +.capture-form input, .capture-form textarea, .capture-form select { + padding: 10px 12px; border: 1px solid var(--border); border-radius: var(--radius-sm); + background: var(--bg-2); color: var(--text-1); font: inherit; font-weight: 400; +} +.capture-form .btn { align-self: flex-start; } +.capture-pre { + background: var(--bg-2); border: 1px solid var(--border); border-radius: var(--radius-sm); + padding: 12px 14px; overflow-x: auto; font-size: 0.82rem; line-height: 1.5; +}