Refactors event handling and grid rendering

Improves calendar performance and data flow by streamlining event emissions and grid rendering logic.

- Replaces generic CONFIG_UPDATE events with REFRESH_REQUESTED
  for more specific refresh triggers.
- Removes redundant grid re-renders on DATE_CHANGED and
  WEEK_CHANGED events, delegating navigation to NavigationManager.
- Introduces VIEW_CHANGED and DATE_CHANGED events for calendar
  mode and date selection, respectively.
- NavigationManager now handles date validation.
- Moves rendering logic from NavigationManager to NavigationRenderer.
- Syncs scroll position based on PERIOD_CHANGED instead of
  NAVIGATION_ANIMATION_COMPLETE.

This change optimizes the calendar's responsiveness and reduces
unnecessary re-renders, leading to a smoother user experience.
This commit is contained in:
Janus Knudsen 2025-08-20 21:38:54 +02:00
parent 4b4dbdc0d6
commit 83c0ce801c
9 changed files with 59 additions and 47 deletions

View file

@ -24,7 +24,7 @@ export interface ColumnRenderContext {
* Date-based column renderer (original functionality)
*/
export class DateColumnRenderer implements ColumnRenderer {
private dateCalculator: DateCalculator;
private dateCalculator!: DateCalculator;
render(columnContainer: HTMLElement, context: ColumnRenderContext): void {
const { currentWeek, config } = context;

View file

@ -176,6 +176,7 @@ export class DateEventRenderer extends BaseEventRenderer {
const matches = eventDateStr === columnDate;
if (!matches) {
if(event.title == 'Architecture Planning')
console.log(`DateEventRenderer: Event ${event.title} (${eventDateStr}) does not match column (${columnDate})`);
}

View file

@ -25,7 +25,7 @@ export interface HeaderRenderContext {
* Date-based header renderer (original functionality)
*/
export class DateHeaderRenderer implements HeaderRenderer {
private dateCalculator: DateCalculator;
private dateCalculator!: DateCalculator;
render(calendarHeader: HTMLElement, context: HeaderRenderContext): void {
const { currentWeek, config, allDayEvents = [] } = context;
@ -34,7 +34,7 @@ export class DateHeaderRenderer implements HeaderRenderer {
this.dateCalculator = new DateCalculator(config);
const dates = this.dateCalculator.getWorkWeekDates(currentWeek);
const weekDays = config.get('weekDays');
const weekDays = config.getDateViewSettings().weekDays;
const daysToShow = dates.slice(0, weekDays);
daysToShow.forEach((date, index) => {
@ -62,7 +62,7 @@ export class DateHeaderRenderer implements HeaderRenderer {
const { currentWeek, config, allDayEvents = [] } = context;
const dates = this.dateCalculator.getWorkWeekDates(currentWeek);
const weekDays = config.get('weekDays');
const weekDays = config.getDateViewSettings().weekDays;
const daysToShow = dates.slice(0, weekDays);
// Process each all-day event to calculate its span

View file

@ -26,7 +26,7 @@ export class NavigationRenderer {
* Setup event listeners for DOM updates
*/
private setupEventListeners(): void {
this.eventBus.on(CoreEvents.WEEK_INFO_UPDATED, (event: Event) => {
this.eventBus.on(CoreEvents.WEEK_CHANGED, (event: Event) => {
const customEvent = event as CustomEvent;
const { weekNumber, dateRange } = customEvent.detail;
this.updateWeekInfoInDOM(weekNumber, dateRange);
@ -83,14 +83,16 @@ export class NavigationRenderer {
console.log('2. Rendering headers and columns...');
this.renderWeekContentInContainer(newGrid, weekStart);
console.log('3. Pre-rendering events synchronously...');
this.eventRenderer.renderEvents({
container: newGrid,
console.log('3. Emitting GRID_RENDERED for navigation container...');
this.eventBus.emit(CoreEvents.GRID_RENDERED, {
container: newGrid, // Specific grid container, not parent
currentDate: weekStart,
startDate: weekStart,
endDate: weekEnd
endDate: weekEnd,
isNavigation: true // Flag to indicate this is navigation rendering
});
console.log('✅ Container ready with pre-rendered events');
console.log('✅ Container ready with GRID_RENDERED event emitted');
console.groupEnd();
return newGrid;
}