Refactors calendar configuration and event handling
Streamlines calendar configuration by adopting a singleton pattern for consistent access and simplifies event handling.
- Removes direct `CalendarConfig` dependency injection in favor of the `calendarConfig` singleton, reducing code complexity.
- Replaces specific event emissions for grid, date, and resource settings updates with a general `REFRESH_REQUESTED` event.
- Updates event names to be more descriptive and consistent ("NAVIGATION_COMPLETED", "PERIOD_INFO_UPDATE").
- Removes the need to pass the calendar config to renderers since it is now a singleton.
This improves code maintainability and simplifies the event emission process.
This commit is contained in:
parent
d0936d1838
commit
2083c6921e
19 changed files with 139 additions and 173 deletions
|
|
@ -34,7 +34,7 @@ export class DateColumnRenderer implements ColumnRenderer {
|
|||
// Initialize date calculator and work hours manager
|
||||
DateCalculator.initialize(config);
|
||||
this.dateCalculator = new DateCalculator();
|
||||
this.workHoursManager = new WorkHoursManager(config);
|
||||
this.workHoursManager = new WorkHoursManager();
|
||||
|
||||
const dates = DateCalculator.getWorkWeekDates(currentWeek);
|
||||
const dateSettings = config.getDateViewSettings();
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
import { CalendarEvent } from '../types/CalendarTypes';
|
||||
import { ALL_DAY_CONSTANTS } from '../core/CalendarConfig';
|
||||
import { CalendarConfig } from '../core/CalendarConfig';
|
||||
import { calendarConfig } from '../core/CalendarConfig';
|
||||
import { DateCalculator } from '../utils/DateCalculator';
|
||||
import { eventBus } from '../core/EventBus';
|
||||
import { CoreEvents } from '../constants/CoreEvents';
|
||||
|
|
@ -11,7 +11,7 @@ import { CoreEvents } from '../constants/CoreEvents';
|
|||
* Interface for event rendering strategies
|
||||
*/
|
||||
export interface EventRendererStrategy {
|
||||
renderEvents(events: CalendarEvent[], container: HTMLElement, config: CalendarConfig): void;
|
||||
renderEvents(events: CalendarEvent[], container: HTMLElement): void;
|
||||
clearEvents(container?: HTMLElement): void;
|
||||
}
|
||||
|
||||
|
|
@ -20,16 +20,14 @@ export interface EventRendererStrategy {
|
|||
*/
|
||||
export abstract class BaseEventRenderer implements EventRendererStrategy {
|
||||
protected dateCalculator: DateCalculator;
|
||||
protected config: CalendarConfig;
|
||||
|
||||
// Drag and drop state
|
||||
private draggedClone: HTMLElement | null = null;
|
||||
private originalEvent: HTMLElement | null = null;
|
||||
|
||||
constructor(config: CalendarConfig, dateCalculator?: DateCalculator) {
|
||||
this.config = config;
|
||||
constructor(dateCalculator?: DateCalculator) {
|
||||
if (!dateCalculator) {
|
||||
DateCalculator.initialize(config);
|
||||
DateCalculator.initialize(calendarConfig);
|
||||
}
|
||||
this.dateCalculator = dateCalculator || new DateCalculator();
|
||||
}
|
||||
|
|
@ -69,7 +67,7 @@ export abstract class BaseEventRenderer implements EventRendererStrategy {
|
|||
});
|
||||
|
||||
// Handle navigation period change (when slide animation completes)
|
||||
eventBus.on(CoreEvents.PERIOD_CHANGED, () => {
|
||||
eventBus.on(CoreEvents.NAVIGATION_COMPLETED, () => {
|
||||
// Animate all-day height after navigation completes
|
||||
this.triggerAllDayHeightAnimation();
|
||||
});
|
||||
|
|
@ -146,7 +144,7 @@ export abstract class BaseEventRenderer implements EventRendererStrategy {
|
|||
* Update clone timestamp based on new position
|
||||
*/
|
||||
private updateCloneTimestamp(clone: HTMLElement, snappedY: number): void {
|
||||
const gridSettings = this.config.getGridSettings();
|
||||
const gridSettings = calendarConfig.getGridSettings();
|
||||
const hourHeight = gridSettings.hourHeight;
|
||||
const dayStartHour = gridSettings.dayStartHour;
|
||||
const snapInterval = 15; // TODO: Get from config
|
||||
|
|
@ -175,7 +173,7 @@ export abstract class BaseEventRenderer implements EventRendererStrategy {
|
|||
* Calculate event duration in minutes from element height
|
||||
*/
|
||||
private getEventDuration(element: HTMLElement): number {
|
||||
const gridSettings = this.config.getGridSettings();
|
||||
const gridSettings = calendarConfig.getGridSettings();
|
||||
const hourHeight = gridSettings.hourHeight;
|
||||
|
||||
// Get height from style or computed
|
||||
|
|
@ -424,7 +422,7 @@ export abstract class BaseEventRenderer implements EventRendererStrategy {
|
|||
}
|
||||
|
||||
}
|
||||
renderEvents(events: CalendarEvent[], container: HTMLElement, config: CalendarConfig): void {
|
||||
renderEvents(events: CalendarEvent[], container: HTMLElement): void {
|
||||
|
||||
// NOTE: Removed clearEvents() to support sliding animation
|
||||
// With sliding animation, multiple grid containers exist simultaneously
|
||||
|
|
@ -437,7 +435,7 @@ export abstract class BaseEventRenderer implements EventRendererStrategy {
|
|||
|
||||
|
||||
// Always call renderAllDayEvents to ensure height is set correctly (even to 0)
|
||||
this.renderAllDayEvents(allDayEvents, container, config);
|
||||
this.renderAllDayEvents(allDayEvents, container);
|
||||
|
||||
// Find columns in the specific container for regular events
|
||||
const columns = this.getColumns(container);
|
||||
|
|
@ -448,7 +446,7 @@ export abstract class BaseEventRenderer implements EventRendererStrategy {
|
|||
const eventsLayer = column.querySelector('swp-events-layer');
|
||||
if (eventsLayer) {
|
||||
columnEvents.forEach(event => {
|
||||
this.renderEvent(event, eventsLayer, config);
|
||||
this.renderEvent(event, eventsLayer);
|
||||
});
|
||||
|
||||
// Debug: Verify events were actually added
|
||||
|
|
@ -465,7 +463,7 @@ export abstract class BaseEventRenderer implements EventRendererStrategy {
|
|||
/**
|
||||
* Render all-day events in the header row 2
|
||||
*/
|
||||
protected renderAllDayEvents(allDayEvents: CalendarEvent[], container: HTMLElement, config: CalendarConfig): void {
|
||||
protected renderAllDayEvents(allDayEvents: CalendarEvent[], container: HTMLElement): void {
|
||||
|
||||
// Find the calendar header
|
||||
const calendarHeader = container.querySelector('swp-calendar-header');
|
||||
|
|
@ -565,7 +563,7 @@ export abstract class BaseEventRenderer implements EventRendererStrategy {
|
|||
|
||||
}
|
||||
|
||||
protected renderEvent(event: CalendarEvent, container: Element, config: CalendarConfig): void {
|
||||
protected renderEvent(event: CalendarEvent, container: Element): void {
|
||||
const eventElement = document.createElement('swp-event');
|
||||
eventElement.dataset.eventId = event.id;
|
||||
eventElement.dataset.title = event.title;
|
||||
|
|
@ -575,7 +573,7 @@ export abstract class BaseEventRenderer implements EventRendererStrategy {
|
|||
eventElement.dataset.duration = event.metadata?.duration?.toString() || '60';
|
||||
|
||||
// Calculate position based on time
|
||||
const position = this.calculateEventPosition(event, config);
|
||||
const position = this.calculateEventPosition(event);
|
||||
eventElement.style.position = 'absolute';
|
||||
eventElement.style.top = `${position.top + 1}px`;
|
||||
eventElement.style.height = `${position.height - 3}px`; //adjusted so bottom does not cover horizontal time lines.
|
||||
|
|
@ -601,11 +599,11 @@ export abstract class BaseEventRenderer implements EventRendererStrategy {
|
|||
container.appendChild(eventElement);
|
||||
}
|
||||
|
||||
protected calculateEventPosition(event: CalendarEvent, config: CalendarConfig): { top: number; height: number } {
|
||||
protected calculateEventPosition(event: CalendarEvent): { top: number; height: number } {
|
||||
const startDate = new Date(event.start);
|
||||
const endDate = new Date(event.end);
|
||||
|
||||
const gridSettings = config.getGridSettings();
|
||||
const gridSettings = calendarConfig.getGridSettings();
|
||||
const dayStartHour = gridSettings.dayStartHour;
|
||||
const hourHeight = gridSettings.hourHeight;
|
||||
|
||||
|
|
@ -681,8 +679,8 @@ export abstract class BaseEventRenderer implements EventRendererStrategy {
|
|||
* Date-based event renderer
|
||||
*/
|
||||
export class DateEventRenderer extends BaseEventRenderer {
|
||||
constructor(config: CalendarConfig, dateCalculator?: DateCalculator) {
|
||||
super(config, dateCalculator);
|
||||
constructor(dateCalculator?: DateCalculator) {
|
||||
super(dateCalculator);
|
||||
this.setupDragEventListeners();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ export class EventRenderingService {
|
|||
}
|
||||
|
||||
// Use cached strategy to render events in the specific container
|
||||
this.strategy.renderEvents(events, context.container, calendarConfig);
|
||||
this.strategy.renderEvents(events, context.container);
|
||||
|
||||
// Emit EVENTS_RENDERED event for filtering system
|
||||
this.eventBus.emit(CoreEvents.EVENTS_RENDERED, {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { CalendarConfig } from '../core/CalendarConfig';
|
||||
import { calendarConfig } from '../core/CalendarConfig';
|
||||
import { ResourceCalendarData, CalendarView } from '../types/CalendarTypes';
|
||||
import { CalendarTypeFactory } from '../factories/CalendarTypeFactory';
|
||||
import { HeaderRenderContext } from './HeaderRenderer';
|
||||
|
|
@ -11,14 +11,12 @@ import { DateCalculator } from '../utils/DateCalculator';
|
|||
* Optimized to reduce redundant DOM operations and improve performance
|
||||
*/
|
||||
export class GridRenderer {
|
||||
private config: CalendarConfig;
|
||||
private headerEventListener: ((event: Event) => void) | null = null;
|
||||
private cachedGridContainer: HTMLElement | null = null;
|
||||
private cachedCalendarHeader: HTMLElement | null = null;
|
||||
private cachedTimeAxis: HTMLElement | null = null;
|
||||
|
||||
constructor(config: CalendarConfig) {
|
||||
this.config = config;
|
||||
constructor() {
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -83,7 +81,7 @@ export class GridRenderer {
|
|||
private createOptimizedTimeAxis(): HTMLElement {
|
||||
const timeAxis = document.createElement('swp-time-axis');
|
||||
const timeAxisContent = document.createElement('swp-time-axis-content');
|
||||
const gridSettings = this.config.getGridSettings();
|
||||
const gridSettings = calendarConfig.getGridSettings();
|
||||
const startHour = gridSettings.dayStartHour;
|
||||
const endHour = gridSettings.dayEndHour;
|
||||
|
||||
|
|
@ -146,12 +144,12 @@ export class GridRenderer {
|
|||
resourceData: ResourceCalendarData | null,
|
||||
view: CalendarView
|
||||
): void {
|
||||
const calendarType = this.config.getCalendarMode();
|
||||
const calendarType = calendarConfig.getCalendarMode();
|
||||
const headerRenderer = CalendarTypeFactory.getHeaderRenderer(calendarType);
|
||||
|
||||
const context: HeaderRenderContext = {
|
||||
currentWeek: currentDate, // HeaderRenderer expects currentWeek property
|
||||
config: this.config,
|
||||
config: calendarConfig,
|
||||
resourceData: resourceData
|
||||
};
|
||||
|
||||
|
|
@ -173,12 +171,12 @@ export class GridRenderer {
|
|||
resourceData: ResourceCalendarData | null,
|
||||
view: CalendarView
|
||||
): void {
|
||||
const calendarType = this.config.getCalendarMode();
|
||||
const calendarType = calendarConfig.getCalendarMode();
|
||||
const columnRenderer = CalendarTypeFactory.getColumnRenderer(calendarType);
|
||||
|
||||
const context: ColumnRenderContext = {
|
||||
currentWeek: currentDate, // ColumnRenderer expects currentWeek property
|
||||
config: this.config,
|
||||
config: calendarConfig,
|
||||
resourceData: resourceData
|
||||
};
|
||||
|
||||
|
|
@ -260,7 +258,7 @@ export class GridRenderer {
|
|||
}
|
||||
|
||||
// Get header renderer once and cache
|
||||
const calendarType = this.config.getCalendarMode();
|
||||
const calendarType = calendarConfig.getCalendarMode();
|
||||
const headerRenderer = CalendarTypeFactory.getHeaderRenderer(calendarType);
|
||||
|
||||
eventBus.emit('header:mouseover', {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { CalendarConfig } from '../core/CalendarConfig';
|
||||
import { calendarConfig } from '../core/CalendarConfig';
|
||||
import { ResourceCalendarData } from '../types/CalendarTypes';
|
||||
|
||||
/**
|
||||
|
|
@ -6,10 +6,7 @@ import { ResourceCalendarData } from '../types/CalendarTypes';
|
|||
* Separated from GridManager to follow Single Responsibility Principle
|
||||
*/
|
||||
export class GridStyleManager {
|
||||
private config: CalendarConfig;
|
||||
|
||||
constructor(config: CalendarConfig) {
|
||||
this.config = config;
|
||||
constructor() {
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -17,9 +14,9 @@ export class GridStyleManager {
|
|||
*/
|
||||
public updateGridStyles(resourceData: ResourceCalendarData | null = null): void {
|
||||
const root = document.documentElement;
|
||||
const gridSettings = this.config.getGridSettings();
|
||||
const gridSettings = calendarConfig.getGridSettings();
|
||||
const calendar = document.querySelector('swp-calendar') as HTMLElement;
|
||||
const calendarType = this.config.getCalendarMode();
|
||||
const calendarType = calendarConfig.getCalendarMode();
|
||||
|
||||
// Set CSS variables for time and grid measurements
|
||||
this.setTimeVariables(root, gridSettings);
|
||||
|
|
@ -58,8 +55,8 @@ export class GridStyleManager {
|
|||
if (calendarType === 'resource' && resourceData) {
|
||||
return resourceData.resources.length;
|
||||
} else if (calendarType === 'date') {
|
||||
const dateSettings = this.config.getDateViewSettings();
|
||||
const workWeekSettings = this.config.getWorkWeekSettings();
|
||||
const dateSettings = calendarConfig.getDateViewSettings();
|
||||
const workWeekSettings = calendarConfig.getWorkWeekSettings();
|
||||
|
||||
switch (dateSettings.period) {
|
||||
case 'day':
|
||||
|
|
@ -73,7 +70,7 @@ export class GridStyleManager {
|
|||
}
|
||||
}
|
||||
|
||||
return this.config.getWorkWeekSettings().totalDays; // Default to work week
|
||||
return calendarConfig.getWorkWeekSettings().totalDays; // Default to work week
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { IEventBus } from '../types/CalendarTypes';
|
||||
import { CoreEvents } from '../constants/CoreEvents';
|
||||
import { CalendarConfig } from '../core/CalendarConfig';
|
||||
import { calendarConfig } from '../core/CalendarConfig';
|
||||
import { DateCalculator } from '../utils/DateCalculator';
|
||||
import { EventRenderingService } from './EventRendererManager';
|
||||
import { CalendarTypeFactory } from '../factories/CalendarTypeFactory';
|
||||
|
|
@ -12,7 +12,6 @@ import { eventBus } from '../core/EventBus';
|
|||
*/
|
||||
export class NavigationRenderer {
|
||||
private eventBus: IEventBus;
|
||||
private config: CalendarConfig;
|
||||
private dateCalculator: DateCalculator;
|
||||
private eventRenderer: EventRenderingService;
|
||||
|
||||
|
|
@ -20,11 +19,10 @@ export class NavigationRenderer {
|
|||
private cachedWeekNumberElement: HTMLElement | null = null;
|
||||
private cachedDateRangeElement: HTMLElement | null = null;
|
||||
|
||||
constructor(eventBus: IEventBus, config: CalendarConfig, eventRenderer: EventRenderingService) {
|
||||
constructor(eventBus: IEventBus, eventRenderer: EventRenderingService) {
|
||||
this.eventBus = eventBus;
|
||||
this.config = config;
|
||||
this.eventRenderer = eventRenderer;
|
||||
DateCalculator.initialize(config);
|
||||
DateCalculator.initialize(calendarConfig);
|
||||
this.dateCalculator = new DateCalculator();
|
||||
this.setupEventListeners();
|
||||
}
|
||||
|
|
@ -61,7 +59,7 @@ export class NavigationRenderer {
|
|||
* Setup event listeners for DOM updates
|
||||
*/
|
||||
private setupEventListeners(): void {
|
||||
this.eventBus.on(CoreEvents.WEEK_CHANGED, (event: Event) => {
|
||||
this.eventBus.on(CoreEvents.PERIOD_INFO_UPDATE, (event: Event) => {
|
||||
const customEvent = event as CustomEvent;
|
||||
const { weekNumber, dateRange } = customEvent.detail;
|
||||
this.updateWeekInfoInDOM(weekNumber, dateRange);
|
||||
|
|
@ -201,7 +199,7 @@ export class NavigationRenderer {
|
|||
});
|
||||
|
||||
// Always ensure all-day containers exist for all days
|
||||
const headerRenderer = CalendarTypeFactory.getHeaderRenderer(this.config.getCalendarMode());
|
||||
const headerRenderer = CalendarTypeFactory.getHeaderRenderer(calendarConfig.getCalendarMode());
|
||||
headerRenderer.ensureAllDayContainers(header as HTMLElement);
|
||||
|
||||
// Add event delegation listener for drag & drop functionality
|
||||
|
|
@ -256,7 +254,7 @@ export class NavigationRenderer {
|
|||
|
||||
|
||||
// Get the header renderer for addToAllDay functionality
|
||||
const calendarType = this.config.getCalendarMode();
|
||||
const calendarType = calendarConfig.getCalendarMode();
|
||||
const headerRenderer = CalendarTypeFactory.getHeaderRenderer(calendarType);
|
||||
|
||||
eventBus.emit('header:mouseover', {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue