// Column rendering strategy interface and implementations import { CalendarConfig } from '../core/CalendarConfig'; import { ResourceCalendarData } from '../types/CalendarTypes'; import { DateCalculator } from '../utils/DateCalculator'; import { WorkHoursManager } from '../managers/WorkHoursManager'; /** * Interface for column rendering strategies */ export interface ColumnRenderer { render(columnContainer: HTMLElement, context: ColumnRenderContext): void; } /** * Context for column rendering */ export interface ColumnRenderContext { currentWeek: Date; config: CalendarConfig; resourceData?: ResourceCalendarData | null; } /** * Date-based column renderer (original functionality) */ export class DateColumnRenderer implements ColumnRenderer { private dateCalculator!: DateCalculator; private workHoursManager!: WorkHoursManager; render(columnContainer: HTMLElement, context: ColumnRenderContext): void { const { currentWeek, config } = context; // Initialize date calculator and work hours manager this.dateCalculator = new DateCalculator(config); this.workHoursManager = new WorkHoursManager(config); const dates = this.dateCalculator.getWorkWeekDates(currentWeek); const dateSettings = config.getDateViewSettings(); const daysToShow = dates.slice(0, dateSettings.weekDays); daysToShow.forEach((date) => { const column = document.createElement('swp-day-column'); (column as any).dataset.date = this.dateCalculator.formatISODate(date); // Apply work hours styling this.applyWorkHoursToColumn(column, date); const eventsLayer = document.createElement('swp-events-layer'); column.appendChild(eventsLayer); columnContainer.appendChild(column); }); } private applyWorkHoursToColumn(column: HTMLElement, date: Date): void { const workHours = this.workHoursManager.getWorkHoursForDate(date); if (workHours === 'off') { // No work hours - mark as off day (full day will be colored) (column as any).dataset.workHours = 'off'; } else { // Calculate and apply non-work hours overlays (before and after work) const nonWorkStyle = this.workHoursManager.calculateNonWorkHoursStyle(workHours); if (nonWorkStyle) { // Before work overlay (::before pseudo-element) column.style.setProperty('--before-work-height', `${nonWorkStyle.beforeWorkHeight}px`); // After work overlay (::after pseudo-element) column.style.setProperty('--after-work-top', `${nonWorkStyle.afterWorkTop}px`); } } } } /** * Resource-based column renderer */ export class ResourceColumnRenderer implements ColumnRenderer { render(columnContainer: HTMLElement, context: ColumnRenderContext): void { const { resourceData } = context; if (!resourceData) { return; } resourceData.resources.forEach((resource) => { const column = document.createElement('swp-resource-column'); (column as any).dataset.resource = resource.name; (column as any).dataset.employeeId = resource.employeeId; (column as any).dataset.date = resourceData.date; const eventsLayer = document.createElement('swp-events-layer'); column.appendChild(eventsLayer); columnContainer.appendChild(column); }); } }