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
159 lines
4.1 KiB
TypeScript
159 lines
4.1 KiB
TypeScript
import { IEventBus, CalendarView } from '../types/CalendarTypes';
|
|
import { CoreEvents } from '../constants/CoreEvents';
|
|
import { DateService } from '../utils/DateService';
|
|
import { Configuration } from '../configurations/CalendarConfig';
|
|
import { INavButtonClickedEventPayload } from '../types/EventTypes';
|
|
|
|
/**
|
|
* NavigationButtons - Manages navigation button UI and navigation logic
|
|
*
|
|
* RESPONSIBILITY:
|
|
* ===============
|
|
* This manager owns all logic related to the <swp-nav-group> UI element
|
|
* and performs the actual navigation calculations.
|
|
*
|
|
* RESPONSIBILITIES:
|
|
* - Handles button clicks on swp-nav-button elements
|
|
* - Validates navigation actions (prev, next, today)
|
|
* - Calculates next/previous dates based on current view
|
|
* - Emits NAVIGATION_COMPLETED events with new date
|
|
* - Manages button UI listeners
|
|
*
|
|
* EVENT FLOW:
|
|
* ===========
|
|
* User clicks button → calculateNewDate() → emit NAVIGATION_COMPLETED → GridManager re-renders
|
|
*/
|
|
export class NavigationButtons {
|
|
private eventBus: IEventBus;
|
|
private buttonListeners: Map<Element, EventListener> = new Map();
|
|
private dateService: DateService;
|
|
private config: Configuration;
|
|
private currentDate: Date = new Date();
|
|
private currentView: CalendarView = 'week';
|
|
|
|
constructor(
|
|
eventBus: IEventBus,
|
|
dateService: DateService,
|
|
config: Configuration
|
|
) {
|
|
this.eventBus = eventBus;
|
|
this.dateService = dateService;
|
|
this.config = config;
|
|
this.setupButtonListeners();
|
|
this.subscribeToEvents();
|
|
}
|
|
|
|
/**
|
|
* Subscribe to events
|
|
*/
|
|
private subscribeToEvents(): void {
|
|
// Listen for view changes
|
|
this.eventBus.on(CoreEvents.VIEW_CHANGED, (e: Event) => {
|
|
const detail = (e as CustomEvent).detail;
|
|
this.currentView = detail.currentView;
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Setup click listeners on all navigation buttons
|
|
*/
|
|
private setupButtonListeners(): void {
|
|
const buttons = document.querySelectorAll('swp-nav-button[data-action]');
|
|
|
|
buttons.forEach(button => {
|
|
const clickHandler = (event: Event) => {
|
|
event.preventDefault();
|
|
const action = button.getAttribute('data-action');
|
|
if (action && this.isValidAction(action)) {
|
|
this.handleNavigation(action);
|
|
}
|
|
};
|
|
|
|
button.addEventListener('click', clickHandler);
|
|
this.buttonListeners.set(button, clickHandler);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Handle navigation action
|
|
*/
|
|
private handleNavigation(action: string): void {
|
|
switch (action) {
|
|
case 'prev':
|
|
this.navigatePrevious();
|
|
break;
|
|
case 'next':
|
|
this.navigateNext();
|
|
break;
|
|
case 'today':
|
|
this.navigateToday();
|
|
break;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Navigate in specified direction
|
|
*/
|
|
private navigate(direction: 'next' | 'previous'): void {
|
|
const offset = direction === 'next' ? 1 : -1;
|
|
let newDate: Date;
|
|
|
|
switch (this.currentView) {
|
|
case 'week':
|
|
newDate = this.dateService.addWeeks(this.currentDate, offset);
|
|
break;
|
|
case 'month':
|
|
newDate = this.dateService.addMonths(this.currentDate, offset);
|
|
break;
|
|
case 'day':
|
|
newDate = this.dateService.addDays(this.currentDate, offset);
|
|
break;
|
|
default:
|
|
newDate = this.dateService.addWeeks(this.currentDate, offset);
|
|
}
|
|
|
|
this.currentDate = newDate;
|
|
|
|
const payload: INavButtonClickedEventPayload = {
|
|
direction: direction,
|
|
newDate: newDate
|
|
};
|
|
|
|
this.eventBus.emit(CoreEvents.NAV_BUTTON_CLICKED, payload);
|
|
}
|
|
|
|
/**
|
|
* Navigate to next period
|
|
*/
|
|
private navigateNext(): void {
|
|
this.navigate('next');
|
|
}
|
|
|
|
/**
|
|
* Navigate to previous period
|
|
*/
|
|
private navigatePrevious(): void {
|
|
this.navigate('previous');
|
|
}
|
|
|
|
/**
|
|
* Navigate to today
|
|
*/
|
|
private navigateToday(): void {
|
|
this.currentDate = new Date();
|
|
|
|
const payload: INavButtonClickedEventPayload = {
|
|
direction: 'today',
|
|
newDate: this.currentDate
|
|
};
|
|
|
|
this.eventBus.emit(CoreEvents.NAV_BUTTON_CLICKED, payload);
|
|
}
|
|
|
|
/**
|
|
* Validate if string is a valid navigation action
|
|
*/
|
|
private isValidAction(action: string): boolean {
|
|
return ['prev', 'next', 'today'].includes(action);
|
|
}
|
|
}
|