Calendar/docs/filter-template.md

181 lines
4.7 KiB
Markdown
Raw Permalink Normal View History

# 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)