Refactors grid creation to GridRenderer

Centralizes grid creation logic within the GridRenderer
for better code organization and reusability. This change
moves the grid rendering functionality from
NavigationRenderer to GridRenderer and updates the
NavigationManager to use the new GridRenderer.
This commit is contained in:
Janus C. H. Knudsen 2025-09-25 17:46:49 +02:00
parent e20e23651c
commit 710dda4c24
3 changed files with 124 additions and 105 deletions

View file

@ -3,6 +3,7 @@ import { EventRenderingService } from '../renderers/EventRendererManager';
import { DateCalculator } from '../utils/DateCalculator';
import { CoreEvents } from '../constants/CoreEvents';
import { NavigationRenderer } from '../renderers/NavigationRenderer';
import { GridRenderer } from '../renderers/GridRenderer';
import { calendarConfig } from '../core/CalendarConfig';
/**
@ -12,6 +13,7 @@ import { calendarConfig } from '../core/CalendarConfig';
export class NavigationManager {
private eventBus: IEventBus;
private navigationRenderer: NavigationRenderer;
private gridRenderer: GridRenderer;
private dateCalculator: DateCalculator;
private currentWeek: Date;
private targetWeek: Date;
@ -22,6 +24,7 @@ export class NavigationManager {
DateCalculator.initialize(calendarConfig);
this.dateCalculator = new DateCalculator();
this.navigationRenderer = new NavigationRenderer(eventBus, eventRenderer);
this.gridRenderer = new GridRenderer();
this.currentWeek = DateCalculator.getISOWeekStart(new Date());
this.targetWeek = new Date(this.currentWeek);
this.init();
@ -206,8 +209,14 @@ export class NavigationManager {
let newGrid: HTMLElement;
console.group('🔧 NavigationManager.refactored');
console.log('Calling GridRenderer instead of NavigationRenderer');
console.log('Target week:', targetWeek);
// Always create a fresh container for consistent behavior
newGrid = this.navigationRenderer.renderContainer(container, targetWeek);
newGrid = this.gridRenderer.createNavigationGrid(container, targetWeek);
console.groupEnd();
// Clear any existing transforms before animation

View file

@ -3,6 +3,8 @@ import { ResourceCalendarData, CalendarView } from '../types/CalendarTypes';
import { CalendarTypeFactory } from '../factories/CalendarTypeFactory';
import { ColumnRenderContext } from './ColumnRenderer';
import { eventBus } from '../core/EventBus';
import { DateCalculator } from '../utils/DateCalculator';
import { CoreEvents } from '../constants/CoreEvents';
/**
* GridRenderer - Centralized DOM rendering for calendar grid
@ -242,4 +244,112 @@ export class GridRenderer {
(this as any).gridBodyEventListener = null;
(this as any).cachedColumnContainer = null;
}
/**
* Create navigation grid container for slide animations
* Moved from NavigationRenderer to centralize grid creation
*/
public createNavigationGrid(parentContainer: HTMLElement, weekStart: Date): HTMLElement {
console.group('🔧 GridRenderer.createNavigationGrid');
console.log('Week start:', weekStart);
console.log('Parent container:', parentContainer);
const weekEnd = DateCalculator.addDays(weekStart, 6);
// Create new grid container
const newGrid = document.createElement('swp-grid-container');
newGrid.innerHTML = `
<swp-calendar-header></swp-calendar-header>
<swp-scrollable-content>
<swp-time-grid>
<swp-grid-lines></swp-grid-lines>
<swp-day-columns></swp-day-columns>
</swp-time-grid>
</swp-scrollable-content>
`;
// Position new grid - NO transform here, let Animation API handle it
newGrid.style.position = 'absolute';
newGrid.style.top = '0';
newGrid.style.left = '0';
newGrid.style.width = '100%';
newGrid.style.height = '100%';
// Add to parent container
parentContainer.appendChild(newGrid);
this.renderWeekContentInNavigationGrid(newGrid, weekStart);
console.log('Grid created:', newGrid);
console.log('Emitting GRID_RENDERED');
eventBus.emit(CoreEvents.GRID_RENDERED, {
container: newGrid, // Specific grid container, not parent
currentDate: weekStart,
startDate: weekStart,
endDate: weekEnd,
isNavigation: true // Flag to indicate this is navigation rendering
});
console.groupEnd();
return newGrid;
}
/**
* Render week content in navigation grid container
* Moved from NavigationRenderer
*/
private renderWeekContentInNavigationGrid(gridContainer: HTMLElement, weekStart: Date): void {
console.group('🔧 GridRenderer.renderWeekContentInNavigationGrid');
console.log('Grid container:', gridContainer);
console.log('Week start:', weekStart);
const header = gridContainer.querySelector('swp-calendar-header');
const dayColumns = gridContainer.querySelector('swp-day-columns');
if (!header || !dayColumns) {
console.log('Missing header or dayColumns');
console.groupEnd();
return;
}
// Clear existing content
header.innerHTML = '';
dayColumns.innerHTML = '';
// Get dates using DateCalculator
const dates = DateCalculator.getWorkWeekDates(weekStart);
// Render headers for target week
dates.forEach((date, i) => {
const headerElement = document.createElement('swp-day-header');
if (DateCalculator.isToday(date)) {
headerElement.dataset.today = 'true';
}
const dayName = DateCalculator.getDayName(date, 'short');
headerElement.innerHTML = `
<swp-day-name>${dayName}</swp-day-name>
<swp-day-date>${date.getDate()}</swp-day-date>
`;
headerElement.dataset.date = DateCalculator.formatISODate(date);
header.appendChild(headerElement);
});
// Render day columns for target week
dates.forEach(date => {
const column = document.createElement('swp-day-column');
column.dataset.date = DateCalculator.formatISODate(date);
const eventsLayer = document.createElement('swp-events-layer');
column.appendChild(eventsLayer);
dayColumns.appendChild(column);
});
console.log('Week content rendered');
console.groupEnd();
}
}

