/* Case-local time grid; the shared planner remains responsible for loading. */ (() => { 'use strict'; window.renderCaseWeekCalendar = function(host, anchor, items) { const esc = value => String(value ?? '').replace(/[&<>"']/g, c => ({'&':'&', '<':'<', '>':'>', '"':'"', "'":'''}[c])); const key = date => `${date.getFullYear()}-${String(date.getMonth()+1).padStart(2,'0')}-${String(date.getDate()).padStart(2,'0')}`; const time = date => date.toLocaleTimeString('da-DK', {hour:'2-digit', minute:'2-digit'}); const monday = new Date(anchor); monday.setHours(0,0,0,0); const days = []; let firstHour = 7, lastHour = 17; for (let index = 0; index < 7; index++) { const date = new Date(monday); date.setDate(date.getDate()+index); const next = new Date(date); next.setDate(next.getDate()+1); const segments = items.filter(item => new Date(item.starts_at) < next && new Date(item.ends_at) > date).map(item => { const start = new Date(Math.max(new Date(item.starts_at).getTime(), date.getTime())); const end = new Date(Math.min(new Date(item.ends_at).getTime(), next.getTime())); const from = start.getHours()*60+start.getMinutes(); const to = end.getTime() === next.getTime() ? 1440 : end.getHours()*60+end.getMinutes(); firstHour = Math.min(firstHour, Math.floor(from/60)); lastHour = Math.max(lastHour, Math.ceil(to/60)); return {item, start, end, from, to}; }).sort((a,b) => a.from-b.from); if (index < 5 || segments.length) days.push({date, segments}); } const height = (lastHour-firstHour)*96; host.classList.add('v5-time-grid'); host.style.setProperty('--week-days', days.length); host.dataset.firstHour = String(firstHour); host.dataset.lastHour = String(lastHour); host.innerHTML = '
Kl.
' + days.map(({date}) => `
${esc(date.toLocaleDateString('da-DK',{weekday:'short',day:'numeric',month:'short'}))}
`).join('') + `
${Array.from({length:lastHour-firstHour+1},(_,i)=>`${String(firstHour+i).padStart(2,'0')}:00`).join('')}
` + days.map(({date,segments}) => { const lanes = []; for (const segment of segments) { let lane = lanes.findIndex(end => end <= segment.from); if (lane < 0) lane = lanes.length; lanes[lane] = segment.to; segment.lane = lane; } return `
${segments.map(({item,start,end,from,to,lane}) => { const canResize = !item.locked && new Date(item.ends_at).getTime() === end.getTime(); return `
${time(start)}–${time(end)}
${esc(item.user_name || 'Ukendt')}
${item.note ? `
${esc(item.note)}
` : ''}${item.conflict_status && item.conflict_status !== 'none' ? 'Overlap' : ''}${canResize ? `` : ''}
`; }).join('')}
`; }).join(''); const friday = days[days.length-1].date; document.getElementById('casePlannerWeekLabel').textContent = `${monday.toLocaleDateString('da-DK',{day:'numeric',month:'short'})} – ${friday.toLocaleDateString('da-DK',{day:'numeric',month:'short',year:'numeric'})}`; if (!host.dataset.timeGridBound) { host.dataset.timeGridBound = 'true'; host.addEventListener('click', event => { if (event.target.closest('.v5-time-event')) return; const day = event.target.closest('.v5-time-day'); if (!day) return; const minutes = Math.max(0, Math.min(1425, Number(host.dataset.firstHour)*60 + Math.floor((event.clientY-day.getBoundingClientRect().top)/24)*15)); window.openEmbeddedPlannerSlot(day.dataset.date); document.getElementById('casePlannerSlotTime').value = `${String(Math.floor(minutes/60)).padStart(2,'0')}:${String(minutes%60).padStart(2,'0')}`; }); } }; })();