wip
This commit is contained in:
parent
88702e574a
commit
89e8a3f7b2
6 changed files with 137 additions and 198 deletions
|
|
@ -3,21 +3,20 @@ import { SwpAllDayEventElement } from '../elements/SwpEventElement';
|
|||
import { EventLayout } from '../utils/AllDayLayoutEngine';
|
||||
import { ColumnBounds } from '../utils/ColumnDetectionUtils';
|
||||
import { EventManager } from '../managers/EventManager';
|
||||
/**
|
||||
* AllDayEventRenderer - Simple rendering of all-day events
|
||||
* Handles adding and removing all-day events from the header container
|
||||
* NOTE: Layout calculation is now handled by AllDayManager
|
||||
*/
|
||||
import { DragStartEventPayload } from '../types/EventTypes';
|
||||
import { EventRendererStrategy } from './EventRenderer';
|
||||
|
||||
export class AllDayEventRenderer {
|
||||
|
||||
private container: HTMLElement | null = null;
|
||||
private originalEvent: HTMLElement | null = null;
|
||||
private draggedClone: HTMLElement | null = null;
|
||||
|
||||
constructor() {
|
||||
this.getContainer();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get or cache all-day container, create if it doesn't exist - SIMPLIFIED (no ghost columns)
|
||||
*/
|
||||
|
||||
private getContainer(): HTMLElement | null {
|
||||
|
||||
const header = document.querySelector('swp-calendar-header');
|
||||
|
|
@ -27,14 +26,45 @@ export class AllDayEventRenderer {
|
|||
if (!this.container) {
|
||||
this.container = document.createElement('swp-allday-container');
|
||||
header.appendChild(this.container);
|
||||
|
||||
}
|
||||
}
|
||||
return this.container;
|
||||
|
||||
}
|
||||
|
||||
// REMOVED: createGhostColumns() method - no longer needed!
|
||||
|
||||
private getAllDayContainer(): HTMLElement | null {
|
||||
return document.querySelector('swp-calendar-header swp-allday-container');
|
||||
}
|
||||
/**
|
||||
* Handle drag start for all-day events
|
||||
*/
|
||||
public handleDragStart(payload: DragStartEventPayload): void {
|
||||
|
||||
this.originalEvent = payload.draggedElement;;
|
||||
this.draggedClone = payload.draggedClone;
|
||||
|
||||
if (this.draggedClone) {
|
||||
|
||||
const container = this.getAllDayContainer();
|
||||
if (!container) return;
|
||||
|
||||
this.draggedClone.style.gridColumn = this.originalEvent.style.gridColumn;
|
||||
this.draggedClone.style.gridRow = this.originalEvent.style.gridRow;
|
||||
console.log('handleDragStart:this.draggedClone', this.draggedClone);
|
||||
container.appendChild(this.draggedClone);
|
||||
|
||||
// Add dragging style
|
||||
this.draggedClone.classList.add('dragging');
|
||||
this.draggedClone.style.zIndex = '1000';
|
||||
this.draggedClone.style.cursor = 'grabbing';
|
||||
|
||||
// Make original semi-transparent
|
||||
this.originalEvent.style.opacity = '0.3';
|
||||
this.originalEvent.style.userSelect = 'none';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Render an all-day event with pre-calculated layout
|
||||
|
|
@ -77,28 +107,14 @@ export class AllDayEventRenderer {
|
|||
* Render all-day events for specific period using AllDayEventRenderer
|
||||
*/
|
||||
public renderAllDayEventsForPeriod(eventLayouts: EventLayout[]): void {
|
||||
// Get events from EventManager for the period
|
||||
// const events = this.eventManager.getEventsForPeriod(startDate, endDate);
|
||||
|
||||
|
||||
|
||||
// Clear existing all-day events first
|
||||
this.clearAllDayEvents();
|
||||
|
||||
// Get actual visible dates from DOM headers instead of generating them
|
||||
|
||||
// const layouts = this.allDayManager.initAllDayEventsLayout(allDayEvents, weekDates);
|
||||
|
||||
// Render each all-day event with pre-calculated layout
|
||||
eventLayouts.forEach(layout => {
|
||||
this.renderAllDayEventWithLayout(layout.calenderEvent, layout);
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
/**
|
||||
* Clear only all-day events
|
||||
*/
|
||||
|
||||
private clearAllDayEvents(): void {
|
||||
const allDayContainer = document.querySelector('swp-allday-container');
|
||||
if (allDayContainer) {
|
||||
|
|
|
|||
|
|
@ -26,25 +26,32 @@ export interface EventRendererStrategy {
|
|||
handleColumnChange?(payload: DragColumnChangeEventPayload): void;
|
||||
handleNavigationCompleted?(): void;
|
||||
}
|
||||
// Abstract methods that subclasses must implement
|
||||
// private getColumns(container: HTMLElement): HTMLElement[];
|
||||
// private getEventsForColumn(column: HTMLElement, events: CalendarEvent[]): CalendarEvent[];
|
||||
|
||||
|
||||
/**
|
||||
* Base class for event renderers with common functionality
|
||||
* Date-based event renderer
|
||||
*/
|
||||
export abstract class BaseEventRenderer implements EventRendererStrategy {
|
||||
protected dateCalculator: DateCalculator;
|
||||
export class DateEventRenderer implements EventRendererStrategy {
|
||||
|
||||
// Drag and drop state
|
||||
private draggedClone: HTMLElement | null = null;
|
||||
private originalEvent: HTMLElement | null = null;
|
||||
|
||||
// Resize manager
|
||||
|
||||
constructor(dateCalculator?: DateCalculator) {
|
||||
|
||||
if (!dateCalculator) {
|
||||
DateCalculator.initialize(calendarConfig);
|
||||
}
|
||||
this.dateCalculator = dateCalculator || new DateCalculator();
|
||||
|
||||
|
||||
this.setupDragEventListeners();
|
||||
}
|
||||
private dateCalculator: DateCalculator;
|
||||
|
||||
private draggedClone: HTMLElement | null = null;
|
||||
private originalEvent: HTMLElement | null = null;
|
||||
|
||||
|
||||
// ============================================
|
||||
// NEW OVERLAP DETECTION SYSTEM
|
||||
|
|
@ -96,10 +103,7 @@ export abstract class BaseEventRenderer implements EventRendererStrategy {
|
|||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Apply common drag styling to an element
|
||||
*/
|
||||
|
||||
private applyDragStyling(element: HTMLElement): void {
|
||||
element.classList.add('dragging');
|
||||
}
|
||||
|
|
@ -127,8 +131,8 @@ export abstract class BaseEventRenderer implements EventRendererStrategy {
|
|||
// Snap to interval
|
||||
const snappedStartMinutes = Math.round(actualStartMinutes / snapInterval) * snapInterval;
|
||||
|
||||
|
||||
if(!clone.dataset.originalDuration)
|
||||
|
||||
if (!clone.dataset.originalDuration)
|
||||
throw new DOMException("missing clone.dataset.originalDuration")
|
||||
|
||||
const endTotalMinutes = snappedStartMinutes + parseInt(clone.dataset.originalDuration);
|
||||
|
|
@ -153,7 +157,7 @@ export abstract class BaseEventRenderer implements EventRendererStrategy {
|
|||
this.draggedClone = payload.draggedClone;
|
||||
|
||||
if (this.draggedClone) {
|
||||
// Apply drag styling
|
||||
// Apply drag styling
|
||||
this.applyDragStyling(this.draggedClone);
|
||||
|
||||
// Add to current column's events layer (not directly to column)
|
||||
|
|
@ -296,7 +300,7 @@ export abstract class BaseEventRenderer implements EventRendererStrategy {
|
|||
|
||||
// Fade out original
|
||||
// TODO: this should be changed into a subscriber which only after a succesful placement is fired, not just mouseup as this can remove elements that are not placed.
|
||||
this.fadeOutAndRemove(originalElement);
|
||||
this.fadeOutAndRemove(originalElement);
|
||||
|
||||
// Remove clone prefix and normalize clone to be a regular event
|
||||
const cloneId = draggedClone.dataset.eventId;
|
||||
|
|
@ -452,17 +456,14 @@ export abstract class BaseEventRenderer implements EventRendererStrategy {
|
|||
});
|
||||
}
|
||||
|
||||
// Abstract methods that subclasses must implement
|
||||
protected abstract getColumns(container: HTMLElement): HTMLElement[];
|
||||
protected abstract getEventsForColumn(column: HTMLElement, events: CalendarEvent[]): CalendarEvent[];
|
||||
|
||||
|
||||
protected renderEvent(event: CalendarEvent): HTMLElement {
|
||||
private renderEvent(event: CalendarEvent): HTMLElement {
|
||||
const swpEvent = SwpEventElement.fromCalendarEvent(event);
|
||||
const eventElement = swpEvent.getElement();
|
||||
|
||||
// Setup resize handles on first mouseover only
|
||||
eventElement.addEventListener('mouseover', () => {
|
||||
eventElement.addEventListener('mouseover', () => { // TODO: This is not the correct way... we should not add eventlistener on every event
|
||||
if (eventElement.dataset.hasResizeHandlers !== 'true') {
|
||||
eventElement.dataset.hasResizeHandlers = 'true';
|
||||
}
|
||||
|
|
@ -544,16 +545,7 @@ export abstract class BaseEventRenderer implements EventRendererStrategy {
|
|||
element.style.minWidth = '50px';
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Date-based event renderer
|
||||
*/
|
||||
export class DateEventRenderer extends BaseEventRenderer {
|
||||
constructor(dateCalculator?: DateCalculator) {
|
||||
super(dateCalculator);
|
||||
this.setupDragEventListeners();
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup drag event listeners - placeholder method
|
||||
|
|
@ -585,32 +577,3 @@ export class DateEventRenderer extends BaseEventRenderer {
|
|||
return columnEvents;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Resource-based event renderer
|
||||
*/
|
||||
export class ResourceEventRenderer extends BaseEventRenderer {
|
||||
protected getColumns(container: HTMLElement): HTMLElement[] {
|
||||
const columns = container.querySelectorAll('swp-resource-column');
|
||||
return Array.from(columns) as HTMLElement[];
|
||||
}
|
||||
|
||||
protected getEventsForColumn(column: HTMLElement, events: CalendarEvent[]): CalendarEvent[] {
|
||||
const resourceName = column.dataset.resource;
|
||||
if (!resourceName) return [];
|
||||
|
||||
const columnEvents = events.filter(event => {
|
||||
return event.resource?.name === resourceName;
|
||||
});
|
||||
|
||||
return columnEvents;
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// NEW OVERLAP DETECTION SYSTEM
|
||||
// All new functions prefixed with new_
|
||||
// ============================================
|
||||
|
||||
protected overlapDetector = new OverlapDetector();
|
||||
|
||||
}
|
||||
|
|
@ -142,29 +142,29 @@ export class EventRenderingService {
|
|||
* Setup all drag event listeners - moved from EventRenderer for better separation of concerns
|
||||
*/
|
||||
private setupDragEventListeners(): void {
|
||||
// Handle drag start
|
||||
this.eventBus.on('drag:start', (event: Event) => {
|
||||
const dragStartPayload = (event as CustomEvent<DragStartEventPayload>).detail;
|
||||
// Use the draggedElement directly - no need for DOM query
|
||||
|
||||
if (dragStartPayload.draggedElement.hasAttribute('data-allday')) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (dragStartPayload.draggedElement && this.strategy.handleDragStart && dragStartPayload.columnBounds) {
|
||||
this.strategy.handleDragStart(dragStartPayload);
|
||||
}
|
||||
});
|
||||
|
||||
// Handle drag move
|
||||
this.eventBus.on('drag:move', (event: Event) => {
|
||||
let dragEvent = (event as CustomEvent<DragMoveEventPayload>).detail;
|
||||
|
||||
// Filter: Only handle events WITHOUT data-allday attribute (normal timed events)
|
||||
if (dragEvent.draggedElement.hasAttribute('data-allday')) {
|
||||
return; // This is an all-day event, let AllDayManager handle it
|
||||
return;
|
||||
}
|
||||
if (this.strategy.handleDragMove) {
|
||||
this.strategy.handleDragMove(dragEvent);
|
||||
}
|
||||
});
|
||||
|
||||
// Handle drag auto-scroll
|
||||
this.eventBus.on('drag:auto-scroll', (event: Event) => {
|
||||
const { draggedElement, snappedY } = (event as CustomEvent).detail;
|
||||
if (this.strategy.handleDragAutoScroll) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue