Cleans up the codebase by removing unnecessary console log statements. These logs were primarily used for debugging and are no longer needed in the production code. This reduces noise in the console and improves overall performance.
238 lines
No EOL
8.2 KiB
TypeScript
238 lines
No EOL
8.2 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';
|
|
import { CalendarTypeFactory } from '../factories/CalendarTypeFactory';
|
|
import { eventBus } from '../core/EventBus';
|
|
|
|
/**
|
|
* 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_CHANGED, (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;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Apply filter state to pre-rendered grids
|
|
*/
|
|
public applyFilterToPreRenderedGrids(filterState: { active: boolean; matchingIds: string[] }): void {
|
|
// Find all grid containers (including pre-rendered ones)
|
|
const allGridContainers = document.querySelectorAll('swp-grid-container');
|
|
|
|
allGridContainers.forEach(container => {
|
|
const eventsLayers = container.querySelectorAll('swp-events-layer');
|
|
|
|
eventsLayers.forEach(layer => {
|
|
if (filterState.active) {
|
|
// Apply filter active state
|
|
layer.setAttribute('data-filter-active', 'true');
|
|
|
|
// Mark matching events in this layer
|
|
const events = layer.querySelectorAll('swp-event');
|
|
events.forEach(event => {
|
|
const eventId = event.getAttribute('data-event-id');
|
|
if (eventId && filterState.matchingIds.includes(eventId)) {
|
|
event.setAttribute('data-matches', 'true');
|
|
} else {
|
|
event.removeAttribute('data-matches');
|
|
}
|
|
});
|
|
} else {
|
|
// Remove filter state
|
|
layer.removeAttribute('data-filter-active');
|
|
|
|
// Remove all match attributes
|
|
const events = layer.querySelectorAll('swp-event');
|
|
events.forEach(event => {
|
|
event.removeAttribute('data-matches');
|
|
});
|
|
}
|
|
});
|
|
});
|
|
|
|
}
|
|
|
|
/**
|
|
* Render a complete container with content and events
|
|
*/
|
|
public renderContainer(parentContainer: HTMLElement, weekStart: Date): HTMLElement {
|
|
const weekEnd = this.dateCalculator.addDays(weekStart, 6);
|
|
|
|
|
|
// 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);
|
|
|
|
this.renderWeekContentInContainer(newGrid, weekStart);
|
|
|
|
this.eventBus.emit(CoreEvents.GRID_RENDERED, {
|
|
container: newGrid, // Specific grid container, not parent
|
|
currentDate: weekStart,
|
|
startDate: weekStart,
|
|
endDate: weekEnd,
|
|
isNavigation: true // Flag to indicate this is navigation rendering
|
|
});
|
|
|
|
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);
|
|
});
|
|
|
|
// Always ensure all-day containers exist for all days
|
|
const headerRenderer = CalendarTypeFactory.getHeaderRenderer(this.config.getCalendarMode());
|
|
headerRenderer.ensureAllDayContainers(header as HTMLElement);
|
|
|
|
// Add event delegation listener for drag & drop functionality
|
|
this.setupHeaderEventListener(header as HTMLElement);
|
|
|
|
// 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);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Setup event delegation listener for header mouseover (same logic as GridRenderer)
|
|
*/
|
|
private setupHeaderEventListener(calendarHeader: HTMLElement): void {
|
|
calendarHeader.addEventListener('mouseover', (event) => {
|
|
const target = event.target as HTMLElement;
|
|
|
|
// Check what was hovered - could be day-header OR all-day-container
|
|
const dayHeader = target.closest('swp-day-header');
|
|
const allDayContainer = target.closest('swp-allday-container');
|
|
|
|
if (dayHeader || allDayContainer) {
|
|
let hoveredElement: HTMLElement;
|
|
let targetDate: string | undefined;
|
|
|
|
if (dayHeader) {
|
|
hoveredElement = dayHeader as HTMLElement;
|
|
targetDate = hoveredElement.dataset.date;
|
|
} else if (allDayContainer) {
|
|
// For all-day areas, we need to determine which day column we're over
|
|
hoveredElement = allDayContainer as HTMLElement;
|
|
|
|
// Calculate which day we're hovering over based on mouse position
|
|
const headerRect = calendarHeader.getBoundingClientRect();
|
|
const dayHeaders = calendarHeader.querySelectorAll('swp-day-header');
|
|
const mouseX = (event as MouseEvent).clientX - headerRect.left;
|
|
const dayWidth = headerRect.width / dayHeaders.length;
|
|
const dayIndex = Math.floor(mouseX / dayWidth);
|
|
|
|
const targetDayHeader = dayHeaders[dayIndex] as HTMLElement;
|
|
targetDate = targetDayHeader?.dataset.date;
|
|
} else {
|
|
return; // No valid element found
|
|
}
|
|
|
|
|
|
// Get the header renderer for addToAllDay functionality
|
|
const calendarType = this.config.getCalendarMode();
|
|
const headerRenderer = CalendarTypeFactory.getHeaderRenderer(calendarType);
|
|
|
|
eventBus.emit('header:mouseover', {
|
|
element: hoveredElement,
|
|
targetDate,
|
|
headerRenderer
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
} |