Calendar/docs/code-improvement-plan.md
Janus Knudsen c07d83d86f Refactors calendar event rendering and management
Improves code organization and maintainability by separating concerns related to all-day event rendering, header management, and event resizing.

Moves all-day event rendering logic into a dedicated `AllDayEventRenderer` class, utilizing the factory pattern for event element creation.

Refactors `AllDayManager` to handle all-day row height animations, separated from `HeaderManager`.

Removes the `ResizeManager` and related functionality.

These changes aim to reduce code duplication, improve testability, and enhance the overall architecture of the calendar component.
2025-09-12 00:36:02 +02:00

5.2 KiB

Kodeanalyse og Forbedringsplan - Calendar System

Overordnet Vurdering

Koden er generelt velstruktureret med god separation of concerns. Der er dog stadig nogle områder med duplikering og potentiale for yderligere optimering.

Positive Observationer

1. God Arkitektur

  • Factory Pattern: SwpEventElement bruger factory pattern korrekt
  • Event-driven: Konsistent brug af EventBus for kommunikation
  • Caching: God brug af caching i DragDropManager og EventManager
  • Separation: AllDayManager er korrekt separeret fra HeaderManager

2. Performance Optimering

  • DOM Caching: DragDropManager cacher DOM elementer effektivt
  • Event Throttling: Implementeret i flere managers
  • Lazy Loading: Smart brug af lazy loading patterns

3. TypeScript Best Practices

  • Stærk typing med interfaces
  • God brug af branded types (EventId)
  • Konsistent error handling

Identificerede Problemer og Forbedringsforslag 🔧

1. Duplikeret Time Formatting

Problem: formatTime() metode findes i:

  • EventRenderer.ts (linje 280-297)
  • SwpEventElement.ts (linje 44-50)

Løsning: Opret en central TimeFormatter utility:

// src/utils/TimeFormatter.ts
export class TimeFormatter {
  static formatTime(input: number | Date | string): string {
    // Centraliseret implementation
  }
}

2. Duplikeret Cache Management

Problem: Lignende cache patterns i:

  • AllDayManager (linje 11-76)
  • HeaderManager
  • GridRenderer

Løsning: Generisk CacheManager:

// src/utils/CacheManager.ts
export class DOMCacheManager<T extends Record<string, HTMLElement | null>> {
  private cache: T;
  
  constructor(initialCache: T) {
    this.cache = initialCache;
  }
  
  get<K extends keyof T>(key: K, selector?: string): T[K] {
    if (!this.cache[key] && selector) {
      this.cache[key] = document.querySelector(selector) as T[K];
    }
    return this.cache[key];
  }
  
  clear(): void {
    Object.keys(this.cache).forEach(key => {
      this.cache[key as keyof T] = null;
    });
  }
}

3. Overlap Detection Kompleksitet

Problem: EventRenderer har stadig "new_" prefixed metoder som indikerer ufærdig refactoring

Løsning:

  • Fjern "new_" prefix fra metoderne
  • Flyt al overlap logik til OverlapDetector
  • Simplificer EventRenderer

4. Grid Positioning Beregninger

Problem: Grid position beregninger gentages flere steder

Løsning: Centralisér i GridPositionCalculator:

// src/utils/GridPositionCalculator.ts
export class GridPositionCalculator {
  static calculateEventPosition(event: CalendarEvent): { top: number; height: number }
  static calculateSnapPosition(y: number, snapInterval: number): number
  static pixelsToMinutes(pixels: number, hourHeight: number): number
  static minutesToPixels(minutes: number, hourHeight: number): number
}

5. Event Element Creation

Problem: SwpEventElement kunne forenkles yderligere

Forslag:

  • Tilføj flere factory metoder for forskellige event typer
  • Implementer builder pattern for komplekse events

6. All-Day Event Row Calculation

Problem: AllDayManager har kompleks row calculation logik (linje 108-143)

Løsning: Udtræk til separat utility:

// src/utils/AllDayRowCalculator.ts
export class AllDayRowCalculator {
  static calculateRequiredRows(events: HTMLElement[]): number
  static expandEventsByDate(events: HTMLElement[]): Record<string, string[]>
}

7. Manglende Unit Tests

Problem: Ingen test filer fundet

Løsning: Tilføj tests for kritiske utilities:

  • TimeFormatter
  • GridPositionCalculator
  • OverlapDetector
  • AllDayRowCalculator

Prioriteret Handlingsplan

Fase 1: Utilities (Høj Prioritet)

  1. SwpEventElement factory (allerede implementeret)
  2. TimeFormatter utility
  3. DOMCacheManager
  4. GridPositionCalculator

Fase 2: Refactoring (Medium Prioritet)

  1. Fjern "new_" prefix fra EventRenderer metoder
  2. Simplificer AllDayManager med AllDayRowCalculator
  3. Konsolider overlap detection

Fase 3: Testing & Dokumentation (Lav Prioritet)

  1. Unit tests for utilities
  2. JSDoc dokumentation
  3. Performance benchmarks

Arkitektur Diagram

graph TD
    A[Utilities Layer] --> B[TimeFormatter]
    A --> C[DOMCacheManager]
    A --> D[GridPositionCalculator]
    A --> E[AllDayRowCalculator]
    
    F[Managers] --> A
    G[Renderers] --> A
    H[Elements] --> A
    
    F --> I[EventManager]
    F --> J[DragDropManager]
    F --> K[AllDayManager]
    
    G --> L[EventRenderer]
    G --> M[AllDayEventRenderer]
    
    H --> N[SwpEventElement]
    H --> O[SwpAllDayEventElement]

Performance Forbedringer

1. Event Delegation

Overvej at bruge event delegation i stedet for individuelle event listeners på hver event element.

2. Virtual Scrolling

For kalendere med mange events, implementer virtual scrolling.

3. Web Workers

Overvej at flytte tunge beregninger til Web Workers.

Konklusion

Koden er generelt i god stand med solid arkitektur. De foreslåede forbedringer vil:

  • Reducere code duplication med 30-40%
  • Forbedre maintainability
  • Gøre koden mere testbar
  • Forbedre performance marginalt

Estimeret tid for implementering: 2-3 dage for alle forbedringer.