Calendar/src/v2/core/CalendarOrchestrator.ts

80 lines
2.7 KiB
TypeScript
Raw Normal View History

import { from } from 'ts-linq-light';
import { ViewConfig } from './ViewConfig';
import { IGroupingRenderer, RenderContext } from './IGroupingRenderer';
import { IGroupingStore } from './IGroupingStore';
import { RenderBuilder } from './RenderBuilder';
2025-12-08 20:05:32 +01:00
import { EventRenderer } from '../features/event/EventRenderer';
2025-12-06 01:22:04 +01:00
export class CalendarOrchestrator {
constructor(
2025-12-08 20:05:32 +01:00
private renderers: IGroupingRenderer[],
private stores: IGroupingStore[],
private eventRenderer: EventRenderer
2025-12-06 01:22:04 +01:00
) {}
2025-12-08 20:05:32 +01:00
private getRenderer(type: string): IGroupingRenderer | undefined {
return from(this.renderers).firstOrDefault(r => r.type === type);
2025-12-08 20:05:32 +01:00
}
private getStore(type: string): IGroupingStore | undefined {
return from(this.stores).firstOrDefault(s => s.type === type);
}
2025-12-06 01:22:04 +01:00
async render(viewConfig: ViewConfig, container: HTMLElement): Promise<void> {
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 };
2025-12-06 01:22:04 +01:00
// Clear containers
headerContainer.innerHTML = '';
columnContainer.innerHTML = '';
2025-12-06 01:22:04 +01:00
// Set header levels
const types = from(viewConfig.groupings).select(g => g.type).toArray();
2025-12-06 01:22:04 +01:00
headerContainer.dataset.levels = types.join(' ');
// Byg renderer chain
const builder = new RenderBuilder(context);
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);
}
}
2025-12-06 01:22:04 +01:00
// Beregn total columns og render
const totalColumns = builder.getTotalCount();
container.style.setProperty('--grid-columns', String(totalColumns));
builder.build();
2025-12-06 01:22:04 +01:00
// Render events
2025-12-08 20:05:32 +01:00
const visibleDates = this.extractVisibleDates(viewConfig);
await this.eventRenderer.render(container, visibleDates);
}
private getItems(type: string, viewConfig: ViewConfig): ReturnType<typeof from> {
const grouping = from(viewConfig.groupings).firstOrDefault(g => g.type === type);
if (!grouping) return from([]);
2025-12-06 01:22:04 +01:00
if (type === 'date') {
return from(grouping.values);
2025-12-06 01:22:04 +01:00
}
const store = this.getStore(type);
if (!store) return from([]);
2025-12-06 01:22:04 +01:00
return from(store.getByIds(grouping.values));
2025-12-06 01:22:04 +01:00
}
private extractVisibleDates(viewConfig: ViewConfig): string[] {
return from(viewConfig.groupings).firstOrDefault(g => g.type === 'date')?.values || [];
2025-12-06 01:22:04 +01:00
}
}