# FilterTemplate System ## Problem En kolonne har en unik nøgle baseret på view-konfigurationen (f.eks. team + resource + date). Events skal matches mod denne nøgle - men kun på de felter viewet definerer. ## Løsning: FilterTemplate ViewConfig definerer hvilke felter (idProperties) der indgår i kolonnens nøgle. Samme template bruges til at bygge nøgle for både kolonne og event. **Princip:** Kolonnens nøgle-template bestemmer hvad der matches på. --- ## ViewConfig med idProperty ViewConfig er kilden til sandhed - den definerer grupper OG deres relations-id property. ```typescript interface GroupingConfig { type: string; // 'team', 'resource', 'date' values: string[]; // ['EMP001', 'EMP002'] idProperty: string; // property-navn på event (eks. 'resourceId') derivedFrom?: string; // for date: udledes fra 'start' } ``` ### Eksempler **Team → Resource → Date view:** ```typescript { groupings: [ { type: 'team', values: ['team-a'], idProperty: 'teamId' }, { type: 'resource', values: ['EMP001', 'EMP002'], idProperty: 'resourceId' }, { type: 'date', values: ['2025-12-09', '2025-12-10'], idProperty: 'date', derivedFrom: 'start' } ] } ``` **Simple date-only view:** ```typescript { groupings: [ { type: 'date', values: ['2025-12-09', '2025-12-10'], idProperty: 'date', derivedFrom: 'start' } ] } ``` --- ## FilterTemplate Klasse ```typescript class FilterTemplate { private fields: Array<{ idProperty: string; derivedFrom?: string; }> = []; addField(idProperty: string, derivedFrom?: string): this { this.fields.push({ idProperty, derivedFrom }); return this; } buildKeyFromColumn(column: HTMLElement): string { return this.fields .map(f => column.dataset[f.idProperty] || '') .join(':'); } buildKeyFromEvent(event: ICalendarEvent, dateService: DateService): string { return this.fields .map(f => { if (f.derivedFrom) { return dateService.getDateKey((event as any)[f.derivedFrom]); } return (event as any)[f.idProperty] || ''; }) .join(':'); } } ``` --- ## Flow ``` Orchestrator │ ├── Læs ViewConfig.groupings │ ├── Byg FilterTemplate fra groupings: │ for (grouping of viewConfig.groupings) { │ template.addField(grouping.idProperty, grouping.derivedFrom); │ } │ ├── Kør group-renderers (bygger headers + kolonner) │ └── DateRenderer sætter column.dataset[idProperty] for ALLE grupperinger │ └── EventRenderer.render(ctx, template) │ └── for each column: columnKey = template.buildKeyFromColumn(column) columnEvents = events.filter(e => template.buildKeyFromEvent(e) === columnKey ) ``` --- ## Eksempler ### 3-niveau view: Team → Resource → Date **ViewConfig:** ```typescript groupings: [ { type: 'team', values: ['team-a'], idProperty: 'teamId' }, { type: 'resource', values: ['EMP001'], idProperty: 'resourceId' }, { type: 'date', values: ['2025-12-09'], idProperty: 'date', derivedFrom: 'start' } ] ``` **Template:** `['teamId', 'resourceId', 'date']` **Kolonne-nøgle:** `"team-a:EMP001:2025-12-09"` **Event-nøgle:** `"team-a:EMP001:2025-12-09"` **Match!** --- ### 2-niveau view: Resource → Date **ViewConfig:** ```typescript groupings: [ { type: 'resource', values: ['EMP001'], idProperty: 'resourceId' }, { type: 'date', values: ['2025-12-09'], idProperty: 'date', derivedFrom: 'start' } ] ``` **Template:** `['resourceId', 'date']` **Kolonne-nøgle:** `"EMP001:2025-12-09"` **Event-nøgle:** `"EMP001:2025-12-09"` (teamId ignoreres - ikke i template) **Match!** --- ### 1-niveau view: Kun Date **ViewConfig:** ```typescript groupings: [ { type: 'date', values: ['2025-12-09'], idProperty: 'date', derivedFrom: 'start' } ] ``` **Template:** `['date']` **Kolonne-nøgle:** `"2025-12-09"` **Event-nøgle:** `"2025-12-09"` (alle andre felter ignoreres) **Match!** Samme event vises i alle views - kun de relevante felter indgår i matching. --- ## Kerneprincipper 1. **ViewConfig definerer nøgle-template** - hvilke idProperties der indgår 2. **Samme template til kolonne og event** - sikrer konsistent matching 3. **Felter udenfor template ignoreres** - event med ekstra felter matcher stadig 4. **idProperty** - eksplicit mapping mellem gruppering og event-felt 5. **derivedFrom** - håndterer felter der udledes (f.eks. date fra start)