From 8a655f993319197d02ed6fcbf03168b68b2b5325 Mon Sep 17 00:00:00 2001 From: louispaulb Date: Tue, 7 Jul 2026 13:36:43 -0400 Subject: [PATCH] =?UTF-8?q?planif:=20assistant=20renfort=20=E2=80=94=20nom?= =?UTF-8?q?=20robuste=20(jamais=20=C2=AB=20undefined=20=C2=BB)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit jdAddAssistant : dérive le nom du tech chargé OU du libellé de l'option choisie OU l'id (jamais undefined), coerce tech_id en String → la réservation (bloc hachuré) se crée correctement. Puce : repli techNameById/id/—. (DB vérifiée : 0 ligne assistant corrompue ; le « undefined » était transitoire à l'ajout.) Co-Authored-By: Claude Opus 4.8 --- apps/ops/src/pages/PlanificationPage.vue | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/apps/ops/src/pages/PlanificationPage.vue b/apps/ops/src/pages/PlanificationPage.vue index 8ae143c..8ffee1f 100644 --- a/apps/ops/src/pages/PlanificationPage.vue +++ b/apps/ops/src/pages/PlanificationPage.vue @@ -1484,7 +1484,7 @@
Équipe / renfort
- {{ a.tech_name || a.tech_id }} + {{ a.tech_name || techNameById(a.tech_id) || a.tech_id || '—' }}
Aucun assistant. Ajoutez un renfort → un bloc hachuré sera réservé dans son horaire (anti double‑booking).
@@ -2383,6 +2383,7 @@ const geoTimeline = computed(() => { }) // Options du sélecteur d'assistant (TechSelect, recherche par nom OU compétence) : tous les techs sauf le lead + l'équipe déjà là. // Label = nom · compétences (searchable) ; CAPABLES d'abord (possèdent la compétence du job) ; value = id (scalaire). +function techNameById (id) { const t = (techs.value || []).find(x => x.id === id); return t ? t.name : '' } // repli nom d'un assistant depuis l'id const jdTeamOptions = computed(() => { const taken = new Set([jobDetail.techId, ...(jobDetail.team || []).map(a => a.tech_id)]) const req = jobDetail.required_skill || jobDetail.skill || '' @@ -2395,13 +2396,16 @@ const jdTeamOptions = computed(() => { const jdMessages = computed(() => { const m = (jobDetail.thread && jobDetail.thread.messages) || []; return m.slice().reverse() }) async function jdAddAssistant () { const id = jobDetail.teamAdd; if (!id || !jobDetail.name) return - const tech = (techs.value || []).find(t => t.id === id); if (!tech) return + const tech = (techs.value || []).find(t => t.id === id) + // Nom robuste : tech chargé, sinon libellé de l'option choisie (« Nom · compétences »), sinon l'id — jamais « undefined ». + const opt = (jdTeamOptions.value || []).find(o => o.value === id) + const name = (tech && tech.name) || (opt && String(opt.label || '').split(' · ')[0].trim()) || String(id) try { - await roster.addAssistant(jobDetail.name, { tech_id: tech.id, tech_name: tech.name, duration_h: 0, pinned: 1 }) + await roster.addAssistant(jobDetail.name, { tech_id: String(id), tech_name: name, duration_h: 0, pinned: 1 }) jobDetail.teamAdd = null const r = await roster.getJobTeam(jobDetail.name); jobDetail.team = r.assistants || [] await reloadOccupancy() - $q.notify({ type: 'positive', icon: 'group_add', message: tech.name + ' ajouté en renfort · bloc hachuré réservé dans son horaire', timeout: 2600 }) + $q.notify({ type: 'positive', icon: 'group_add', message: name + ' ajouté en renfort · bloc hachuré réservé dans son horaire', timeout: 2600 }) } catch (e) { err(e) } } async function jdRemoveAssistant (techId) {