Improves all-day event drag and drop
Addresses issues with all-day event duration calculation and positioning during drag and drop. - Uses `differenceInCalendarDays` to correctly calculate event duration across timezone and DST boundaries. - Preserves the original event time when moving events to a different day. - Snaps dragged event to the top of the target time slot.
This commit is contained in:
parent
53cf097a47
commit
4fea01c76b
3 changed files with 26 additions and 5 deletions
|
|
@ -17,6 +17,7 @@ import {
|
||||||
import { DragOffset, MousePosition } from '../types/DragDropTypes';
|
import { DragOffset, MousePosition } from '../types/DragDropTypes';
|
||||||
import { CoreEvents } from '../constants/CoreEvents';
|
import { CoreEvents } from '../constants/CoreEvents';
|
||||||
import { EventManager } from './EventManager';
|
import { EventManager } from './EventManager';
|
||||||
|
import { differenceInCalendarDays } from 'date-fns';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AllDayManager - Handles all-day row height animations and management
|
* AllDayManager - Handles all-day row height animations and management
|
||||||
|
|
@ -379,7 +380,9 @@ export class AllDayManager {
|
||||||
throw new Error('Ugyldig start eller slut-dato i dataset');
|
throw new Error('Ugyldig start eller slut-dato i dataset');
|
||||||
}
|
}
|
||||||
|
|
||||||
return Math.round((endDate.getTime() - startDate.getTime()) / (1000 * 60 * 60 * 24));
|
// Use differenceInCalendarDays for proper calendar day calculation
|
||||||
|
// This correctly handles timezone differences and DST changes
|
||||||
|
return differenceInCalendarDays(endDate, startDate);
|
||||||
};
|
};
|
||||||
|
|
||||||
if (dragEndEvent.draggedClone == null)
|
if (dragEndEvent.draggedClone == null)
|
||||||
|
|
@ -403,10 +406,23 @@ export class AllDayManager {
|
||||||
|
|
||||||
|
|
||||||
const durationDays = getEventDurationDays(dragEndEvent.draggedClone.dataset.start, dragEndEvent.draggedClone.dataset.end);
|
const durationDays = getEventDurationDays(dragEndEvent.draggedClone.dataset.start, dragEndEvent.draggedClone.dataset.end);
|
||||||
const newStartDate = new Date(eventDate);
|
|
||||||
const newEndDate = new Date(newStartDate);
|
|
||||||
newEndDate.setDate(newEndDate.getDate() + durationDays);
|
|
||||||
|
|
||||||
|
// Get original dates to preserve time
|
||||||
|
const originalStartDate = new Date(dragEndEvent.draggedClone.dataset.start!);
|
||||||
|
const originalEndDate = new Date(dragEndEvent.draggedClone.dataset.end!);
|
||||||
|
|
||||||
|
// Create new start date with the new day but preserve original time
|
||||||
|
const newStartDate = new Date(eventDate);
|
||||||
|
newStartDate.setHours(originalStartDate.getHours(), originalStartDate.getMinutes(), originalStartDate.getSeconds(), originalStartDate.getMilliseconds());
|
||||||
|
|
||||||
|
// Create new end date with the new day + duration, preserving original end time
|
||||||
|
const newEndDate = new Date(eventDate);
|
||||||
|
newEndDate.setDate(newEndDate.getDate() + durationDays);
|
||||||
|
newEndDate.setHours(originalEndDate.getHours(), originalEndDate.getMinutes(), originalEndDate.getSeconds(), originalEndDate.getMilliseconds());
|
||||||
|
|
||||||
|
// Update data attributes with new dates
|
||||||
|
dragEndEvent.draggedClone.dataset.start = newStartDate.toISOString();
|
||||||
|
dragEndEvent.draggedClone.dataset.end = newEndDate.toISOString();
|
||||||
|
|
||||||
const droppedEvent: CalendarEvent = {
|
const droppedEvent: CalendarEvent = {
|
||||||
id: eventId,
|
id: eventId,
|
||||||
|
|
|
||||||
|
|
@ -367,7 +367,11 @@ export class DragDropManager {
|
||||||
* Optimized snap position calculation using PositionUtils
|
* Optimized snap position calculation using PositionUtils
|
||||||
*/
|
*/
|
||||||
private calculateSnapPosition(mouseY: number, column: ColumnBounds): number {
|
private calculateSnapPosition(mouseY: number, column: ColumnBounds): number {
|
||||||
const snappedY = PositionUtils.getPositionFromCoordinate(mouseY, column);
|
// Calculate where the event top would be (accounting for mouse offset)
|
||||||
|
const eventTopY = mouseY - this.mouseOffset.y;
|
||||||
|
|
||||||
|
// Snap the event top position, not the mouse position
|
||||||
|
const snappedY = PositionUtils.getPositionFromCoordinate(eventTopY, column);
|
||||||
|
|
||||||
return Math.max(0, snappedY);
|
return Math.max(0, snappedY);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -239,8 +239,9 @@ export class DateEventRenderer implements EventRendererStrategy {
|
||||||
public handleDragMove(payload: DragMoveEventPayload): void {
|
public handleDragMove(payload: DragMoveEventPayload): void {
|
||||||
if (!this.draggedClone) return;
|
if (!this.draggedClone) return;
|
||||||
|
|
||||||
// Update position
|
// Update position - snappedY is already the event top position
|
||||||
this.draggedClone.style.top = (payload.snappedY - payload.mouseOffset.y) + 'px';
|
// Add +1px to match the initial positioning offset from SwpEventElement
|
||||||
|
this.draggedClone.style.top = (payload.snappedY + 1) + 'px';
|
||||||
|
|
||||||
// Update timestamp display
|
// Update timestamp display
|
||||||
this.updateCloneTimestamp(payload);
|
this.updateCloneTimestamp(payload);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue