Refactor calendar event handling with EventBus

Migrates calendar commands from DOM events to EventBus for better decoupling
Adds support for workweek change and simplified rendering commands
Removes direction parameter from render method for cleaner implementation
This commit is contained in:
Janus C. H. Knudsen 2025-12-17 18:09:54 +01:00
parent 3710bb50c0
commit 8d938c721c
3 changed files with 40 additions and 23 deletions

View file

@ -71,5 +71,8 @@ export const CoreEvents = {
// Calendar command events // Calendar command events
CALENDAR_CMD_NAVIGATE_PREV: 'calendar:cmd:navigate:prev', CALENDAR_CMD_NAVIGATE_PREV: 'calendar:cmd:navigate:prev',
CALENDAR_CMD_NAVIGATE_NEXT: 'calendar:cmd:navigate:next' 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'
} as const; } as const;

View file

@ -86,26 +86,27 @@ export class CalendarApp {
this.handleNavigateNext(); this.handleNavigateNext();
}); });
// Other commands via container DOM events (migrates later) // Drawer toggle via EventBus
this.container.addEventListener('calendar:cmd:render', ((e: CustomEvent) => { this.eventBus.on(CoreEvents.CALENDAR_CMD_DRAWER_TOGGLE, () => {
const { viewId, direction } = e.detail; this.headerDrawerManager.toggle();
this.handleRenderCommand(viewId, direction); });
// Render command via EventBus
this.eventBus.on(CoreEvents.CALENDAR_CMD_RENDER, ((e: CustomEvent) => {
const { viewId } = e.detail;
this.handleRenderCommand(viewId);
}) as EventListener); }) as EventListener);
this.container.addEventListener('calendar:cmd:drawer:toggle', (() => { // Workweek change via EventBus
this.headerDrawerManager.toggle(); this.eventBus.on(CoreEvents.CALENDAR_CMD_WORKWEEK_CHANGE, ((e: CustomEvent) => {
const { presetId } = e.detail;
this.handleWorkweekChange(presetId);
}) as EventListener); }) as EventListener);
} }
private async handleRenderCommand(viewId: string, direction?: 'left' | 'right'): Promise<void> { private async handleRenderCommand(viewId: string): Promise<void> {
this.currentViewId = viewId; this.currentViewId = viewId;
await this.render();
if (direction) {
await this.animator.slide(direction, () => this.render());
} else {
await this.render();
}
this.emitStatus('rendered', { viewId }); this.emitStatus('rendered', { viewId });
} }
@ -121,6 +122,15 @@ export class CalendarApp {
this.emitStatus('rendered', { viewId: this.currentViewId }); this.emitStatus('rendered', { viewId: this.currentViewId });
} }
private async handleWorkweekChange(presetId: string): Promise<void> {
const preset = await this.settingsService.getWorkweekPreset(presetId);
if (preset) {
this.workweekPreset = preset;
await this.render();
this.emitStatus('rendered', { viewId: this.currentViewId });
}
}
private async render(): Promise<void> { private async render(): Promise<void> {
const storedConfig = await this.viewConfigService.getById(this.currentViewId); const storedConfig = await this.viewConfigService.getById(this.currentViewId);
if (!storedConfig) { if (!storedConfig) {

View file

@ -41,12 +41,13 @@ export class DemoApp {
this.setupNavigation(); this.setupNavigation();
this.setupDrawerToggle(); this.setupDrawerToggle();
this.setupViewSwitching(); this.setupViewSwitching();
this.setupWorkweekSelector();
// Listen for calendar status events // Listen for calendar status events
this.setupStatusListeners(); this.setupStatusListeners();
// Initial render // Initial render
this.emitRenderCommand(this.currentView); this.eventBus.emit(CoreEvents.CALENDAR_CMD_RENDER, { viewId: this.currentView });
} }
private setupNavigation(): void { private setupNavigation(): void {
@ -69,7 +70,7 @@ export class DemoApp {
const view = (chip as HTMLElement).dataset.view; const view = (chip as HTMLElement).dataset.view;
if (view) { if (view) {
this.currentView = view; this.currentView = view;
this.emitRenderCommand(view); this.eventBus.emit(CoreEvents.CALENDAR_CMD_RENDER, { viewId: view });
} }
}); });
}); });
@ -77,10 +78,18 @@ export class DemoApp {
private setupDrawerToggle(): void { private setupDrawerToggle(): void {
document.getElementById('btn-drawer')!.onclick = () => { document.getElementById('btn-drawer')!.onclick = () => {
this.container.dispatchEvent(new CustomEvent('calendar:cmd:drawer:toggle')); this.eventBus.emit(CoreEvents.CALENDAR_CMD_DRAWER_TOGGLE);
}; };
} }
private setupWorkweekSelector(): void {
const workweekSelect = document.getElementById('workweek-select') as HTMLSelectElement;
workweekSelect?.addEventListener('change', () => {
const presetId = workweekSelect.value;
this.eventBus.emit(CoreEvents.CALENDAR_CMD_WORKWEEK_CHANGE, { presetId });
});
}
private setupStatusListeners(): void { private setupStatusListeners(): void {
this.container.addEventListener('calendar:status:ready', () => { this.container.addEventListener('calendar:status:ready', () => {
console.log('[DemoApp] Calendar ready'); console.log('[DemoApp] Calendar ready');
@ -95,9 +104,4 @@ export class DemoApp {
}) as EventListener); }) as EventListener);
} }
private emitRenderCommand(viewId: string, direction?: 'left' | 'right'): void {
this.container.dispatchEvent(new CustomEvent('calendar:cmd:render', {
detail: { viewId, direction }
}));
}
} }