Major refactorering to get a hold on all these events

This commit is contained in:
Janus Knudsen 2025-08-09 00:31:44 +02:00
parent 2a766cf685
commit 59b3c64c55
18 changed files with 1901 additions and 357 deletions

View file

@ -3,6 +3,7 @@
import { eventBus } from '../core/EventBus';
import { calendarConfig } from '../core/CalendarConfig';
import { EventTypes } from '../constants/EventTypes';
import { StateEvents } from '../types/CalendarState';
import { DateUtils } from '../utils/DateUtils';
import { ResourceCalendarData } from '../types/CalendarTypes';
import { CalendarTypeFactory } from '../factories/CalendarTypeFactory';
@ -29,13 +30,11 @@ export class GridManager {
private resourceData: ResourceCalendarData | null = null; // Store resource data for resource calendar
constructor() {
console.log('🏗️ GridManager: Constructor called');
this.init();
}
private init(): void {
// Initialize the factory
CalendarTypeFactory.initialize();
this.findElements();
this.subscribeToEvents();
@ -43,8 +42,8 @@ export class GridManager {
if (!this.currentWeek) {
this.currentWeek = this.getWeekStart(new Date());
console.log('GridManager: Set initial currentWeek to', this.currentWeek);
// Render initial grid
this.render();
// Don't render immediately - wait for proper initialization event
console.log('GridManager: Waiting for initialization complete before rendering');
}
}
@ -58,6 +57,13 @@ export class GridManager {
}
private subscribeToEvents(): void {
// Listen for state-driven rendering start event
eventBus.on(StateEvents.RENDERING_STARTED, (e: Event) => {
const detail = (e as CustomEvent).detail;
console.log('GridManager: Received RENDERING_STARTED, starting DOM structure setup');
this.render();
});
// Re-render grid on config changes
eventBus.on(EventTypes.CONFIG_UPDATE, (e: Event) => {
const detail = (e as CustomEvent).detail;
@ -96,18 +102,15 @@ export class GridManager {
this.updateAllDayEvents(detail.events);
});
// Handle resource data loaded
eventBus.on(EventTypes.RESOURCE_DATA_LOADED, (e: Event) => {
// Handle data loaded for resource mode
eventBus.on(StateEvents.DATA_LOADED, (e: Event) => {
const detail = (e as CustomEvent).detail;
this.resourceData = detail.resourceData;
console.log(`GridManager: Received resource data for ${this.resourceData!.resources.length} resources`);
console.log(`GridManager: Received DATA_LOADED`);
// Update grid styles with new column count immediately
this.updateGridStyles();
// Re-render if grid is already rendered
if (this.grid && this.grid.children.length > 0) {
this.render();
if (detail.data && detail.data.calendarMode === 'resource') {
// Resource data will be passed in the state event
// For now just update grid styles
this.updateGridStyles();
}
});
@ -124,12 +127,54 @@ export class GridManager {
this.updateGridStyles();
this.renderGrid();
// Emit grid rendered event
// Emit state-driven grid rendered event
const columnCount = this.getColumnCount();
console.log('GridManager: Emitting GRID_RENDERED event');
eventBus.emit(EventTypes.GRID_RENDERED);
eventBus.emit(StateEvents.GRID_RENDERED, {
type: StateEvents.GRID_RENDERED,
component: 'GridManager',
timestamp: Date.now(),
data: {
columnCount,
gridMode: calendarConfig.getCalendarMode(),
domElementsCreated: [
'swp-header-spacer',
'swp-time-axis',
'swp-grid-container',
'swp-calendar-header',
'swp-scrollable-content'
]
},
metadata: {
phase: 'rendering'
}
});
console.log('GridManager: GRID_RENDERED event emitted');
}
/**
* Get current column count based on calendar mode
*/
private getColumnCount(): number {
const calendarType = calendarConfig.getCalendarMode();
if (calendarType === 'resource' && this.resourceData) {
return this.resourceData.resources.length;
} else if (calendarType === 'date') {
const dateSettings = calendarConfig.getDateViewSettings();
switch (dateSettings.period) {
case 'day': return 1;
case 'week': return dateSettings.weekDays;
case 'month': return 7;
default: return dateSettings.weekDays;
}
}
return 7; // Default
}
/**
* Render the complete grid using POC structure
*/
@ -148,10 +193,10 @@ export class GridManager {
// Only clear and rebuild if grid is empty (first render)
if (this.grid.children.length === 0) {
console.log('GridManager: First render - creating grid structure');
// Create POC structure: header-spacer + time-axis + week-container + right-column + bottom spacers
// Create POC structure: header-spacer + time-axis + grid-container
this.createHeaderSpacer();
this.createTimeAxis();
this.createWeekContainer();
this.createGridContainer();
} else {
console.log('GridManager: Re-render - updating existing structure');
// Just update the calendar header for all-day events
@ -172,15 +217,16 @@ export class GridManager {
}
/**
* Create time axis (positioned beside week container) like in POC
* Create time axis (positioned beside grid container) like in POC
*/
private createTimeAxis(): void {
if (!this.grid) return;
const timeAxis = document.createElement('swp-time-axis');
const timeAxisContent = document.createElement('swp-time-axis-content');
const startHour = calendarConfig.get('dayStartHour');
const endHour = calendarConfig.get('dayEndHour');
const gridSettings = calendarConfig.getGridSettings();
const startHour = gridSettings.dayStartHour;
const endHour = gridSettings.dayEndHour;
console.log('GridManager: Creating time axis - startHour:', startHour, 'endHour:', endHour);
for (let hour = startHour; hour < endHour; hour++) {
@ -196,17 +242,17 @@ export class GridManager {
}
/**
* Create week container with header and scrollable content using Strategy Pattern
* Create grid container with header and scrollable content using Strategy Pattern
*/
private createWeekContainer(): void {
private createGridContainer(): void {
if (!this.grid || !this.currentWeek) return;
const weekContainer = document.createElement('swp-grid-container');
const gridContainer = document.createElement('swp-grid-container');
// Create calendar header using Strategy Pattern
const calendarHeader = document.createElement('swp-calendar-header');
this.renderCalendarHeader(calendarHeader);
weekContainer.appendChild(calendarHeader);
gridContainer.appendChild(calendarHeader);
// Create scrollable content
const scrollableContent = document.createElement('swp-scrollable-content');
@ -222,9 +268,9 @@ export class GridManager {
timeGrid.appendChild(columnContainer);
scrollableContent.appendChild(timeGrid);
weekContainer.appendChild(scrollableContent);
gridContainer.appendChild(scrollableContent);
this.grid.appendChild(weekContainer);
this.grid.appendChild(gridContainer);
}
/**
@ -233,7 +279,7 @@ export class GridManager {
private renderCalendarHeader(calendarHeader: HTMLElement): void {
if (!this.currentWeek) return;
const calendarType = calendarConfig.getCalendarType();
const calendarType = calendarConfig.getCalendarMode();
const headerRenderer = CalendarTypeFactory.getHeaderRenderer(calendarType);
const context: HeaderRenderContext = {
@ -256,7 +302,7 @@ export class GridManager {
if (!this.currentWeek) return;
console.log('GridManager: renderColumnContainer called');
const calendarType = calendarConfig.getCalendarType();
const calendarType = calendarConfig.getCalendarMode();
const columnRenderer = CalendarTypeFactory.getColumnRenderer(calendarType);
const context: ColumnRenderContext = {
@ -330,30 +376,44 @@ export class GridManager {
*/
private updateGridStyles(): void {
const root = document.documentElement;
const config = calendarConfig.getAll();
const gridSettings = calendarConfig.getGridSettings();
const calendar = document.querySelector('swp-calendar') as HTMLElement;
const calendarType = calendarConfig.getCalendarType();
const calendarType = calendarConfig.getCalendarMode();
// Set CSS variables
root.style.setProperty('--hour-height', `${config.hourHeight}px`);
root.style.setProperty('--minute-height', `${config.hourHeight / 60}px`);
root.style.setProperty('--snap-interval', config.snapInterval.toString());
root.style.setProperty('--day-start-hour', config.dayStartHour.toString());
root.style.setProperty('--day-end-hour', config.dayEndHour.toString());
root.style.setProperty('--work-start-hour', config.workStartHour.toString());
root.style.setProperty('--work-end-hour', config.workEndHour.toString());
root.style.setProperty('--hour-height', `${gridSettings.hourHeight}px`);
root.style.setProperty('--minute-height', `${gridSettings.hourHeight / 60}px`);
root.style.setProperty('--snap-interval', gridSettings.snapInterval.toString());
root.style.setProperty('--day-start-hour', gridSettings.dayStartHour.toString());
root.style.setProperty('--day-end-hour', gridSettings.dayEndHour.toString());
root.style.setProperty('--work-start-hour', gridSettings.workStartHour.toString());
root.style.setProperty('--work-end-hour', gridSettings.workEndHour.toString());
// Set number of columns based on calendar type
let columnCount = 7; // Default for date mode
if (calendarType === 'resource' && this.resourceData) {
columnCount = this.resourceData.resources.length;
} else if (calendarType === 'date') {
columnCount = config.weekDays;
const dateSettings = calendarConfig.getDateViewSettings();
// Calculate columns based on view type - business logic moved from config
switch (dateSettings.period) {
case 'day':
columnCount = 1;
break;
case 'week':
columnCount = dateSettings.weekDays;
break;
case 'month':
columnCount = 7;
break;
default:
columnCount = dateSettings.weekDays;
}
}
root.style.setProperty('--grid-columns', columnCount.toString());
// Set day column min width based on fitToWidth setting
if (config.fitToWidth) {
if (gridSettings.fitToWidth) {
root.style.setProperty('--day-column-min-width', '50px'); // Small min-width allows columns to fit available space
} else {
root.style.setProperty('--day-column-min-width', '250px'); // Default min-width for horizontal scroll mode
@ -361,7 +421,7 @@ export class GridManager {
// Set fitToWidth data attribute for CSS targeting
if (calendar) {
calendar.setAttribute('data-fit-to-width', config.fitToWidth.toString());
calendar.setAttribute('data-fit-to-width', gridSettings.fitToWidth.toString());
}
console.log('GridManager: Updated grid styles with', columnCount, 'columns for', calendarType, 'calendar');
@ -419,10 +479,11 @@ export class GridManager {
const rect = dayColumn.getBoundingClientRect();
const y = event.clientY - rect.top;
const hourHeight = calendarConfig.get('hourHeight');
const gridSettings = calendarConfig.getGridSettings();
const hourHeight = gridSettings.hourHeight;
const minuteHeight = hourHeight / 60;
const snapInterval = calendarConfig.get('snapInterval');
const dayStartHour = calendarConfig.get('dayStartHour');
const snapInterval = gridSettings.snapInterval;
const dayStartHour = gridSettings.dayStartHour;
// Calculate total minutes from day start
let totalMinutes = Math.floor(y / minuteHeight);
@ -446,8 +507,9 @@ export class GridManager {
scrollToHour(hour: number): void {
if (!this.grid) return;
const hourHeight = calendarConfig.get('hourHeight');
const dayStartHour = calendarConfig.get('dayStartHour');
const gridSettings = calendarConfig.getGridSettings();
const hourHeight = gridSettings.hourHeight;
const dayStartHour = gridSettings.dayStartHour;
const headerHeight = 80; // Header row height
const scrollTop = headerHeight + ((hour - dayStartHour) * hourHeight);