View file

@ -1,10 +1,6 @@
import { IEventBus } from '../types/CalendarTypes';
import { CoreEvents } from '../constants/CoreEvents';
import { calendarConfig } from '../core/CalendarConfig';
import { DateCalculator } from '../utils/DateCalculator';
import { EventRenderingService } from './EventRendererManager';
import { CalendarTypeFactory } from '../factories/CalendarTypeFactory';
import { HeaderReadyEventPayload } from '../types/EventTypes';
/**
* NavigationRenderer - Handles DOM rendering for navigation containers
@ -19,7 +15,6 @@ export class NavigationRenderer {
constructor(eventBus: IEventBus, eventRenderer: EventRenderingService) {
this.eventBus = eventBus;
DateCalculator.initialize(calendarConfig);
this.setupEventListeners();
}
@ -116,105 +111,10 @@ export class NavigationRenderer {
});
});
}
/**
* Render a complete container with content and events
*/
public renderContainer(parentContainer: HTMLElement, weekStart: Date): HTMLElement {
const weekEnd = DateCalculator.addDays(weekStart, 6);
// Create new grid container
const newGrid = document.createElement('swp-grid-container');
newGrid.innerHTML = `
<swp-calendar-header></swp-calendar-header>
<swp-scrollable-content>
<swp-time-grid>
<swp-grid-lines></swp-grid-lines>
<swp-day-columns></swp-day-columns>
</swp-time-grid>
</swp-scrollable-content>
`;
// Position new grid - NO transform here, let Animation API handle it
newGrid.style.position = 'absolute';
newGrid.style.top = '0';
newGrid.style.left = '0';
newGrid.style.width = '100%';
newGrid.style.height = '100%';
// Add to parent container
parentContainer.appendChild(newGrid);
this.renderWeekContentInContainer(newGrid, weekStart);
this.eventBus.emit(CoreEvents.GRID_RENDERED, {
container: newGrid, // Specific grid container, not parent
currentDate: weekStart,
startDate: weekStart,
endDate: weekEnd,
isNavigation: true // Flag to indicate this is navigation rendering
});
return newGrid;
}
/**
* Render week content in specific container
*/
private renderWeekContentInContainer(gridContainer: HTMLElement, weekStart: Date): void {
const header = gridContainer.querySelector('swp-calendar-header');
const dayColumns = gridContainer.querySelector('swp-day-columns');
if (!header || !dayColumns) return;
// Clear existing content
header.innerHTML = '';
dayColumns.innerHTML = '';
// Get dates using DateCalculator
const dates = DateCalculator.getWorkWeekDates(weekStart);
// Render headers for target week
dates.forEach((date, i) => {
const headerElement = document.createElement('swp-day-header');
if (DateCalculator.isToday(date)) {
headerElement.dataset.today = 'true';
}
const dayName = DateCalculator.getDayName(date, 'short');
headerElement.innerHTML = `
<swp-day-name>${dayName}</swp-day-name>
<swp-day-date>${date.getDate()}</swp-day-date>
`;
headerElement.dataset.date = DateCalculator.formatISODate(date);
header.appendChild(headerElement);
});
// Render day columns for target week
dates.forEach(date => {
const column = document.createElement('swp-day-column');
column.dataset.date = DateCalculator.formatISODate(date);
const eventsLayer = document.createElement('swp-events-layer');
column.appendChild(eventsLayer);
dayColumns.appendChild(column);
});
// Emit header:ready after header has been populated with date elements
const weekEnd = DateCalculator.addDays(weekStart, 6);
const payload: HeaderReadyEventPayload = {
headerElement: header as HTMLElement,
startDate: weekStart,
endDate: weekEnd,
isNavigation: true
};
//this.eventBus.emit('header:ready', payload);
console.group('🔧 NavigationRenderer.cleanup');
console.log('Removed methods: renderContainer, renderWeekContentInContainer');
console.log('Grid creation now handled by GridRenderer');
console.groupEnd();
}
/**