diff --git a/CHANGELOG.md b/CHANGELOG.md
index 25622f5..4f84ceb 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,33 @@
# Changelog
+## 0.33.0 — 2026-10-26
+
+### Ajouté — filtrage professionnel sur « Mes issues » (/my)
+
+Demande de Bruno : retrouver vite une issue parmi toutes
+celles qui lui sont assignées (467 ouvertes au moment du
+test réel).
+
+- **Barre de filtres** en carte, dans la langue visuelle du
+ compositeur 0.31.1 : recherche texte plein champ
+ (titre, projet, #numéro, étiquettes — insensible aux
+ accents et à la casse, raccourci « / », Échap pour
+ effacer), listes **Projet** et **Étiquette** avec
+ compteurs, **chips de colonnes** colorées avec compteurs
+ (multi-sélection), **tri** (activité récente, plus
+ anciennes, titre, projet).
+- **Performance** : filtrage 100 % côté client sur des
+ attributs précalculés côté serveur — aucun aller-retour
+ réseau par frappe, application en requestAnimationFrame.
+ Compteur en direct (« 24 sur 467 issues »), compteurs de
+ section mis à jour, état vide propre avec réinitialisation
+ en un clic.
+- **Persistance** : projet, colonnes, étiquette et tri sont
+ retenus en localStorage d'une visite à l'autre (la
+ recherche texte reste éphémère) ; bouton « Réinitialiser
+ les filtres » dès qu'un filtre est actif.
+
+
## 0.32.2 — 2026-10-25
### Corrigé — console du panneau morte et liens pas tous en dev : résolution par requête
diff --git a/app/config.py b/app/config.py
index d5b4607..2508b7a 100644
--- a/app/config.py
+++ b/app/config.py
@@ -177,7 +177,7 @@ from urllib.parse import urlparse
BASE_DIR = Path(__file__).resolve().parent.parent
-APP_VERSION = "0.32.2"
+APP_VERSION = "0.33.0"
def _env_bool(name: str, default: bool) -> bool:
diff --git a/app/main.py b/app/main.py
index 25a2871..9deeacc 100644
--- a/app/main.py
+++ b/app/main.py
@@ -4245,14 +4245,48 @@ async def my_issues(request: Request):
logger.debug("search failed for /my (conn %s): %s", cid, exc)
total = len(results)
groups = _group_issue_results(results)
+ # Facettes de filtrage (0.33.0) : compteurs calculés une
+ # fois côté serveur ; le filtrage lui-même est instantané
+ # côté client, sur des attributs data-* des lignes.
+ names = _ws_names(request)
+ order = _ws_keys(request)
+ repo_facets = [
+ {"full_name": g["full_name"], "count": len(g["rows"])}
+ for g in groups
+ ]
+ col_counts: dict[str, int] = {}
+ label_counts: dict[str, int] = {}
+ for g in groups:
+ for row in g["rows"]:
+ col_counts[row["column"]] = col_counts.get(row["column"], 0) + 1
+ for label in row["issue"].get("labels") or []:
+ name = label.get("name") or ""
+ if name:
+ label_counts[name] = label_counts.get(name, 0) + 1
+ column_facets = [
+ {"key": key, "count": col_counts[key]}
+ for key in order
+ if key in col_counts
+ ] + [
+ {"key": key, "count": count}
+ for key, count in col_counts.items()
+ if key not in order
+ ]
+ label_facets = [
+ {"name": name, "count": label_counts[name]}
+ for name in sorted(label_counts, key=str.lower)
+ ]
return render(
request,
"my.html",
user=user,
groups=groups,
total=total,
- column_labels=_ws_names(request),
+ column_labels=names,
column_colors=_ws_colors(request),
+ repo_facets=repo_facets,
+ column_facets=column_facets,
+ label_facets=label_facets,
)
diff --git a/app/templates/my.html b/app/templates/my.html
index 663bc8c..c81ef97 100644
--- a/app/templates/my.html
+++ b/app/templates/my.html
@@ -5,7 +5,7 @@
Mes issues — Kanbante
-
+
{% include "_header.html" %}
@@ -15,17 +15,68 @@
🔑 Aucun utilisateur Gitea résolu : définissez GITEA_TOKEN pour voir les issues qui vous sont assignées.
{% else %}
Issues ouvertes assignées à {{ user.login }}, tous projets confondus — {{ total }} au total.
+
+ {% if groups %}
+
+
+
+ 🔍
+
+
+
+
+
+
+
+
+
+ {% for f in column_facets %}
+
+ {% endfor %}
+
+
+
+
+
+ {% endif %}
+
+
🔍 Aucune issue ne correspond à ces filtres.
+
+
{% if not groups %}
🎉 Aucune issue ne vous est assignée pour le moment.