2025-07-24 22:17:38 +02:00
|
|
|
import { EventBus } from '../core/EventBus';
|
2025-11-03 21:30:50 +01:00
|
|
|
import { IEventBus, ICalendarEvent, IRenderContext } from '../types/CalendarTypes';
|
2025-08-20 19:52:18 +02:00
|
|
|
import { CoreEvents } from '../constants/CoreEvents';
|
2025-08-17 22:54:00 +02:00
|
|
|
import { EventManager } from '../managers/EventManager';
|
2025-11-01 16:28:45 +01:00
|
|
|
import { IEventRenderer } from './EventRenderer';
|
2025-09-19 00:20:30 +02:00
|
|
|
import { SwpEventElement } from '../elements/SwpEventElement';
|
2025-11-03 21:30:50 +01:00
|
|
|
import { IDragStartEventPayload, IDragMoveEventPayload, IDragEndEventPayload, IDragMouseEnterHeaderEventPayload, IDragMouseLeaveHeaderEventPayload, IDragMouseEnterColumnEventPayload, IDragColumnChangeEventPayload, IHeaderReadyEventPayload, IResizeEndEventPayload } from '../types/EventTypes';
|
2025-10-08 22:18:06 +02:00
|
|
|
import { DateService } from '../utils/DateService';
|
2025-11-03 21:30:50 +01:00
|
|
|
import { IColumnBounds } from '../utils/ColumnDetectionUtils';
|
2025-07-24 22:17:38 +02:00
|
|
|
/**
|
2025-08-17 23:44:30 +02:00
|
|
|
* EventRenderingService - Render events i DOM med positionering using Strategy Pattern
|
2025-07-24 22:17:38 +02:00
|
|
|
* Håndterer event positioning og overlap detection
|
|
|
|
|
*/
|
2025-08-17 23:44:30 +02:00
|
|
|
export class EventRenderingService {
|
2025-07-24 22:17:38 +02:00
|
|
|
private eventBus: IEventBus;
|
2025-08-16 00:51:12 +02:00
|
|
|
private eventManager: EventManager;
|
2025-11-01 16:28:45 +01:00
|
|
|
private strategy: IEventRenderer;
|
2025-10-08 22:18:06 +02:00
|
|
|
private dateService: DateService;
|
2025-07-24 22:17:38 +02:00
|
|
|
|
2025-09-21 15:48:13 +02:00
|
|
|
private dragMouseLeaveHeaderListener: ((event: Event) => void) | null = null;
|
|
|
|
|
|
2025-10-30 23:47:30 +01:00
|
|
|
constructor(
|
|
|
|
|
eventBus: IEventBus,
|
|
|
|
|
eventManager: EventManager,
|
2025-11-01 16:28:45 +01:00
|
|
|
strategy: IEventRenderer,
|
2025-10-30 23:47:30 +01:00
|
|
|
dateService: DateService
|
|
|
|
|
) {
|
2025-07-24 22:17:38 +02:00
|
|
|
this.eventBus = eventBus;
|
2025-08-16 00:51:12 +02:00
|
|
|
this.eventManager = eventManager;
|
2025-10-15 00:58:29 +02:00
|
|
|
this.strategy = strategy;
|
2025-10-30 23:47:30 +01:00
|
|
|
this.dateService = dateService;
|
2025-10-08 22:18:06 +02:00
|
|
|
|
2025-07-24 22:17:38 +02:00
|
|
|
this.setupEventListeners();
|
|
|
|
|
}
|
|
|
|
|
|
2025-08-09 01:16:04 +02:00
|
|
|
/**
|
2025-08-16 00:51:12 +02:00
|
|
|
* Render events in a specific container for a given period
|
2025-08-09 01:16:04 +02:00
|
|
|
*/
|
2025-11-05 00:37:57 +01:00
|
|
|
public async renderEvents(context: IRenderContext): Promise<void> {
|
2025-08-20 20:22:51 +02:00
|
|
|
// Clear existing events in the specific container first
|
|
|
|
|
this.strategy.clearEvents(context.container);
|
2025-09-21 15:48:13 +02:00
|
|
|
|
2025-08-16 00:51:12 +02:00
|
|
|
// Get events from EventManager for the period
|
2025-11-05 00:37:57 +01:00
|
|
|
const events = await this.eventManager.getEventsForPeriod(
|
2025-08-16 00:51:12 +02:00
|
|
|
context.startDate,
|
|
|
|
|
context.endDate
|
|
|
|
|
);
|
2025-09-21 15:48:13 +02:00
|
|
|
|
2025-08-16 00:51:12 +02:00
|
|
|
if (events.length === 0) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
2025-09-21 15:48:13 +02:00
|
|
|
|
2025-09-22 23:37:43 +02:00
|
|
|
// Filter events by type - only render timed events here
|
2025-09-22 21:53:18 +02:00
|
|
|
const timedEvents = events.filter(event => !event.allDay);
|
|
|
|
|
|
|
|
|
|
console.log('🎯 EventRenderingService: Event filtering', {
|
|
|
|
|
totalEvents: events.length,
|
|
|
|
|
timedEvents: timedEvents.length,
|
2025-09-22 23:37:43 +02:00
|
|
|
allDayEvents: events.length - timedEvents.length
|
2025-09-22 21:53:18 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Render timed events using existing strategy
|
|
|
|
|
if (timedEvents.length > 0) {
|
|
|
|
|
this.strategy.renderEvents(timedEvents, context.container);
|
|
|
|
|
}
|
|
|
|
|
|
2025-08-23 00:01:59 +02:00
|
|
|
// Emit EVENTS_RENDERED event for filtering system
|
|
|
|
|
this.eventBus.emit(CoreEvents.EVENTS_RENDERED, {
|
|
|
|
|
events: events,
|
|
|
|
|
container: context.container
|
|
|
|
|
});
|
2025-08-09 01:16:04 +02:00
|
|
|
}
|
2025-08-02 23:59:52 +02:00
|
|
|
|
2025-08-09 01:16:04 +02:00
|
|
|
private setupEventListeners(): void {
|
2025-09-21 15:48:13 +02:00
|
|
|
|
2025-08-20 19:52:18 +02:00
|
|
|
this.eventBus.on(CoreEvents.GRID_RENDERED, (event: Event) => {
|
2025-08-16 00:51:12 +02:00
|
|
|
this.handleGridRendered(event as CustomEvent);
|
|
|
|
|
});
|
|
|
|
|
|
2025-08-20 20:22:51 +02:00
|
|
|
this.eventBus.on(CoreEvents.VIEW_CHANGED, (event: Event) => {
|
2025-08-16 00:51:12 +02:00
|
|
|
this.handleViewChanged(event as CustomEvent);
|
2025-08-09 01:16:04 +02:00
|
|
|
});
|
2025-09-19 00:20:30 +02:00
|
|
|
|
2025-09-22 21:53:18 +02:00
|
|
|
|
2025-09-20 09:40:56 +02:00
|
|
|
// Handle all drag events and delegate to appropriate renderer
|
|
|
|
|
this.setupDragEventListeners();
|
2025-09-19 00:20:30 +02:00
|
|
|
|
2025-07-24 22:17:38 +02:00
|
|
|
}
|
|
|
|
|
|
2025-08-09 01:16:04 +02:00
|
|
|
|
2025-08-16 00:51:12 +02:00
|
|
|
/**
|
|
|
|
|
* Handle GRID_RENDERED event - render events in the current grid
|
|
|
|
|
*/
|
|
|
|
|
private handleGridRendered(event: CustomEvent): void {
|
2025-10-08 23:29:56 +02:00
|
|
|
const { container, startDate, endDate } = event.detail;
|
2025-09-21 15:48:13 +02:00
|
|
|
|
2025-10-08 23:29:56 +02:00
|
|
|
if (!container || !startDate || !endDate) {
|
2025-08-20 19:52:18 +02:00
|
|
|
return;
|
|
|
|
|
}
|
2025-09-21 15:48:13 +02:00
|
|
|
|
2025-08-16 00:51:12 +02:00
|
|
|
this.renderEvents({
|
2025-10-08 23:29:56 +02:00
|
|
|
container,
|
|
|
|
|
startDate,
|
|
|
|
|
endDate
|
2025-08-16 00:51:12 +02:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2025-07-24 22:17:38 +02:00
|
|
|
|
2025-08-16 00:51:12 +02:00
|
|
|
/**
|
|
|
|
|
* Handle VIEW_CHANGED event - clear and re-render for new view
|
|
|
|
|
*/
|
|
|
|
|
private handleViewChanged(event: CustomEvent): void {
|
|
|
|
|
// Clear all existing events since view structure may have changed
|
2025-08-09 01:16:04 +02:00
|
|
|
this.clearEvents();
|
2025-09-21 15:48:13 +02:00
|
|
|
|
2025-08-16 00:51:12 +02:00
|
|
|
// New rendering will be triggered by subsequent GRID_RENDERED event
|
|
|
|
|
}
|
2025-09-19 00:20:30 +02:00
|
|
|
|
|
|
|
|
|
2025-09-20 09:40:56 +02:00
|
|
|
/**
|
|
|
|
|
* Setup all drag event listeners - moved from EventRenderer for better separation of concerns
|
|
|
|
|
*/
|
|
|
|
|
private setupDragEventListeners(): void {
|
2025-10-08 23:29:56 +02:00
|
|
|
this.setupDragStartListener();
|
|
|
|
|
this.setupDragMoveListener();
|
|
|
|
|
this.setupDragEndListener();
|
|
|
|
|
this.setupDragColumnChangeListener();
|
|
|
|
|
this.setupDragMouseLeaveHeaderListener();
|
2025-10-10 19:37:10 +02:00
|
|
|
this.setupDragMouseEnterColumnListener();
|
2025-10-08 23:29:56 +02:00
|
|
|
this.setupResizeEndListener();
|
|
|
|
|
this.setupNavigationCompletedListener();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private setupDragStartListener(): void {
|
2025-09-20 09:40:56 +02:00
|
|
|
this.eventBus.on('drag:start', (event: Event) => {
|
2025-11-03 21:30:50 +01:00
|
|
|
const dragStartPayload = (event as CustomEvent<IDragStartEventPayload>).detail;
|
2025-10-08 23:29:56 +02:00
|
|
|
|
2025-10-12 22:00:02 +02:00
|
|
|
if (dragStartPayload.originalElement.hasAttribute('data-allday')) {
|
2025-10-08 23:29:56 +02:00
|
|
|
return;
|
2025-10-02 23:11:26 +02:00
|
|
|
}
|
|
|
|
|
|
2025-10-12 22:00:02 +02:00
|
|
|
if (dragStartPayload.originalElement && this.strategy.handleDragStart && dragStartPayload.columnBounds) {
|
2025-09-26 22:53:49 +02:00
|
|
|
this.strategy.handleDragStart(dragStartPayload);
|
2025-09-20 09:40:56 +02:00
|
|
|
}
|
|
|
|
|
});
|
2025-10-08 23:29:56 +02:00
|
|
|
}
|
2025-09-20 09:40:56 +02:00
|
|
|
|
2025-10-08 23:29:56 +02:00
|
|
|
private setupDragMoveListener(): void {
|
2025-09-20 09:40:56 +02:00
|
|
|
this.eventBus.on('drag:move', (event: Event) => {
|
2025-11-03 21:30:50 +01:00
|
|
|
let dragEvent = (event as CustomEvent<IDragMoveEventPayload>).detail;
|
2025-09-28 13:25:09 +02:00
|
|
|
|
2025-10-11 01:30:41 +02:00
|
|
|
if (dragEvent.draggedClone.hasAttribute('data-allday')) {
|
2025-10-08 23:29:56 +02:00
|
|
|
return;
|
2025-09-26 22:11:57 +02:00
|
|
|
}
|
2025-09-28 13:25:09 +02:00
|
|
|
if (this.strategy.handleDragMove) {
|
|
|
|
|
this.strategy.handleDragMove(dragEvent);
|
2025-09-20 09:40:56 +02:00
|
|
|
}
|
|
|
|
|
});
|
2025-10-08 23:29:56 +02:00
|
|
|
}
|
2025-09-20 09:40:56 +02:00
|
|
|
|
2025-10-08 23:29:56 +02:00
|
|
|
private setupDragEndListener(): void {
|
2025-11-05 00:37:57 +01:00
|
|
|
this.eventBus.on('drag:end', async (event: Event) => {
|
2025-10-12 22:00:02 +02:00
|
|
|
|
2025-11-03 21:30:50 +01:00
|
|
|
const { originalElement: draggedElement, sourceColumn, finalPosition, target } = (event as CustomEvent<IDragEndEventPayload>).detail;
|
2025-09-21 15:48:13 +02:00
|
|
|
const finalColumn = finalPosition.column;
|
|
|
|
|
const finalY = finalPosition.snappedY;
|
|
|
|
|
const eventId = draggedElement.dataset.eventId || '';
|
|
|
|
|
|
2025-09-20 09:40:56 +02:00
|
|
|
// Only handle day column drops for EventRenderer
|
2025-09-21 15:48:13 +02:00
|
|
|
if (target === 'swp-day-column' && finalColumn) {
|
|
|
|
|
// Find dragged clone - use draggedElement as original
|
2025-09-20 09:40:56 +02:00
|
|
|
const draggedClone = document.querySelector(`swp-day-column swp-event[data-event-id="clone-${eventId}"]`) as HTMLElement;
|
2025-09-21 15:48:13 +02:00
|
|
|
|
|
|
|
|
if (draggedElement && draggedClone && this.strategy.handleDragEnd) {
|
|
|
|
|
this.strategy.handleDragEnd(eventId, draggedElement, draggedClone, finalColumn, finalY);
|
2025-09-20 09:40:56 +02:00
|
|
|
}
|
2025-10-08 22:18:06 +02:00
|
|
|
|
|
|
|
|
// Update event data in EventManager with new position from clone
|
|
|
|
|
if (draggedClone) {
|
|
|
|
|
const swpEvent = draggedClone as SwpEventElement;
|
|
|
|
|
const newStart = swpEvent.start;
|
|
|
|
|
const newEnd = swpEvent.end;
|
|
|
|
|
|
2025-11-05 00:37:57 +01:00
|
|
|
await this.eventManager.updateEvent(eventId, {
|
2025-10-08 22:18:06 +02:00
|
|
|
start: newStart,
|
2025-11-05 22:19:48 +01:00
|
|
|
end: newEnd,
|
|
|
|
|
allDay: false
|
2025-10-08 22:18:06 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
console.log('📝 EventRendererManager: Updated event in EventManager', {
|
|
|
|
|
eventId,
|
|
|
|
|
newStart,
|
2025-11-05 22:19:48 +01:00
|
|
|
newEnd,
|
|
|
|
|
allDay: false
|
2025-10-08 22:18:06 +02:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Re-render affected columns for stacking/grouping (now with updated data)
|
|
|
|
|
this.reRenderAffectedColumns(sourceColumn, finalColumn);
|
2025-09-20 09:40:56 +02:00
|
|
|
}
|
2025-09-21 15:48:13 +02:00
|
|
|
|
2025-09-20 09:40:56 +02:00
|
|
|
// Clean up any remaining day event clones
|
2025-09-21 21:30:51 +02:00
|
|
|
const dayEventClone = document.querySelector(`swp-day-column swp-event[data-event-id="clone-${eventId}"]`);
|
2025-09-20 09:40:56 +02:00
|
|
|
if (dayEventClone) {
|
|
|
|
|
dayEventClone.remove();
|
|
|
|
|
}
|
|
|
|
|
});
|
2025-10-08 23:29:56 +02:00
|
|
|
}
|
2025-09-20 09:40:56 +02:00
|
|
|
|
2025-10-08 23:29:56 +02:00
|
|
|
private setupDragColumnChangeListener(): void {
|
2025-09-20 09:40:56 +02:00
|
|
|
this.eventBus.on('drag:column-change', (event: Event) => {
|
2025-11-03 21:30:50 +01:00
|
|
|
let columnChangeEvent = (event as CustomEvent<IDragColumnChangeEventPayload>).detail;
|
2025-09-28 13:25:09 +02:00
|
|
|
|
2025-09-26 22:53:49 +02:00
|
|
|
// Filter: Only handle events where clone is NOT an all-day event (normal timed events)
|
2025-09-28 13:25:09 +02:00
|
|
|
if (columnChangeEvent.draggedClone && columnChangeEvent.draggedClone.hasAttribute('data-allday')) {
|
2025-10-01 21:27:13 +02:00
|
|
|
return;
|
2025-09-26 22:53:49 +02:00
|
|
|
}
|
2025-09-28 13:25:09 +02:00
|
|
|
|
2025-09-20 09:40:56 +02:00
|
|
|
if (this.strategy.handleColumnChange) {
|
2025-10-01 21:27:13 +02:00
|
|
|
this.strategy.handleColumnChange(columnChangeEvent);
|
2025-09-20 09:40:56 +02:00
|
|
|
}
|
|
|
|
|
});
|
2025-10-08 23:29:56 +02:00
|
|
|
}
|
2025-09-20 09:40:56 +02:00
|
|
|
|
2025-10-08 23:29:56 +02:00
|
|
|
private setupDragMouseLeaveHeaderListener(): void {
|
2025-10-14 19:21:28 +02:00
|
|
|
|
2025-09-21 15:48:13 +02:00
|
|
|
this.dragMouseLeaveHeaderListener = (event: Event) => {
|
2025-11-03 21:30:50 +01:00
|
|
|
const { targetDate, mousePosition, originalElement, draggedClone: cloneElement } = (event as CustomEvent<IDragMouseLeaveHeaderEventPayload>).detail;
|
2025-09-21 15:48:13 +02:00
|
|
|
|
|
|
|
|
if (cloneElement)
|
|
|
|
|
cloneElement.style.display = '';
|
|
|
|
|
|
|
|
|
|
console.log('🚪 EventRendererManager: Received drag:mouseleave-header', {
|
|
|
|
|
targetDate,
|
|
|
|
|
originalElement: originalElement,
|
|
|
|
|
cloneElement: cloneElement
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
this.eventBus.on('drag:mouseleave-header', this.dragMouseLeaveHeaderListener);
|
2025-10-08 23:29:56 +02:00
|
|
|
}
|
2025-09-21 15:48:13 +02:00
|
|
|
|
2025-10-10 19:37:10 +02:00
|
|
|
private setupDragMouseEnterColumnListener(): void {
|
|
|
|
|
this.eventBus.on('drag:mouseenter-column', (event: Event) => {
|
2025-11-03 21:30:50 +01:00
|
|
|
const payload = (event as CustomEvent<IDragMouseEnterColumnEventPayload>).detail;
|
2025-10-10 19:37:10 +02:00
|
|
|
|
|
|
|
|
// Only handle if clone is an all-day event
|
|
|
|
|
if (!payload.draggedClone.hasAttribute('data-allday')) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
console.log('🎯 EventRendererManager: Received drag:mouseenter-column', {
|
|
|
|
|
targetColumn: payload.targetColumn,
|
|
|
|
|
snappedY: payload.snappedY,
|
|
|
|
|
calendarEvent: payload.calendarEvent
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Delegate to strategy for conversion
|
|
|
|
|
if (this.strategy.handleConvertAllDayToTimed) {
|
|
|
|
|
this.strategy.handleConvertAllDayToTimed(payload);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2025-10-08 23:29:56 +02:00
|
|
|
private setupResizeEndListener(): void {
|
2025-11-05 00:37:57 +01:00
|
|
|
this.eventBus.on('resize:end', async (event: Event) => {
|
2025-11-03 21:30:50 +01:00
|
|
|
const { eventId, element } = (event as CustomEvent<IResizeEndEventPayload>).detail;
|
2025-10-08 22:18:06 +02:00
|
|
|
|
|
|
|
|
// Update event data in EventManager with new end time from resized element
|
|
|
|
|
const swpEvent = element as SwpEventElement;
|
|
|
|
|
const newStart = swpEvent.start;
|
|
|
|
|
const newEnd = swpEvent.end;
|
|
|
|
|
|
2025-11-05 00:37:57 +01:00
|
|
|
await this.eventManager.updateEvent(eventId, {
|
2025-10-08 22:18:06 +02:00
|
|
|
start: newStart,
|
|
|
|
|
end: newEnd
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
console.log('📝 EventRendererManager: Updated event after resize', {
|
|
|
|
|
eventId,
|
|
|
|
|
newStart,
|
|
|
|
|
newEnd
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Find the column for this event
|
|
|
|
|
const columnElement = element.closest('swp-day-column') as HTMLElement;
|
|
|
|
|
if (columnElement) {
|
|
|
|
|
const columnDate = columnElement.dataset.date;
|
|
|
|
|
if (columnDate) {
|
|
|
|
|
// Re-render the column to recalculate stacking/grouping
|
|
|
|
|
this.renderSingleColumn(columnDate);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
});
|
2025-10-08 23:29:56 +02:00
|
|
|
}
|
2025-10-08 22:18:06 +02:00
|
|
|
|
2025-10-08 23:29:56 +02:00
|
|
|
private setupNavigationCompletedListener(): void {
|
2025-09-20 09:40:56 +02:00
|
|
|
this.eventBus.on(CoreEvents.NAVIGATION_COMPLETED, () => {
|
|
|
|
|
// Delegate to strategy if it handles navigation
|
|
|
|
|
if (this.strategy.handleNavigationCompleted) {
|
|
|
|
|
this.strategy.handleNavigationCompleted();
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
2025-10-10 16:41:48 +02:00
|
|
|
|
2025-09-19 00:20:30 +02:00
|
|
|
|
2025-10-08 22:18:06 +02:00
|
|
|
/**
|
|
|
|
|
* Re-render affected columns after drag to recalculate stacking/grouping
|
|
|
|
|
*/
|
2025-11-03 21:30:50 +01:00
|
|
|
private reRenderAffectedColumns(sourceColumn: IColumnBounds | null, targetColumn: IColumnBounds | null): void {
|
2025-10-08 22:18:06 +02:00
|
|
|
const columnsToRender = new Set<string>();
|
|
|
|
|
|
|
|
|
|
// Add source column if exists
|
|
|
|
|
if (sourceColumn) {
|
|
|
|
|
columnsToRender.add(sourceColumn.date);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Add target column if exists and different from source
|
|
|
|
|
if (targetColumn && targetColumn.date !== sourceColumn?.date) {
|
|
|
|
|
columnsToRender.add(targetColumn.date);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Re-render each affected column
|
|
|
|
|
columnsToRender.forEach(columnDate => {
|
|
|
|
|
this.renderSingleColumn(columnDate);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Render events for a single column by re-rendering entire container
|
|
|
|
|
*/
|
|
|
|
|
private renderSingleColumn(columnDate: string): void {
|
|
|
|
|
// Find the column element
|
|
|
|
|
const columnElement = document.querySelector(`swp-day-column[data-date="${columnDate}"]`) as HTMLElement;
|
|
|
|
|
if (!columnElement) {
|
|
|
|
|
console.warn('EventRendererManager: Column not found', { columnDate });
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Find the parent container (swp-day-columns)
|
|
|
|
|
const container = columnElement.closest('swp-day-columns') as HTMLElement;
|
|
|
|
|
if (!container) {
|
|
|
|
|
console.warn('EventRendererManager: Container not found');
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Get all columns in container to determine date range
|
|
|
|
|
const allColumns = Array.from(container.querySelectorAll<HTMLElement>('swp-day-column'));
|
|
|
|
|
if (allColumns.length === 0) return;
|
|
|
|
|
|
|
|
|
|
// Get date range from first and last column
|
|
|
|
|
const firstColumnDate = allColumns[0].dataset.date;
|
|
|
|
|
const lastColumnDate = allColumns[allColumns.length - 1].dataset.date;
|
|
|
|
|
|
|
|
|
|
if (!firstColumnDate || !lastColumnDate) return;
|
|
|
|
|
|
|
|
|
|
const startDate = this.dateService.parseISO(`${firstColumnDate}T00:00:00`);
|
|
|
|
|
const endDate = this.dateService.parseISO(`${lastColumnDate}T23:59:59.999`);
|
|
|
|
|
|
|
|
|
|
// Re-render entire container (this will recalculate stacking for all columns)
|
|
|
|
|
this.renderEvents({
|
|
|
|
|
container,
|
|
|
|
|
startDate,
|
|
|
|
|
endDate
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
console.log('🔄 EventRendererManager: Re-rendered container for column', {
|
|
|
|
|
columnDate,
|
|
|
|
|
startDate: firstColumnDate,
|
|
|
|
|
endDate: lastColumnDate
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-22 23:37:43 +02:00
|
|
|
private clearEvents(container?: HTMLElement): void {
|
|
|
|
|
this.strategy.clearEvents(container);
|
2025-08-16 00:51:12 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public refresh(container?: HTMLElement): void {
|
|
|
|
|
this.clearEvents(container);
|
2025-07-24 22:17:38 +02:00
|
|
|
}
|
|
|
|
|
}
|