2025-09-10 22:07:40 +02:00
|
|
|
import { eventBus } from '../core/EventBus';
|
|
|
|
|
import { calendarConfig } from '../core/CalendarConfig';
|
|
|
|
|
import { CalendarTypeFactory } from '../factories/CalendarTypeFactory';
|
2025-09-17 23:39:29 +02:00
|
|
|
import { CoreEvents } from '../constants/CoreEvents';
|
|
|
|
|
import { HeaderRenderContext } from '../renderers/HeaderRenderer';
|
|
|
|
|
import { ResourceCalendarData } from '../types/CalendarTypes';
|
2025-09-22 23:37:43 +02:00
|
|
|
import { DragMouseEnterHeaderEventPayload, DragMouseLeaveHeaderEventPayload, HeaderReadyEventPayload } from '../types/EventTypes';
|
2025-10-01 21:27:13 +02:00
|
|
|
import { ColumnDetectionUtils } from '../utils/ColumnDetectionUtils';
|
2025-09-10 22:07:40 +02:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* HeaderManager - Handles all header-related event logic
|
|
|
|
|
* Separates event handling from rendering concerns
|
|
|
|
|
*/
|
|
|
|
|
export class HeaderManager {
|
2025-10-10 16:41:48 +02:00
|
|
|
|
2025-09-10 22:07:40 +02:00
|
|
|
constructor() {
|
2025-10-14 17:47:12 +02:00
|
|
|
// Bind handler methods for event listeners
|
|
|
|
|
this.handleDragMouseEnterHeader = this.handleDragMouseEnterHeader.bind(this);
|
|
|
|
|
this.handleDragMouseLeaveHeader = this.handleDragMouseLeaveHeader.bind(this);
|
2025-10-10 16:41:48 +02:00
|
|
|
|
2025-09-17 23:39:29 +02:00
|
|
|
// Listen for navigation events to update header
|
|
|
|
|
this.setupNavigationListener();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Initialize header with initial date
|
|
|
|
|
*/
|
|
|
|
|
public initializeHeader(currentDate: Date, resourceData: ResourceCalendarData | null = null): void {
|
|
|
|
|
this.updateHeader(currentDate, resourceData);
|
2025-09-10 22:07:40 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Get cached calendar header element
|
|
|
|
|
*/
|
|
|
|
|
private getCalendarHeader(): HTMLElement | null {
|
2025-10-10 16:41:48 +02:00
|
|
|
return document.querySelector('swp-calendar-header');
|
2025-09-10 22:07:40 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2025-10-14 17:47:12 +02:00
|
|
|
* Setup header drag event listeners - Listen to DragDropManager events
|
2025-09-10 22:07:40 +02:00
|
|
|
*/
|
|
|
|
|
public setupHeaderDragListeners(): void {
|
2025-09-21 15:48:13 +02:00
|
|
|
console.log('🎯 HeaderManager: Setting up drag event listeners');
|
2025-09-10 22:07:40 +02:00
|
|
|
|
2025-10-14 17:47:12 +02:00
|
|
|
// Subscribe to drag events from DragDropManager
|
|
|
|
|
eventBus.on('drag:mouseenter-header', this.handleDragMouseEnterHeader);
|
|
|
|
|
eventBus.on('drag:mouseleave-header', this.handleDragMouseLeaveHeader);
|
2025-10-10 16:41:48 +02:00
|
|
|
|
2025-10-14 17:47:12 +02:00
|
|
|
console.log('✅ HeaderManager: Drag event listeners attached');
|
|
|
|
|
}
|
2025-09-10 22:07:40 +02:00
|
|
|
|
2025-10-14 17:47:12 +02:00
|
|
|
/**
|
|
|
|
|
* Handle drag mouse enter header event
|
|
|
|
|
*/
|
|
|
|
|
private handleDragMouseEnterHeader(event: Event): void {
|
|
|
|
|
const { targetColumn: targetDate, mousePosition, originalElement, draggedClone: cloneElement } =
|
|
|
|
|
(event as CustomEvent<DragMouseEnterHeaderEventPayload>).detail;
|
|
|
|
|
|
|
|
|
|
console.log('🎯 HeaderManager: Received drag:mouseenter-header', {
|
|
|
|
|
targetDate,
|
|
|
|
|
originalElement: !!originalElement,
|
|
|
|
|
cloneElement: !!cloneElement
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (targetDate) {
|
|
|
|
|
const calendarType = calendarConfig.getCalendarMode();
|
|
|
|
|
const headerRenderer = CalendarTypeFactory.getHeaderRenderer(calendarType);
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-10-10 16:41:48 +02:00
|
|
|
|
2025-10-14 17:47:12 +02:00
|
|
|
/**
|
|
|
|
|
* Handle drag mouse leave header event
|
|
|
|
|
*/
|
|
|
|
|
private handleDragMouseLeaveHeader(event: Event): void {
|
|
|
|
|
const { targetDate, mousePosition, originalElement, draggedClone: cloneElement } =
|
|
|
|
|
(event as CustomEvent<DragMouseLeaveHeaderEventPayload>).detail;
|
|
|
|
|
|
|
|
|
|
console.log('🚪 HeaderManager: Received drag:mouseleave-header', {
|
|
|
|
|
targetDate,
|
|
|
|
|
originalElement: !!originalElement,
|
|
|
|
|
cloneElement: !!cloneElement
|
|
|
|
|
});
|
2025-09-18 17:55:52 +02:00
|
|
|
}
|
|
|
|
|
|
2025-09-17 23:39:29 +02:00
|
|
|
/**
|
|
|
|
|
* Setup navigation event listener
|
|
|
|
|
*/
|
|
|
|
|
private setupNavigationListener(): void {
|
|
|
|
|
eventBus.on(CoreEvents.NAVIGATION_COMPLETED, (event) => {
|
|
|
|
|
const { currentDate, resourceData } = (event as CustomEvent).detail;
|
|
|
|
|
this.updateHeader(currentDate, resourceData);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Also listen for date changes (including initial setup)
|
|
|
|
|
eventBus.on(CoreEvents.DATE_CHANGED, (event) => {
|
|
|
|
|
const { currentDate } = (event as CustomEvent).detail;
|
|
|
|
|
this.updateHeader(currentDate, null);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Listen for workweek header updates after grid rebuild
|
|
|
|
|
eventBus.on('workweek:header-update', (event) => {
|
|
|
|
|
const { currentDate } = (event as CustomEvent).detail;
|
|
|
|
|
this.updateHeader(currentDate, null);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Update header content for navigation
|
|
|
|
|
*/
|
|
|
|
|
private updateHeader(currentDate: Date, resourceData: ResourceCalendarData | null = null): void {
|
|
|
|
|
const calendarHeader = this.getOrCreateCalendarHeader();
|
|
|
|
|
if (!calendarHeader) return;
|
|
|
|
|
|
2025-10-10 16:41:48 +02:00
|
|
|
// Clear existing content
|
2025-09-17 23:39:29 +02:00
|
|
|
calendarHeader.innerHTML = '';
|
|
|
|
|
|
|
|
|
|
// Render new header content
|
|
|
|
|
const calendarType = calendarConfig.getCalendarMode();
|
|
|
|
|
const headerRenderer = CalendarTypeFactory.getHeaderRenderer(calendarType);
|
2025-10-10 16:41:48 +02:00
|
|
|
|
2025-09-17 23:39:29 +02:00
|
|
|
const context: HeaderRenderContext = {
|
|
|
|
|
currentWeek: currentDate,
|
|
|
|
|
config: calendarConfig,
|
|
|
|
|
resourceData: resourceData
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
headerRenderer.render(calendarHeader, context);
|
|
|
|
|
|
2025-09-18 14:52:38 +02:00
|
|
|
// Setup event listeners on the new content
|
2025-09-17 23:39:29 +02:00
|
|
|
this.setupHeaderDragListeners();
|
|
|
|
|
|
2025-09-22 23:37:43 +02:00
|
|
|
// Notify other managers that header is ready with period data
|
|
|
|
|
const payload: HeaderReadyEventPayload = {
|
2025-10-01 21:27:13 +02:00
|
|
|
headerElements: ColumnDetectionUtils.getHeaderColumns(),
|
2025-09-22 23:37:43 +02:00
|
|
|
};
|
|
|
|
|
eventBus.emit('header:ready', payload);
|
2025-09-17 23:39:29 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2025-09-22 21:53:18 +02:00
|
|
|
* Get calendar header element - header always exists now
|
2025-09-17 23:39:29 +02:00
|
|
|
*/
|
|
|
|
|
private getOrCreateCalendarHeader(): HTMLElement | null {
|
2025-09-22 21:53:18 +02:00
|
|
|
const calendarHeader = this.getCalendarHeader();
|
2025-10-10 16:41:48 +02:00
|
|
|
|
2025-09-17 23:39:29 +02:00
|
|
|
if (!calendarHeader) {
|
2025-09-22 21:53:18 +02:00
|
|
|
console.warn('HeaderManager: Calendar header not found - should always exist now!');
|
|
|
|
|
return null;
|
2025-09-17 23:39:29 +02:00
|
|
|
}
|
2025-10-10 16:41:48 +02:00
|
|
|
|
2025-09-17 23:39:29 +02:00
|
|
|
return calendarHeader;
|
|
|
|
|
}
|
2025-09-10 22:07:40 +02:00
|
|
|
}
|