2025-12-08 22:26:38 +01:00
|
|
|
import { from } from 'ts-linq-light';
|
2025-12-09 00:51:41 +01:00
|
|
|
import { ViewConfig } from './ViewConfig';
|
|
|
|
|
import { IGroupingRenderer, RenderContext } from './IGroupingRenderer';
|
2025-12-07 14:31:16 +01:00
|
|
|
import { IGroupingStore } from './IGroupingStore';
|
2025-12-09 15:24:19 +01:00
|
|
|
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 {
|
2025-12-08 22:26:38 +01:00
|
|
|
return from(this.renderers).firstOrDefault(r => r.type === type);
|
2025-12-08 20:05:32 +01:00
|
|
|
}
|
|
|
|
|
|
2025-12-07 14:31:16 +01:00
|
|
|
private getStore(type: string): IGroupingStore | undefined {
|
2025-12-08 22:26:38 +01:00
|
|
|
return from(this.stores).firstOrDefault(s => s.type === type);
|
2025-12-07 14:31:16 +01:00
|
|
|
}
|
|
|
|
|
|
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');
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-09 00:51:41 +01:00
|
|
|
const context: RenderContext = { headerContainer, columnContainer };
|
2025-12-06 01:22:04 +01:00
|
|
|
|
2025-12-09 00:51:41 +01:00
|
|
|
// Clear containers
|
|
|
|
|
headerContainer.innerHTML = '';
|
|
|
|
|
columnContainer.innerHTML = '';
|
2025-12-06 01:22:04 +01:00
|
|
|
|
2025-12-09 00:51:41 +01:00
|
|
|
// Set header levels
|
2025-12-08 22:26:38 +01:00
|
|
|
const types = from(viewConfig.groupings).select(g => g.type).toArray();
|
2025-12-06 01:22:04 +01:00
|
|
|
headerContainer.dataset.levels = types.join(' ');
|
|
|
|
|
|
2025-12-09 00:51:41 +01:00
|
|
|
// Byg renderer chain
|
2025-12-09 15:24:19 +01:00
|
|
|
const builder = new RenderBuilder(context);
|
2025-12-09 00:51:41 +01:00
|
|
|
|
|
|
|
|
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
|
|
|
|
2025-12-09 00:51:41 +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
|
|
|
|
2025-12-09 00:51:41 +01:00
|
|
|
// Render events
|
2025-12-08 20:05:32 +01:00
|
|
|
const visibleDates = this.extractVisibleDates(viewConfig);
|
|
|
|
|
await this.eventRenderer.render(container, visibleDates);
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-09 00:51:41 +01:00
|
|
|
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
|
|
|
|
2025-12-09 00:51:41 +01:00
|
|
|
if (type === 'date') {
|
|
|
|
|
return from(grouping.values);
|
2025-12-06 01:22:04 +01:00
|
|
|
}
|
|
|
|
|
|
2025-12-09 00:51:41 +01:00
|
|
|
const store = this.getStore(type);
|
|
|
|
|
if (!store) return from([]);
|
2025-12-06 01:22:04 +01:00
|
|
|
|
2025-12-09 00:51:41 +01:00
|
|
|
return from(store.getByIds(grouping.values));
|
2025-12-06 01:22:04 +01:00
|
|
|
}
|
|
|
|
|
|
2025-12-09 00:51:41 +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
|
|
|
}
|
|
|
|
|
}
|