import { CoreEvents } from '../constants/CoreEvents'; /** * ViewSelectorManager - Manages view selector UI and state * * RESPONSIBILITY: * =============== * This manager owns all logic related to the UI element. * It follows the principle that each functional UI element has its own manager. * * RESPONSIBILITIES: * - Handles button clicks on swp-view-button elements * - Manages current view state (day/week/month) * - Validates view values * - Emits VIEW_CHANGED and VIEW_RENDERED events * - Updates button UI states (data-active attributes) * * EVENT FLOW: * =========== * User clicks button → changeView() → validate → update state → emit event → update UI * * IMPLEMENTATION STATUS: * ====================== * - Week view: FULLY IMPLEMENTED * - Day view: NOT IMPLEMENTED (button exists but no rendering) * - Month view: NOT IMPLEMENTED (button exists but no rendering) * * SUBSCRIBERS: * ============ * - GridRenderer: Uses view parameter (currently only supports 'week') * - Future: DayRenderer, MonthRenderer when implemented */ export class ViewSelectorManager { constructor(eventBus, config) { this.buttonListeners = new Map(); this.eventBus = eventBus; this.config = config; this.setupButtonListeners(); this.setupEventListeners(); } /** * Setup click listeners on all view selector buttons */ setupButtonListeners() { const buttons = document.querySelectorAll('swp-view-button[data-view]'); buttons.forEach(button => { const clickHandler = (event) => { event.preventDefault(); const view = button.getAttribute('data-view'); if (view && this.isValidView(view)) { this.changeView(view); } }; button.addEventListener('click', clickHandler); this.buttonListeners.set(button, clickHandler); }); // Initialize button states this.updateButtonStates(); } /** * Setup event bus listeners */ setupEventListeners() { this.eventBus.on(CoreEvents.INITIALIZED, () => { this.initializeView(); }); this.eventBus.on(CoreEvents.DATE_CHANGED, () => { this.refreshCurrentView(); }); } /** * Change the active view */ changeView(newView) { if (newView === this.config.currentView) { return; // No change } const previousView = this.config.currentView; this.config.currentView = newView; // Update button UI states this.updateButtonStates(); // Emit event for subscribers this.eventBus.emit(CoreEvents.VIEW_CHANGED, { previousView, currentView: newView }); } /** * Update button states (data-active attributes) */ updateButtonStates() { const buttons = document.querySelectorAll('swp-view-button[data-view]'); buttons.forEach(button => { const buttonView = button.getAttribute('data-view'); if (buttonView === this.config.currentView) { button.setAttribute('data-active', 'true'); } else { button.removeAttribute('data-active'); } }); } /** * Initialize view on INITIALIZED event */ initializeView() { this.updateButtonStates(); this.emitViewRendered(); } /** * Emit VIEW_RENDERED event */ emitViewRendered() { this.eventBus.emit(CoreEvents.VIEW_RENDERED, { view: this.config.currentView }); } /** * Refresh current view on DATE_CHANGED event */ refreshCurrentView() { this.emitViewRendered(); } /** * Validate if string is a valid CalendarView type */ isValidView(view) { return ['day', 'week', 'month'].includes(view); } } //# sourceMappingURL=ViewSelectorManager.js.map