diff --git a/apps/ops/src/pages/PlanificationPage.vue b/apps/ops/src/pages/PlanificationPage.vue
index f11ed06..f3b464a 100644
--- a/apps/ops/src/pages/PlanificationPage.vue
+++ b/apps/ops/src/pages/PlanificationPage.vue
@@ -96,6 +96,7 @@
+ Générer l'horaire (semaine)solveur de quarts — la semaine affichée
Générer les horaires (lot)modèle → plusieurs techs, N semaines
Rotation de garde
@@ -109,7 +110,7 @@
Appliquer le modèle par défaut (consciente des absences)
-
+ Répartition automatique des jobs du jour sélectionné (distance · compétence · priorité · taux d'occupation) — revue avant d'appliquer
Notifier les techs par SMS à la publication
Réassigne les tickets aux techniciens DANS le système legacy (osTicket) selon l'assignation Ops — aperçu avant d'écrire.
@@ -119,7 +120,6 @@
-
{{ visibleTechs.length }} / {{ techs.length }} techs
{{ cellClipboard.length }} copié(s)
@@ -3760,7 +3760,7 @@ const priorityScores = computed(() => {
function techScore (t) { const v = priorityScores.value[t.id]; return v == null ? 0 : v }
function techRank (t) { if (!skillFilter.value.length) return null; const i = visibleTechs.value.findIndex(x => x.id === t.id); return i >= 0 ? i + 1 : null }
const visibleTechs = computed(() => {
- const q = search.value.trim().toLowerCase()
+ const q = (search.value || '').trim().toLowerCase() // clearable (X) met search=null → null-safe (sinon le computed plante et le champ « ne se vide pas »)
const list = techs.value.filter(t => (showHidden.value || !isHidden(t.id)) && (!groupFilter.value || t.group === groupFilter.value) && techHasSkill(t) && (!q || (t.name || '').toLowerCase().includes(q) || (t.group || '').toLowerCase().includes(q)))
// Filtre par compétence actif → on TRIE par priorité (meilleur score d'abord) ; sinon ordre équipe/nom.
if (skillFilter.value.length) return list.slice().sort((a, b) => techScore(a) - techScore(b) || (a.name || '').localeCompare(b.name || ''))
@@ -4389,7 +4389,8 @@ function buildSuggestion () {
suggestDlg.plan = plan
}
function openSuggest () {
- suggestDay.value = mobileSelIso.value || kbSelIso.value || todayISO() // repli si aucun chip coché
+ // Jour de base = la sélection de la vue active (strip Tournées, Jour kanban, ou bande mobile) → « Suggérer se base sur la journée sélectionnée »
+ suggestDay.value = (boardView.value === 'routes' && routesDay.value) || (boardView.value === 'kanban' && kbSelIso.value) || mobileSelIso.value || routesDay.value || kbSelIso.value || todayISO()
suggestDlg.fromSel = selectedNames.value.length > 0
// Étape « disponibilité » d'abord : défaut = techs AVEC un quart sur un des jours de la fenêtre (= disponibles) ; sinon tous les visibles.
const win = suggestWindow.value // fenêtre = chips de date cochés, sinon le jour du sélecteur