2025-07-24 22:17:38 +02:00
|
|
|
import { EventBus } from '../core/EventBus';
|
|
|
|
|
import { CalendarView, IEventBus } from '../types/CalendarTypes';
|
|
|
|
|
import { calendarConfig } from '../core/CalendarConfig';
|
2025-08-20 20:22:51 +02:00
|
|
|
import { CoreEvents } from '../constants/CoreEvents';
|
2025-07-24 22:17:38 +02:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* ViewManager - Håndterer skift mellem dag/uge/måned visninger
|
|
|
|
|
* Arbejder med custom tags fra POC design
|
|
|
|
|
*/
|
|
|
|
|
export class ViewManager {
|
|
|
|
|
private eventBus: IEventBus;
|
|
|
|
|
private currentView: CalendarView = 'week';
|
2025-08-20 19:42:13 +02:00
|
|
|
private eventCleanup: (() => void)[] = [];
|
|
|
|
|
private buttonListeners: Map<Element, EventListener> = new Map();
|
2025-07-24 22:17:38 +02:00
|
|
|
|
|
|
|
|
constructor(eventBus: IEventBus) {
|
|
|
|
|
this.eventBus = eventBus;
|
|
|
|
|
this.setupEventListeners();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private setupEventListeners(): void {
|
2025-08-20 19:42:13 +02:00
|
|
|
// Track event bus listeners for cleanup
|
|
|
|
|
this.eventCleanup.push(
|
2025-08-20 20:22:51 +02:00
|
|
|
this.eventBus.on(CoreEvents.INITIALIZED, () => {
|
2025-08-20 19:42:13 +02:00
|
|
|
this.initializeView();
|
|
|
|
|
})
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
this.eventCleanup.push(
|
2025-08-20 20:22:51 +02:00
|
|
|
this.eventBus.on(CoreEvents.VIEW_CHANGED, (event: Event) => {
|
2025-08-20 19:42:13 +02:00
|
|
|
const customEvent = event as CustomEvent;
|
|
|
|
|
const { currentView } = customEvent.detail;
|
|
|
|
|
this.changeView(currentView);
|
|
|
|
|
})
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
this.eventCleanup.push(
|
2025-08-20 20:22:51 +02:00
|
|
|
this.eventBus.on(CoreEvents.DATE_CHANGED, () => {
|
2025-08-20 19:42:13 +02:00
|
|
|
this.refreshCurrentView();
|
|
|
|
|
})
|
|
|
|
|
);
|
2025-07-24 22:17:38 +02:00
|
|
|
|
|
|
|
|
// Setup view button handlers
|
|
|
|
|
this.setupViewButtonHandlers();
|
2025-08-18 22:27:17 +02:00
|
|
|
|
|
|
|
|
// Setup workweek preset button handlers
|
|
|
|
|
this.setupWorkweekButtonHandlers();
|
2025-08-20 00:39:31 +02:00
|
|
|
|
2025-07-24 22:17:38 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private setupViewButtonHandlers(): void {
|
|
|
|
|
const viewButtons = document.querySelectorAll('swp-view-button[data-view]');
|
|
|
|
|
viewButtons.forEach(button => {
|
2025-08-20 19:42:13 +02:00
|
|
|
const handler = (event: Event) => {
|
2025-07-24 22:17:38 +02:00
|
|
|
event.preventDefault();
|
|
|
|
|
const view = button.getAttribute('data-view') as CalendarView;
|
|
|
|
|
if (view && this.isValidView(view)) {
|
|
|
|
|
this.changeView(view);
|
|
|
|
|
}
|
2025-08-20 19:42:13 +02:00
|
|
|
};
|
|
|
|
|
button.addEventListener('click', handler);
|
|
|
|
|
this.buttonListeners.set(button, handler);
|
2025-07-24 22:17:38 +02:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2025-08-18 22:27:17 +02:00
|
|
|
private setupWorkweekButtonHandlers(): void {
|
|
|
|
|
const workweekButtons = document.querySelectorAll('swp-preset-button[data-workweek]');
|
|
|
|
|
workweekButtons.forEach(button => {
|
2025-08-20 19:42:13 +02:00
|
|
|
const handler = (event: Event) => {
|
2025-08-18 22:27:17 +02:00
|
|
|
event.preventDefault();
|
|
|
|
|
const workweekId = button.getAttribute('data-workweek');
|
|
|
|
|
if (workweekId) {
|
|
|
|
|
this.changeWorkweek(workweekId);
|
|
|
|
|
}
|
2025-08-20 19:42:13 +02:00
|
|
|
};
|
|
|
|
|
button.addEventListener('click', handler);
|
|
|
|
|
this.buttonListeners.set(button, handler);
|
2025-08-18 22:27:17 +02:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2025-08-20 00:39:31 +02:00
|
|
|
|
2025-07-24 22:17:38 +02:00
|
|
|
private initializeView(): void {
|
|
|
|
|
this.updateViewButtons();
|
2025-08-18 22:27:17 +02:00
|
|
|
this.updateWorkweekButtons();
|
2025-07-24 22:17:38 +02:00
|
|
|
|
2025-08-20 20:22:51 +02:00
|
|
|
this.eventBus.emit(CoreEvents.VIEW_RENDERED, {
|
2025-07-24 22:17:38 +02:00
|
|
|
view: this.currentView
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private changeView(newView: CalendarView): void {
|
|
|
|
|
if (newView === this.currentView) return;
|
|
|
|
|
|
|
|
|
|
const previousView = this.currentView;
|
|
|
|
|
this.currentView = newView;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
this.updateViewButtons();
|
|
|
|
|
|
2025-08-20 20:22:51 +02:00
|
|
|
this.eventBus.emit(CoreEvents.VIEW_CHANGED, {
|
2025-07-24 22:17:38 +02:00
|
|
|
previousView,
|
|
|
|
|
currentView: newView
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2025-08-18 22:27:17 +02:00
|
|
|
private changeWorkweek(workweekId: string): void {
|
|
|
|
|
|
|
|
|
|
// Update the calendar config
|
|
|
|
|
calendarConfig.setWorkWeek(workweekId);
|
|
|
|
|
|
|
|
|
|
// Update button states
|
|
|
|
|
this.updateWorkweekButtons();
|
|
|
|
|
|
|
|
|
|
// Trigger a calendar refresh to apply the new workweek
|
2025-08-20 20:22:51 +02:00
|
|
|
this.eventBus.emit(CoreEvents.REFRESH_REQUESTED);
|
2025-08-18 22:27:17 +02:00
|
|
|
}
|
2025-07-24 22:17:38 +02:00
|
|
|
|
|
|
|
|
private updateViewButtons(): void {
|
|
|
|
|
const viewButtons = document.querySelectorAll('swp-view-button[data-view]');
|
|
|
|
|
viewButtons.forEach(button => {
|
|
|
|
|
const buttonView = button.getAttribute('data-view') as CalendarView;
|
|
|
|
|
if (buttonView === this.currentView) {
|
|
|
|
|
button.setAttribute('data-active', 'true');
|
|
|
|
|
} else {
|
|
|
|
|
button.removeAttribute('data-active');
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2025-08-18 22:27:17 +02:00
|
|
|
private updateWorkweekButtons(): void {
|
|
|
|
|
const currentWorkweek = calendarConfig.getCurrentWorkWeek();
|
|
|
|
|
const workweekButtons = document.querySelectorAll('swp-preset-button[data-workweek]');
|
|
|
|
|
|
|
|
|
|
workweekButtons.forEach(button => {
|
|
|
|
|
const buttonWorkweek = button.getAttribute('data-workweek');
|
|
|
|
|
if (buttonWorkweek === currentWorkweek) {
|
|
|
|
|
button.setAttribute('data-active', 'true');
|
|
|
|
|
} else {
|
|
|
|
|
button.removeAttribute('data-active');
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2025-07-24 22:17:38 +02:00
|
|
|
private refreshCurrentView(): void {
|
2025-08-20 20:22:51 +02:00
|
|
|
this.eventBus.emit(CoreEvents.VIEW_RENDERED, {
|
2025-07-24 22:17:38 +02:00
|
|
|
view: this.currentView
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private isValidView(view: string): view is CalendarView {
|
|
|
|
|
return ['day', 'week', 'month'].includes(view);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public getCurrentView(): CalendarView {
|
|
|
|
|
return this.currentView;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public refresh(): void {
|
|
|
|
|
this.refreshCurrentView();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public destroy(): void {
|
2025-08-20 19:42:13 +02:00
|
|
|
// Clean up event bus listeners
|
|
|
|
|
this.eventCleanup.forEach(cleanup => cleanup());
|
|
|
|
|
this.eventCleanup = [];
|
|
|
|
|
|
|
|
|
|
// Clean up button listeners
|
|
|
|
|
this.buttonListeners.forEach((handler, button) => {
|
|
|
|
|
button.removeEventListener('click', handler);
|
|
|
|
|
});
|
|
|
|
|
this.buttonListeners.clear();
|
2025-07-24 22:17:38 +02:00
|
|
|
}
|
|
|
|
|
}
|