Fixes drag and drop to header issues
Addresses two key issues related to dragging events to the header: the premature removal of the original event element and the creation of duplicate all-day events. The original event is no longer removed when dragging to the header; it is now only removed upon a successful drop. Also, it prevents the creation of duplicate all-day events by checking for existing all-day events before creating new ones, using DOM queries to ensure accurate state.
This commit is contained in:
parent
b4af5a9211
commit
46b8bf9fb5
10 changed files with 684 additions and 61 deletions
|
|
@ -170,10 +170,11 @@ export class SwpAllDayEventElement extends BaseEventElement {
|
|||
*/
|
||||
private setAllDayAttributes(): void {
|
||||
this.element.dataset.allDay = "true";
|
||||
// Override start/end times to be full day
|
||||
const dateStr = this.event.start.toISOString().split('T')[0];
|
||||
this.element.dataset.start = `${dateStr}T00:00:00`;
|
||||
this.element.dataset.end = `${dateStr}T23:59:59`;
|
||||
// For all-day events, preserve original start/end dates but set to full day times
|
||||
const startDateStr = this.event.start.toISOString().split('T')[0];
|
||||
const endDateStr = this.event.end.toISOString().split('T')[0];
|
||||
this.element.dataset.start = `${startDateStr}T00:00:00`;
|
||||
this.element.dataset.end = `${endDateStr}T23:59:59`;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -197,28 +198,36 @@ export class SwpAllDayEventElement extends BaseEventElement {
|
|||
this.element.style.gridRow = row.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set grid column span for this all-day event
|
||||
*/
|
||||
public setColumnSpan(startColumn: number, endColumn: number): void {
|
||||
this.element.style.gridColumn = `${startColumn} / ${endColumn + 1}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method to create from CalendarEvent and target date
|
||||
*/
|
||||
public static fromCalendarEvent(event: CalendarEvent, targetDate: string): SwpAllDayEventElement {
|
||||
// Calculate column index
|
||||
const dayHeaders = document.querySelectorAll('swp-day-header');
|
||||
let columnIndex = 1;
|
||||
dayHeaders.forEach((header, index) => {
|
||||
if ((header as HTMLElement).dataset.date === targetDate) {
|
||||
columnIndex = index + 1;
|
||||
}
|
||||
});
|
||||
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);
|
||||
|
||||
// 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 this column using computedStyle
|
||||
// Find occupied rows in the spanned columns using computedStyle
|
||||
const existingEvents = document.querySelectorAll('swp-allday-event');
|
||||
const occupiedRows = new Set<number>();
|
||||
|
||||
existingEvents.forEach(existingEvent => {
|
||||
const style = getComputedStyle(existingEvent);
|
||||
const eventCol = parseInt(style.gridColumnStart);
|
||||
const eventStartCol = parseInt(style.gridColumnStart);
|
||||
const eventEndCol = parseInt(style.gridColumnEnd);
|
||||
|
||||
if (eventCol === columnIndex) {
|
||||
// Check if this existing event overlaps with our column span
|
||||
if (this.columnsOverlap(eventStartCol, eventEndCol, finalStartColumn, finalEndColumn)) {
|
||||
const eventRow = parseInt(style.gridRowStart) || 1;
|
||||
occupiedRows.add(eventRow);
|
||||
}
|
||||
|
|
@ -230,9 +239,73 @@ export class SwpAllDayEventElement extends BaseEventElement {
|
|||
targetRow++;
|
||||
}
|
||||
|
||||
// Create element with both column and row
|
||||
const element = new SwpAllDayEventElement(event, columnIndex);
|
||||
// Create element with calculated column span
|
||||
const element = new SwpAllDayEventElement(event, finalStartColumn);
|
||||
element.setGridRow(targetRow);
|
||||
element.setColumnSpan(finalStartColumn, finalEndColumn);
|
||||
return element;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate column span based on event start and end dates
|
||||
*/
|
||||
private static calculateColumnSpan(event: CalendarEvent): { startColumn: number; endColumn: number; columnSpan: number } {
|
||||
const dayHeaders = document.querySelectorAll('swp-day-header');
|
||||
|
||||
// Extract dates from headers
|
||||
const headerDates: string[] = [];
|
||||
dayHeaders.forEach(header => {
|
||||
const date = (header as HTMLElement).dataset.date;
|
||||
if (date) {
|
||||
headerDates.push(date);
|
||||
}
|
||||
});
|
||||
|
||||
// Format event dates for comparison (YYYY-MM-DD format)
|
||||
const eventStartDate = event.start.toISOString().split('T')[0];
|
||||
const eventEndDate = event.end.toISOString().split('T')[0];
|
||||
|
||||
// Find start and end column indices
|
||||
let startColumn = 1;
|
||||
let endColumn = headerDates.length;
|
||||
|
||||
headerDates.forEach((dateStr, index) => {
|
||||
if (dateStr === eventStartDate) {
|
||||
startColumn = index + 1;
|
||||
}
|
||||
if (dateStr === eventEndDate) {
|
||||
endColumn = index + 1;
|
||||
}
|
||||
});
|
||||
|
||||
// Ensure end column is at least start column
|
||||
if (endColumn < startColumn) {
|
||||
endColumn = startColumn;
|
||||
}
|
||||
|
||||
const columnSpan = endColumn - startColumn + 1;
|
||||
|
||||
return { startColumn, endColumn, columnSpan };
|
||||
}
|
||||
|
||||
/**
|
||||
* Get column index for a specific date
|
||||
*/
|
||||
private static getColumnIndexForDate(targetDate: string): number {
|
||||
const dayHeaders = document.querySelectorAll('swp-day-header');
|
||||
let columnIndex = 1;
|
||||
dayHeaders.forEach((header, index) => {
|
||||
if ((header as HTMLElement).dataset.date === targetDate) {
|
||||
columnIndex = index + 1;
|
||||
}
|
||||
});
|
||||
return columnIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if two column ranges overlap
|
||||
*/
|
||||
private static columnsOverlap(startA: number, endA: number, startB: number, endB: number): boolean {
|
||||
return !(endA < startB || endB < startA);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue