Refactors calendar managers to components

Reorganizes navigation, view selector, and workweek preset managers into separate component files

Improves code organization by moving specialized manager classes to a more descriptive components directory

Adds enhanced logging for all-day event management and drag-and-drop interactions
This commit is contained in:
Janus C. H. Knudsen 2025-11-08 14:30:18 +01:00
parent bd8f5ae6c6
commit b566aafb19
5 changed files with 73 additions and 15 deletions

View file

@ -23,7 +23,7 @@ import { CoreEvents } from '../constants/CoreEvents';
* ============
* - NavigationManager: Performs actual navigation logic (animations, grid updates, week calculations)
*/
export class NavigationButtonsManager {
export class NavigationButtons {
private eventBus: IEventBus;
private buttonListeners: Map<Element, EventListener> = new Map();

View file

@ -32,7 +32,7 @@ import { Configuration } from '../configurations/CalendarConfig';
* - GridRenderer: Uses view parameter (currently only supports 'week')
* - Future: DayRenderer, MonthRenderer when implemented
*/
export class ViewSelectorManager {
export class ViewSelector {
private eventBus: IEventBus;
private config: Configuration;
private buttonListeners: Map<Element, EventListener> = new Map();

View file

@ -30,7 +30,7 @@ import { WORK_WEEK_PRESETS, Configuration } from '../configurations/CalendarConf
* - CalendarManager: Relays to header update (via workweek:header-update)
* - HeaderManager: Updates date headers
*/
export class WorkweekPresetsManager {
export class WorkweekPresets {
private eventBus: IEventBus;
private config: Configuration;
private buttonListeners: Map<Element, EventListener> = new Map();

View file

@ -12,15 +12,15 @@ import { EventRenderingService } from './renderers/EventRendererManager';
import { GridManager } from './managers/GridManager';
import { ScrollManager } from './managers/ScrollManager';
import { NavigationManager } from './managers/NavigationManager';
import { NavigationButtonsManager } from './managers/NavigationButtonsManager';
import { ViewSelectorManager } from './managers/ViewSelectorManager';
import { NavigationButtons } from './components/NavigationButtons';
import { ViewSelector } from './components/ViewSelector';
import { CalendarManager } from './managers/CalendarManager';
import { DragDropManager } from './managers/DragDropManager';
import { AllDayManager } from './managers/AllDayManager';
import { ResizeHandleManager } from './managers/ResizeHandleManager';
import { EdgeScrollManager } from './managers/EdgeScrollManager';
import { HeaderManager } from './managers/HeaderManager';
import { WorkweekPresetsManager } from './managers/WorkweekPresetsManager';
import { WorkweekPresets } from './components/WorkweekPresets';
// Import repositories and storage
import { IEventRepository } from './repositories/IEventRepository';
@ -125,15 +125,15 @@ async function initializeCalendar(): Promise<void> {
builder.registerType(GridManager).as<GridManager>();
builder.registerType(ScrollManager).as<ScrollManager>();
builder.registerType(NavigationManager).as<NavigationManager>();
builder.registerType(NavigationButtonsManager).as<NavigationButtonsManager>();
builder.registerType(ViewSelectorManager).as<ViewSelectorManager>();
builder.registerType(NavigationButtons).as<NavigationButtons>();
builder.registerType(ViewSelector).as<ViewSelector>();
builder.registerType(DragDropManager).as<DragDropManager>();
builder.registerType(AllDayManager).as<AllDayManager>();
builder.registerType(ResizeHandleManager).as<ResizeHandleManager>();
builder.registerType(EdgeScrollManager).as<EdgeScrollManager>();
builder.registerType(HeaderManager).as<HeaderManager>();
builder.registerType(CalendarManager).as<CalendarManager>();
builder.registerType(WorkweekPresetsManager).as<WorkweekPresetsManager>();
builder.registerType(WorkweekPresets).as<WorkweekPresets>();
builder.registerType(ConfigManager).as<ConfigManager>();
builder.registerType(EventManager).as<EventManager>();
@ -148,13 +148,13 @@ async function initializeCalendar(): Promise<void> {
const resizeHandleManager = app.resolveType<ResizeHandleManager>();
const headerManager = app.resolveType<HeaderManager>();
const dragDropManager = app.resolveType<DragDropManager>();
const viewSelectorManager = app.resolveType<ViewSelectorManager>();
const viewSelectorManager = app.resolveType<ViewSelector>();
const navigationManager = app.resolveType<NavigationManager>();
const navigationButtonsManager = app.resolveType<NavigationButtonsManager>();
const navigationButtonsManager = app.resolveType<NavigationButtons>();
const edgeScrollManager = app.resolveType<EdgeScrollManager>();
const allDayManager = app.resolveType<AllDayManager>();
const urlManager = app.resolveType<URLManager>();
const workweekPresetsManager = app.resolveType<WorkweekPresetsManager>();
const workweekPresetsManager = app.resolveType<WorkweekPresets>();
const configManager = app.resolveType<ConfigManager>();
// Initialize managers

View file

@ -9,6 +9,7 @@ import { ICalendarEvent } from '../types/CalendarTypes';
import { SwpAllDayEventElement } from '../elements/SwpEventElement';
import {
IDragMouseEnterHeaderEventPayload,
IDragMouseEnterColumnEventPayload,
IDragStartEventPayload,
IDragMoveEventPayload,
IDragEndEventPayload,
@ -107,12 +108,45 @@ export class AllDayManager {
});
eventBus.on('drag:end', (event) => {
let draggedElement: IDragEndEventPayload = (event as CustomEvent<IDragEndEventPayload>).detail;
let dragEndPayload: IDragEndEventPayload = (event as CustomEvent<IDragEndEventPayload>).detail;
if (draggedElement.target != 'swp-day-header') // we are not inside the swp-day-header, so just ignore.
console.log('🎯 AllDayManager: drag:end received', {
target: dragEndPayload.target,
originalElementTag: dragEndPayload.originalElement?.tagName,
hasAllDayAttribute: dragEndPayload.originalElement?.hasAttribute('data-allday'),
eventId: dragEndPayload.originalElement?.dataset.eventId
});
// Handle all-day → all-day drops (within header)
if (dragEndPayload.target === 'swp-day-header') {
console.log('✅ AllDayManager: Handling all-day → all-day drop');
this.handleDragEnd(dragEndPayload);
return;
}
this.handleDragEnd(draggedElement);
// Handle all-day → timed conversion (dropped in column)
if (dragEndPayload.target === 'swp-day-column' && dragEndPayload.originalElement?.hasAttribute('data-allday')) {
const eventId = dragEndPayload.originalElement.dataset.eventId;
console.log('🔄 AllDayManager: All-day → timed conversion', {
eventId,
currentLayoutsCount: this.currentLayouts.length,
layoutsBeforeFilter: this.currentLayouts.map(l => l.calenderEvent.id)
});
// Remove event from currentLayouts since it's now a timed event
this.currentLayouts = this.currentLayouts.filter(
layout => layout.calenderEvent.id !== eventId
);
console.log('📊 AllDayManager: After filter', {
currentLayoutsCount: this.currentLayouts.length,
layoutsAfterFilter: this.currentLayouts.map(l => l.calenderEvent.id)
});
// Recalculate and animate header height
this.checkAndAnimateAllDayHeight();
}
});
// Listen for drag cancellation to recalculate height
@ -189,6 +223,15 @@ export class AllDayManager {
* Check current all-day events and animate to correct height
*/
public checkAndAnimateAllDayHeight(): void {
console.log('📏 AllDayManager: checkAndAnimateAllDayHeight called', {
currentLayoutsCount: this.currentLayouts.length,
layouts: this.currentLayouts.map(l => ({
id: l.calenderEvent.id,
row: l.row,
title: l.calenderEvent.title
}))
});
// Calculate required rows - 0 if no events (will collapse)
let maxRows = 0;
@ -205,6 +248,12 @@ export class AllDayManager {
}
console.log('📊 AllDayManager: Height calculation', {
maxRows,
currentLayoutsLength: this.currentLayouts.length,
isExpanded: this.isExpanded
});
// Store actual row count
this.actualRowCount = maxRows;
@ -233,6 +282,12 @@ export class AllDayManager {
this.clearOverflowIndicators();
}
console.log('🎬 AllDayManager: Will animate to', {
displayRows,
maxRows,
willAnimate: displayRows !== this.actualRowCount
});
// Animate to required rows (0 = collapse, >0 = expand)
this.animateToRows(displayRows);
}
@ -339,6 +394,9 @@ export class AllDayManager {
ColumnDetectionUtils.updateColumnBoundsCache();
// Recalculate height after adding all-day event
this.checkAndAnimateAllDayHeight();
}