import { from } from 'ts-linq-light'; import { ViewConfig } from './ViewConfig'; import { IGroupingRenderer, RenderContext } from './IGroupingRenderer'; import { IGroupingStore } from './IGroupingStore'; import { RenderBuilder, RenderData } from './RenderBuilder'; import { EventRenderer } from '../features/event/EventRenderer'; export class CalendarOrchestrator { constructor( private renderers: IGroupingRenderer[], private stores: IGroupingStore[], private eventRenderer: EventRenderer ) {} private getRenderer(type: string): IGroupingRenderer | undefined { return from(this.renderers).firstOrDefault(r => r.type === type); } private getStore(type: string): IGroupingStore | undefined { return from(this.stores).firstOrDefault(s => s.type === type); } 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'); } const context: RenderContext = { headerContainer, columnContainer }; // Clear containers headerContainer.innerHTML = ''; columnContainer.innerHTML = ''; // Set header levels const types = from(viewConfig.groupings).select(g => g.type).toArray(); headerContainer.dataset.levels = types.join(' '); // Hent alt data const data: RenderData = { teams: this.getItems('team', viewConfig), resources: this.getItems('resource', viewConfig), dates: this.getItems('date', viewConfig) }; // Byg renderer chain const builder = new RenderBuilder(context, data); for (const grouping of viewConfig.groupings) { const renderer = this.getRenderer(grouping.type); if (renderer) { const items = this.getItems(grouping.type, viewConfig); builder.add(renderer, items); } } // Beregn total columns og render const totalColumns = builder.getTotalCount(); container.style.setProperty('--grid-columns', String(totalColumns)); builder.build(); // Render events const visibleDates = this.extractVisibleDates(viewConfig); await this.eventRenderer.render(container, visibleDates); } private getItems(type: string, viewConfig: ViewConfig): ReturnType { const grouping = from(viewConfig.groupings).firstOrDefault(g => g.type === type); if (!grouping) return from([]); if (type === 'date') { return from(grouping.values); } const store = this.getStore(type); if (!store) return from([]); return from(store.getByIds(grouping.values)); } private extractVisibleDates(viewConfig: ViewConfig): string[] { return from(viewConfig.groupings).firstOrDefault(g => g.type === 'date')?.values || []; } }