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.
This commit is contained in:
parent
e0b83ebd70
commit
c07d83d86f
13 changed files with 599 additions and 1306 deletions
183
docs/code-improvement-plan.md
Normal file
183
docs/code-improvement-plan.md
Normal file
|
|
@ -0,0 +1,183 @@
|
|||
# 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:
|
||||
```typescript
|
||||
// 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:
|
||||
```typescript
|
||||
// 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:
|
||||
```typescript
|
||||
// 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:
|
||||
```typescript
|
||||
// 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)
|
||||
5. ⬜ Fjern "new_" prefix fra EventRenderer metoder
|
||||
6. ⬜ Simplificer AllDayManager med AllDayRowCalculator
|
||||
7. ⬜ Konsolider overlap detection
|
||||
|
||||
### Fase 3: Testing & Dokumentation (Lav Prioritet)
|
||||
8. ⬜ Unit tests for utilities
|
||||
9. ⬜ JSDoc dokumentation
|
||||
10. ⬜ Performance benchmarks
|
||||
|
||||
## Arkitektur Diagram
|
||||
|
||||
```mermaid
|
||||
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.
|
||||
Loading…
Add table
Add a link
Reference in a new issue