import { eventBus } from '../core/EventBus'; import { calendarConfig } from '../core/CalendarConfig'; import { CalendarTypeFactory } from '../factories/CalendarTypeFactory'; import { CoreEvents } from '../constants/CoreEvents'; import { HeaderRenderContext } from '../renderers/HeaderRenderer'; import { ResourceCalendarData } from '../types/CalendarTypes'; import { DragMouseEnterHeaderEventPayload, DragMouseLeaveHeaderEventPayload, HeaderReadyEventPayload } from '../types/EventTypes'; import { ColumnDetectionUtils } from '../utils/ColumnDetectionUtils'; /** * HeaderManager - Handles all header-related event logic * Separates event handling from rendering concerns */ export class HeaderManager { constructor() { // Bind handler methods for event listeners this.handleDragMouseEnterHeader = this.handleDragMouseEnterHeader.bind(this); this.handleDragMouseLeaveHeader = this.handleDragMouseLeaveHeader.bind(this); // 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); } /** * Get cached calendar header element */ private getCalendarHeader(): HTMLElement | null { return document.querySelector('swp-calendar-header'); } /** * Setup header drag event listeners - Listen to DragDropManager events */ public setupHeaderDragListeners(): void { console.log('🎯 HeaderManager: Setting up drag event listeners'); // Subscribe to drag events from DragDropManager eventBus.on('drag:mouseenter-header', this.handleDragMouseEnterHeader); eventBus.on('drag:mouseleave-header', this.handleDragMouseLeaveHeader); console.log('✅ HeaderManager: Drag event listeners attached'); } /** * Handle drag mouse enter header event */ private handleDragMouseEnterHeader(event: Event): void { const { targetColumn: targetDate, mousePosition, originalElement, draggedClone: cloneElement } = (event as CustomEvent).detail; console.log('🎯 HeaderManager: Received drag:mouseenter-header', { targetDate, originalElement: !!originalElement, cloneElement: !!cloneElement }); if (targetDate) { const calendarType = calendarConfig.getCalendarMode(); const headerRenderer = CalendarTypeFactory.getHeaderRenderer(calendarType); } } /** * Handle drag mouse leave header event */ private handleDragMouseLeaveHeader(event: Event): void { const { targetDate, mousePosition, originalElement, draggedClone: cloneElement } = (event as CustomEvent).detail; console.log('🚪 HeaderManager: Received drag:mouseleave-header', { targetDate, originalElement: !!originalElement, cloneElement: !!cloneElement }); } /** * 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; // Clear existing content calendarHeader.innerHTML = ''; // Render new header content const calendarType = calendarConfig.getCalendarMode(); const headerRenderer = CalendarTypeFactory.getHeaderRenderer(calendarType); const context: HeaderRenderContext = { currentWeek: currentDate, config: calendarConfig, resourceData: resourceData }; headerRenderer.render(calendarHeader, context); // Setup event listeners on the new content this.setupHeaderDragListeners(); // Notify other managers that header is ready with period data const payload: HeaderReadyEventPayload = { headerElements: ColumnDetectionUtils.getHeaderColumns(), }; eventBus.emit('header:ready', payload); } /** * Get calendar header element - header always exists now */ private getOrCreateCalendarHeader(): HTMLElement | null { const calendarHeader = this.getCalendarHeader(); if (!calendarHeader) { console.warn('HeaderManager: Calendar header not found - should always exist now!'); return null; } return calendarHeader; } }