/* Move existing bookings without changing employee or duration. */ (() => { 'use strict'; const host = document.getElementById('casePlannerWeek'); if (!host) return; let drag = null, saving = false; function clear() { host.querySelectorAll('.is-moving,.is-drop-target').forEach(node => node.classList.remove('is-moving','is-drop-target')); drag = null; } function target(event) { const day = event.target.closest('.v5-time-day'); if (!day || !drag) return null; const offset = (event.clientY-day.getBoundingClientRect().top)/1.6 - drag.offset; const minutes = Math.max(0, Math.min(1425, Math.round((Number(host.dataset.firstHour)*60+offset)/15)*15)); const start = new Date(`${day.dataset.date}T00:00:00`); start.setMinutes(minutes); // A segment after midnight still moves the complete original booking. start.setTime(start.getTime() - drag.segmentOffset); return {day, start}; } host.addEventListener('dragstart', event => { const card = event.target.closest('[data-move-id]'); if (!card || saving || event.target.closest('.case-slot-resize')) {event.preventDefault(); return;} drag = { card, offset: (event.clientY-card.getBoundingClientRect().top)/1.6, segmentOffset: new Date(card.dataset.segmentStart)-new Date(card.dataset.start), }; card.classList.add('is-moving'); event.dataTransfer.effectAllowed = 'move'; event.dataTransfer.setData('text/plain', card.dataset.moveId); }); host.addEventListener('dragover', event => { const drop = target(event); if (!drop) return; event.preventDefault(); event.dataTransfer.dropEffect = 'move'; host.querySelectorAll('.is-drop-target').forEach(node => node.classList.remove('is-drop-target')); drop.day.classList.add('is-drop-target'); drag.card.title = `Flyt til ${drop.start.toLocaleString('da-DK', {weekday:'short',hour:'2-digit',minute:'2-digit'})}`; }); host.addEventListener('drop', async event => { const drop = target(event); if (!drop || saving) return; event.preventDefault(); event.stopPropagation(); const {card} = drag; const start = new Date(card.dataset.start), end = new Date(card.dataset.end); clear(); if (drop.start.getTime() === start.getTime()) return; const payload = { version: Number(card.dataset.version), starts_at: drop.start.toISOString(), ends_at: new Date(drop.start.getTime()+(end.getTime()-start.getTime())).toISOString(), }; saving = true; try { for (;;) { const response = await fetch(`/api/v1/planner/allocations/${Number(card.dataset.moveId)}`, { method:'PATCH', credentials:'include', headers:{'Content-Type':'application/json'}, body:JSON.stringify(payload), }); const body = await response.json(); if (response.ok) break; const message = typeof body.detail === 'string' ? body.detail : body.detail?.message; if (response.status === 409 && body.detail?.conflict_status && !payload.confirm_conflicts && window.confirm(`${message}. Vil du flytte aftalen alligevel?`)) { payload.confirm_conflicts = true; continue; } throw new Error(message || 'Kunne ikke flytte aftalen'); } window.showCaseFeedback('Aftalen er flyttet', 'success'); } catch (error) { window.showCaseFeedback(error.message); } finally { try {await window.loadEmbeddedCasePlanner(true);} finally {saving = false;} } }); host.addEventListener('dragend', clear); })();