Steps in the right direction for animated date change
This commit is contained in:
parent
5e966ddea2
commit
f50f5ad53b
7 changed files with 378 additions and 37 deletions
|
|
@ -24,6 +24,7 @@ export const EventTypes = {
|
||||||
// Navigation events
|
// Navigation events
|
||||||
WEEK_CHANGED: 'calendar:weekchanged',
|
WEEK_CHANGED: 'calendar:weekchanged',
|
||||||
WEEK_INFO_UPDATED: 'calendar:weekinfoupdated',
|
WEEK_INFO_UPDATED: 'calendar:weekinfoupdated',
|
||||||
|
WEEK_CONTENT_RENDERED: 'calendar:weekcontentrendered',
|
||||||
NAV_PREV: 'calendar:navprev',
|
NAV_PREV: 'calendar:navprev',
|
||||||
NAV_NEXT: 'calendar:navnext',
|
NAV_NEXT: 'calendar:navnext',
|
||||||
NAV_TODAY: 'calendar:navtoday',
|
NAV_TODAY: 'calendar:navtoday',
|
||||||
|
|
|
||||||
|
|
@ -76,9 +76,9 @@ export class CalendarManager {
|
||||||
this.setView(this.currentView);
|
this.setView(this.currentView);
|
||||||
this.setCurrentDate(this.currentDate);
|
this.setCurrentDate(this.currentDate);
|
||||||
|
|
||||||
// Step 5: Render events (after view is set)
|
// Step 5: Render events (after view is set) - only render events for current period
|
||||||
console.log('🎨 Rendering events...');
|
console.log('🎨 Rendering events for current period...');
|
||||||
const events = this.eventManager.getEvents();
|
const events = this.getEventsForCurrentPeriod();
|
||||||
await this.eventRenderer.renderEvents(events);
|
await this.eventRenderer.renderEvents(events);
|
||||||
|
|
||||||
this.isInitialized = true;
|
this.isInitialized = true;
|
||||||
|
|
@ -109,6 +109,11 @@ export class CalendarManager {
|
||||||
currentView: view,
|
currentView: view,
|
||||||
date: this.currentDate
|
date: this.currentDate
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Re-render events for new view if calendar is initialized
|
||||||
|
if (this.isInitialized) {
|
||||||
|
this.rerenderEventsForCurrentPeriod();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -126,6 +131,11 @@ export class CalendarManager {
|
||||||
currentDate: this.currentDate,
|
currentDate: this.currentDate,
|
||||||
view: this.currentView
|
view: this.currentView
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Re-render events for new period if calendar is initialized
|
||||||
|
if (this.isInitialized) {
|
||||||
|
this.rerenderEventsForCurrentPeriod();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -302,4 +312,99 @@ export class CalendarManager {
|
||||||
|
|
||||||
return previousDate;
|
return previousDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get events filtered for the current period (week/month/day)
|
||||||
|
*/
|
||||||
|
private getEventsForCurrentPeriod(): CalendarEvent[] {
|
||||||
|
const allEvents = this.eventManager.getEvents();
|
||||||
|
|
||||||
|
// Calculate current period based on view
|
||||||
|
const period = this.calculateCurrentPeriod();
|
||||||
|
|
||||||
|
// Filter events to only include those in the current period
|
||||||
|
const filteredEvents = allEvents.filter(event => {
|
||||||
|
const eventStart = new Date(event.start);
|
||||||
|
const eventEnd = new Date(event.end);
|
||||||
|
const periodStart = new Date(period.start);
|
||||||
|
const periodEnd = new Date(period.end);
|
||||||
|
|
||||||
|
// Include event if it overlaps with the period
|
||||||
|
return eventStart <= periodEnd && eventEnd >= periodStart;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Also filter out all-day events (handled by GridManager)
|
||||||
|
const nonAllDayEvents = filteredEvents.filter(event => !event.allDay);
|
||||||
|
|
||||||
|
console.log(`CalendarManager: Filtered ${allEvents.length} total events to ${nonAllDayEvents.length} non-all-day events for current period`);
|
||||||
|
|
||||||
|
return nonAllDayEvents;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate the current period based on view and date
|
||||||
|
*/
|
||||||
|
private calculateCurrentPeriod(): { start: string; end: string } {
|
||||||
|
const current = new Date(this.currentDate);
|
||||||
|
|
||||||
|
switch (this.currentView) {
|
||||||
|
case 'day':
|
||||||
|
const dayStart = new Date(current);
|
||||||
|
dayStart.setHours(0, 0, 0, 0);
|
||||||
|
const dayEnd = new Date(current);
|
||||||
|
dayEnd.setHours(23, 59, 59, 999);
|
||||||
|
return {
|
||||||
|
start: dayStart.toISOString(),
|
||||||
|
end: dayEnd.toISOString()
|
||||||
|
};
|
||||||
|
|
||||||
|
case 'week':
|
||||||
|
// Find start of week (Monday)
|
||||||
|
const weekStart = new Date(current);
|
||||||
|
const dayOfWeek = weekStart.getDay();
|
||||||
|
const daysToMonday = dayOfWeek === 0 ? 6 : dayOfWeek - 1; // Sunday = 0, so 6 days back to Monday
|
||||||
|
weekStart.setDate(weekStart.getDate() - daysToMonday);
|
||||||
|
weekStart.setHours(0, 0, 0, 0);
|
||||||
|
|
||||||
|
// Find end of week (Sunday)
|
||||||
|
const weekEnd = new Date(weekStart);
|
||||||
|
weekEnd.setDate(weekEnd.getDate() + 6);
|
||||||
|
weekEnd.setHours(23, 59, 59, 999);
|
||||||
|
|
||||||
|
return {
|
||||||
|
start: weekStart.toISOString(),
|
||||||
|
end: weekEnd.toISOString()
|
||||||
|
};
|
||||||
|
|
||||||
|
case 'month':
|
||||||
|
const monthStart = new Date(current.getFullYear(), current.getMonth(), 1);
|
||||||
|
const monthEnd = new Date(current.getFullYear(), current.getMonth() + 1, 0, 23, 59, 59, 999);
|
||||||
|
return {
|
||||||
|
start: monthStart.toISOString(),
|
||||||
|
end: monthEnd.toISOString()
|
||||||
|
};
|
||||||
|
|
||||||
|
default:
|
||||||
|
// Fallback to week view
|
||||||
|
const fallbackStart = new Date(current);
|
||||||
|
fallbackStart.setDate(fallbackStart.getDate() - 3);
|
||||||
|
fallbackStart.setHours(0, 0, 0, 0);
|
||||||
|
const fallbackEnd = new Date(current);
|
||||||
|
fallbackEnd.setDate(fallbackEnd.getDate() + 3);
|
||||||
|
fallbackEnd.setHours(23, 59, 59, 999);
|
||||||
|
return {
|
||||||
|
start: fallbackStart.toISOString(),
|
||||||
|
end: fallbackEnd.toISOString()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Re-render events for the current period
|
||||||
|
*/
|
||||||
|
private async rerenderEventsForCurrentPeriod(): Promise<void> {
|
||||||
|
console.log('CalendarManager: Re-rendering events for current period');
|
||||||
|
const events = this.getEventsForCurrentPeriod();
|
||||||
|
await this.eventRenderer.renderEvents(events);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -113,6 +113,44 @@ export class DataManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filter events to only include those within the specified period
|
||||||
|
*/
|
||||||
|
public filterEventsForPeriod(events: CalendarEvent[], period: Period): CalendarEvent[] {
|
||||||
|
const startDate = new Date(period.start);
|
||||||
|
const endDate = new Date(period.end);
|
||||||
|
|
||||||
|
return events.filter(event => {
|
||||||
|
const eventStart = new Date(event.start);
|
||||||
|
const eventEnd = new Date(event.end);
|
||||||
|
|
||||||
|
// Include event if it overlaps with the period
|
||||||
|
return eventStart <= endDate && eventEnd >= startDate;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get events filtered by period and optionally by all-day status
|
||||||
|
*/
|
||||||
|
public getFilteredEvents(period: Period, excludeAllDay: boolean = false): CalendarEvent[] {
|
||||||
|
const cacheKey = `${period.start}-${period.end}`;
|
||||||
|
const cachedData = this.cache.get(cacheKey);
|
||||||
|
|
||||||
|
if (!cachedData) {
|
||||||
|
console.warn('DataManager: No cached data found for period', period);
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
let filteredEvents = this.filterEventsForPeriod(cachedData.events, period);
|
||||||
|
|
||||||
|
if (excludeAllDay) {
|
||||||
|
filteredEvents = filteredEvents.filter(event => !event.allDay);
|
||||||
|
console.log(`DataManager: Filtered out all-day events, ${filteredEvents.length} non-all-day events remaining`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return filteredEvents;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new event
|
* Create a new event
|
||||||
*/
|
*/
|
||||||
|
|
@ -270,7 +308,7 @@ export class DataManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate mock data for testing
|
* Generate mock data for testing - only generates events within the specified period
|
||||||
*/
|
*/
|
||||||
private getMockData(period: Period): EventData {
|
private getMockData(period: Period): EventData {
|
||||||
const events: CalendarEvent[] = [];
|
const events: CalendarEvent[] = [];
|
||||||
|
|
@ -282,11 +320,13 @@ export class DataManager {
|
||||||
milestone: ['Project Deadline', 'Release Day', 'Demo Day']
|
milestone: ['Project Deadline', 'Release Day', 'Demo Day']
|
||||||
};
|
};
|
||||||
|
|
||||||
// Parse dates
|
// Parse dates - only generate events within this exact period
|
||||||
const startDate = new Date(period.start);
|
const startDate = new Date(period.start);
|
||||||
const endDate = new Date(period.end);
|
const endDate = new Date(period.end);
|
||||||
|
|
||||||
// Generate some events for each day
|
console.log(`DataManager: Generating mock events for period ${period.start} to ${period.end}`);
|
||||||
|
|
||||||
|
// Generate some events for each day within the period
|
||||||
for (let d = new Date(startDate); d <= endDate; d.setDate(d.getDate() + 1)) {
|
for (let d = new Date(startDate); d <= endDate; d.setDate(d.getDate() + 1)) {
|
||||||
// Skip weekends for most events
|
// Skip weekends for most events
|
||||||
const dayOfWeek = d.getDay();
|
const dayOfWeek = d.getDay();
|
||||||
|
|
|
||||||
|
|
@ -20,8 +20,9 @@ export class EventManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
private setupEventListeners(): void {
|
private setupEventListeners(): void {
|
||||||
// Keep only UI-related event listeners here if needed
|
// NOTE: Removed POC event listener to prevent interference with production code
|
||||||
// Data loading is now handled via direct method calls
|
// POC sliding animation should not trigger separate event rendering
|
||||||
|
// this.eventBus.on(EventTypes.WEEK_CONTENT_RENDERED, ...);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -170,6 +171,82 @@ export class EventManager {
|
||||||
this.syncEvents();
|
this.syncEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load events for a specific week into a container (POC-style)
|
||||||
|
*/
|
||||||
|
private loadEventsForWeek(weekStart: Date, weekEnd: Date, container: HTMLElement): void {
|
||||||
|
console.log(`EventManager: Loading events for week ${weekStart.toDateString()} - ${weekEnd.toDateString()}`);
|
||||||
|
|
||||||
|
// Filter events for this week
|
||||||
|
const weekEvents = this.events.filter(event => {
|
||||||
|
const eventDate = new Date(event.start);
|
||||||
|
return eventDate >= weekStart && eventDate <= weekEnd;
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log(`EventManager: Found ${weekEvents.length} events for this week`);
|
||||||
|
|
||||||
|
// Render events in the container (POC approach)
|
||||||
|
this.renderEventsInContainer(weekEvents, container);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render events in a specific container (POC-style)
|
||||||
|
*/
|
||||||
|
private renderEventsInContainer(events: CalendarEvent[], container: HTMLElement): void {
|
||||||
|
const dayColumns = container.querySelectorAll('swp-day-column');
|
||||||
|
|
||||||
|
events.forEach(event => {
|
||||||
|
const eventDate = new Date(event.start);
|
||||||
|
const dayOfWeek = eventDate.getDay(); // 0 = Sunday
|
||||||
|
const column = dayColumns[dayOfWeek];
|
||||||
|
|
||||||
|
if (column) {
|
||||||
|
const eventsLayer = column.querySelector('swp-events-layer');
|
||||||
|
if (eventsLayer) {
|
||||||
|
this.renderEventInColumn(event, eventsLayer as HTMLElement);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render a single event in a column (POC-style)
|
||||||
|
*/
|
||||||
|
private renderEventInColumn(event: CalendarEvent, eventsLayer: HTMLElement): void {
|
||||||
|
const eventElement = document.createElement('swp-event');
|
||||||
|
eventElement.dataset.type = event.type || 'meeting';
|
||||||
|
|
||||||
|
// Calculate position (simplified - assumes 7 AM start like POC)
|
||||||
|
const startTime = new Date(event.start);
|
||||||
|
const hours = startTime.getHours();
|
||||||
|
const minutes = startTime.getMinutes();
|
||||||
|
const startMinutes = (hours - 7) * 60 + minutes; // 7 is start hour like POC
|
||||||
|
|
||||||
|
// Calculate duration
|
||||||
|
const endTime = new Date(event.end);
|
||||||
|
const durationMs = endTime.getTime() - startTime.getTime();
|
||||||
|
const durationMinutes = Math.floor(durationMs / (1000 * 60));
|
||||||
|
|
||||||
|
eventElement.style.top = `${startMinutes}px`;
|
||||||
|
eventElement.style.height = `${durationMinutes}px`;
|
||||||
|
|
||||||
|
eventElement.innerHTML = `
|
||||||
|
<swp-event-time>${this.formatTime(hours, minutes)}</swp-event-time>
|
||||||
|
<swp-event-title>${event.title}</swp-event-title>
|
||||||
|
`;
|
||||||
|
|
||||||
|
eventsLayer.appendChild(eventElement);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Format time for display (POC-style)
|
||||||
|
*/
|
||||||
|
private formatTime(hours: number, minutes: number): string {
|
||||||
|
const period = hours >= 12 ? 'PM' : 'AM';
|
||||||
|
const displayHours = hours % 12 || 12;
|
||||||
|
return `${displayHours}:${String(minutes).padStart(2, '0')} ${period}`;
|
||||||
|
}
|
||||||
|
|
||||||
public destroy(): void {
|
public destroy(): void {
|
||||||
this.events = [];
|
this.events = [];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -112,28 +112,65 @@ export class NavigationManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* POC-style animation transition - creates new grid container and slides it in
|
||||||
|
*/
|
||||||
private animateTransition(direction: 'prev' | 'next', targetWeek: Date): void {
|
private animateTransition(direction: 'prev' | 'next', targetWeek: Date): void {
|
||||||
const calendarContainer = document.querySelector('swp-calendar-container');
|
const container = document.querySelector('swp-calendar-container');
|
||||||
|
const currentGrid = container?.querySelector('swp-grid-container');
|
||||||
|
|
||||||
if (!calendarContainer) {
|
if (!container || !currentGrid) {
|
||||||
console.warn('NavigationManager: Calendar container not found');
|
console.warn('NavigationManager: Required DOM elements not found');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add transition class for visual feedback
|
console.log(`NavigationManager: Starting ${direction} animation to ${targetWeek.toDateString()}`);
|
||||||
calendarContainer.classList.add('week-transition');
|
|
||||||
|
|
||||||
// Brief fade effect
|
// Create new grid container (POC approach)
|
||||||
setTimeout(() => {
|
const newGrid = document.createElement('swp-grid-container');
|
||||||
calendarContainer.classList.add('week-transition-out');
|
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>
|
||||||
|
`;
|
||||||
|
|
||||||
// Update the week after fade starts
|
// Position new grid off-screen (POC positioning)
|
||||||
|
newGrid.style.position = 'absolute';
|
||||||
|
newGrid.style.top = '0';
|
||||||
|
newGrid.style.left = '0';
|
||||||
|
newGrid.style.width = '100%';
|
||||||
|
newGrid.style.height = '100%';
|
||||||
|
newGrid.style.transform = direction === 'next' ? 'translateX(100%)' : 'translateX(-100%)';
|
||||||
|
|
||||||
|
// Add to container
|
||||||
|
container.appendChild(newGrid);
|
||||||
|
|
||||||
|
// Render new content for target week
|
||||||
|
this.renderWeekContent(newGrid, targetWeek);
|
||||||
|
|
||||||
|
// Animate transition (POC animation)
|
||||||
|
requestAnimationFrame(() => {
|
||||||
|
// Slide out current grid
|
||||||
|
(currentGrid as HTMLElement).style.transform = direction === 'next' ? 'translateX(-100%)' : 'translateX(100%)';
|
||||||
|
(currentGrid as HTMLElement).style.opacity = '0.5';
|
||||||
|
|
||||||
|
// Slide in new grid
|
||||||
|
newGrid.style.transform = 'translateX(0)';
|
||||||
|
|
||||||
|
// Clean up after animation (POC cleanup)
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
// Update currentWeek
|
currentGrid.remove();
|
||||||
|
newGrid.style.position = 'relative';
|
||||||
|
|
||||||
|
// Update currentWeek only after animation is complete (POC logic)
|
||||||
this.currentWeek = new Date(targetWeek);
|
this.currentWeek = new Date(targetWeek);
|
||||||
this.animationQueue--;
|
this.animationQueue--;
|
||||||
|
|
||||||
// If this was the last queued animation, ensure we're in sync
|
// If this was the last queued animation, ensure we're in sync (POC sync)
|
||||||
if (this.animationQueue === 0) {
|
if (this.animationQueue === 0) {
|
||||||
this.currentWeek = new Date(this.targetWeek);
|
this.currentWeek = new Date(this.targetWeek);
|
||||||
}
|
}
|
||||||
|
|
@ -145,13 +182,70 @@ export class NavigationManager {
|
||||||
weekEnd: DateUtils.addDays(this.currentWeek, 6)
|
weekEnd: DateUtils.addDays(this.currentWeek, 6)
|
||||||
});
|
});
|
||||||
|
|
||||||
// Remove transition classes
|
console.log(`NavigationManager: Completed ${direction} animation`);
|
||||||
setTimeout(() => {
|
}, 400); // Match POC timing
|
||||||
calendarContainer.classList.remove('week-transition', 'week-transition-out');
|
});
|
||||||
}, 150);
|
}
|
||||||
|
|
||||||
}, 150); // Half of transition duration
|
/**
|
||||||
}, 50);
|
* Render week content in the new grid container
|
||||||
|
*/
|
||||||
|
private renderWeekContent(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 = '';
|
||||||
|
|
||||||
|
// Render headers for target week
|
||||||
|
const days = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
|
||||||
|
for (let i = 0; i < 7; i++) {
|
||||||
|
const date = new Date(weekStart);
|
||||||
|
date.setDate(date.getDate() + i);
|
||||||
|
|
||||||
|
const headerElement = document.createElement('swp-day-header');
|
||||||
|
if (this.isToday(date)) {
|
||||||
|
headerElement.dataset.today = 'true';
|
||||||
|
}
|
||||||
|
|
||||||
|
headerElement.innerHTML = `
|
||||||
|
<swp-day-name>${days[date.getDay()]}</swp-day-name>
|
||||||
|
<swp-day-date>${date.getDate()}</swp-day-date>
|
||||||
|
`;
|
||||||
|
headerElement.dataset.date = this.formatDate(date);
|
||||||
|
|
||||||
|
header.appendChild(headerElement);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Render day columns for target week
|
||||||
|
for (let i = 0; i < 7; i++) {
|
||||||
|
const column = document.createElement('swp-day-column');
|
||||||
|
const date = new Date(weekStart);
|
||||||
|
date.setDate(date.getDate() + i);
|
||||||
|
column.dataset.date = this.formatDate(date);
|
||||||
|
|
||||||
|
const eventsLayer = document.createElement('swp-events-layer');
|
||||||
|
column.appendChild(eventsLayer);
|
||||||
|
|
||||||
|
dayColumns.appendChild(column);
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE: Removed POC event emission to prevent interference with production code
|
||||||
|
// POC events should not trigger production event rendering
|
||||||
|
// this.eventBus.emit(EventTypes.WEEK_CONTENT_RENDERED, { ... });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Utility functions (from POC)
|
||||||
|
private formatDate(date: Date): string {
|
||||||
|
return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
private isToday(date: Date): boolean {
|
||||||
|
const today = new Date();
|
||||||
|
return date.toDateString() === today.toDateString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private updateWeekInfo(): void {
|
private updateWeekInfo(): void {
|
||||||
|
|
|
||||||
|
|
@ -25,12 +25,11 @@ export abstract class BaseEventRenderer implements EventRendererStrategy {
|
||||||
// Clear existing events first
|
// Clear existing events first
|
||||||
this.clearEvents();
|
this.clearEvents();
|
||||||
|
|
||||||
// Filter out all-day events (handled by GridManager)
|
// Events should already be filtered by DataManager - no need to filter here
|
||||||
const nonAllDayEvents = events.filter(event => !event.allDay);
|
console.log('BaseEventRenderer: Rendering', events.length, 'pre-filtered events');
|
||||||
console.log('BaseEventRenderer: Rendering', nonAllDayEvents.length, 'non-all-day events');
|
|
||||||
|
|
||||||
// Render each event in the correct column
|
// Render each event in the correct column
|
||||||
nonAllDayEvents.forEach(event => {
|
events.forEach(event => {
|
||||||
const column = this.findColumn(event);
|
const column = this.findColumn(event);
|
||||||
|
|
||||||
if (column) {
|
if (column) {
|
||||||
|
|
@ -166,13 +165,14 @@ export class DateEventRenderer extends BaseEventRenderer {
|
||||||
*/
|
*/
|
||||||
export class ResourceEventRenderer extends BaseEventRenderer {
|
export class ResourceEventRenderer extends BaseEventRenderer {
|
||||||
findColumn(event: CalendarEvent): HTMLElement | null {
|
findColumn(event: CalendarEvent): HTMLElement | null {
|
||||||
if (!event.resourceName) {
|
const resourceName = event.resource?.name;
|
||||||
console.warn('ResourceEventRenderer: Event has no resourceName', event);
|
if (!resourceName) {
|
||||||
|
console.warn('ResourceEventRenderer: Event has no resource.name', event);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const resourceColumn = document.querySelector(`swp-resource-column[data-resource="${event.resourceName}"]`) as HTMLElement;
|
const resourceColumn = document.querySelector(`swp-resource-column[data-resource="${resourceName}"]`) as HTMLElement;
|
||||||
console.log('ResourceEventRenderer: Looking for resource column with name', event.resourceName, 'found:', !!resourceColumn);
|
console.log('ResourceEventRenderer: Looking for resource column with name', resourceName, 'found:', !!resourceColumn);
|
||||||
return resourceColumn;
|
return resourceColumn;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
24
wwwroot/css/calendar-sliding-animation.css
Normal file
24
wwwroot/css/calendar-sliding-animation.css
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
/* POC-style Calendar Sliding Animation CSS */
|
||||||
|
|
||||||
|
/* Grid container base styles */
|
||||||
|
swp-grid-container {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
transition: transform 400ms cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
|
will-change: transform;
|
||||||
|
backface-visibility: hidden;
|
||||||
|
transform: translateZ(0); /* GPU acceleration */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Calendar container for sliding */
|
||||||
|
swp-calendar-container {
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Accessibility: Respect reduced motion preference */
|
||||||
|
@media (prefers-reduced-motion: reduce) {
|
||||||
|
swp-grid-container {
|
||||||
|
transition: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue