This commit is contained in:
Janus C. H. Knudsen 2025-12-09 21:02:44 +01:00
parent c16e432b29
commit 2ec4b93fa5
9 changed files with 187 additions and 249 deletions

View file

@ -1,25 +1,14 @@
import { from } from 'ts-linq-light';
import { ViewConfig } from './ViewConfig';
import { IGroupingRenderer, RenderContext } from './IGroupingRenderer';
import { IGroupingStore } from './IGroupingStore';
import { RenderBuilder } from './RenderBuilder';
import { Renderer, RenderContext } from './IGroupingRenderer';
import { buildPipeline } from './RenderBuilder';
import { EventRenderer } from '../features/event/EventRenderer';
import { ViewConfig } from './ViewConfig';
export class CalendarOrchestrator {
constructor(
private renderers: IGroupingRenderer[],
private stores: IGroupingStore[],
private allRenderers: Renderer[],
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<void> {
const headerContainer = container.querySelector('swp-calendar-header') as HTMLElement;
const columnContainer = container.querySelector('swp-day-columns') as HTMLElement;
@ -27,53 +16,42 @@ export class CalendarOrchestrator {
throw new Error('Missing swp-calendar-header or swp-day-columns');
}
const context: RenderContext = { headerContainer, columnContainer };
// Byg filter fra viewConfig
const filter: Record<string, string[]> = {};
for (const grouping of viewConfig.groupings) {
filter[grouping.type] = grouping.values;
}
// Clear containers
const context: RenderContext = { headerContainer, columnContainer, filter };
// Clear
headerContainer.innerHTML = '';
columnContainer.innerHTML = '';
// Set header levels
const types = from(viewConfig.groupings).select(g => g.type).toArray();
headerContainer.dataset.levels = types.join(' ');
// Vælg renderers baseret på groupings types
const activeRenderers = this.selectRenderers(viewConfig);
// 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);
}
}
// Beregn total columns og render
const totalColumns = builder.getTotalCount();
// Beregn total kolonner dynamisk
const totalColumns = this.calculateTotalColumns(viewConfig);
container.style.setProperty('--grid-columns', String(totalColumns));
builder.build();
// Byg og kør pipeline
const pipeline = buildPipeline(activeRenderers);
pipeline.run(context);
// Render events
const visibleDates = this.extractVisibleDates(viewConfig);
await this.eventRenderer.render(container, visibleDates);
// Events
const dates = filter['date'] || [];
await this.eventRenderer.render(container, dates);
}
private getItems(type: string, viewConfig: ViewConfig): ReturnType<typeof from> {
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 selectRenderers(viewConfig: ViewConfig): Renderer[] {
const types = viewConfig.groupings.map(g => g.type);
return this.allRenderers.filter(r => types.includes(r.type));
}
private extractVisibleDates(viewConfig: ViewConfig): string[] {
return from(viewConfig.groupings).firstOrDefault(g => g.type === 'date')?.values || [];
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;
}
}