Planification: cellule sans icônes — juste intervalle + timeline

Retrait des icônes en cellule (☀/🌆/🌙/🛡️). Le libellé = uniquement l'intervalle début–fin
(ex 8–16) ; le timeline (bande pleine vs garde hachurée) porte le reste visuellement.
Tag garde dans l'infobulle: '(garde)' au lieu de l'emoji.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
louispaulb 2026-06-04 15:55:02 -04:00
parent 17d8442b98
commit dfefd7822f

View File

@ -385,11 +385,10 @@ function cellBands (techId, iso) {
return out
}
function blockStyle (blk, pct) { return { ...pos(blk.s, Math.min(blk.e, 24)), background: pct == null ? '#6d4c41' : occColor(pct) } }
// Fenêtre des shifts RÉGULIERS (la garde ne compte pas comme dispo offrable)
function cellRegWindow (techId, iso) { let s = Infinity; let e = -Infinity; for (const a of cellsOf(techId, iso)) { const t = tplByName.value[a.shift]; if (!t || t.on_call) continue; const st = hToNum(t.start_time); const en = hToNum(t.end_time); if (st != null) s = Math.min(s, st); if (en != null) e = Math.max(e, en) } return isFinite(s) ? { s, e } : null }
function cellPeriod (techId, iso) { const w = cellRegWindow(techId, iso); if (!w) return ''; const m = (w.s + w.e) / 2; return m < 14 ? '☀️' : m < 20 ? '🌆' : '🌙' }
// Libellé inline = icône période + intervalle débutfin (la référence) + 🛡 si garde
function cellLabel (techId, iso) { const o = cellOcc(techId, iso); if (!o) return ''; const w = cellRegWindow(techId, iso); let s = o.hasReg ? cellPeriod(techId, iso) : ''; if (w) s += (s ? ' ' : '') + fmtH(w.s) + '' + fmtH(w.e); if (o.hasGarde) s += ' 🛡️'; return s || '🛡️ garde' }
// Fenêtre des shifts (garde=true seulement les quarts de garde ; garde=false réguliers)
function winOf (techId, iso, garde) { let s = Infinity; let e = -Infinity; for (const a of cellsOf(techId, iso)) { const t = tplByName.value[a.shift]; if (!t || (!!t.on_call) !== garde) continue; const st = hToNum(t.start_time); const en = hToNum(t.end_time); if (st != null) s = Math.min(s, st); if (en != null) e = Math.max(e, en) } return isFinite(s) ? { s, e } : null }
// Libellé inline = intervalle débutfin seulement (pas d'icône : le timeline + l'heure suffisent)
function cellLabel (techId, iso) { const w = winOf(techId, iso, false) || winOf(techId, iso, true); return w ? (fmtH(w.s) + '' + fmtH(w.e)) : '' }
const occCells = computed(() => {
const m = {}; const ct = cellsByTechDay.value
for (const techId in ct) for (const iso in ct[techId]) {
@ -404,7 +403,7 @@ const occCells = computed(() => {
function cellOcc (techId, iso) { return occCells.value[techId + '|' + iso] || null }
function occColor (pct) { return pct >= 100 ? '#e53935' : pct >= 70 ? '#fb8c00' : '#43a047' }
function cellInterval (techId, iso) {
return cellsOf(techId, iso).map(a => { const t = tplByName.value[a.shift]; const nm = (t && t.template_name) ? t.template_name.split(' ')[0] + ' ' : ''; const tag = (t && t.on_call) ? ' 🛡️ garde' : ''; return (t && t.start_time) ? (nm + t.start_time.slice(0, 5) + '' + (t.end_time || '').slice(0, 5) + tag) : (a.shift_name || a.shift) }).join(' + ')
return cellsOf(techId, iso).map(a => { const t = tplByName.value[a.shift]; const nm = (t && t.template_name) ? t.template_name.split(' ')[0] + ' ' : ''; const tag = (t && t.on_call) ? ' (garde)' : ''; return (t && t.start_time) ? (nm + t.start_time.slice(0, 5) + '' + (t.end_time || '').slice(0, 5) + tag) : (a.shift_name || a.shift) }).join(' + ')
}
// coût de main-d'œuvre (coût chargé × heures)