Major refactor into type safe TS
With a risk oof rolling it all back
This commit is contained in:
parent
c08fa02c29
commit
48d1fd681c
19 changed files with 449 additions and 81 deletions
|
|
@ -80,7 +80,7 @@ export interface CalendarConfig {
|
|||
|
||||
export interface EventLogEntry {
|
||||
type: string;
|
||||
detail: any;
|
||||
detail: unknown;
|
||||
timestamp: number;
|
||||
}
|
||||
|
||||
|
|
@ -94,7 +94,7 @@ export interface IEventBus {
|
|||
on(eventType: string, handler: EventListener, options?: AddEventListenerOptions): () => void;
|
||||
once(eventType: string, handler: EventListener): () => void;
|
||||
off(eventType: string, handler: EventListener): void;
|
||||
emit(eventType: string, detail?: any): boolean;
|
||||
emit(eventType: string, detail?: unknown): boolean;
|
||||
getEventLog(eventType?: string): EventLogEntry[];
|
||||
setDebug(enabled: boolean): void;
|
||||
destroy(): void;
|
||||
|
|
|
|||
47
src/types/DragDropTypes.ts
Normal file
47
src/types/DragDropTypes.ts
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
/**
|
||||
* Type definitions for drag and drop functionality
|
||||
*/
|
||||
|
||||
export interface MousePosition {
|
||||
x: number;
|
||||
y: number;
|
||||
clientX?: number;
|
||||
clientY?: number;
|
||||
}
|
||||
|
||||
export interface DragOffset {
|
||||
x: number;
|
||||
y: number;
|
||||
offsetX?: number;
|
||||
offsetY?: number;
|
||||
}
|
||||
|
||||
export interface DragState {
|
||||
isDragging: boolean;
|
||||
draggedElement: HTMLElement | null;
|
||||
draggedClone: HTMLElement | null;
|
||||
eventId: string | null;
|
||||
startColumn: string | null;
|
||||
currentColumn: string | null;
|
||||
mouseOffset: DragOffset;
|
||||
}
|
||||
|
||||
export interface DragEndPosition {
|
||||
column: string;
|
||||
y: number;
|
||||
snappedY: number;
|
||||
time?: Date;
|
||||
}
|
||||
|
||||
export interface StackLinkData {
|
||||
prev?: string;
|
||||
next?: string;
|
||||
isFirst?: boolean;
|
||||
isLast?: boolean;
|
||||
}
|
||||
|
||||
export interface DragEventHandlers {
|
||||
handleDragStart?(originalElement: HTMLElement, eventId: string, mouseOffset: DragOffset, column: string): void;
|
||||
handleDragMove?(eventId: string, snappedY: number, column: string, mouseOffset: DragOffset): void;
|
||||
handleDragEnd?(eventId: string, originalElement: HTMLElement, draggedClone: HTMLElement, finalColumn: string, finalY: number): void;
|
||||
}
|
||||
177
src/types/EventPayloadMap.ts
Normal file
177
src/types/EventPayloadMap.ts
Normal file
|
|
@ -0,0 +1,177 @@
|
|||
import { CalendarEvent, CalendarView } from './CalendarTypes';
|
||||
import {
|
||||
DragStartEventPayload,
|
||||
DragMoveEventPayload,
|
||||
DragEndEventPayload,
|
||||
DragMouseEnterHeaderEventPayload,
|
||||
DragMouseLeaveHeaderEventPayload,
|
||||
HeaderReadyEventPayload
|
||||
} from './EventTypes';
|
||||
import { CoreEvents } from '../constants/CoreEvents';
|
||||
|
||||
/**
|
||||
* Complete type mapping for all calendar events
|
||||
* This enables type-safe event emission and handling
|
||||
*/
|
||||
export interface CalendarEventPayloadMap {
|
||||
// Lifecycle events
|
||||
[CoreEvents.INITIALIZED]: {
|
||||
initialized: boolean;
|
||||
timestamp: number;
|
||||
};
|
||||
[CoreEvents.READY]: undefined;
|
||||
[CoreEvents.DESTROYED]: undefined;
|
||||
|
||||
// View events
|
||||
[CoreEvents.VIEW_CHANGED]: {
|
||||
view: CalendarView;
|
||||
previousView?: CalendarView;
|
||||
};
|
||||
[CoreEvents.VIEW_RENDERED]: {
|
||||
view: CalendarView;
|
||||
};
|
||||
[CoreEvents.WORKWEEK_CHANGED]: {
|
||||
settings: unknown;
|
||||
};
|
||||
|
||||
// Navigation events
|
||||
[CoreEvents.DATE_CHANGED]: {
|
||||
date: Date;
|
||||
view?: CalendarView;
|
||||
};
|
||||
[CoreEvents.NAVIGATION_COMPLETED]: {
|
||||
direction: 'previous' | 'next' | 'today';
|
||||
};
|
||||
[CoreEvents.PERIOD_INFO_UPDATE]: {
|
||||
label: string;
|
||||
startDate: Date;
|
||||
endDate: Date;
|
||||
};
|
||||
[CoreEvents.NAVIGATE_TO_EVENT]: {
|
||||
eventId: string;
|
||||
};
|
||||
|
||||
// Data events
|
||||
[CoreEvents.DATA_LOADING]: undefined;
|
||||
[CoreEvents.DATA_LOADED]: {
|
||||
events: CalendarEvent[];
|
||||
count: number;
|
||||
};
|
||||
[CoreEvents.DATA_ERROR]: {
|
||||
error: Error;
|
||||
};
|
||||
[CoreEvents.EVENTS_FILTERED]: {
|
||||
filteredEvents: CalendarEvent[];
|
||||
};
|
||||
|
||||
// Grid events
|
||||
[CoreEvents.GRID_RENDERED]: {
|
||||
container: HTMLElement;
|
||||
currentDate: Date;
|
||||
startDate: Date;
|
||||
endDate: Date;
|
||||
columnCount: number;
|
||||
};
|
||||
[CoreEvents.GRID_CLICKED]: {
|
||||
column: string;
|
||||
row: number;
|
||||
};
|
||||
[CoreEvents.CELL_SELECTED]: {
|
||||
cell: HTMLElement;
|
||||
};
|
||||
|
||||
// Event management
|
||||
[CoreEvents.EVENT_CREATED]: {
|
||||
event: CalendarEvent;
|
||||
};
|
||||
[CoreEvents.EVENT_UPDATED]: {
|
||||
event: CalendarEvent;
|
||||
previousData?: Partial<CalendarEvent>;
|
||||
};
|
||||
[CoreEvents.EVENT_DELETED]: {
|
||||
eventId: string;
|
||||
};
|
||||
[CoreEvents.EVENT_SELECTED]: {
|
||||
eventId: string;
|
||||
event?: CalendarEvent;
|
||||
};
|
||||
|
||||
// System events
|
||||
[CoreEvents.ERROR]: {
|
||||
error: Error;
|
||||
context?: string;
|
||||
};
|
||||
[CoreEvents.REFRESH_REQUESTED]: {
|
||||
view?: CalendarView;
|
||||
date?: Date;
|
||||
};
|
||||
|
||||
// Filter events
|
||||
[CoreEvents.FILTER_CHANGED]: {
|
||||
activeFilters: string[];
|
||||
visibleEvents: CalendarEvent[];
|
||||
};
|
||||
|
||||
// Rendering events
|
||||
[CoreEvents.EVENTS_RENDERED]: {
|
||||
eventCount: number;
|
||||
};
|
||||
|
||||
// Drag events
|
||||
'drag:start': DragStartEventPayload;
|
||||
'drag:move': DragMoveEventPayload;
|
||||
'drag:end': DragEndEventPayload;
|
||||
'drag:mouseenter-header': DragMouseEnterHeaderEventPayload;
|
||||
'drag:mouseleave-header': DragMouseLeaveHeaderEventPayload;
|
||||
'drag:cancelled': {
|
||||
reason: string;
|
||||
};
|
||||
|
||||
// Header events
|
||||
'header:ready': HeaderReadyEventPayload;
|
||||
'header:height-changed': {
|
||||
height: number;
|
||||
rowCount: number;
|
||||
};
|
||||
|
||||
// All-day events
|
||||
'allday:checkHeight': undefined;
|
||||
'allday:convert-to-allday': {
|
||||
eventId: string;
|
||||
element: HTMLElement;
|
||||
};
|
||||
'allday:convert-from-allday': {
|
||||
eventId: string;
|
||||
element: HTMLElement;
|
||||
};
|
||||
|
||||
// Scroll events
|
||||
'scroll:sync': {
|
||||
scrollTop: number;
|
||||
source: string;
|
||||
};
|
||||
'scroll:to-hour': {
|
||||
hour: number;
|
||||
};
|
||||
|
||||
// Filter events
|
||||
'filter:updated': {
|
||||
activeFilters: string[];
|
||||
visibleEvents: CalendarEvent[];
|
||||
};
|
||||
'filter:search': {
|
||||
query: string;
|
||||
results: CalendarEvent[];
|
||||
};
|
||||
}
|
||||
|
||||
// Helper type to get payload type for a specific event
|
||||
export type EventPayload<T extends keyof CalendarEventPayloadMap> = CalendarEventPayloadMap[T];
|
||||
|
||||
// Type guard to check if an event has a payload
|
||||
export function hasPayload<T extends keyof CalendarEventPayloadMap>(
|
||||
eventType: T,
|
||||
payload: unknown
|
||||
): payload is CalendarEventPayloadMap[T] {
|
||||
return payload !== undefined;
|
||||
}
|
||||
92
src/types/ManagerTypes.ts
Normal file
92
src/types/ManagerTypes.ts
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
import { IEventBus, CalendarEvent, CalendarView } from './CalendarTypes';
|
||||
import { IManager } from '../interfaces/IManager';
|
||||
|
||||
/**
|
||||
* Complete type definition for all managers returned by ManagerFactory
|
||||
*/
|
||||
export interface CalendarManagers {
|
||||
eventManager: EventManager;
|
||||
eventRenderer: EventRenderingService;
|
||||
gridManager: GridManager;
|
||||
scrollManager: ScrollManager;
|
||||
navigationManager: unknown; // Avoid interface conflicts
|
||||
viewManager: ViewManager;
|
||||
calendarManager: CalendarManager;
|
||||
dragDropManager: unknown; // Avoid interface conflicts
|
||||
allDayManager: unknown; // Avoid interface conflicts
|
||||
}
|
||||
|
||||
export interface EventManager extends IManager {
|
||||
loadData(): Promise<void>;
|
||||
getEvents(): CalendarEvent[];
|
||||
getEventsForPeriod(startDate: Date, endDate: Date): CalendarEvent[];
|
||||
getResourceData(): ResourceData | null;
|
||||
navigateToEvent(eventId: string): boolean;
|
||||
}
|
||||
|
||||
export interface EventRenderingService extends IManager {
|
||||
// EventRenderingService doesn't have a render method in current implementation
|
||||
}
|
||||
|
||||
export interface GridManager extends IManager {
|
||||
render(): Promise<void>;
|
||||
getDisplayDates(): Date[];
|
||||
setResourceData(resourceData: import('./CalendarTypes').ResourceCalendarData | null): void;
|
||||
}
|
||||
|
||||
export interface ScrollManager extends IManager {
|
||||
scrollTo(scrollTop: number): void;
|
||||
scrollToHour(hour: number): void;
|
||||
}
|
||||
|
||||
// Use a more flexible interface that matches actual implementation
|
||||
export interface NavigationManager extends IManager {
|
||||
[key: string]: unknown; // Allow any properties from actual implementation
|
||||
}
|
||||
|
||||
export interface ViewManager extends IManager {
|
||||
// ViewManager doesn't have setView in current implementation
|
||||
getCurrentView?(): CalendarView;
|
||||
}
|
||||
|
||||
export interface CalendarManager extends IManager {
|
||||
setView(view: CalendarView): void;
|
||||
setCurrentDate(date: Date): void;
|
||||
getInitializationReport(): InitializationReport;
|
||||
}
|
||||
|
||||
export interface DragDropManager extends IManager {
|
||||
// DragDropManager has different interface in current implementation
|
||||
}
|
||||
|
||||
export interface AllDayManager extends IManager {
|
||||
[key: string]: unknown; // Allow any properties from actual implementation
|
||||
}
|
||||
|
||||
export interface ResourceData {
|
||||
resources: Resource[];
|
||||
assignments?: ResourceAssignment[];
|
||||
}
|
||||
|
||||
export interface Resource {
|
||||
id: string;
|
||||
name: string;
|
||||
type?: string;
|
||||
color?: string;
|
||||
}
|
||||
|
||||
export interface ResourceAssignment {
|
||||
resourceId: string;
|
||||
eventId: string;
|
||||
}
|
||||
|
||||
export interface InitializationReport {
|
||||
initialized: boolean;
|
||||
timestamp: number;
|
||||
managers: {
|
||||
[key: string]: {
|
||||
initialized: boolean;
|
||||
error?: string;
|
||||
};
|
||||
};
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue