Enhances event rendering and grid updates
Improves event rendering by adding styling, filtering out all-day events (handled by GridManager), and calculating accurate positioning within the time grid. Optimizes grid updates to avoid unnecessary rebuilding, instead updating only the week header for all-day events, leading to better performance.
This commit is contained in:
parent
7ac7e0f7f8
commit
dc5063729b
3 changed files with 64 additions and 43 deletions
|
|
@ -54,27 +54,28 @@ export class EventRenderer {
|
||||||
|
|
||||||
private renderEvents(events: CalendarEvent[]): void {
|
private renderEvents(events: CalendarEvent[]): void {
|
||||||
console.log('EventRenderer: renderEvents called with', events.length, 'events');
|
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
|
// Clear existing events first
|
||||||
this.clearEvents();
|
this.clearEvents();
|
||||||
|
|
||||||
// Get current week dates for filtering
|
// Get current week dates for filtering
|
||||||
const currentWeekDates = this.getCurrentWeekDates();
|
const currentWeekDates = this.getCurrentWeekDates();
|
||||||
console.log('EventRenderer: Current week dates:', currentWeekDates.map(d => DateUtils.formatDate(d)));
|
// Filter events for current week and exclude all-day events (handled by GridManager)
|
||||||
|
|
||||||
// Filter events for current week
|
|
||||||
const currentWeekEvents = events.filter(event => {
|
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 eventDate = new Date(event.start);
|
||||||
const eventDateStr = DateUtils.formatDate(eventDate);
|
const eventDateStr = DateUtils.formatDate(eventDate);
|
||||||
const isInCurrentWeek = currentWeekDates.some(weekDate =>
|
const isInCurrentWeek = currentWeekDates.some(weekDate =>
|
||||||
DateUtils.formatDate(weekDate) === eventDateStr
|
DateUtils.formatDate(weekDate) === eventDateStr
|
||||||
);
|
);
|
||||||
console.log('EventRenderer: Event', event.title, 'on', eventDateStr, 'is in current week:', isInCurrentWeek);
|
|
||||||
return isInCurrentWeek;
|
return isInCurrentWeek;
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log('EventRenderer: Rendering', currentWeekEvents.length, 'events for current week');
|
|
||||||
|
|
||||||
// Render each event in the correct day column
|
// Render each event in the correct day column
|
||||||
currentWeekEvents.forEach(event => {
|
currentWeekEvents.forEach(event => {
|
||||||
const eventDate = new Date(event.start);
|
const eventDate = new Date(event.start);
|
||||||
|
|
@ -83,7 +84,6 @@ export class EventRenderer {
|
||||||
if (dayColumn) {
|
if (dayColumn) {
|
||||||
const eventsLayer = dayColumn.querySelector('swp-events-layer');
|
const eventsLayer = dayColumn.querySelector('swp-events-layer');
|
||||||
if (eventsLayer) {
|
if (eventsLayer) {
|
||||||
console.log('EventRenderer: Rendering event', event.title, 'in day column for', DateUtils.formatDate(eventDate));
|
|
||||||
this.renderEvent(event, eventsLayer);
|
this.renderEvent(event, eventsLayer);
|
||||||
} else {
|
} else {
|
||||||
console.warn('EventRenderer: No events layer found in day column for', DateUtils.formatDate(eventDate));
|
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, {
|
this.eventBus.emit(EventTypes.EVENT_RENDERED, {
|
||||||
count: currentWeekEvents.length
|
count: currentWeekEvents.length
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -139,6 +140,15 @@ export class EventRenderer {
|
||||||
eventElement.style.right = '2px';
|
eventElement.style.right = '2px';
|
||||||
eventElement.style.zIndex = '10';
|
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
|
// Format time for display
|
||||||
const startTime = this.formatTime(event.start);
|
const startTime = this.formatTime(event.start);
|
||||||
const endTime = this.formatTime(event.end);
|
const endTime = this.formatTime(event.end);
|
||||||
|
|
@ -153,17 +163,19 @@ export class EventRenderer {
|
||||||
this.addEventListeners(eventElement, event);
|
this.addEventListeners(eventElement, event);
|
||||||
|
|
||||||
container.appendChild(eventElement);
|
container.appendChild(eventElement);
|
||||||
|
|
||||||
|
// Event successfully rendered
|
||||||
}
|
}
|
||||||
|
|
||||||
private calculateEventPosition(event: CalendarEvent): { top: number; height: number } {
|
private calculateEventPosition(event: CalendarEvent): { top: number; height: number } {
|
||||||
const startDate = new Date(event.start);
|
const startDate = new Date(event.start);
|
||||||
const endDate = new Date(event.end);
|
const endDate = new Date(event.end);
|
||||||
|
|
||||||
// Use dayStartHour to match time-axis positioning
|
// Use dayStartHour to match time-axis positioning - this is the visible start hour (6 AM)
|
||||||
const dayStartHour = calendarConfig.get('dayStartHour'); // 0 (midnight)
|
const dayStartHour = calendarConfig.get('dayStartHour'); // 6 (6 AM)
|
||||||
const hourHeight = calendarConfig.get('hourHeight');
|
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 eventHour = startDate.getHours();
|
||||||
const eventMinutes = startDate.getMinutes();
|
const eventMinutes = startDate.getMinutes();
|
||||||
const startMinutes = (eventHour - dayStartHour) * 60 + eventMinutes;
|
const startMinutes = (eventHour - dayStartHour) * 60 + eventMinutes;
|
||||||
|
|
@ -171,29 +183,10 @@ export class EventRenderer {
|
||||||
// Calculate duration in minutes
|
// Calculate duration in minutes
|
||||||
const duration = (endDate.getTime() - startDate.getTime()) / (1000 * 60);
|
const duration = (endDate.getTime() - startDate.getTime()) / (1000 * 60);
|
||||||
|
|
||||||
// Convert to pixels - this gives absolute position from top of time-grid
|
// Convert to pixels - position relative to visible time-grid (starts at dayStartHour)
|
||||||
const absoluteTop = startMinutes * (hourHeight / 60);
|
const top = startMinutes * (hourHeight / 60);
|
||||||
const height = duration * (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 };
|
return { top, height };
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -117,16 +117,21 @@ export class GridManager {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear existing grid and rebuild POC structure
|
// Only clear and rebuild if grid is empty (first render)
|
||||||
this.grid.innerHTML = '';
|
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 + week-container + right-column + bottom spacers
|
||||||
this.createHeaderSpacer();
|
this.createHeaderSpacer();
|
||||||
this.createRightHeaderSpacer();
|
this.createRightHeaderSpacer();
|
||||||
this.createTimeAxis();
|
this.createTimeAxis();
|
||||||
this.createWeekContainer();
|
this.createWeekContainer();
|
||||||
this.createRightColumn();
|
this.createRightColumn();
|
||||||
this.createBottomRow();
|
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');
|
console.log('GridManager: Grid rendered successfully with POC structure');
|
||||||
}
|
}
|
||||||
|
|
@ -269,6 +274,26 @@ export class GridManager {
|
||||||
this.updateSpacerHeights();
|
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
|
* 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);
|
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) {
|
if (this.grid && this.grid.children.length > 0) {
|
||||||
this.render();
|
this.updateWeekHeader();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -370,6 +370,9 @@ swp-day-column:last-child {
|
||||||
swp-events-layer {
|
swp-events-layer {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
inset: 0;
|
inset: 0;
|
||||||
|
display: block;
|
||||||
|
z-index: var(--z-event);
|
||||||
|
pointer-events: none; /* Allow clicks to pass through to day column */
|
||||||
}
|
}
|
||||||
|
|
||||||
swp-event {
|
swp-event {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue