import { IRenderer, IRenderContext } from './IGroupingRenderer'; import { buildPipeline } from './RenderBuilder'; import { EventRenderer } from '../features/event/EventRenderer'; import { ScheduleRenderer } from '../features/schedule/ScheduleRenderer'; import { HeaderDrawerRenderer } from '../features/headerdrawer/HeaderDrawerRenderer'; import { ViewConfig } from './ViewConfig'; import { FilterTemplate } from './FilterTemplate'; import { DateService } from './DateService'; export class CalendarOrchestrator { constructor( private allRenderers: IRenderer[], private eventRenderer: EventRenderer, private scheduleRenderer: ScheduleRenderer, private headerDrawerRenderer: HeaderDrawerRenderer, private dateService: DateService ) {} async render(viewConfig: ViewConfig, container: HTMLElement): Promise { const headerContainer = container.querySelector('swp-calendar-header') as HTMLElement; const columnContainer = container.querySelector('swp-day-columns') as HTMLElement; if (!headerContainer || !columnContainer) { throw new Error('Missing swp-calendar-header or swp-day-columns'); } // Byg filter fra viewConfig const filter: Record = {}; for (const grouping of viewConfig.groupings) { filter[grouping.type] = grouping.values; } // Byg FilterTemplate fra viewConfig groupings const filterTemplate = new FilterTemplate(this.dateService); for (const grouping of viewConfig.groupings) { filterTemplate.addField(grouping.idProperty, grouping.derivedFrom); } const context: IRenderContext = { headerContainer, columnContainer, filter }; // Clear headerContainer.innerHTML = ''; columnContainer.innerHTML = ''; // Sæt data-levels attribut for CSS grid-row styling const levels = viewConfig.groupings.map(g => g.type).join(' '); headerContainer.dataset.levels = levels; // Vælg renderers baseret på groupings types const activeRenderers = this.selectRenderers(viewConfig); // Beregn total kolonner dynamisk const totalColumns = this.calculateTotalColumns(viewConfig); container.style.setProperty('--grid-columns', String(totalColumns)); // Byg og kør pipeline const pipeline = buildPipeline(activeRenderers); await pipeline.run(context); // Render schedule unavailable zones (før events) await this.scheduleRenderer.render(container, filter); // Render timed events in grid (med filterTemplate til matching) await this.eventRenderer.render(container, filter, filterTemplate); // Render allDay events in header drawer (med filterTemplate til matching) await this.headerDrawerRenderer.render(container, filter, filterTemplate); } private selectRenderers(viewConfig: ViewConfig): IRenderer[] { const types = viewConfig.groupings.map(g => g.type); // Sortér renderers i samme rækkefølge som viewConfig.groupings return types .map(type => this.allRenderers.find(r => r.type === type)) .filter((r): r is IRenderer => r !== undefined); } private calculateTotalColumns(viewConfig: ViewConfig): number { const dateCount = viewConfig.groupings.find(g => g.type === 'date')?.values.length || 1; const resourceCount = viewConfig.groupings.find(g => g.type === 'resource')?.values.length || 1; return dateCount * resourceCount; } }