Refactors navigation event handling and payload

Updates navigation button event emission to use a more consistent payload type

Simplifies navigation logic by centralizing date navigation in NavigationManager
Removes redundant method implementations and standardizes event handling
This commit is contained in:
Janus C. H. Knudsen 2025-11-13 20:41:33 +01:00
parent a666a632bd
commit 5075b71eb2
3 changed files with 42 additions and 96 deletions

View file

@ -2,6 +2,7 @@ import { IEventBus, CalendarView } from '../types/CalendarTypes';
import { CoreEvents } from '../constants/CoreEvents'; import { CoreEvents } from '../constants/CoreEvents';
import { DateService } from '../utils/DateService'; import { DateService } from '../utils/DateService';
import { Configuration } from '../configurations/CalendarConfig'; import { Configuration } from '../configurations/CalendarConfig';
import { INavButtonClickedEventPayload } from '../types/EventTypes';
/** /**
* NavigationButtons - Manages navigation button UI and navigation logic * NavigationButtons - Manages navigation button UI and navigation logic
@ -93,7 +94,7 @@ export class NavigationButtons {
/** /**
* Navigate in specified direction * Navigate in specified direction
*/ */
private navigate(direction: 'next' | 'prev'): void { private navigate(direction: 'next' | 'previous'): void {
const offset = direction === 'next' ? 1 : -1; const offset = direction === 'next' ? 1 : -1;
let newDate: Date; let newDate: Date;
@ -113,11 +114,12 @@ export class NavigationButtons {
this.currentDate = newDate; this.currentDate = newDate;
this.eventBus.emit(CoreEvents.NAVIGATION_COMPLETED, { const payload: INavButtonClickedEventPayload = {
direction: direction === 'next' ? 'next' : 'previous', direction: direction,
newDate: newDate, newDate: newDate
periodLabel: this.getCurrentPeriodLabel() };
});
this.eventBus.emit(CoreEvents.NAV_BUTTON_CLICKED, payload);
} }
/** /**
@ -131,7 +133,7 @@ export class NavigationButtons {
* Navigate to previous period * Navigate to previous period
*/ */
private navigatePrevious(): void { private navigatePrevious(): void {
this.navigate('prev'); this.navigate('previous');
} }
/** /**
@ -140,46 +142,12 @@ export class NavigationButtons {
private navigateToday(): void { private navigateToday(): void {
this.currentDate = new Date(); this.currentDate = new Date();
this.eventBus.emit(CoreEvents.NAVIGATION_COMPLETED, { const payload: INavButtonClickedEventPayload = {
direction: 'today', direction: 'today',
newDate: this.currentDate, newDate: this.currentDate
periodLabel: this.getCurrentPeriodLabel() };
});
}
/** this.eventBus.emit(CoreEvents.NAV_BUTTON_CLICKED, payload);
* Get ISO week start (Monday)
*/
private getISOWeekStart(date: Date): Date {
const weekBounds = this.dateService.getWeekBounds(date);
return this.dateService.startOfDay(weekBounds.start);
}
/**
* Get week end (Sunday)
*/
private getWeekEnd(date: Date): Date {
const weekBounds = this.dateService.getWeekBounds(date);
return this.dateService.endOfDay(weekBounds.end);
}
/**
* Get current period label
*/
private getCurrentPeriodLabel(): string {
switch (this.currentView) {
case 'week':
case 'day':
const weekStart = this.getISOWeekStart(this.currentDate);
const weekEnd = this.getWeekEnd(this.currentDate);
return this.dateService.formatDateRange(weekStart, weekEnd);
case 'month':
return this.dateService.formatMonthYear(this.currentDate);
default:
const defaultWeekStart = this.getISOWeekStart(this.currentDate);
const defaultWeekEnd = this.getWeekEnd(this.currentDate);
return this.dateService.formatDateRange(defaultWeekStart, defaultWeekEnd);
}
} }
/** /**

View file

@ -4,6 +4,7 @@ import { DateService } from '../utils/DateService';
import { CoreEvents } from '../constants/CoreEvents'; import { CoreEvents } from '../constants/CoreEvents';
import { WeekInfoRenderer } from '../renderers/WeekInfoRenderer'; import { WeekInfoRenderer } from '../renderers/WeekInfoRenderer';
import { GridRenderer } from '../renderers/GridRenderer'; import { GridRenderer } from '../renderers/GridRenderer';
import { INavButtonClickedEventPayload } from '../types/EventTypes';
export class NavigationManager { export class NavigationManager {
private eventBus: IEventBus; private eventBus: IEventBus;
@ -57,21 +58,12 @@ export class NavigationManager {
this.weekInfoRenderer.applyFilterToPreRenderedGrids(detail); this.weekInfoRenderer.applyFilterToPreRenderedGrids(detail);
}); });
// Listen for navigation button clicks from NavigationButtonsManager // Listen for navigation button clicks from NavigationButtons
this.eventBus.on(CoreEvents.NAV_BUTTON_CLICKED, (event: Event) => { this.eventBus.on(CoreEvents.NAV_BUTTON_CLICKED, (event: Event) => {
const { action } = (event as CustomEvent).detail; const { direction, newDate } = (event as CustomEvent<INavButtonClickedEventPayload>).detail;
switch (action) { // Navigate to the new date with animation
case 'prev': this.navigateToDate(newDate, direction);
this.navigateToPreviousWeek();
break;
case 'next':
this.navigateToNextWeek();
break;
case 'today':
this.navigateToToday();
break;
}
}); });
// Listen for external navigation requests // Listen for external navigation requests
@ -145,52 +137,32 @@ export class NavigationManager {
} }
} }
private navigateToPreviousWeek(): void {
this.targetWeek = this.dateService.addWeeks(this.targetWeek, -1);
const weekToShow = new Date(this.targetWeek);
this.animationQueue++;
this.animateTransition('prev', weekToShow);
}
private navigateToNextWeek(): void { private navigateToDate(date: Date, direction?: 'next' | 'previous' | 'today'): void {
this.targetWeek = this.dateService.addWeeks(this.targetWeek, 1);
const weekToShow = new Date(this.targetWeek);
this.animationQueue++;
this.animateTransition('next', weekToShow);
}
private navigateToToday(): void {
const today = new Date();
const todayWeekStart = this.getISOWeekStart(today);
// Reset to today
this.targetWeek = new Date(todayWeekStart);
const currentTime = this.currentWeek.getTime();
const targetTime = todayWeekStart.getTime();
if (currentTime < targetTime) {
this.animationQueue++;
this.animateTransition('next', todayWeekStart);
} else if (currentTime > targetTime) {
this.animationQueue++;
this.animateTransition('prev', todayWeekStart);
}
}
private navigateToDate(date: Date): void {
const weekStart = this.getISOWeekStart(date); const weekStart = this.getISOWeekStart(date);
this.targetWeek = new Date(weekStart); this.targetWeek = new Date(weekStart);
const currentTime = this.currentWeek.getTime(); const currentTime = this.currentWeek.getTime();
const targetTime = weekStart.getTime(); const targetTime = weekStart.getTime();
if (currentTime < targetTime) { // Use provided direction or calculate based on time comparison
let animationDirection: 'next' | 'prev';
if (direction === 'next') {
animationDirection = 'next';
} else if (direction === 'previous') {
animationDirection = 'prev';
} else if (direction === 'today') {
// For "today", determine direction based on current position
animationDirection = currentTime < targetTime ? 'next' : 'prev';
} else {
// Fallback: calculate direction
animationDirection = currentTime < targetTime ? 'next' : 'prev';
}
if (currentTime !== targetTime) {
this.animationQueue++; this.animationQueue++;
this.animateTransition('next', weekStart); this.animateTransition(animationDirection, weekStart);
} else if (currentTime > targetTime) {
this.animationQueue++;
this.animateTransition('prev', weekStart);
} }
} }

View file

@ -98,3 +98,9 @@ export interface IResizeEndEventPayload {
element: HTMLElement; element: HTMLElement;
finalHeight: number; finalHeight: number;
} }
// Navigation button clicked event payload
export interface INavButtonClickedEventPayload {
direction: 'next' | 'previous' | 'today';
newDate: Date;
}