planif: assistant renfort — nom robuste (jamais « undefined »)
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 <noreply@anthropic.com>
This commit is contained in:
parent
969d5af9f9
commit
8a655f9933
|
|
@ -1484,7 +1484,7 @@
|
||||||
<div v-if="jobDetail.canTeam" class="jd-team">
|
<div v-if="jobDetail.canTeam" class="jd-team">
|
||||||
<div class="text-subtitle2 row items-center q-mb-xs"><q-icon name="group" size="18px" class="q-mr-xs" /> Équipe / renfort<q-space /><q-spinner v-if="jobDetail.teamLoading" size="16px" color="deep-purple" /></div>
|
<div class="text-subtitle2 row items-center q-mb-xs"><q-icon name="group" size="18px" class="q-mr-xs" /> Équipe / renfort<q-space /><q-spinner v-if="jobDetail.teamLoading" size="16px" color="deep-purple" /></div>
|
||||||
<div v-if="jobDetail.team && jobDetail.team.length" class="row items-center q-gutter-xs q-mb-xs">
|
<div v-if="jobDetail.team && jobDetail.team.length" class="row items-center q-gutter-xs q-mb-xs">
|
||||||
<q-chip v-for="a in jobDetail.team" :key="a.tech_id" dense removable @remove="jdRemoveAssistant(a.tech_id)" color="deep-purple-1" text-color="deep-purple-9" icon="group">{{ a.tech_name || a.tech_id }}</q-chip>
|
<q-chip v-for="a in jobDetail.team" :key="a.tech_id" dense removable @remove="jdRemoveAssistant(a.tech_id)" color="deep-purple-1" text-color="deep-purple-9" icon="group">{{ a.tech_name || techNameById(a.tech_id) || a.tech_id || '—' }}</q-chip>
|
||||||
</div>
|
</div>
|
||||||
<div v-else class="text-caption text-grey-6 q-mb-xs">Aucun assistant. Ajoutez un renfort → un bloc <b>hachuré</b> sera réservé dans son horaire (anti double‑booking).</div>
|
<div v-else class="text-caption text-grey-6 q-mb-xs">Aucun assistant. Ajoutez un renfort → un bloc <b>hachuré</b> sera réservé dans son horaire (anti double‑booking).</div>
|
||||||
<div class="row items-center no-wrap q-gutter-xs">
|
<div class="row items-center no-wrap q-gutter-xs">
|
||||||
|
|
@ -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à.
|
// 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).
|
// 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 jdTeamOptions = computed(() => {
|
||||||
const taken = new Set([jobDetail.techId, ...(jobDetail.team || []).map(a => a.tech_id)])
|
const taken = new Set([jobDetail.techId, ...(jobDetail.team || []).map(a => a.tech_id)])
|
||||||
const req = jobDetail.required_skill || jobDetail.skill || ''
|
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() })
|
const jdMessages = computed(() => { const m = (jobDetail.thread && jobDetail.thread.messages) || []; return m.slice().reverse() })
|
||||||
async function jdAddAssistant () {
|
async function jdAddAssistant () {
|
||||||
const id = jobDetail.teamAdd; if (!id || !jobDetail.name) return
|
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 {
|
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
|
jobDetail.teamAdd = null
|
||||||
const r = await roster.getJobTeam(jobDetail.name); jobDetail.team = r.assistants || []
|
const r = await roster.getJobTeam(jobDetail.name); jobDetail.team = r.assistants || []
|
||||||
await reloadOccupancy()
|
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) }
|
} catch (e) { err(e) }
|
||||||
}
|
}
|
||||||
async function jdRemoveAssistant (techId) {
|
async function jdRemoveAssistant (techId) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user