Migrates the application to use a new CoreEvents system. This change removes the legacy EventTypes constant file and updates all managers, renderers, and core components to use the CoreEvents constant file for event emission and subscription. This improves code maintainability and promotes a consistent eventing strategy across the application. Adds validation to EventBus emit and extractCategory functions.
144 lines
No EOL
4.6 KiB
TypeScript
144 lines
No EOL
4.6 KiB
TypeScript
import { IEventBus } from '../types/CalendarTypes';
|
|
import { CoreEvents } from '../constants/CoreEvents';
|
|
import { CalendarConfig } from '../core/CalendarConfig';
|
|
import { DateCalculator } from '../utils/DateCalculator';
|
|
import { EventRenderingService } from './EventRendererManager';
|
|
|
|
/**
|
|
* NavigationRenderer - Handles DOM rendering for navigation containers
|
|
* Separated from NavigationManager to follow Single Responsibility Principle
|
|
*/
|
|
export class NavigationRenderer {
|
|
private eventBus: IEventBus;
|
|
private config: CalendarConfig;
|
|
private dateCalculator: DateCalculator;
|
|
private eventRenderer: EventRenderingService;
|
|
|
|
constructor(eventBus: IEventBus, config: CalendarConfig, eventRenderer: EventRenderingService) {
|
|
this.eventBus = eventBus;
|
|
this.config = config;
|
|
this.eventRenderer = eventRenderer;
|
|
this.dateCalculator = new DateCalculator(config);
|
|
this.setupEventListeners();
|
|
}
|
|
|
|
/**
|
|
* Setup event listeners for DOM updates
|
|
*/
|
|
private setupEventListeners(): void {
|
|
this.eventBus.on(CoreEvents.WEEK_INFO_UPDATED, (event: Event) => {
|
|
const customEvent = event as CustomEvent;
|
|
const { weekNumber, dateRange } = customEvent.detail;
|
|
this.updateWeekInfoInDOM(weekNumber, dateRange);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Update week info in DOM elements
|
|
*/
|
|
private updateWeekInfoInDOM(weekNumber: number, dateRange: string): void {
|
|
const weekNumberElement = document.querySelector('swp-week-number');
|
|
const dateRangeElement = document.querySelector('swp-date-range');
|
|
|
|
if (weekNumberElement) {
|
|
weekNumberElement.textContent = `Week ${weekNumber}`;
|
|
}
|
|
|
|
if (dateRangeElement) {
|
|
dateRangeElement.textContent = dateRange;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Render a complete container with content and events
|
|
*/
|
|
public renderContainer(parentContainer: HTMLElement, weekStart: Date): HTMLElement {
|
|
const weekEnd = this.dateCalculator.addDays(weekStart, 6);
|
|
|
|
console.group(`🎨 RENDERING CONTAINER: ${weekStart.toDateString()} - ${weekEnd.toDateString()}`);
|
|
console.log('1. Creating grid structure...');
|
|
|
|
// Create new grid container
|
|
const newGrid = document.createElement('swp-grid-container');
|
|
newGrid.innerHTML = `
|
|
<swp-calendar-header></swp-calendar-header>
|
|
<swp-scrollable-content>
|
|
<swp-time-grid>
|
|
<swp-grid-lines></swp-grid-lines>
|
|
<swp-day-columns></swp-day-columns>
|
|
</swp-time-grid>
|
|
</swp-scrollable-content>
|
|
`;
|
|
|
|
// Position new grid - NO transform here, let Animation API handle it
|
|
newGrid.style.position = 'absolute';
|
|
newGrid.style.top = '0';
|
|
newGrid.style.left = '0';
|
|
newGrid.style.width = '100%';
|
|
newGrid.style.height = '100%';
|
|
|
|
// Add to parent container
|
|
parentContainer.appendChild(newGrid);
|
|
|
|
console.log('2. Rendering headers and columns...');
|
|
this.renderWeekContentInContainer(newGrid, weekStart);
|
|
|
|
console.log('3. Pre-rendering events synchronously...');
|
|
this.eventRenderer.renderEvents({
|
|
container: newGrid,
|
|
startDate: weekStart,
|
|
endDate: weekEnd
|
|
});
|
|
|
|
console.log('✅ Container ready with pre-rendered events');
|
|
console.groupEnd();
|
|
return newGrid;
|
|
}
|
|
|
|
/**
|
|
* Render week content in specific container
|
|
*/
|
|
private renderWeekContentInContainer(gridContainer: HTMLElement, weekStart: Date): void {
|
|
const header = gridContainer.querySelector('swp-calendar-header');
|
|
const dayColumns = gridContainer.querySelector('swp-day-columns');
|
|
|
|
if (!header || !dayColumns) return;
|
|
|
|
// Clear existing content
|
|
header.innerHTML = '';
|
|
dayColumns.innerHTML = '';
|
|
|
|
// Get dates using DateCalculator
|
|
const dates = this.dateCalculator.getWorkWeekDates(weekStart);
|
|
|
|
// Render headers for target week
|
|
dates.forEach((date, i) => {
|
|
const headerElement = document.createElement('swp-day-header');
|
|
if (this.dateCalculator.isToday(date)) {
|
|
headerElement.dataset.today = 'true';
|
|
}
|
|
|
|
const dayName = this.dateCalculator.getDayName(date, 'short');
|
|
|
|
headerElement.innerHTML = `
|
|
<swp-day-name>${dayName}</swp-day-name>
|
|
<swp-day-date>${date.getDate()}</swp-day-date>
|
|
`;
|
|
headerElement.dataset.date = this.dateCalculator.formatISODate(date);
|
|
|
|
header.appendChild(headerElement);
|
|
});
|
|
|
|
// Render day columns for target week
|
|
dates.forEach(date => {
|
|
const column = document.createElement('swp-day-column');
|
|
column.dataset.date = this.dateCalculator.formatISODate(date);
|
|
|
|
const eventsLayer = document.createElement('swp-events-layer');
|
|
column.appendChild(eventsLayer);
|
|
|
|
dayColumns.appendChild(column);
|
|
});
|
|
}
|
|
|
|
} |