Introduces SwpEvent class to centralize event element data and calculations Improves drag and resize event handling by extracting common logic Simplifies calculation of event start/end times from element positions Enhances type safety and reduces code complexity in event managers Removes direct pixel/minute calculations from multiple managers
101 lines
3.4 KiB
TypeScript
101 lines
3.4 KiB
TypeScript
/**
|
|
* EventPersistenceManager - Persists event changes to IndexedDB
|
|
*
|
|
* Listens to drag/resize events and updates IndexedDB via EventService.
|
|
* This bridges the gap between UI interactions and data persistence.
|
|
*/
|
|
|
|
import { ICalendarEvent, IEventBus, IEventUpdatedPayload } from '../types/CalendarTypes';
|
|
import { EventService } from '../storage/events/EventService';
|
|
import { DateService } from '../core/DateService';
|
|
import { CoreEvents } from '../constants/CoreEvents';
|
|
import { IDragEndPayload } from '../types/DragTypes';
|
|
import { IResizeEndPayload } from '../types/ResizeTypes';
|
|
|
|
export class EventPersistenceManager {
|
|
constructor(
|
|
private eventService: EventService,
|
|
private eventBus: IEventBus,
|
|
private dateService: DateService
|
|
) {
|
|
this.setupListeners();
|
|
}
|
|
|
|
private setupListeners(): void {
|
|
this.eventBus.on(CoreEvents.EVENT_DRAG_END, this.handleDragEnd);
|
|
this.eventBus.on(CoreEvents.EVENT_RESIZE_END, this.handleResizeEnd);
|
|
}
|
|
|
|
/**
|
|
* Handle drag end - update event position in IndexedDB
|
|
*/
|
|
private handleDragEnd = async (e: Event): Promise<void> => {
|
|
const payload = (e as CustomEvent<IDragEndPayload>).detail;
|
|
const { swpEvent } = payload;
|
|
|
|
// Get existing event to merge with
|
|
const event = await this.eventService.get(swpEvent.eventId);
|
|
if (!event) {
|
|
console.warn(`EventPersistenceManager: Event ${swpEvent.eventId} not found`);
|
|
return;
|
|
}
|
|
|
|
// Update and save - start/end already calculated in SwpEvent
|
|
const updatedEvent: ICalendarEvent = {
|
|
...event,
|
|
start: swpEvent.start,
|
|
end: swpEvent.end,
|
|
resourceId: swpEvent.resourceId ?? event.resourceId,
|
|
syncStatus: 'pending'
|
|
};
|
|
|
|
await this.eventService.save(updatedEvent);
|
|
|
|
// Emit EVENT_UPDATED for EventRenderer to re-render affected columns
|
|
const targetDateKey = this.dateService.getDateKey(swpEvent.start);
|
|
const updatePayload: IEventUpdatedPayload = {
|
|
eventId: updatedEvent.id,
|
|
sourceDateKey: payload.sourceDateKey,
|
|
sourceResourceId: payload.sourceResourceId,
|
|
targetDateKey,
|
|
targetResourceId: swpEvent.resourceId
|
|
};
|
|
this.eventBus.emit(CoreEvents.EVENT_UPDATED, updatePayload);
|
|
};
|
|
|
|
/**
|
|
* Handle resize end - update event duration in IndexedDB
|
|
*/
|
|
private handleResizeEnd = async (e: Event): Promise<void> => {
|
|
const payload = (e as CustomEvent<IResizeEndPayload>).detail;
|
|
const { swpEvent } = payload;
|
|
|
|
// Get existing event to merge with
|
|
const event = await this.eventService.get(swpEvent.eventId);
|
|
if (!event) {
|
|
console.warn(`EventPersistenceManager: Event ${swpEvent.eventId} not found`);
|
|
return;
|
|
}
|
|
|
|
// Update and save - end already calculated in SwpEvent
|
|
const updatedEvent: ICalendarEvent = {
|
|
...event,
|
|
end: swpEvent.end,
|
|
syncStatus: 'pending'
|
|
};
|
|
|
|
await this.eventService.save(updatedEvent);
|
|
|
|
// Emit EVENT_UPDATED for EventRenderer to re-render the column
|
|
// Resize stays in same column, so source and target are the same
|
|
const dateKey = this.dateService.getDateKey(swpEvent.start);
|
|
const updatePayload: IEventUpdatedPayload = {
|
|
eventId: updatedEvent.id,
|
|
sourceDateKey: dateKey,
|
|
sourceResourceId: swpEvent.resourceId,
|
|
targetDateKey: dateKey,
|
|
targetResourceId: swpEvent.resourceId
|
|
};
|
|
this.eventBus.emit(CoreEvents.EVENT_UPDATED, updatePayload);
|
|
};
|
|
}
|