diff --git a/src/renderers/EventRenderer.ts b/src/renderers/EventRenderer.ts index ecff38c..a361f7f 100644 --- a/src/renderers/EventRenderer.ts +++ b/src/renderers/EventRenderer.ts @@ -366,22 +366,51 @@ export abstract class BaseEventRenderer implements EventRendererStrategy { const eventsLayer = columnElement.querySelector('swp-events-layer'); if (!eventsLayer) return; - // Get all existing events in the column (excluding the dropped element) - const existingEvents = Array.from(eventsLayer.querySelectorAll('swp-event')) - .filter(el => el !== droppedElement) as HTMLElement[]; - // Convert dropped element to CalendarEvent using its NEW position const droppedEvent = this.elementToCalendarEventWithNewPosition(droppedElement, targetColumn); if (!droppedEvent) return; + // Check if there's already an existing swp-event-group in the column + const existingGroup = eventsLayer.querySelector('swp-event-group') as HTMLElement; + if (existingGroup) { + // Check if dropped event overlaps with the group's events + const groupEvents = Array.from(existingGroup.querySelectorAll('swp-event')) as HTMLElement[]; + let overlapsWithGroup = false; + + for (const groupEvent of groupEvents) { + const existingEvent = this.elementToCalendarEvent(groupEvent); + if (!existingEvent) continue; + + const overlapType = this.overlapManager.detectOverlap(droppedEvent, existingEvent); + if (overlapType === OverlapType.COLUMN_SHARING) { + overlapsWithGroup = true; + break; + } + } + + if (overlapsWithGroup) { + // Simply add the dropped event to the existing group + this.updateElementDataset(droppedElement, droppedEvent); + this.overlapManager.addToEventGroup(existingGroup, droppedElement); + return; + } + } + + // No existing group or no overlap with existing group - run full overlap detection + const existingEvents = Array.from(eventsLayer.querySelectorAll('swp-event')) + .filter(el => el !== droppedElement) as HTMLElement[]; + // Check if dropped event overlaps with any existing events let hasOverlaps = false; - const overlappingEvents: CalendarEvent[] = [droppedEvent]; + const overlappingEvents: CalendarEvent[] = []; for (const existingElement of existingEvents) { const existingEvent = this.elementToCalendarEvent(existingElement); if (!existingEvent) continue; + // Skip if it's the same event (comparing IDs) + if (existingEvent.id === droppedEvent.id) continue; + const overlapType = this.overlapManager.detectOverlap(droppedEvent, existingEvent); if (overlapType !== OverlapType.NONE) { hasOverlaps = true; @@ -389,6 +418,9 @@ export abstract class BaseEventRenderer implements EventRendererStrategy { } } + // Add dropped event LAST so it appears rightmost in flexbox + overlappingEvents.push(droppedEvent); + // Only re-render if there are actual overlaps if (!hasOverlaps) { // No overlaps - just update the dropped element's dataset with new times