Implements FilterTemplate system for event matching

Introduces flexible key-based filtering for calendar events across different view configurations

Adds new FilterTemplate class to:
- Define event matching rules based on view configuration
- Support multi-level grouping (team/resource/date)
- Handle dynamic key generation for columns and events

Enhances view configuration with explicit id properties and derived fields
This commit is contained in:
Janus C. H. Knudsen 2025-12-15 00:33:27 +01:00
parent c2f7564f8e
commit dd647acab8
8 changed files with 331 additions and 41 deletions

View file

@ -4,6 +4,7 @@ import { CoreEvents } from '../../constants/CoreEvents';
import { HeaderDrawerManager } from '../../core/HeaderDrawerManager';
import { EventService } from '../../storage/events/EventService';
import { DateService } from '../../core/DateService';
import { FilterTemplate } from '../../core/FilterTemplate';
import {
IDragEnterHeaderPayload,
IDragMoveHeaderPayload,
@ -36,6 +37,7 @@ export class HeaderDrawerRenderer {
private container: HTMLElement | null = null;
private sourceElement: HTMLElement | null = null;
private wasExpandedBeforeDrag = false;
private filterTemplate: FilterTemplate | null = null;
constructor(
private eventBus: IEventBus,
@ -49,8 +51,12 @@ export class HeaderDrawerRenderer {
/**
* Render allDay events into the header drawer with row stacking
* @param filterTemplate - Template for matching events to columns
*/
async render(container: HTMLElement, filter: Record<string, string[]>): Promise<void> {
async render(container: HTMLElement, filter: Record<string, string[]>, filterTemplate: FilterTemplate): Promise<void> {
// Store filterTemplate for buildColumnKeyFromEvent
this.filterTemplate = filterTemplate;
const drawer = container.querySelector('swp-header-drawer');
if (!drawer) return;
@ -150,14 +156,24 @@ export class HeaderDrawerRenderer {
}
/**
* Build columnKey from event fields
* This is the only place we construct columnKey from event data
* Build columnKey from event using FilterTemplate
* Uses the same template that columns use for matching
*/
private buildColumnKeyFromEvent(event: ICalendarEvent, date?: Date): string {
const dateStr = this.dateService.getDateKey(date || event.start);
const segments: Record<string, string> = { date: dateStr };
if (event.resourceId) segments.resource = event.resourceId;
return this.dateService.buildColumnKey(segments);
if (!this.filterTemplate) {
// Fallback if no template - shouldn't happen in normal flow
const dateStr = this.dateService.getDateKey(date || event.start);
return dateStr;
}
// For multi-day events, we need to override the date in the event
if (date && date.getTime() !== event.start.getTime()) {
// Create temporary event with overridden start for key generation
const tempEvent = { ...event, start: date };
return this.filterTemplate.buildKeyFromEvent(tempEvent);
}
return this.filterTemplate.buildKeyFromEvent(event);
}
/**