Calendar/docs/drag-drop-header-bug-analysis.md
Janus Knudsen 46b8bf9fb5 Fixes drag and drop to header issues
Addresses two key issues related to dragging events to the header: the premature removal of the original event element and the creation of duplicate all-day events.

The original event is no longer removed when dragging to the header; it is now only removed upon a successful drop.

Also, it prevents the creation of duplicate all-day events by checking for existing all-day events before creating new ones, using DOM queries to ensure accurate state.
2025-09-17 23:39:29 +02:00

3.6 KiB

Bug Analyse: Day Event Drag til Header og Tilbage

Problem Beskrivelse

Når en day event dragges op til headeren (for at konvertere til all-day) og derefter dragges tilbage til grid UDEN at droppe, opstår der et kritisk problem hvor original event forsvinder.

Flow Analyse

Trin 1: Drag Start (Day Event)

  • DragDropManager (linje 139-182): handleMouseDown() registrerer drag start
  • Original event element gemmes
  • isDragStarted = false indtil movement threshold nås

Trin 2: Drag bevæger sig op mod Header

  • DragDropManager (linje 187-253): handleMouseMove() tracker bevægelse
  • Når threshold nås: drag:start event emitted
  • EventRenderer opretter drag clone

Trin 3: Mouse enters Header ⚠️ PROBLEM STARTER HER

  • DragDropManager (linje 95-112): Lytter til header:mouseover
  • Emitter drag:convert-to-allday event
  • AllDayManager (linje 232-285): handleConvertToAllDay():
    • Opretter all-day event i header
    • FJERNER original timed event permanent (linje 274: originalElement.remove())
    • Skjuler drag clone

Trin 4: Mouse leaves Header (tilbage til grid) ⚠️ PROBLEM FORTSÆTTER

  • DragDropManager (linje 128-136): Lytter til header:mouseleave
  • Emitter drag:convert-from-allday event
  • AllDayManager (linje 290-311): handleConvertFromAllDay():
    • Fjerner all-day event fra container
    • Viser drag clone igen
    • MEN: Original event er allerede fjernet og kan ikke genskabes!

Trin 5: Drop i Grid ⚠️ DATA TABT

  • DragDropManager (linje 258-291): handleMouseUp()
  • Emitter drag:end event
  • Original element eksisterer ikke længere
  • Kun clone eksisterer med ID "clone-{id}"

Root Cause

AllDayManager.handleConvertToAllDay() fjerner permanent det originale element (linje 274) i stedet for at skjule det midlertidigt.

Konsekvenser

  1. Original event data går tabt
  2. Event ID bliver "clone-{id}" i stedet for "{id}"
  3. Event metadata kan mangle
  4. Potentielle styling/positioning problemer

Løsningsforslag

Option 1: Behold Original Element (Anbefalet)

// AllDayManager.handleConvertToAllDay() - linje 274
// FØR: originalElement.remove();
// EFTER: 
originalElement.style.display = 'none';
originalElement.dataset.temporarilyHidden = 'true';

Option 2: Gem Original Data

// Gem original element data før fjernelse
const originalData = {
  id: originalElement.dataset.eventId,
  title: originalElement.dataset.title,
  start: originalElement.dataset.start,
  end: originalElement.dataset.end,
  // ... andre properties
};
// Gem i DragDropManager eller AllDayManager

Option 3: Re-create Original on Leave

// AllDayManager.handleConvertFromAllDay()
// Genskab original element fra all-day event data
const originalElement = this.recreateTimedEvent(allDayEvent);

Implementeringsplan

  1. Modificer AllDayManager.handleConvertToAllDay()

    • Skjul original element i stedet for at fjerne
    • Marker element som midlertidigt skjult
  2. Modificer AllDayManager.handleConvertFromAllDay()

    • Find original element (ikke kun clone)
    • Vis original element igen
    • Synkroniser position med clone
  3. Opdater DragDropManager

    • Hold reference til både original og clone
    • Ved drop: opdater original, fjern clone
  4. Test Scenarios

    • Drag day event → header → tilbage → drop
    • Drag day event → header → drop i header
    • Drag day event → header → ESC key
    • Multiple hurtige hover over header

Affected Files

  • src/managers/AllDayManager.ts (linje 274, 290-311)
  • src/managers/DragDropManager.ts (linje 95-136)
  • src/renderers/EventRenderer.ts (potentielt)