Calendar/event-overlap-implementation-plan.md
Janus Knudsen ff067cfac3 Implements event overlap rendering
Adds logic to handle event overlaps in the calendar view. It introduces two patterns: column sharing for events with the same start time (rendered using flexbox) and stacking for events with a >30 min difference (rendered with reduced width and z-index).

It also introduces deep linking to specific events via URL parameters.
2025-09-04 00:16:35 +02:00

4.1 KiB

Event Overlap Rendering Implementation Plan

Oversigt

Implementer event overlap rendering med to forskellige patterns:

  1. Column Sharing: Events med samme start tid deles om bredden med flexbox
  2. Stacking: Events med >30 min forskel ligger oven på med reduceret bredde

Test Scenarier (fra mock-events.json)

September 2 - Stacking Test

  • Event 93: "Team Standup" 09:00-09:30
  • Event 94: "Product Planning" 14:00-16:00
  • Event 96: "Deep Work" 15:00-15:30 (>30 min efter standup, skal være 15px mindre)

September 4 - Column Sharing Test

  • Event 97: "Team Standup" 09:00-09:30
  • Event 98: "Technical Review" 15:00-16:30
  • Event 100: "Sprint Review" 15:00-16:00 (samme start tid som Technical Review - skal deles 50/50)

Teknisk Arkitektur

1. EventOverlapManager Klasse

class EventOverlapManager {
  detectOverlap(events: CalendarEvent[]): OverlapGroup[]
  createEventGroup(events: CalendarEvent[]): HTMLElement
  addToEventGroup(group: HTMLElement, event: CalendarEvent): void
  removeFromEventGroup(group: HTMLElement, eventId: string): void
  createStackedEvent(event: CalendarEvent, underlyingWidth: number): HTMLElement
}

2. CSS Struktur

.event-group {
  position: absolute;
  display: flex;
  gap: 1px;
  width: 100%;
}

.event-group swp-event {
  flex: 1;
  position: relative;
}

.stacked-event {
  position: absolute;
  width: calc(100% - 15px);
  right: 0;
  z-index: var(--z-stacked-event);
}

3. DOM Struktur

<!-- Normal event -->
<swp-event>Single Event</swp-event>

<!-- Column sharing group -->
<div class="event-group" style="position: absolute; top: 200px;">
  <swp-event>Event 1</swp-event>
  <swp-event>Event 2</swp-event>
</div>

<!-- Stacked event -->
<swp-event class="stacked-event" style="top: 210px;">Stacked Event</swp-event>

Implementerings Steps

Phase 1: Core Infrastructure

  1. Opret EventOverlapManager klasse
  2. Implementer overlap detection algoritme
  3. Tilføj CSS klasser for event-group og stacked-event

Phase 2: Column Sharing (Flexbox)

  1. Implementer createEventGroup metode med flexbox
  2. Implementer addToEventGroup og removeFromEventGroup
  3. Integrér i BaseEventRenderer.renderEvent

Phase 3: Stacking Logic

  1. Implementer stacking detection (>30 min forskel)
  2. Implementer createStackedEvent med reduceret bredde
  3. Tilføj z-index management

Phase 4: Drag & Drop Integration

  1. Modificer drag & drop handleDragEnd til overlap detection
  2. Implementer event repositioning ved drop på eksisterende events
  3. Tilføj cleanup logik for tomme event-group containers

Phase 5: Testing & Optimization

  1. Test column sharing med September 4 events (samme start tid)
  2. Test stacking med September 2 events (>30 min forskel)
  3. Test kombinerede scenarier
  4. Performance optimering og cleanup

Algoritmer

Overlap Detection

function detectOverlap(events: CalendarEvent[]): OverlapType {
  const timeDiff = Math.abs(event1.startTime - event2.startTime);
  
  if (timeDiff === 0) return 'COLUMN_SHARING';
  if (timeDiff > 30 * 60 * 1000) return 'STACKING';
  return 'NORMAL';
}

Column Sharing Calculation

function calculateColumnSharing(events: CalendarEvent[]) {
  const eventCount = events.length;
  // Flexbox håndterer automatisk: flex: 1 på hver event
  return { width: `${100 / eventCount}%`, flex: 1 };
}

Stacking Calculation

function calculateStacking(underlyingEvent: HTMLElement) {
  const underlyingWidth = underlyingEvent.offsetWidth;
  return {
    width: underlyingWidth - 15,
    right: 0,
    zIndex: getNextZIndex()
  };
}

Event Bus Integration

  • overlap:detected - Når overlap detekteres
  • overlap:group-created - Når event-group oprettes
  • overlap:event-stacked - Når event stacks oven på andet
  • overlap:group-cleanup - Når tom group fjernes

Success Criteria

  • September 4: Technical Review og Sprint Review deles 50/50 i bredden
  • September 2: Deep Work ligger oven på med 15px mindre bredde
  • Drag & drop fungerer med overlap detection
  • Cleanup af tomme event-group containers
  • Z-index management - nyere events øverst