diff --git a/src/v2/constants/CoreEvents.ts b/src/v2/constants/CoreEvents.ts index 1425a2f..d4c9894 100644 --- a/src/v2/constants/CoreEvents.ts +++ b/src/v2/constants/CoreEvents.ts @@ -74,5 +74,6 @@ export const CoreEvents = { CALENDAR_CMD_NAVIGATE_NEXT: 'calendar:cmd:navigate:next', CALENDAR_CMD_DRAWER_TOGGLE: 'calendar:cmd:drawer:toggle', CALENDAR_CMD_RENDER: 'calendar:cmd:render', - CALENDAR_CMD_WORKWEEK_CHANGE: 'calendar:cmd:workweek:change' + CALENDAR_CMD_WORKWEEK_CHANGE: 'calendar:cmd:workweek:change', + CALENDAR_CMD_VIEW_UPDATE: 'calendar:cmd:view:update' } as const; diff --git a/src/v2/core/CalendarApp.ts b/src/v2/core/CalendarApp.ts index 375ca76..43b3c27 100644 --- a/src/v2/core/CalendarApp.ts +++ b/src/v2/core/CalendarApp.ts @@ -23,6 +23,7 @@ export class CalendarApp { private weekOffset = 0; private currentViewId = 'simple'; private workweekPreset: IWorkweekPreset | null = null; + private groupingOverrides: Map = new Map(); constructor( private orchestrator: CalendarOrchestrator, @@ -102,6 +103,12 @@ export class CalendarApp { const { presetId } = e.detail; this.handleWorkweekChange(presetId); }) as EventListener); + + // View update via EventBus + this.eventBus.on(CoreEvents.CALENDAR_CMD_VIEW_UPDATE, ((e: CustomEvent) => { + const { type, values } = e.detail; + this.handleViewUpdate(type, values); + }) as EventListener); } private async handleRenderCommand(viewId: string): Promise { @@ -131,6 +138,12 @@ export class CalendarApp { } } + private async handleViewUpdate(type: string, values: string[]): Promise { + this.groupingOverrides.set(type, values); + await this.render(); + this.emitStatus('rendered', { viewId: this.currentViewId }); + } + private async render(): Promise { const storedConfig = await this.viewConfigService.getById(this.currentViewId); if (!storedConfig) { @@ -144,12 +157,21 @@ export class CalendarApp { ? this.dateService.getWeekDates(this.weekOffset, 1) : this.dateService.getWorkWeekDates(this.weekOffset, workDays); - // Clone config and populate dates + // Clone config and apply overrides const viewConfig: ViewConfig = { ...storedConfig, - groupings: storedConfig.groupings.map(g => - g.type === 'date' ? { ...g, values: dates } : g - ) + groupings: storedConfig.groupings.map(g => { + // Apply date values + if (g.type === 'date') { + return { ...g, values: dates }; + } + // Apply grouping overrides + const override = this.groupingOverrides.get(g.type); + if (override) { + return { ...g, values: override }; + } + return g; + }) }; await this.orchestrator.render(viewConfig, this.container); diff --git a/src/v2/demo/DemoApp.ts b/src/v2/demo/DemoApp.ts index c7083cd..a36ecf0 100644 --- a/src/v2/demo/DemoApp.ts +++ b/src/v2/demo/DemoApp.ts @@ -3,6 +3,7 @@ import { DataSeeder } from '../workers/DataSeeder'; import { AuditService } from '../storage/audit/AuditService'; import { CalendarApp } from '../core/CalendarApp'; import { DateService } from '../core/DateService'; +import { ResourceService } from '../storage/resources/ResourceService'; import { IEventBus } from '../types/CalendarTypes'; import { CoreEvents } from '../constants/CoreEvents'; @@ -16,6 +17,7 @@ export class DemoApp { private auditService: AuditService, private calendarApp: CalendarApp, private dateService: DateService, + private resourceService: ResourceService, private eventBus: IEventBus ) {} @@ -42,6 +44,7 @@ export class DemoApp { this.setupDrawerToggle(); this.setupViewSwitching(); this.setupWorkweekSelector(); + await this.setupResourceSelector(); // Listen for calendar status events this.setupStatusListeners(); @@ -70,12 +73,19 @@ export class DemoApp { const view = (chip as HTMLElement).dataset.view; if (view) { this.currentView = view; + this.updateSelectorVisibility(); this.eventBus.emit(CoreEvents.CALENDAR_CMD_RENDER, { viewId: view }); } }); }); } + private updateSelectorVisibility(): void { + const selector = document.querySelector('swp-resource-selector'); + const showSelector = this.currentView === 'picker' || this.currentView === 'day'; + selector?.classList.toggle('hidden', !showSelector); + } + private setupDrawerToggle(): void { document.getElementById('btn-drawer')!.onclick = () => { this.eventBus.emit(CoreEvents.CALENDAR_CMD_DRAWER_TOGGLE); @@ -90,6 +100,29 @@ export class DemoApp { }); } + private async setupResourceSelector(): Promise { + const resources = await this.resourceService.getAll(); + const container = document.querySelector('.resource-checkboxes') as HTMLElement; + if (!container) return; + + container.innerHTML = ''; + + resources.forEach(r => { + const label = document.createElement('label'); + label.innerHTML = ` + + ${r.displayName} + `; + container.appendChild(label); + }); + + container.addEventListener('change', () => { + const checked = container.querySelectorAll('input:checked') as NodeListOf; + const values = Array.from(checked).map(cb => cb.value); + this.eventBus.emit(CoreEvents.CALENDAR_CMD_VIEW_UPDATE, { type: 'resource', values }); + }); + } + private setupStatusListeners(): void { this.container.addEventListener('calendar:status:ready', () => { console.log('[DemoApp] Calendar ready');