diff --git a/src/managers/EventRenderer.ts b/src/managers/EventRenderer.ts index f977cd4..b2c6926 100644 --- a/src/managers/EventRenderer.ts +++ b/src/managers/EventRenderer.ts @@ -54,27 +54,28 @@ export class EventRenderer { private renderEvents(events: CalendarEvent[]): void { console.log('EventRenderer: renderEvents called with', events.length, 'events'); + console.log('EventRenderer: All events:', events.map(e => ({ title: e.title, allDay: e.allDay, start: e.start }))); // Clear existing events first this.clearEvents(); // Get current week dates for filtering const currentWeekDates = this.getCurrentWeekDates(); - console.log('EventRenderer: Current week dates:', currentWeekDates.map(d => DateUtils.formatDate(d))); - - // Filter events for current week + // Filter events for current week and exclude all-day events (handled by GridManager) const currentWeekEvents = events.filter(event => { + // Skip all-day events - they are handled by GridManager + if (event.allDay) { + return false; + } + const eventDate = new Date(event.start); const eventDateStr = DateUtils.formatDate(eventDate); const isInCurrentWeek = currentWeekDates.some(weekDate => DateUtils.formatDate(weekDate) === eventDateStr ); - console.log('EventRenderer: Event', event.title, 'on', eventDateStr, 'is in current week:', isInCurrentWeek); return isInCurrentWeek; }); - console.log('EventRenderer: Rendering', currentWeekEvents.length, 'events for current week'); - // Render each event in the correct day column currentWeekEvents.forEach(event => { const eventDate = new Date(event.start); @@ -83,7 +84,6 @@ export class EventRenderer { if (dayColumn) { const eventsLayer = dayColumn.querySelector('swp-events-layer'); if (eventsLayer) { - console.log('EventRenderer: Rendering event', event.title, 'in day column for', DateUtils.formatDate(eventDate)); this.renderEvent(event, eventsLayer); } else { console.warn('EventRenderer: No events layer found in day column for', DateUtils.formatDate(eventDate)); @@ -97,6 +97,7 @@ export class EventRenderer { this.eventBus.emit(EventTypes.EVENT_RENDERED, { count: currentWeekEvents.length }); + } /** @@ -138,6 +139,15 @@ export class EventRenderer { eventElement.style.left = '2px'; eventElement.style.right = '2px'; eventElement.style.zIndex = '10'; + + // Style the event element + eventElement.style.backgroundColor = event.metadata?.color || '#3498db'; + eventElement.style.color = 'white'; + eventElement.style.fontSize = '12px'; + eventElement.style.padding = '2px 4px'; + eventElement.style.borderRadius = '3px'; + eventElement.style.overflow = 'hidden'; + eventElement.style.cursor = 'pointer'; // Format time for display const startTime = this.formatTime(event.start); @@ -153,17 +163,19 @@ export class EventRenderer { this.addEventListeners(eventElement, event); container.appendChild(eventElement); + + // Event successfully rendered } private calculateEventPosition(event: CalendarEvent): { top: number; height: number } { const startDate = new Date(event.start); const endDate = new Date(event.end); - // Use dayStartHour to match time-axis positioning - const dayStartHour = calendarConfig.get('dayStartHour'); // 0 (midnight) + // Use dayStartHour to match time-axis positioning - this is the visible start hour (6 AM) + const dayStartHour = calendarConfig.get('dayStartHour'); // 6 (6 AM) const hourHeight = calendarConfig.get('hourHeight'); - // Calculate minutes from day start (midnight) + // Calculate minutes from visible day start (6 AM, not midnight) const eventHour = startDate.getHours(); const eventMinutes = startDate.getMinutes(); const startMinutes = (eventHour - dayStartHour) * 60 + eventMinutes; @@ -171,29 +183,10 @@ export class EventRenderer { // Calculate duration in minutes const duration = (endDate.getTime() - startDate.getTime()) / (1000 * 60); - // Convert to pixels - this gives absolute position from top of time-grid - const absoluteTop = startMinutes * (hourHeight / 60); + // Convert to pixels - position relative to visible time-grid (starts at dayStartHour) + const top = startMinutes * (hourHeight / 60); const height = duration * (hourHeight / 60); - // Get current scroll position to adjust for viewport - const scrollableContent = document.querySelector('swp-scrollable-content') as HTMLElement; - const scrollTop = scrollableContent ? scrollableContent.scrollTop : 0; - - // Calculate relative position within the visible viewport - // Events are positioned relative to their day-column, not the scrollable content - // So we use the absolute position directly - const top = absoluteTop; - - console.log('EventRenderer: Position calculation for', event.title, { - eventTime: `${eventHour}:${eventMinutes.toString().padStart(2, '0')}`, - dayStartHour, - startMinutes, - duration, - absoluteTop, - scrollTop, - finalTop: top, - height - }); return { top, height }; } diff --git a/src/managers/GridManager.ts b/src/managers/GridManager.ts index 91b7be1..e2f1bed 100644 --- a/src/managers/GridManager.ts +++ b/src/managers/GridManager.ts @@ -117,16 +117,21 @@ export class GridManager { return; } - // Clear existing grid and rebuild POC structure - this.grid.innerHTML = ''; - - // Create POC structure: header-spacer + time-axis + week-container + right-column + bottom spacers - this.createHeaderSpacer(); - this.createRightHeaderSpacer(); - this.createTimeAxis(); - this.createWeekContainer(); - this.createRightColumn(); - this.createBottomRow(); + // 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 + this.createHeaderSpacer(); + this.createRightHeaderSpacer(); + this.createTimeAxis(); + this.createWeekContainer(); + this.createRightColumn(); + this.createBottomRow(); + } else { + console.log('GridManager: Re-render - updating existing structure'); + // Just update the week header for all-day events + this.updateWeekHeader(); + } console.log('GridManager: Grid rendered successfully with POC structure'); } @@ -269,6 +274,26 @@ export class GridManager { this.updateSpacerHeights(); } + /** + * Update only the week header (for all-day events) without rebuilding entire grid + */ + private updateWeekHeader(): void { + if (!this.grid || !this.currentWeek) return; + + const weekHeader = this.grid.querySelector('swp-week-header'); + if (!weekHeader) return; + + // Clear existing all-day events but keep day headers + const allDayEvents = weekHeader.querySelectorAll('swp-allday-event'); + allDayEvents.forEach(event => event.remove()); + + // Re-render all-day events + this.renderAllDayEvents(weekHeader as HTMLElement); + + // Update spacer heights + this.updateSpacerHeights(); + } + /** * Update all-day events data and re-render if needed */ @@ -289,9 +314,9 @@ export class GridManager { console.log('GridManager: Updated all-day events:', this.allDayEvents.length); - // Re-render if grid is already rendered + // Update only the week header if grid is already rendered if (this.grid && this.grid.children.length > 0) { - this.render(); + this.updateWeekHeader(); } } diff --git a/wwwroot/css/calendar-layout-css.css b/wwwroot/css/calendar-layout-css.css index 949bad9..bf31c12 100644 --- a/wwwroot/css/calendar-layout-css.css +++ b/wwwroot/css/calendar-layout-css.css @@ -370,6 +370,9 @@ swp-day-column:last-child { swp-events-layer { position: absolute; inset: 0; + display: block; + z-index: var(--z-event); + pointer-events: none; /* Allow clicks to pass through to day column */ } swp-event {