Fixes event stacking order during drag and drop
Ensures existing events maintain their base positions when a new event is dragged and dropped into an overlapping time slot. The fix prioritizes existing events in the stack, placing the newly dropped event on top. This ensures correct visual representation and expected behavior during event manipulation.
This commit is contained in:
parent
c7716d1b8f
commit
727a6ec53a
1 changed files with 17 additions and 6 deletions
|
|
@ -574,13 +574,24 @@ export abstract class BaseEventRenderer implements EventRendererStrategy {
|
|||
|
||||
eventsLayer.appendChild(groupContainer);
|
||||
} else if (overlapType === OverlapType.STACKING) {
|
||||
// Handle stacking - sort by duration and stack shorter events on top
|
||||
const sortedEvents = [...overlappingEvents].sort((a, b) => {
|
||||
// CRITICAL FIX: Respect existing event position - they stay as base
|
||||
|
||||
// Separate existing events from the dropped event
|
||||
const existingInOverlap = overlappingEvents.filter(e => e.id !== droppedEvent.id);
|
||||
const droppedIsInList = overlappingEvents.find(e => e.id === droppedEvent.id);
|
||||
|
||||
// Sort ONLY existing events by duration (among themselves)
|
||||
const sortedExisting = [...existingInOverlap].sort((a, b) => {
|
||||
const durationA = new Date(a.end).getTime() - new Date(a.start).getTime();
|
||||
const durationB = new Date(b.end).getTime() - new Date(b.start).getTime();
|
||||
return durationB - durationA; // Longer duration first (background)
|
||||
return durationB - durationA; // Longer existing first
|
||||
});
|
||||
|
||||
// FINAL ORDER: Existing events first (base), dropped event LAST (stacked on top)
|
||||
const finalEventOrder = droppedIsInList
|
||||
? [...sortedExisting, droppedEvent]
|
||||
: sortedExisting;
|
||||
|
||||
// Remove overlapping events from DOM
|
||||
const overlappingEventIds = new Set(overlappingEvents.map(e => e.id));
|
||||
existingEvents
|
||||
|
|
@ -590,16 +601,16 @@ export abstract class BaseEventRenderer implements EventRendererStrategy {
|
|||
|
||||
let underlyingElement: HTMLElement | null = null;
|
||||
|
||||
sortedEvents.forEach((event, index) => {
|
||||
finalEventOrder.forEach((event, index) => {
|
||||
const eventElement = this.createEventElement(event);
|
||||
this.positionEvent(eventElement, event);
|
||||
|
||||
if (index === 0) {
|
||||
// First (longest duration) event renders normally at full width
|
||||
// First event (existing) - always remains base position
|
||||
eventsLayer.appendChild(eventElement);
|
||||
underlyingElement = eventElement;
|
||||
} else {
|
||||
// Shorter events are stacked with margin-left offset and higher z-index
|
||||
// Subsequent events (including dropped) - stacked on top
|
||||
if (underlyingElement) {
|
||||
this.overlapManager.createStackedEvent(eventElement, underlyingElement, index);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue