Calendar/src/v2/core/CalendarOrchestrator.ts
Janus C. H. Knudsen a2b95515fd Adds resource scheduling and unavailability tracking
Introduces comprehensive schedule management for resources:
- Adds DateService with advanced time and date utilities
- Implements ResourceScheduleService for managing work hours
- Creates ScheduleRenderer to visualize unavailable time zones
- Extends resource model to support default weekly schedules

Enables granular tracking of resource availability and working hours
2025-12-10 00:27:19 +01:00

68 lines
2.7 KiB
TypeScript

import { IRenderer, IRenderContext } from './IGroupingRenderer';
import { buildPipeline } from './RenderBuilder';
import { EventRenderer } from '../features/event/EventRenderer';
import { ScheduleRenderer } from '../features/schedule/ScheduleRenderer';
import { ViewConfig } from './ViewConfig';
export class CalendarOrchestrator {
constructor(
private allRenderers: IRenderer[],
private eventRenderer: EventRenderer,
private scheduleRenderer: ScheduleRenderer
) {}
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');
}
// Byg filter fra viewConfig
const filter: Record<string, string[]> = {};
for (const grouping of viewConfig.groupings) {
filter[grouping.type] = grouping.values;
}
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 events med hele filter (date + resource)
await this.eventRenderer.render(container, filter);
}
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;
}
}