From efa652fffbfeb651b428fe433c11fd9529ff8478 Mon Sep 17 00:00:00 2001 From: AdamThomas Date: Tue, 15 Sep 2026 22:43:10 +0200 Subject: [PATCH] =?UTF-8?q?Panneau=20d'affectation=20:=20barre=20de=20rech?= =?UTF-8?q?erche=20pour=20retrouver=20un=20b=C3=A9n=C3=A9vole?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit La liste des candidats se limitait aux 10 mieux classés par le score de chance — un bénévole précis pouvait ne jamais y apparaître. Un champ de recherche (nom/prénom, insensible aux accents/casse) permet maintenant de le retrouver et de l'affecter directement, sans être limité au classement. - Recherche vide : comportement inchangé (top 10 par score de chance). - Recherche non vide : jusqu'à 20 bénévoles non affectés dont le nom correspond, triés par le même score ; message dédié si aucun ne correspond. - `foldAccents` (accents/casse) déplacé de `ConfigVolunteers.tsx` vers `lib/planning.ts` pour être partagé avec le panneau d'affectation. - `GrillePage.tsx` : `key={shift.shift_id}` sur `AssignmentPanel` pour que la recherche (et tout futur état local) reparte à zéro en changeant de créneau, plutôt que de persister sur le suivant. Vérifié : typecheck, lint, build, smoke frontend OK. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_017uUsRg7XzopkCPWimwg9ZM --- frontend/src/i18n/locales/fr.json | 3 +- frontend/src/lib/planning.ts | 8 +++ frontend/src/pages/GrillePage.tsx | 3 +- .../src/pages/config/ConfigVolunteers.tsx | 8 +-- frontend/src/pages/grille/AssignmentPanel.tsx | 49 ++++++++++++++----- 5 files changed, 49 insertions(+), 22 deletions(-) diff --git a/frontend/src/i18n/locales/fr.json b/frontend/src/i18n/locales/fr.json index 5d95742..98827bb 100644 --- a/frontend/src/i18n/locales/fr.json +++ b/frontend/src/i18n/locales/fr.json @@ -92,7 +92,8 @@ "grille.panel.noneAssigned": "Personne n'est encore affecté sur ce créneau.", "grille.panel.hoursTotal": "{hours} H AU TOTAL", "grille.panel.candidates": "CANDIDATS", - "grille.panel.candidatesHint": "LES MOINS CHARGÉS D'ABORD", + "grille.panel.searchVolunteer": "Rechercher un bénévole…", + "grille.panel.searchNoMatch": "Aucun bénévole ne correspond à cette recherche.", "grille.panel.hoursAssigned": "{hours} H · {slots} CRÉNEAUX", "grille.panel.assign": "AFFECTER", "grille.panel.blocked": "BLOQUÉ", diff --git a/frontend/src/lib/planning.ts b/frontend/src/lib/planning.ts index 9f59c93..5499f49 100644 --- a/frontend/src/lib/planning.ts +++ b/frontend/src/lib/planning.ts @@ -16,6 +16,14 @@ export function categoryLabel(category: PositionCategory): string { return t(`position.category.${category.toLowerCase()}`); } +/** Normalise pour une recherche insensible aux accents et à la casse. */ +export function foldAccents(value: string): string { + return value + .normalize('NFD') + .replace(/[\u0300-\u036f]/g, '') + .toLowerCase(); +} + // --------------------------------------------------------------------------- // // Disponibilités : couverture d'un créneau par les fenêtres déclarées // // (portage de `backend/app/validation/engine.py`). // diff --git a/frontend/src/pages/GrillePage.tsx b/frontend/src/pages/GrillePage.tsx index 10a935c..1ccd63b 100644 --- a/frontend/src/pages/GrillePage.tsx +++ b/frontend/src/pages/GrillePage.tsx @@ -175,6 +175,7 @@ export function GrillePage() {