Refactor event rendering with column-based event management
Improves event rendering by integrating event filtering directly into column data sources Key changes: - Moves event filtering responsibility to IColumnDataSource - Simplifies event rendering pipeline by pre-filtering events per column - Supports both date and resource-based calendar modes - Enhances drag and drop event update mechanism Optimizes calendar rendering performance and flexibility
This commit is contained in:
parent
eeaeddeef8
commit
17909696ed
9 changed files with 179 additions and 250 deletions
|
|
@ -1,6 +1,7 @@
|
|||
// Event rendering strategy interface and implementations
|
||||
|
||||
import { ICalendarEvent } from '../types/CalendarTypes';
|
||||
import { IColumnInfo } from '../types/ColumnDataSource';
|
||||
import { Configuration } from '../configurations/CalendarConfig';
|
||||
import { SwpEventElement } from '../elements/SwpEventElement';
|
||||
import { PositionUtils } from '../utils/PositionUtils';
|
||||
|
|
@ -12,9 +13,12 @@ import { EventLayoutCoordinator, IGridGroupLayout, IStackedEventLayout } from '.
|
|||
|
||||
/**
|
||||
* Interface for event rendering strategies
|
||||
*
|
||||
* Note: renderEvents now receives columns with pre-filtered events,
|
||||
* not a flat array of events. Each column contains its own events.
|
||||
*/
|
||||
export interface IEventRenderer {
|
||||
renderEvents(events: ICalendarEvent[], container: HTMLElement): void;
|
||||
renderEvents(columns: IColumnInfo[], container: HTMLElement): void;
|
||||
clearEvents(container?: HTMLElement): void;
|
||||
renderSingleColumnEvents?(column: IColumnBounds, events: ICalendarEvent[]): void;
|
||||
handleDragStart?(payload: IDragStartEventPayload): void;
|
||||
|
|
@ -98,28 +102,22 @@ export class DateEventRenderer implements IEventRenderer {
|
|||
|
||||
/**
|
||||
* Handle drag move event
|
||||
* Only updates visual position and time - date stays the same
|
||||
*/
|
||||
public handleDragMove(payload: IDragMoveEventPayload): void {
|
||||
|
||||
const swpEvent = payload.draggedClone as SwpEventElement;
|
||||
const columnDate = this.dateService.parseISO(payload.columnBounds!!.identifier);
|
||||
swpEvent.updatePosition(columnDate, payload.snappedY);
|
||||
swpEvent.updatePosition(payload.snappedY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle column change during drag
|
||||
* Only moves the element visually - no data updates here
|
||||
* Data updates happen on drag:end in EventRenderingService
|
||||
*/
|
||||
public handleColumnChange(payload: IDragColumnChangeEventPayload): void {
|
||||
|
||||
const eventsLayer = payload.newColumn.element.querySelector('swp-events-layer');
|
||||
if (eventsLayer && payload.draggedClone.parentElement !== eventsLayer) {
|
||||
eventsLayer.appendChild(payload.draggedClone);
|
||||
|
||||
// Recalculate timestamps with new column date
|
||||
const currentTop = parseFloat(payload.draggedClone.style.top) || 0;
|
||||
const swpEvent = payload.draggedClone as SwpEventElement;
|
||||
const columnDate = this.dateService.parseISO(payload.newColumn.identifier);
|
||||
swpEvent.updatePosition(columnDate, currentTop);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -220,32 +218,36 @@ export class DateEventRenderer implements IEventRenderer {
|
|||
}
|
||||
|
||||
|
||||
renderEvents(events: ICalendarEvent[], container: HTMLElement): void {
|
||||
// Filter out all-day events - they should be handled by AllDayEventRenderer
|
||||
const timedEvents = events.filter(event => !event.allDay);
|
||||
renderEvents(columns: IColumnInfo[], container: HTMLElement): void {
|
||||
// Find column DOM elements in the container
|
||||
const columnElements = this.getColumns(container);
|
||||
|
||||
// Find columns in the specific container for regular events
|
||||
const columns = this.getColumns(container);
|
||||
// Render events for each column using pre-filtered events from IColumnInfo
|
||||
columns.forEach((columnInfo, index) => {
|
||||
const columnElement = columnElements[index];
|
||||
if (!columnElement) return;
|
||||
|
||||
columns.forEach(column => {
|
||||
const columnEvents = this.getEventsForColumn(column, timedEvents);
|
||||
const eventsLayer = column.querySelector('swp-events-layer') as HTMLElement;
|
||||
// Filter out all-day events - they should be handled by AllDayEventRenderer
|
||||
const timedEvents = columnInfo.events.filter(event => !event.allDay);
|
||||
|
||||
if (eventsLayer) {
|
||||
this.renderColumnEvents(columnEvents, eventsLayer);
|
||||
const eventsLayer = columnElement.querySelector('swp-events-layer') as HTMLElement;
|
||||
if (eventsLayer && timedEvents.length > 0) {
|
||||
this.renderColumnEvents(timedEvents, eventsLayer);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Render events for a single column
|
||||
* Note: events are already filtered for this column
|
||||
*/
|
||||
public renderSingleColumnEvents(column: IColumnBounds, events: ICalendarEvent[]): void {
|
||||
const columnEvents = this.getEventsForColumn(column.element, events);
|
||||
// Filter out all-day events
|
||||
const timedEvents = events.filter(event => !event.allDay);
|
||||
const eventsLayer = column.element.querySelector('swp-events-layer') as HTMLElement;
|
||||
|
||||
if (eventsLayer) {
|
||||
this.renderColumnEvents(columnEvents, eventsLayer);
|
||||
if (eventsLayer && timedEvents.length > 0) {
|
||||
this.renderColumnEvents(timedEvents, eventsLayer);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -388,24 +390,4 @@ export class DateEventRenderer implements IEventRenderer {
|
|||
const columns = container.querySelectorAll('swp-day-column');
|
||||
return Array.from(columns) as HTMLElement[];
|
||||
}
|
||||
|
||||
protected getEventsForColumn(column: HTMLElement, events: ICalendarEvent[]): ICalendarEvent[] {
|
||||
const columnId = column.dataset.columnId;
|
||||
if (!columnId) {
|
||||
return [];
|
||||
}
|
||||
|
||||
// Create start and end of day for interval overlap check
|
||||
// In date-mode, columnId is ISO date string like "2024-11-13"
|
||||
const columnStart = this.dateService.parseISO(`${columnId}T00:00:00`);
|
||||
const columnEnd = this.dateService.parseISO(`${columnId}T23:59:59.999`);
|
||||
|
||||
const columnEvents = events.filter(event => {
|
||||
// Interval overlap: event overlaps with column day if event.start < columnEnd AND event.end > columnStart
|
||||
const overlaps = event.start < columnEnd && event.end > columnStart;
|
||||
return overlaps;
|
||||
});
|
||||
|
||||
return columnEvents;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
import { IEventBus, ICalendarEvent, IRenderContext } from '../types/CalendarTypes';
|
||||
import { IEventBus } from '../types/CalendarTypes';
|
||||
import { IColumnInfo, IColumnDataSource } from '../types/ColumnDataSource';
|
||||
import { CoreEvents } from '../constants/CoreEvents';
|
||||
import { EventManager } from '../managers/EventManager';
|
||||
import { IEventRenderer } from './EventRenderer';
|
||||
import { SwpEventElement } from '../elements/SwpEventElement';
|
||||
import { IDragStartEventPayload, IDragMoveEventPayload, IDragEndEventPayload, IDragMouseEnterHeaderEventPayload, IDragMouseLeaveHeaderEventPayload, IDragMouseEnterColumnEventPayload, IDragColumnChangeEventPayload, IHeaderReadyEventPayload, IResizeEndEventPayload } from '../types/EventTypes';
|
||||
import { IDragStartEventPayload, IDragMoveEventPayload, IDragEndEventPayload, IDragMouseEnterHeaderEventPayload, IDragMouseLeaveHeaderEventPayload, IDragMouseEnterColumnEventPayload, IDragColumnChangeEventPayload, IResizeEndEventPayload } from '../types/EventTypes';
|
||||
import { DateService } from '../utils/DateService';
|
||||
import { IColumnBounds, ColumnDetectionUtils } from '../utils/ColumnDetectionUtils';
|
||||
|
||||
/**
|
||||
* EventRenderingService - Render events i DOM med positionering using Strategy Pattern
|
||||
* Håndterer event positioning og overlap detection
|
||||
|
|
@ -14,6 +15,7 @@ export class EventRenderingService {
|
|||
private eventBus: IEventBus;
|
||||
private eventManager: EventManager;
|
||||
private strategy: IEventRenderer;
|
||||
private dataSource: IColumnDataSource;
|
||||
private dateService: DateService;
|
||||
|
||||
private dragMouseLeaveHeaderListener: ((event: Event) => void) | null = null;
|
||||
|
|
@ -22,54 +24,18 @@ export class EventRenderingService {
|
|||
eventBus: IEventBus,
|
||||
eventManager: EventManager,
|
||||
strategy: IEventRenderer,
|
||||
dataSource: IColumnDataSource,
|
||||
dateService: DateService
|
||||
) {
|
||||
this.eventBus = eventBus;
|
||||
this.eventManager = eventManager;
|
||||
this.strategy = strategy;
|
||||
this.dataSource = dataSource;
|
||||
this.dateService = dateService;
|
||||
|
||||
this.setupEventListeners();
|
||||
}
|
||||
|
||||
/**
|
||||
* Render events in a specific container for a given period
|
||||
*/
|
||||
public async renderEvents(context: IRenderContext): Promise<void> {
|
||||
// Clear existing events in the specific container first
|
||||
this.strategy.clearEvents(context.container);
|
||||
|
||||
// Get events from EventManager for the period
|
||||
const events = await this.eventManager.getEventsForPeriod(
|
||||
context.startDate,
|
||||
context.endDate
|
||||
);
|
||||
|
||||
if (events.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Filter events by type - only render timed events here
|
||||
const timedEvents = events.filter(event => !event.allDay);
|
||||
|
||||
console.log('🎯 EventRenderingService: Event filtering', {
|
||||
totalEvents: events.length,
|
||||
timedEvents: timedEvents.length,
|
||||
allDayEvents: events.length - timedEvents.length
|
||||
});
|
||||
|
||||
// Render timed events using existing strategy
|
||||
if (timedEvents.length > 0) {
|
||||
this.strategy.renderEvents(timedEvents, context.container);
|
||||
}
|
||||
|
||||
// Emit EVENTS_RENDERED event for filtering system
|
||||
this.eventBus.emit(CoreEvents.EVENTS_RENDERED, {
|
||||
events: events,
|
||||
container: context.container
|
||||
});
|
||||
}
|
||||
|
||||
private setupEventListeners(): void {
|
||||
|
||||
this.eventBus.on(CoreEvents.GRID_RENDERED, (event: Event) => {
|
||||
|
|
@ -89,6 +55,7 @@ export class EventRenderingService {
|
|||
|
||||
/**
|
||||
* Handle GRID_RENDERED event - render events in the current grid
|
||||
* Events are now pre-filtered per column by IColumnDataSource
|
||||
*/
|
||||
private handleGridRendered(event: CustomEvent): void {
|
||||
const { container, columns } = event.detail;
|
||||
|
|
@ -97,17 +64,23 @@ export class EventRenderingService {
|
|||
return;
|
||||
}
|
||||
|
||||
// Extract dates from columns
|
||||
const dates = columns.map((col: any) => col.data as Date);
|
||||
// Render events directly from columns (pre-filtered by IColumnDataSource)
|
||||
this.renderEventsFromColumns(container, columns);
|
||||
}
|
||||
|
||||
// Calculate startDate and endDate from dates array
|
||||
const startDate = dates[0];
|
||||
const endDate = dates[dates.length - 1];
|
||||
/**
|
||||
* Render events from pre-filtered columns
|
||||
* Each column already contains its events (filtered by IColumnDataSource)
|
||||
*/
|
||||
private renderEventsFromColumns(container: HTMLElement, columns: IColumnInfo[]): void {
|
||||
this.strategy.clearEvents(container);
|
||||
this.strategy.renderEvents(columns, container);
|
||||
|
||||
this.renderEvents({
|
||||
container,
|
||||
startDate,
|
||||
endDate
|
||||
// Emit EVENTS_RENDERED for filtering system
|
||||
const allEvents = columns.flatMap(col => col.events);
|
||||
this.eventBus.emit(CoreEvents.EVENTS_RENDERED, {
|
||||
events: allEvents,
|
||||
container: container
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -166,29 +139,42 @@ export class EventRenderingService {
|
|||
|
||||
private setupDragEndListener(): void {
|
||||
this.eventBus.on('drag:end', async (event: Event) => {
|
||||
|
||||
const { originalElement, draggedClone, originalSourceColumn, finalPosition, target } = (event as CustomEvent<IDragEndEventPayload>).detail;
|
||||
const { originalElement, draggedClone, finalPosition, target } = (event as CustomEvent<IDragEndEventPayload>).detail;
|
||||
const finalColumn = finalPosition.column;
|
||||
const finalY = finalPosition.snappedY;
|
||||
|
||||
let element = draggedClone as SwpEventElement;
|
||||
// Only handle day column drops for EventRenderer
|
||||
// Only handle day column drops
|
||||
if (target === 'swp-day-column' && finalColumn) {
|
||||
const element = draggedClone as SwpEventElement;
|
||||
|
||||
if (originalElement && draggedClone && this.strategy.handleDragEnd) {
|
||||
this.strategy.handleDragEnd(originalElement, draggedClone, finalColumn, finalY);
|
||||
}
|
||||
|
||||
await this.eventManager.updateEvent(element.eventId, {
|
||||
// Build update payload based on mode
|
||||
const updatePayload: { start: Date; end: Date; allDay: boolean; resourceId?: string } = {
|
||||
start: element.start,
|
||||
end: element.end,
|
||||
allDay: false
|
||||
});
|
||||
};
|
||||
|
||||
// Re-render affected columns for stacking/grouping (now with updated data)
|
||||
await this.reRenderAffectedColumns(originalSourceColumn, finalColumn);
|
||||
if (this.dataSource.isResource()) {
|
||||
// Resource mode: update resourceId, keep existing date
|
||||
updatePayload.resourceId = finalColumn.identifier;
|
||||
} else {
|
||||
// Date mode: update date from column, keep existing time
|
||||
const newDate = this.dateService.parseISO(finalColumn.identifier);
|
||||
const startTimeMinutes = this.dateService.getMinutesSinceMidnight(element.start);
|
||||
const endTimeMinutes = this.dateService.getMinutesSinceMidnight(element.end);
|
||||
updatePayload.start = this.dateService.createDateAtTime(newDate, startTimeMinutes);
|
||||
updatePayload.end = this.dateService.createDateAtTime(newDate, endTimeMinutes);
|
||||
}
|
||||
|
||||
await this.eventManager.updateEvent(element.eventId, updatePayload);
|
||||
|
||||
// Trigger full refresh to re-render with updated data
|
||||
this.eventBus.emit(CoreEvents.REFRESH_REQUESTED, {});
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -252,27 +238,14 @@ export class EventRenderingService {
|
|||
this.eventBus.on('resize:end', async (event: Event) => {
|
||||
const { eventId, element } = (event as CustomEvent<IResizeEndEventPayload>).detail;
|
||||
|
||||
// Update event data in EventManager with new end time from resized element
|
||||
const swpEvent = element as SwpEventElement;
|
||||
const newStart = swpEvent.start;
|
||||
const newEnd = swpEvent.end;
|
||||
|
||||
await this.eventManager.updateEvent(eventId, {
|
||||
start: newStart,
|
||||
end: newEnd
|
||||
start: swpEvent.start,
|
||||
end: swpEvent.end
|
||||
});
|
||||
|
||||
console.log('📝 EventRendererManager: Updated event after resize', {
|
||||
eventId,
|
||||
newStart,
|
||||
newEnd
|
||||
});
|
||||
|
||||
const dateIdentifier = newStart.toISOString().split('T')[0];
|
||||
let columnBounds = ColumnDetectionUtils.getColumnBoundsByIdentifier(dateIdentifier);
|
||||
if (columnBounds)
|
||||
await this.renderSingleColumn(columnBounds);
|
||||
|
||||
// Trigger full refresh to re-render with updated data
|
||||
this.eventBus.emit(CoreEvents.REFRESH_REQUESTED, {});
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -286,68 +259,6 @@ export class EventRenderingService {
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Re-render affected columns after drag to recalculate stacking/grouping
|
||||
*/
|
||||
private async reRenderAffectedColumns(originalSourceColumn: IColumnBounds | null, targetColumn: IColumnBounds | null): Promise<void> {
|
||||
// Re-render original source column if exists
|
||||
if (originalSourceColumn) {
|
||||
await this.renderSingleColumn(originalSourceColumn);
|
||||
}
|
||||
|
||||
// Re-render target column if exists and different from source
|
||||
if (targetColumn && targetColumn.identifier !== originalSourceColumn?.identifier) {
|
||||
await this.renderSingleColumn(targetColumn);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear events in a single column's events layer
|
||||
*/
|
||||
private clearColumnEvents(eventsLayer: HTMLElement): void {
|
||||
const existingEvents = eventsLayer.querySelectorAll('swp-event');
|
||||
const existingGroups = eventsLayer.querySelectorAll('swp-event-group');
|
||||
|
||||
existingEvents.forEach(event => event.remove());
|
||||
existingGroups.forEach(group => group.remove());
|
||||
}
|
||||
|
||||
/**
|
||||
* Render events for a single column
|
||||
*/
|
||||
private async renderSingleColumn(column: IColumnBounds): Promise<void> {
|
||||
// Get events for just this column's date
|
||||
const dateString = column.identifier;
|
||||
const columnStart = this.dateService.parseISO(`${dateString}T00:00:00`);
|
||||
const columnEnd = this.dateService.parseISO(`${dateString}T23:59:59.999`);
|
||||
|
||||
// Get events from EventManager for this single date
|
||||
const events = await this.eventManager.getEventsForPeriod(columnStart, columnEnd);
|
||||
|
||||
// Filter to timed events only
|
||||
const timedEvents = events.filter(event => !event.allDay);
|
||||
|
||||
// Get events layer within this specific column
|
||||
const eventsLayer = column.element.querySelector('swp-events-layer') as HTMLElement;
|
||||
if (!eventsLayer) {
|
||||
console.warn('EventRendererManager: Events layer not found in column');
|
||||
return;
|
||||
}
|
||||
|
||||
// Clear only this column's events
|
||||
this.clearColumnEvents(eventsLayer);
|
||||
|
||||
// Render events for this column using strategy
|
||||
if (this.strategy.renderSingleColumnEvents) {
|
||||
this.strategy.renderSingleColumnEvents(column, timedEvents);
|
||||
}
|
||||
|
||||
console.log('🔄 EventRendererManager: Re-rendered single column', {
|
||||
columnDate: column.identifier,
|
||||
eventsCount: timedEvents.length
|
||||
});
|
||||
}
|
||||
|
||||
private clearEvents(container?: HTMLElement): void {
|
||||
this.strategy.clearEvents(container);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { Configuration } from '../configurations/CalendarConfig';
|
||||
import { CalendarView, ICalendarEvent } from '../types/CalendarTypes';
|
||||
import { CalendarView } from '../types/CalendarTypes';
|
||||
import { IColumnRenderer, IColumnRenderContext } from './ColumnRenderer';
|
||||
import { eventBus } from '../core/EventBus';
|
||||
import { DateService } from '../utils/DateService';
|
||||
|
|
@ -105,15 +105,13 @@ export class GridRenderer {
|
|||
* @param grid - Container element where grid will be rendered
|
||||
* @param currentDate - Base date for the current view (e.g., any date in the week)
|
||||
* @param view - Calendar view type (day/week/month)
|
||||
* @param dates - Array of dates to render as columns
|
||||
* @param events - All events for the period
|
||||
* @param columns - Array of columns to render (each column contains its events)
|
||||
*/
|
||||
public renderGrid(
|
||||
grid: HTMLElement,
|
||||
currentDate: Date,
|
||||
view: CalendarView = 'week',
|
||||
columns: IColumnInfo[] = [],
|
||||
events: ICalendarEvent[] = []
|
||||
columns: IColumnInfo[] = []
|
||||
): void {
|
||||
|
||||
if (!grid || !currentDate) {
|
||||
|
|
@ -125,10 +123,10 @@ export class GridRenderer {
|
|||
|
||||
// Only clear and rebuild if grid is empty (first render)
|
||||
if (grid.children.length === 0) {
|
||||
this.createCompleteGridStructure(grid, currentDate, view, columns, events);
|
||||
this.createCompleteGridStructure(grid, currentDate, view, columns);
|
||||
} else {
|
||||
// Optimized update - only refresh dynamic content
|
||||
this.updateGridContent(grid, currentDate, view, columns, events);
|
||||
this.updateGridContent(grid, currentDate, view, columns);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -146,14 +144,13 @@ export class GridRenderer {
|
|||
* @param grid - Parent container
|
||||
* @param currentDate - Current view date
|
||||
* @param view - View type
|
||||
* @param dates - Array of dates to render
|
||||
* @param columns - Array of columns to render (each column contains its events)
|
||||
*/
|
||||
private createCompleteGridStructure(
|
||||
grid: HTMLElement,
|
||||
currentDate: Date,
|
||||
view: CalendarView,
|
||||
columns: IColumnInfo[],
|
||||
events: ICalendarEvent[]
|
||||
columns: IColumnInfo[]
|
||||
): void {
|
||||
// Create all elements in memory first for better performance
|
||||
const fragment = document.createDocumentFragment();
|
||||
|
|
@ -168,7 +165,7 @@ export class GridRenderer {
|
|||
fragment.appendChild(timeAxis);
|
||||
|
||||
// Create grid container with caching
|
||||
const gridContainer = this.createOptimizedGridContainer(columns, events);
|
||||
const gridContainer = this.createOptimizedGridContainer(columns);
|
||||
this.cachedGridContainer = gridContainer;
|
||||
fragment.appendChild(gridContainer);
|
||||
|
||||
|
|
@ -213,14 +210,11 @@ export class GridRenderer {
|
|||
* - Time grid (grid lines + day columns) - structure created here
|
||||
* - Column container - created here, populated by ColumnRenderer
|
||||
*
|
||||
* @param currentDate - Current view date
|
||||
* @param view - View type
|
||||
* @param dates - Array of dates to render
|
||||
* @param columns - Array of columns to render (each column contains its events)
|
||||
* @returns Complete grid container element
|
||||
*/
|
||||
private createOptimizedGridContainer(
|
||||
columns: IColumnInfo[],
|
||||
events: ICalendarEvent[]
|
||||
columns: IColumnInfo[]
|
||||
): HTMLElement {
|
||||
const gridContainer = document.createElement('swp-grid-container');
|
||||
|
||||
|
|
@ -238,7 +232,7 @@ export class GridRenderer {
|
|||
|
||||
// Create column container
|
||||
const columnContainer = document.createElement('swp-day-columns');
|
||||
this.renderColumnContainer(columnContainer, columns, events);
|
||||
this.renderColumnContainer(columnContainer, columns);
|
||||
timeGrid.appendChild(columnContainer);
|
||||
|
||||
scrollableContent.appendChild(timeGrid);
|
||||
|
|
@ -255,13 +249,11 @@ export class GridRenderer {
|
|||
* Event rendering is handled by EventRenderingService listening to GRID_RENDERED.
|
||||
*
|
||||
* @param columnContainer - Empty container to populate
|
||||
* @param dates - Array of dates to render
|
||||
* @param events - All events for the period (passed through, not used here)
|
||||
* @param columns - Array of columns to render (each column contains its events)
|
||||
*/
|
||||
private renderColumnContainer(
|
||||
columnContainer: HTMLElement,
|
||||
columns: IColumnInfo[],
|
||||
events: ICalendarEvent[]
|
||||
columns: IColumnInfo[]
|
||||
): void {
|
||||
// Delegate to ColumnRenderer
|
||||
this.columnRenderer.render(columnContainer, {
|
||||
|
|
@ -279,21 +271,19 @@ export class GridRenderer {
|
|||
* @param grid - Existing grid element
|
||||
* @param currentDate - New view date
|
||||
* @param view - View type
|
||||
* @param dates - Array of dates to render
|
||||
* @param events - All events for the period
|
||||
* @param columns - Array of columns to render (each column contains its events)
|
||||
*/
|
||||
private updateGridContent(
|
||||
grid: HTMLElement,
|
||||
currentDate: Date,
|
||||
view: CalendarView,
|
||||
columns: IColumnInfo[],
|
||||
events: ICalendarEvent[]
|
||||
columns: IColumnInfo[]
|
||||
): void {
|
||||
// Update column container if needed
|
||||
const columnContainer = grid.querySelector('swp-day-columns');
|
||||
if (columnContainer) {
|
||||
columnContainer.innerHTML = '';
|
||||
this.renderColumnContainer(columnContainer as HTMLElement, columns, events);
|
||||
this.renderColumnContainer(columnContainer as HTMLElement, columns);
|
||||
}
|
||||
}
|
||||
/**
|
||||
|
|
@ -310,8 +300,8 @@ export class GridRenderer {
|
|||
* @returns New grid element ready for animation
|
||||
*/
|
||||
public createNavigationGrid(parentContainer: HTMLElement, columns: IColumnInfo[]): HTMLElement {
|
||||
// Create grid structure without events (events rendered by EventRenderingService)
|
||||
const newGrid = this.createOptimizedGridContainer(columns, []);
|
||||
// Create grid structure (events are in columns, rendered by EventRenderingService)
|
||||
const newGrid = this.createOptimizedGridContainer(columns);
|
||||
|
||||
// Position new grid for animation - NO transform here, let Animation API handle it
|
||||
newGrid.style.position = 'absolute';
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue