Improves all-day event layout calculation
Refactors all-day event rendering to use a layout engine for overlap detection and positioning, ensuring events are placed in available rows and columns. Removes deprecated method and adds unit tests.
This commit is contained in:
parent
274753936e
commit
a624394ffb
11 changed files with 2898 additions and 145 deletions
|
|
@ -283,80 +283,49 @@ export class SwpAllDayEventElement extends BaseEventElement {
|
|||
}
|
||||
|
||||
/**
|
||||
* Factory method to create from CalendarEvent and target date
|
||||
* Factory method to create from CalendarEvent and layout (provided by AllDayManager)
|
||||
*/
|
||||
public static fromCalendarEvent(event: CalendarEvent, targetDate?: string): SwpAllDayEventElement {
|
||||
// Calculate column span based on event start and end dates
|
||||
const { startColumn, endColumn, columnSpan } = this.calculateColumnSpan(event);
|
||||
public static fromCalendarEventWithLayout(
|
||||
event: CalendarEvent,
|
||||
layout: { startColumn: number; endColumn: number; row: number; columnSpan: number }
|
||||
): SwpAllDayEventElement {
|
||||
// Create element with provided layout
|
||||
const element = new SwpAllDayEventElement(event, layout.startColumn);
|
||||
|
||||
// For backwards compatibility, use targetDate if provided, otherwise use calculated start column
|
||||
const finalStartColumn = targetDate ? this.getColumnIndexForDate(targetDate) : startColumn;
|
||||
const finalEndColumn = targetDate ? finalStartColumn : endColumn;
|
||||
const finalColumnSpan = targetDate ? 1 : columnSpan;
|
||||
|
||||
// Find occupied rows in the spanned columns using computedStyle
|
||||
const existingEvents = document.querySelectorAll('swp-allday-container swp-event');
|
||||
const occupiedRows = new Set<number>();
|
||||
// Set complete grid-area instead of individual properties
|
||||
const gridArea = `${layout.row} / ${layout.startColumn} / ${layout.row + 1} / ${layout.endColumn + 1}`;
|
||||
element.element.style.gridArea = gridArea;
|
||||
|
||||
console.log('🔍 SwpAllDayEventElement: Checking grid row for new event', {
|
||||
targetDate,
|
||||
finalStartColumn,
|
||||
finalEndColumn,
|
||||
existingEventsCount: existingEvents.length
|
||||
});
|
||||
|
||||
existingEvents.forEach(existingEvent => {
|
||||
const style = getComputedStyle(existingEvent);
|
||||
const eventStartCol = parseInt(style.gridColumnStart);
|
||||
const eventEndCol = parseInt(style.gridColumnEnd);
|
||||
const eventRow = parseInt(style.gridRowStart) || 1;
|
||||
const eventId = (existingEvent as HTMLElement).dataset.eventId;
|
||||
|
||||
console.log('📊 SwpAllDayEventElement: Checking existing event', {
|
||||
eventId,
|
||||
eventStartCol,
|
||||
eventEndCol,
|
||||
eventRow,
|
||||
newEventColumn: finalStartColumn
|
||||
});
|
||||
|
||||
// FIXED: Only check events in the same column (not overlap detection)
|
||||
if (eventStartCol === finalStartColumn) {
|
||||
console.log('✅ SwpAllDayEventElement: Same column - adding occupied row', eventRow);
|
||||
occupiedRows.add(eventRow);
|
||||
} else {
|
||||
console.log('⏭️ SwpAllDayEventElement: Different column - skipping');
|
||||
}
|
||||
});
|
||||
|
||||
// Find first available row
|
||||
let targetRow = 1;
|
||||
while (occupiedRows.has(targetRow)) {
|
||||
targetRow++;
|
||||
}
|
||||
|
||||
console.log('🎯 SwpAllDayEventElement: Final row assignment', {
|
||||
targetDate,
|
||||
finalStartColumn,
|
||||
occupiedRows: Array.from(occupiedRows).sort(),
|
||||
assignedRow: targetRow
|
||||
});
|
||||
|
||||
// Create element with calculated column span
|
||||
const element = new SwpAllDayEventElement(event, finalStartColumn);
|
||||
element.setGridRow(targetRow);
|
||||
element.setColumnSpan(finalStartColumn, finalEndColumn);
|
||||
|
||||
console.log('✅ SwpAllDayEventElement: Created all-day event', {
|
||||
console.log('✅ SwpAllDayEventElement: Created all-day event with AllDayLayoutEngine', {
|
||||
eventId: event.id,
|
||||
title: event.title,
|
||||
column: finalStartColumn,
|
||||
row: targetRow
|
||||
gridArea: gridArea,
|
||||
layout: layout
|
||||
});
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method to create from CalendarEvent and target date (DEPRECATED - use AllDayManager.calculateAllDayEventLayout)
|
||||
* @deprecated Use AllDayManager.calculateAllDayEventLayout() and fromCalendarEventWithLayout() instead
|
||||
*/
|
||||
public static fromCalendarEvent(event: CalendarEvent, targetDate?: string): SwpAllDayEventElement {
|
||||
console.warn('⚠️ SwpAllDayEventElement.fromCalendarEvent is deprecated. Use AllDayManager.calculateAllDayEventLayout() instead.');
|
||||
|
||||
// Fallback to simple column calculation without overlap detection
|
||||
const { startColumn, endColumn } = this.calculateColumnSpan(event);
|
||||
const finalStartColumn = targetDate ? this.getColumnIndexForDate(targetDate) : startColumn;
|
||||
const finalEndColumn = targetDate ? finalStartColumn : endColumn;
|
||||
|
||||
// Create element with row 1 (no overlap detection)
|
||||
const element = new SwpAllDayEventElement(event, finalStartColumn);
|
||||
element.setGridRow(1);
|
||||
element.setColumnSpan(finalStartColumn, finalEndColumn);
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate column span based on event start and end dates
|
||||
*/
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue