Refactors all-day event rendering and DOM access
Decouples all-day event rendering, making it reactive to header readiness with period data. Eliminates explicit DOM element caching, simplifying element access. Enhances the `header:ready` event payload with `startDate` and `endDate`. Improves all-day row height animation and calculation.
This commit is contained in:
parent
f5e9909935
commit
6498b0ba8e
6 changed files with 98 additions and 116 deletions
|
|
@ -7,7 +7,7 @@ import { EventManager } from '../managers/EventManager';
|
|||
import { EventRendererStrategy } from './EventRenderer';
|
||||
import { SwpEventElement } from '../elements/SwpEventElement';
|
||||
import { AllDayEventRenderer } from './AllDayEventRenderer';
|
||||
import { DragStartEventPayload, DragMoveEventPayload, DragEndEventPayload, DragMouseEnterHeaderEventPayload, DragMouseLeaveHeaderEventPayload } from '../types/EventTypes';
|
||||
import { DragStartEventPayload, DragMoveEventPayload, DragEndEventPayload, DragMouseEnterHeaderEventPayload, DragMouseLeaveHeaderEventPayload, HeaderReadyEventPayload } from '../types/EventTypes';
|
||||
/**
|
||||
* EventRenderingService - Render events i DOM med positionering using Strategy Pattern
|
||||
* Håndterer event positioning og overlap detection
|
||||
|
|
@ -18,9 +18,6 @@ export class EventRenderingService {
|
|||
private strategy: EventRendererStrategy;
|
||||
private allDayEventRenderer: AllDayEventRenderer;
|
||||
|
||||
// Store all-day events until header is ready with dates
|
||||
private pendingAllDayEvents: CalendarEvent[] = [];
|
||||
private isHeaderReady: boolean = false;
|
||||
|
||||
private dragMouseLeaveHeaderListener: ((event: Event) => void) | null = null;
|
||||
|
||||
|
|
@ -42,7 +39,6 @@ export class EventRenderingService {
|
|||
* Render events in a specific container for a given period
|
||||
*/
|
||||
public renderEvents(context: RenderContext): void {
|
||||
|
||||
// Clear existing events in the specific container first
|
||||
this.strategy.clearEvents(context.container);
|
||||
|
||||
|
|
@ -56,15 +52,13 @@ export class EventRenderingService {
|
|||
return;
|
||||
}
|
||||
|
||||
// Filter events by type
|
||||
// Filter events by type - only render timed events here
|
||||
const timedEvents = events.filter(event => !event.allDay);
|
||||
const allDayEvents = events.filter(event => event.allDay);
|
||||
|
||||
console.log('🎯 EventRenderingService: Event filtering', {
|
||||
totalEvents: events.length,
|
||||
timedEvents: timedEvents.length,
|
||||
allDayEvents: allDayEvents.length,
|
||||
allDayEventIds: allDayEvents.map(e => e.id)
|
||||
allDayEvents: events.length - timedEvents.length
|
||||
});
|
||||
|
||||
// Render timed events using existing strategy
|
||||
|
|
@ -72,21 +66,6 @@ export class EventRenderingService {
|
|||
this.strategy.renderEvents(timedEvents, context.container);
|
||||
}
|
||||
|
||||
// Render all-day events - wait for header if not ready
|
||||
if (allDayEvents.length > 0) {
|
||||
if (this.isHeaderReady) {
|
||||
this.renderAllDayEvents(allDayEvents);
|
||||
// Check and adjust all-day container height after rendering
|
||||
this.eventBus.emit('allday:checkHeight');
|
||||
} else {
|
||||
console.log('🕐 EventRendererManager: Header not ready, storing all-day events for later');
|
||||
// Only store if we don't already have pending events to avoid duplicates
|
||||
if (this.pendingAllDayEvents.length === 0) {
|
||||
this.pendingAllDayEvents = [...allDayEvents];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Emit EVENTS_RENDERED event for filtering system
|
||||
this.eventBus.emit(CoreEvents.EVENTS_RENDERED, {
|
||||
events: events,
|
||||
|
|
@ -104,18 +83,16 @@ export class EventRenderingService {
|
|||
this.handleViewChanged(event as CustomEvent);
|
||||
});
|
||||
|
||||
// Listen for header ready - when dates are populated
|
||||
this.eventBus.on('header:ready', () => {
|
||||
console.log('🎯 EventRendererManager: Header ready, rendering pending all-day events');
|
||||
this.isHeaderReady = true;
|
||||
// Listen for header ready - when dates are populated with period data
|
||||
this.eventBus.on('header:ready', (event: Event) => {
|
||||
const { startDate, endDate } = (event as CustomEvent<HeaderReadyEventPayload>).detail;
|
||||
console.log('🎯 EventRendererManager: Header ready with period data', {
|
||||
startDate: startDate.toISOString(),
|
||||
endDate: endDate.toISOString()
|
||||
});
|
||||
|
||||
if (this.pendingAllDayEvents.length > 0) {
|
||||
this.renderAllDayEvents(this.pendingAllDayEvents);
|
||||
this.pendingAllDayEvents = []; // Clear after rendering
|
||||
|
||||
// Check and adjust all-day container height after rendering
|
||||
this.eventBus.emit('allday:checkHeight');
|
||||
}
|
||||
// Render all-day events using period from header
|
||||
this.renderAllDayEventsForPeriod(startDate, endDate);
|
||||
});
|
||||
|
||||
// Handle all drag events and delegate to appropriate renderer
|
||||
|
|
@ -139,12 +116,13 @@ export class EventRenderingService {
|
|||
* Handle GRID_RENDERED event - render events in the current grid
|
||||
*/
|
||||
private handleGridRendered(event: CustomEvent): void {
|
||||
const { container, startDate, endDate, currentDate } = event.detail;
|
||||
const { container, startDate, endDate, currentDate, isNavigation } = event.detail;
|
||||
|
||||
if (!container) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
let periodStart: Date;
|
||||
let periodEnd: Date;
|
||||
|
||||
|
|
@ -350,15 +328,28 @@ export class EventRenderingService {
|
|||
}
|
||||
|
||||
/**
|
||||
* Render all-day events using AllDayEventRenderer
|
||||
* Render all-day events for specific period using AllDayEventRenderer
|
||||
*/
|
||||
private renderAllDayEvents(allDayEvents: CalendarEvent[]): void {
|
||||
private renderAllDayEventsForPeriod(startDate: Date, endDate: Date): void {
|
||||
// Get events from EventManager for the period
|
||||
const events = this.eventManager.getEventsForPeriod(startDate, endDate);
|
||||
|
||||
// Filter for all-day events
|
||||
const allDayEvents = events.filter(event => event.allDay);
|
||||
|
||||
console.log('🏗️ EventRenderingService: Rendering all-day events', {
|
||||
period: {
|
||||
start: startDate.toISOString(),
|
||||
end: endDate.toISOString()
|
||||
},
|
||||
count: allDayEvents.length,
|
||||
events: allDayEvents.map(e => ({ id: e.id, title: e.title }))
|
||||
});
|
||||
|
||||
// Header always exists now, so we can render directly
|
||||
// Clear existing all-day events first
|
||||
this.clearAllDayEvents();
|
||||
|
||||
// Render each all-day event
|
||||
allDayEvents.forEach(event => {
|
||||
const renderedElement = this.allDayEventRenderer.renderAllDayEvent(event);
|
||||
if (renderedElement) {
|
||||
|
|
@ -374,20 +365,26 @@ export class EventRenderingService {
|
|||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Check and adjust all-day container height after rendering
|
||||
this.eventBus.emit('allday:checkHeight');
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear only all-day events
|
||||
*/
|
||||
private clearAllDayEvents(): void {
|
||||
const allDayContainer = document.querySelector('swp-allday-container');
|
||||
if (allDayContainer) {
|
||||
allDayContainer.querySelectorAll('swp-event').forEach(event => event.remove());
|
||||
}
|
||||
}
|
||||
|
||||
private clearEvents(container?: HTMLElement): void {
|
||||
this.strategy.clearEvents(container);
|
||||
|
||||
// Also clear all-day events
|
||||
const allDayContainer = document.querySelector('swp-allday-container');
|
||||
if (allDayContainer) {
|
||||
allDayContainer.querySelectorAll('swp-event').forEach(event => event.remove());
|
||||
}
|
||||
|
||||
// Clear pending all-day events
|
||||
this.pendingAllDayEvents = [];
|
||||
this.isHeaderReady = false;
|
||||
this.clearAllDayEvents();
|
||||
}
|
||||
|
||||
public refresh(container?: HTMLElement): void {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue