Refactors all-day event rendering and DOM access
Decouples all-day event rendering, making it reactive to header readiness with period data. Eliminates explicit DOM element caching, simplifying element access. Enhances the `header:ready` event payload with `startDate` and `endDate`. Improves all-day row height animation and calculation.
This commit is contained in:
parent
f5e9909935
commit
6498b0ba8e
6 changed files with 98 additions and 116 deletions
|
|
@ -16,9 +16,6 @@ import {
|
|||
* Separated from HeaderManager for clean responsibility separation
|
||||
*/
|
||||
export class AllDayManager {
|
||||
private cachedAllDayContainer: HTMLElement | null = null;
|
||||
private cachedCalendarHeader: HTMLElement | null = null;
|
||||
private cachedHeaderSpacer: HTMLElement | null = null;
|
||||
private allDayEventRenderer: AllDayEventRenderer;
|
||||
|
||||
constructor() {
|
||||
|
|
@ -40,12 +37,12 @@ export class AllDayManager {
|
|||
originalElementId: originalElement?.dataset?.eventId,
|
||||
originalElementTag: originalElement?.tagName
|
||||
});
|
||||
|
||||
|
||||
if (targetDate && cloneElement) {
|
||||
this.handleConvertToAllDay(targetDate, cloneElement);
|
||||
}
|
||||
|
||||
this.checkAndAnimateAllDayHeight ();
|
||||
this.checkAndAnimateAllDayHeight();
|
||||
});
|
||||
|
||||
eventBus.on('drag:mouseleave-header', (event) => {
|
||||
|
|
@ -59,7 +56,7 @@ export class AllDayManager {
|
|||
this.handleConvertFromAllDay(cloneElement);
|
||||
}
|
||||
|
||||
this.checkAndAnimateAllDayHeight ();
|
||||
this.checkAndAnimateAllDayHeight();
|
||||
|
||||
});
|
||||
|
||||
|
|
@ -111,12 +108,12 @@ export class AllDayManager {
|
|||
// Listen for drag cancellation to recalculate height
|
||||
eventBus.on('drag:cancelled', (event) => {
|
||||
const { draggedElement, reason } = (event as CustomEvent).detail;
|
||||
|
||||
|
||||
console.log('🚫 AllDayManager: Drag cancelled', {
|
||||
eventId: draggedElement?.dataset?.eventId,
|
||||
reason
|
||||
});
|
||||
|
||||
|
||||
// Recalculate all-day height since clones may have been removed
|
||||
this.checkAndAnimateAllDayHeight();
|
||||
});
|
||||
|
|
@ -128,37 +125,17 @@ export class AllDayManager {
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get cached all-day container element
|
||||
*/
|
||||
|
||||
private getAllDayContainer(): HTMLElement | null {
|
||||
if (!this.cachedAllDayContainer) {
|
||||
const calendarHeader = this.getCalendarHeader();
|
||||
if (calendarHeader) {
|
||||
this.cachedAllDayContainer = calendarHeader.querySelector('swp-allday-container');
|
||||
}
|
||||
}
|
||||
return this.cachedAllDayContainer;
|
||||
return document.querySelector('swp-calendar-header swp-allday-container');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get cached calendar header element
|
||||
*/
|
||||
private getCalendarHeader(): HTMLElement | null {
|
||||
if (!this.cachedCalendarHeader) {
|
||||
this.cachedCalendarHeader = document.querySelector('swp-calendar-header');
|
||||
}
|
||||
return this.cachedCalendarHeader;
|
||||
return document.querySelector('swp-calendar-header');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get cached header spacer element
|
||||
*/
|
||||
private getHeaderSpacer(): HTMLElement | null {
|
||||
if (!this.cachedHeaderSpacer) {
|
||||
this.cachedHeaderSpacer = document.querySelector('swp-header-spacer');
|
||||
}
|
||||
return this.cachedHeaderSpacer;
|
||||
return document.querySelector('swp-header-spacer');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -177,15 +154,6 @@ export class AllDayManager {
|
|||
return { targetHeight, currentHeight, heightDifference };
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear cached DOM elements (call when DOM structure changes)
|
||||
*/
|
||||
private clearCache(): void {
|
||||
this.cachedCalendarHeader = null;
|
||||
this.cachedAllDayContainer = null;
|
||||
this.cachedHeaderSpacer = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Collapse all-day row when no events
|
||||
*/
|
||||
|
|
@ -198,7 +166,10 @@ export class AllDayManager {
|
|||
*/
|
||||
public checkAndAnimateAllDayHeight(): void {
|
||||
const container = this.getAllDayContainer();
|
||||
if (!container) return;
|
||||
if (!container) {
|
||||
this.animateToRows(0);
|
||||
return;
|
||||
}
|
||||
|
||||
const allDayEvents = container.querySelectorAll('swp-event');
|
||||
|
||||
|
|
@ -208,15 +179,15 @@ export class AllDayManager {
|
|||
if (allDayEvents.length > 0) {
|
||||
// Track which rows are actually used by checking grid positions
|
||||
const usedRows = new Set<number>();
|
||||
|
||||
|
||||
(Array.from(allDayEvents) as HTMLElement[]).forEach((event: HTMLElement) => {
|
||||
const gridRow = parseInt(getComputedStyle(event).gridRowStart) || 1;
|
||||
usedRows.add(gridRow);
|
||||
});
|
||||
|
||||
|
||||
// Max rows = highest row number in use
|
||||
maxRows = usedRows.size > 0 ? Math.max(...usedRows) : 0;
|
||||
|
||||
|
||||
console.log('🔍 AllDayManager: Height calculation', {
|
||||
totalEvents: allDayEvents.length,
|
||||
usedRows: Array.from(usedRows).sort(),
|
||||
|
|
@ -254,7 +225,7 @@ export class AllDayManager {
|
|||
{ height: `${currentParentHeight}px` },
|
||||
{ height: `${targetParentHeight}px` }
|
||||
], {
|
||||
duration: 300,
|
||||
duration: 150,
|
||||
easing: 'ease-out',
|
||||
fill: 'forwards'
|
||||
})
|
||||
|
|
@ -464,7 +435,7 @@ export class AllDayManager {
|
|||
* Handle drag end for all-day events
|
||||
*/
|
||||
private handleDragEnd(originalElement: HTMLElement, dragClone: HTMLElement, finalPosition: any): void {
|
||||
|
||||
|
||||
// Normalize clone
|
||||
const cloneId = dragClone.dataset.eventId;
|
||||
if (cloneId?.startsWith('clone-')) {
|
||||
|
|
@ -484,12 +455,4 @@ export class AllDayManager {
|
|||
finalColumn: dragClone.style.gridColumn
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Clean up cached elements and resources
|
||||
*/
|
||||
public destroy(): void {
|
||||
this.clearCache();
|
||||
}
|
||||
}
|
||||
|
|
@ -4,7 +4,8 @@ import { CalendarTypeFactory } from '../factories/CalendarTypeFactory';
|
|||
import { CoreEvents } from '../constants/CoreEvents';
|
||||
import { HeaderRenderContext } from '../renderers/HeaderRenderer';
|
||||
import { ResourceCalendarData } from '../types/CalendarTypes';
|
||||
import { DragMouseEnterHeaderEventPayload, DragMouseLeaveHeaderEventPayload } from '../types/EventTypes';
|
||||
import { DragMouseEnterHeaderEventPayload, DragMouseLeaveHeaderEventPayload, HeaderReadyEventPayload } from '../types/EventTypes';
|
||||
import { DateCalculator } from '../utils/DateCalculator';
|
||||
|
||||
/**
|
||||
* HeaderManager - Handles all header-related event logic
|
||||
|
|
@ -172,10 +173,18 @@ export class HeaderManager {
|
|||
// Setup event listeners on the new content
|
||||
this.setupHeaderDragListeners();
|
||||
|
||||
// Notify other managers that header is ready
|
||||
eventBus.emit('header:ready', {
|
||||
headerElement: calendarHeader
|
||||
});
|
||||
// Calculate period from current date
|
||||
const weekStart = DateCalculator.getISOWeekStart(currentDate);
|
||||
const weekEnd = DateCalculator.addDays(weekStart, 6);
|
||||
|
||||
// Notify other managers that header is ready with period data
|
||||
const payload: HeaderReadyEventPayload = {
|
||||
headerElement: calendarHeader,
|
||||
startDate: weekStart,
|
||||
endDate: weekEnd,
|
||||
isNavigation: false
|
||||
};
|
||||
eventBus.emit('header:ready', payload);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue