Some ignored filles was missing
This commit is contained in:
parent
7db22245e2
commit
fd5ab6bc0d
268 changed files with 31970 additions and 4 deletions
225
wwwroot/js/core/CalendarConfig.d.ts
vendored
Normal file
225
wwwroot/js/core/CalendarConfig.d.ts
vendored
Normal file
|
|
@ -0,0 +1,225 @@
|
|||
import { CalendarConfig as ICalendarConfig, ViewPeriod, CalendarMode } from '../types/CalendarTypes';
|
||||
/**
|
||||
* All-day event layout constants
|
||||
*/
|
||||
export declare const ALL_DAY_CONSTANTS: {
|
||||
readonly EVENT_HEIGHT: 22;
|
||||
readonly EVENT_GAP: 2;
|
||||
readonly CONTAINER_PADDING: 4;
|
||||
readonly MAX_COLLAPSED_ROWS: 4;
|
||||
readonly SINGLE_ROW_HEIGHT: number;
|
||||
};
|
||||
/**
|
||||
* Layout and timing settings for the calendar grid
|
||||
*/
|
||||
interface GridSettings {
|
||||
dayStartHour: number;
|
||||
dayEndHour: number;
|
||||
workStartHour: number;
|
||||
workEndHour: number;
|
||||
hourHeight: number;
|
||||
snapInterval: number;
|
||||
fitToWidth: boolean;
|
||||
scrollToHour: number | null;
|
||||
gridStartThresholdMinutes: number;
|
||||
showCurrentTime: boolean;
|
||||
showWorkHours: boolean;
|
||||
}
|
||||
/**
|
||||
* View settings for date-based calendar mode
|
||||
*/
|
||||
interface DateViewSettings {
|
||||
period: ViewPeriod;
|
||||
weekDays: number;
|
||||
firstDayOfWeek: number;
|
||||
showAllDay: boolean;
|
||||
}
|
||||
/**
|
||||
* Work week configuration settings
|
||||
*/
|
||||
interface WorkWeekSettings {
|
||||
id: string;
|
||||
workDays: number[];
|
||||
totalDays: number;
|
||||
firstWorkDay: number;
|
||||
}
|
||||
/**
|
||||
* View settings for resource-based calendar mode
|
||||
*/
|
||||
interface ResourceViewSettings {
|
||||
maxResources: number;
|
||||
showAvatars: boolean;
|
||||
avatarSize: number;
|
||||
resourceNameFormat: 'full' | 'short';
|
||||
showResourceDetails: boolean;
|
||||
showAllDay: boolean;
|
||||
}
|
||||
/**
|
||||
* Time format configuration settings
|
||||
*/
|
||||
interface TimeFormatConfig {
|
||||
timezone: string;
|
||||
use24HourFormat: boolean;
|
||||
locale: string;
|
||||
dateFormat: 'locale' | 'technical';
|
||||
showSeconds: boolean;
|
||||
}
|
||||
/**
|
||||
* Calendar configuration management
|
||||
*/
|
||||
export declare class CalendarConfig {
|
||||
private config;
|
||||
private calendarMode;
|
||||
private selectedDate;
|
||||
private gridSettings;
|
||||
private dateViewSettings;
|
||||
private resourceViewSettings;
|
||||
private currentWorkWeek;
|
||||
private timeFormatConfig;
|
||||
constructor();
|
||||
/**
|
||||
* Load calendar type and date from URL parameters
|
||||
*/
|
||||
private loadCalendarType;
|
||||
/**
|
||||
* Load configuration from DOM data attributes
|
||||
*/
|
||||
private loadFromDOM;
|
||||
/**
|
||||
* Get a config value
|
||||
*/
|
||||
get<K extends keyof ICalendarConfig>(key: K): ICalendarConfig[K];
|
||||
/**
|
||||
* Set a config value
|
||||
*/
|
||||
set<K extends keyof ICalendarConfig>(key: K, value: ICalendarConfig[K]): void;
|
||||
/**
|
||||
* Update multiple config values
|
||||
*/
|
||||
update(updates: Partial<ICalendarConfig>): void;
|
||||
/**
|
||||
* Get all config
|
||||
*/
|
||||
getAll(): ICalendarConfig;
|
||||
/**
|
||||
* Calculate derived values
|
||||
*/
|
||||
get minuteHeight(): number;
|
||||
get totalHours(): number;
|
||||
get totalMinutes(): number;
|
||||
get slotsPerHour(): number;
|
||||
get totalSlots(): number;
|
||||
get slotHeight(): number;
|
||||
/**
|
||||
* Validate snap interval
|
||||
*/
|
||||
isValidSnapInterval(interval: number): boolean;
|
||||
/**
|
||||
* Get grid display settings
|
||||
*/
|
||||
getGridSettings(): GridSettings;
|
||||
/**
|
||||
* Update grid display settings
|
||||
*/
|
||||
updateGridSettings(updates: Partial<GridSettings>): void;
|
||||
/**
|
||||
* Get date view settings
|
||||
*/
|
||||
getDateViewSettings(): DateViewSettings;
|
||||
/**
|
||||
* Update date view settings
|
||||
*/
|
||||
updateDateViewSettings(updates: Partial<DateViewSettings>): void;
|
||||
/**
|
||||
* Get resource view settings
|
||||
*/
|
||||
getResourceViewSettings(): ResourceViewSettings;
|
||||
/**
|
||||
* Update resource view settings
|
||||
*/
|
||||
updateResourceViewSettings(updates: Partial<ResourceViewSettings>): void;
|
||||
/**
|
||||
* Check if current mode is resource-based
|
||||
*/
|
||||
isResourceMode(): boolean;
|
||||
/**
|
||||
* Check if current mode is date-based
|
||||
*/
|
||||
isDateMode(): boolean;
|
||||
/**
|
||||
* Get calendar mode
|
||||
*/
|
||||
getCalendarMode(): CalendarMode;
|
||||
/**
|
||||
* Set calendar mode
|
||||
*/
|
||||
setCalendarMode(mode: CalendarMode): void;
|
||||
/**
|
||||
* Get selected date
|
||||
*/
|
||||
getSelectedDate(): Date | null;
|
||||
/**
|
||||
* Set selected date
|
||||
* Note: Does not emit events - caller is responsible for event emission
|
||||
*/
|
||||
setSelectedDate(date: Date): void;
|
||||
/**
|
||||
* Get work week presets
|
||||
*/
|
||||
private getWorkWeekPresets;
|
||||
/**
|
||||
* Get current work week settings
|
||||
*/
|
||||
getWorkWeekSettings(): WorkWeekSettings;
|
||||
/**
|
||||
* Set work week preset
|
||||
* Note: Does not emit events - caller is responsible for event emission
|
||||
*/
|
||||
setWorkWeek(workWeekId: string): void;
|
||||
/**
|
||||
* Get current work week ID
|
||||
*/
|
||||
getCurrentWorkWeek(): string;
|
||||
/**
|
||||
* Get time format settings
|
||||
*/
|
||||
getTimeFormatSettings(): TimeFormatConfig;
|
||||
/**
|
||||
* Update time format settings
|
||||
*/
|
||||
updateTimeFormatSettings(updates: Partial<TimeFormatConfig>): void;
|
||||
/**
|
||||
* Set timezone (convenience method)
|
||||
*/
|
||||
setTimezone(timezone: string): void;
|
||||
/**
|
||||
* Set 12/24 hour format (convenience method)
|
||||
*/
|
||||
set24HourFormat(use24Hour: boolean): void;
|
||||
/**
|
||||
* Get configured timezone
|
||||
*/
|
||||
getTimezone(): string;
|
||||
/**
|
||||
* Get configured locale
|
||||
*/
|
||||
getLocale(): string;
|
||||
/**
|
||||
* Check if using 24-hour format
|
||||
*/
|
||||
is24HourFormat(): boolean;
|
||||
/**
|
||||
* Set date format (convenience method)
|
||||
*/
|
||||
setDateFormat(format: 'locale' | 'technical'): void;
|
||||
/**
|
||||
* Set whether to show seconds (convenience method)
|
||||
*/
|
||||
setShowSeconds(show: boolean): void;
|
||||
/**
|
||||
* Get current date format
|
||||
*/
|
||||
getDateFormat(): 'locale' | 'technical';
|
||||
}
|
||||
export declare const calendarConfig: CalendarConfig;
|
||||
export {};
|
||||
421
wwwroot/js/core/CalendarConfig.js
Normal file
421
wwwroot/js/core/CalendarConfig.js
Normal file
|
|
@ -0,0 +1,421 @@
|
|||
// Calendar configuration management
|
||||
import { eventBus } from './EventBus';
|
||||
import { CoreEvents } from '../constants/CoreEvents';
|
||||
import { TimeFormatter } from '../utils/TimeFormatter';
|
||||
/**
|
||||
* All-day event layout constants
|
||||
*/
|
||||
export const ALL_DAY_CONSTANTS = {
|
||||
EVENT_HEIGHT: 22, // Height of single all-day event
|
||||
EVENT_GAP: 2, // Gap between stacked events
|
||||
CONTAINER_PADDING: 4, // Container padding (top + bottom)
|
||||
get SINGLE_ROW_HEIGHT() {
|
||||
return this.EVENT_HEIGHT + this.EVENT_GAP + this.CONTAINER_PADDING; // 28px
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Calendar configuration management
|
||||
*/
|
||||
export class CalendarConfig {
|
||||
constructor() {
|
||||
this.calendarMode = 'date';
|
||||
this.selectedDate = null;
|
||||
this.currentWorkWeek = 'standard';
|
||||
this.config = {
|
||||
// Scrollbar styling
|
||||
scrollbarWidth: 16, // Width of scrollbar in pixels
|
||||
scrollbarColor: '#666', // Scrollbar thumb color
|
||||
scrollbarTrackColor: '#f0f0f0', // Scrollbar track color
|
||||
scrollbarHoverColor: '#b53f7aff', // Scrollbar thumb hover color
|
||||
scrollbarBorderRadius: 6, // Border radius for scrollbar thumb
|
||||
// Interaction settings
|
||||
allowDrag: true,
|
||||
allowResize: true,
|
||||
allowCreate: true,
|
||||
// API settings
|
||||
apiEndpoint: '/api/events',
|
||||
dateFormat: 'YYYY-MM-DD',
|
||||
timeFormat: 'HH:mm',
|
||||
// Feature flags
|
||||
enableSearch: true,
|
||||
enableTouch: true,
|
||||
// Event defaults
|
||||
defaultEventDuration: 60, // Minutes
|
||||
minEventDuration: 15, // Will be same as snapInterval
|
||||
maxEventDuration: 480 // 8 hours
|
||||
};
|
||||
// Grid display settings
|
||||
this.gridSettings = {
|
||||
hourHeight: 60,
|
||||
dayStartHour: 0,
|
||||
dayEndHour: 24,
|
||||
workStartHour: 8,
|
||||
workEndHour: 17,
|
||||
snapInterval: 15,
|
||||
showCurrentTime: true,
|
||||
showWorkHours: true,
|
||||
fitToWidth: false,
|
||||
scrollToHour: 8
|
||||
};
|
||||
// Date view settings
|
||||
this.dateViewSettings = {
|
||||
period: 'week',
|
||||
weekDays: 7,
|
||||
firstDayOfWeek: 1,
|
||||
showAllDay: true
|
||||
};
|
||||
// Resource view settings
|
||||
this.resourceViewSettings = {
|
||||
maxResources: 10,
|
||||
showAvatars: true,
|
||||
avatarSize: 32,
|
||||
resourceNameFormat: 'full',
|
||||
showResourceDetails: true,
|
||||
showAllDay: true
|
||||
};
|
||||
// Time format settings - default to Denmark
|
||||
this.timeFormatConfig = {
|
||||
timezone: 'Europe/Copenhagen',
|
||||
use24HourFormat: true,
|
||||
locale: 'da-DK'
|
||||
};
|
||||
// Set computed values
|
||||
this.config.minEventDuration = this.gridSettings.snapInterval;
|
||||
// Initialize TimeFormatter with default settings
|
||||
TimeFormatter.configure(this.timeFormatConfig);
|
||||
// Load calendar type from URL parameter
|
||||
this.loadCalendarType();
|
||||
// Load from data attributes
|
||||
this.loadFromDOM();
|
||||
}
|
||||
/**
|
||||
* Load calendar type and date from URL parameters
|
||||
*/
|
||||
loadCalendarType() {
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
const typeParam = urlParams.get('type');
|
||||
const dateParam = urlParams.get('date');
|
||||
// Set calendar mode
|
||||
if (typeParam === 'resource' || typeParam === 'date') {
|
||||
this.calendarMode = typeParam;
|
||||
}
|
||||
else {
|
||||
this.calendarMode = 'date'; // Default
|
||||
}
|
||||
// Set selected date
|
||||
if (dateParam) {
|
||||
const parsedDate = new Date(dateParam);
|
||||
if (!isNaN(parsedDate.getTime())) {
|
||||
this.selectedDate = parsedDate;
|
||||
}
|
||||
else {
|
||||
this.selectedDate = new Date();
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.selectedDate = new Date(); // Default to today
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Load configuration from DOM data attributes
|
||||
*/
|
||||
loadFromDOM() {
|
||||
const calendar = document.querySelector('swp-calendar');
|
||||
if (!calendar)
|
||||
return;
|
||||
// Read data attributes
|
||||
const attrs = calendar.dataset;
|
||||
// Update date view settings
|
||||
if (attrs.view)
|
||||
this.dateViewSettings.period = attrs.view;
|
||||
if (attrs.weekDays)
|
||||
this.dateViewSettings.weekDays = parseInt(attrs.weekDays);
|
||||
// Update grid settings
|
||||
if (attrs.snapInterval)
|
||||
this.gridSettings.snapInterval = parseInt(attrs.snapInterval);
|
||||
if (attrs.dayStartHour)
|
||||
this.gridSettings.dayStartHour = parseInt(attrs.dayStartHour);
|
||||
if (attrs.dayEndHour)
|
||||
this.gridSettings.dayEndHour = parseInt(attrs.dayEndHour);
|
||||
if (attrs.hourHeight)
|
||||
this.gridSettings.hourHeight = parseInt(attrs.hourHeight);
|
||||
if (attrs.fitToWidth !== undefined)
|
||||
this.gridSettings.fitToWidth = attrs.fitToWidth === 'true';
|
||||
// Update computed values
|
||||
this.config.minEventDuration = this.gridSettings.snapInterval;
|
||||
}
|
||||
/**
|
||||
* Get a config value
|
||||
*/
|
||||
get(key) {
|
||||
return this.config[key];
|
||||
}
|
||||
/**
|
||||
* Set a config value
|
||||
*/
|
||||
set(key, value) {
|
||||
const oldValue = this.config[key];
|
||||
this.config[key] = value;
|
||||
// Update computed values handled in specific update methods
|
||||
// Emit config update event
|
||||
eventBus.emit(CoreEvents.REFRESH_REQUESTED, {
|
||||
key,
|
||||
value,
|
||||
oldValue
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Update multiple config values
|
||||
*/
|
||||
update(updates) {
|
||||
Object.entries(updates).forEach(([key, value]) => {
|
||||
this.set(key, value);
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Get all config
|
||||
*/
|
||||
getAll() {
|
||||
return { ...this.config };
|
||||
}
|
||||
/**
|
||||
* Calculate derived values
|
||||
*/
|
||||
get minuteHeight() {
|
||||
return this.gridSettings.hourHeight / 60;
|
||||
}
|
||||
get totalHours() {
|
||||
return this.gridSettings.dayEndHour - this.gridSettings.dayStartHour;
|
||||
}
|
||||
get totalMinutes() {
|
||||
return this.totalHours * 60;
|
||||
}
|
||||
get slotsPerHour() {
|
||||
return 60 / this.gridSettings.snapInterval;
|
||||
}
|
||||
get totalSlots() {
|
||||
return this.totalHours * this.slotsPerHour;
|
||||
}
|
||||
get slotHeight() {
|
||||
return this.gridSettings.hourHeight / this.slotsPerHour;
|
||||
}
|
||||
/**
|
||||
* Validate snap interval
|
||||
*/
|
||||
isValidSnapInterval(interval) {
|
||||
return [5, 10, 15, 30, 60].includes(interval);
|
||||
}
|
||||
/**
|
||||
* Get grid display settings
|
||||
*/
|
||||
getGridSettings() {
|
||||
return { ...this.gridSettings };
|
||||
}
|
||||
/**
|
||||
* Update grid display settings
|
||||
*/
|
||||
updateGridSettings(updates) {
|
||||
this.gridSettings = { ...this.gridSettings, ...updates };
|
||||
// Update computed values
|
||||
if (updates.snapInterval) {
|
||||
this.config.minEventDuration = updates.snapInterval;
|
||||
}
|
||||
// Grid settings changes trigger general refresh - avoid specific event
|
||||
eventBus.emit(CoreEvents.REFRESH_REQUESTED, {
|
||||
key: 'gridSettings',
|
||||
value: this.gridSettings
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Get date view settings
|
||||
*/
|
||||
getDateViewSettings() {
|
||||
return { ...this.dateViewSettings };
|
||||
}
|
||||
/**
|
||||
* Update date view settings
|
||||
*/
|
||||
updateDateViewSettings(updates) {
|
||||
this.dateViewSettings = { ...this.dateViewSettings, ...updates };
|
||||
// Date view settings changes trigger general refresh - avoid specific event
|
||||
eventBus.emit(CoreEvents.REFRESH_REQUESTED, {
|
||||
key: 'dateViewSettings',
|
||||
value: this.dateViewSettings
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Get resource view settings
|
||||
*/
|
||||
getResourceViewSettings() {
|
||||
return { ...this.resourceViewSettings };
|
||||
}
|
||||
/**
|
||||
* Update resource view settings
|
||||
*/
|
||||
updateResourceViewSettings(updates) {
|
||||
this.resourceViewSettings = { ...this.resourceViewSettings, ...updates };
|
||||
// Resource view settings changes trigger general refresh - avoid specific event
|
||||
eventBus.emit(CoreEvents.REFRESH_REQUESTED, {
|
||||
key: 'resourceViewSettings',
|
||||
value: this.resourceViewSettings
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Check if current mode is resource-based
|
||||
*/
|
||||
isResourceMode() {
|
||||
return this.calendarMode === 'resource';
|
||||
}
|
||||
/**
|
||||
* Check if current mode is date-based
|
||||
*/
|
||||
isDateMode() {
|
||||
return this.calendarMode === 'date';
|
||||
}
|
||||
/**
|
||||
* Get calendar mode
|
||||
*/
|
||||
getCalendarMode() {
|
||||
return this.calendarMode;
|
||||
}
|
||||
/**
|
||||
* Set calendar mode
|
||||
*/
|
||||
setCalendarMode(mode) {
|
||||
const oldMode = this.calendarMode;
|
||||
this.calendarMode = mode;
|
||||
// Emit calendar mode change event
|
||||
eventBus.emit(CoreEvents.VIEW_CHANGED, {
|
||||
oldType: oldMode,
|
||||
newType: mode
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Get selected date
|
||||
*/
|
||||
getSelectedDate() {
|
||||
return this.selectedDate;
|
||||
}
|
||||
/**
|
||||
* Set selected date
|
||||
*/
|
||||
setSelectedDate(date) {
|
||||
this.selectedDate = date;
|
||||
// Emit date change event
|
||||
eventBus.emit(CoreEvents.DATE_CHANGED, {
|
||||
date: date
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Get work week presets
|
||||
*/
|
||||
getWorkWeekPresets() {
|
||||
return {
|
||||
'standard': {
|
||||
id: 'standard',
|
||||
workDays: [1, 2, 3, 4, 5], // Monday-Friday (ISO)
|
||||
totalDays: 5,
|
||||
firstWorkDay: 1
|
||||
},
|
||||
'compressed': {
|
||||
id: 'compressed',
|
||||
workDays: [1, 2, 3, 4], // Monday-Thursday (ISO)
|
||||
totalDays: 4,
|
||||
firstWorkDay: 1
|
||||
},
|
||||
'midweek': {
|
||||
id: 'midweek',
|
||||
workDays: [3, 4, 5], // Wednesday-Friday (ISO)
|
||||
totalDays: 3,
|
||||
firstWorkDay: 3
|
||||
},
|
||||
'weekend': {
|
||||
id: 'weekend',
|
||||
workDays: [6, 7], // Saturday-Sunday (ISO)
|
||||
totalDays: 2,
|
||||
firstWorkDay: 6
|
||||
},
|
||||
'fullweek': {
|
||||
id: 'fullweek',
|
||||
workDays: [1, 2, 3, 4, 5, 6, 7], // Monday-Sunday (ISO)
|
||||
totalDays: 7,
|
||||
firstWorkDay: 1
|
||||
}
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Get current work week settings
|
||||
*/
|
||||
getWorkWeekSettings() {
|
||||
const presets = this.getWorkWeekPresets();
|
||||
return presets[this.currentWorkWeek] || presets['standard'];
|
||||
}
|
||||
/**
|
||||
* Set work week preset
|
||||
*/
|
||||
setWorkWeek(workWeekId) {
|
||||
const presets = this.getWorkWeekPresets();
|
||||
if (presets[workWeekId]) {
|
||||
this.currentWorkWeek = workWeekId;
|
||||
// Update dateViewSettings to match work week
|
||||
this.dateViewSettings.weekDays = presets[workWeekId].totalDays;
|
||||
// Emit work week change event
|
||||
eventBus.emit(CoreEvents.WORKWEEK_CHANGED, {
|
||||
workWeekId: workWeekId,
|
||||
settings: presets[workWeekId]
|
||||
});
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Get current work week ID
|
||||
*/
|
||||
getCurrentWorkWeek() {
|
||||
return this.currentWorkWeek;
|
||||
}
|
||||
/**
|
||||
* Get time format settings
|
||||
*/
|
||||
getTimeFormatSettings() {
|
||||
return { ...this.timeFormatConfig };
|
||||
}
|
||||
/**
|
||||
* Update time format settings
|
||||
*/
|
||||
updateTimeFormatSettings(updates) {
|
||||
this.timeFormatConfig = { ...this.timeFormatConfig, ...updates };
|
||||
// Update TimeFormatter with new settings
|
||||
TimeFormatter.configure(this.timeFormatConfig);
|
||||
// Emit time format change event
|
||||
eventBus.emit(CoreEvents.REFRESH_REQUESTED, {
|
||||
key: 'timeFormatSettings',
|
||||
value: this.timeFormatConfig
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Set timezone (convenience method)
|
||||
*/
|
||||
setTimezone(timezone) {
|
||||
this.updateTimeFormatSettings({ timezone });
|
||||
}
|
||||
/**
|
||||
* Set 12/24 hour format (convenience method)
|
||||
*/
|
||||
set24HourFormat(use24Hour) {
|
||||
this.updateTimeFormatSettings({ use24HourFormat: use24Hour });
|
||||
}
|
||||
/**
|
||||
* Get configured timezone
|
||||
*/
|
||||
getTimezone() {
|
||||
return this.timeFormatConfig.timezone;
|
||||
}
|
||||
/**
|
||||
* Check if using 24-hour format
|
||||
*/
|
||||
is24HourFormat() {
|
||||
return this.timeFormatConfig.use24HourFormat;
|
||||
}
|
||||
}
|
||||
// Create singleton instance
|
||||
export const calendarConfig = new CalendarConfig();
|
||||
//# sourceMappingURL=CalendarConfig.js.map
|
||||
1
wwwroot/js/core/CalendarConfig.js.map
Normal file
1
wwwroot/js/core/CalendarConfig.js.map
Normal file
File diff suppressed because one or more lines are too long
60
wwwroot/js/core/EventBus.d.ts
vendored
Normal file
60
wwwroot/js/core/EventBus.d.ts
vendored
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
import { IEventLogEntry, IEventBus } from '../types/CalendarTypes';
|
||||
/**
|
||||
* Central event dispatcher for calendar using DOM CustomEvents
|
||||
* Provides logging and debugging capabilities
|
||||
*/
|
||||
export declare class EventBus implements IEventBus {
|
||||
private eventLog;
|
||||
private debug;
|
||||
private listeners;
|
||||
private logConfig;
|
||||
/**
|
||||
* Subscribe to an event via DOM addEventListener
|
||||
*/
|
||||
on(eventType: string, handler: EventListener, options?: AddEventListenerOptions): () => void;
|
||||
/**
|
||||
* Subscribe to an event once
|
||||
*/
|
||||
once(eventType: string, handler: EventListener): () => void;
|
||||
/**
|
||||
* Unsubscribe from an event
|
||||
*/
|
||||
off(eventType: string, handler: EventListener): void;
|
||||
/**
|
||||
* Emit an event via DOM CustomEvent
|
||||
*/
|
||||
emit(eventType: string, detail?: unknown): boolean;
|
||||
/**
|
||||
* Log event with console grouping
|
||||
*/
|
||||
private logEventWithGrouping;
|
||||
/**
|
||||
* Extract category from event type
|
||||
*/
|
||||
private extractCategory;
|
||||
/**
|
||||
* Get styling for different categories
|
||||
*/
|
||||
private getCategoryStyle;
|
||||
/**
|
||||
* Configure logging for specific categories
|
||||
*/
|
||||
setLogConfig(config: {
|
||||
[key: string]: boolean;
|
||||
}): void;
|
||||
/**
|
||||
* Get current log configuration
|
||||
*/
|
||||
getLogConfig(): {
|
||||
[key: string]: boolean;
|
||||
};
|
||||
/**
|
||||
* Get event history
|
||||
*/
|
||||
getEventLog(eventType?: string): IEventLogEntry[];
|
||||
/**
|
||||
* Enable/disable debug mode
|
||||
*/
|
||||
setDebug(enabled: boolean): void;
|
||||
}
|
||||
export declare const eventBus: EventBus;
|
||||
158
wwwroot/js/core/EventBus.js
Normal file
158
wwwroot/js/core/EventBus.js
Normal file
|
|
@ -0,0 +1,158 @@
|
|||
/**
|
||||
* Central event dispatcher for calendar using DOM CustomEvents
|
||||
* Provides logging and debugging capabilities
|
||||
*/
|
||||
export class EventBus {
|
||||
constructor() {
|
||||
this.eventLog = [];
|
||||
this.debug = false;
|
||||
this.listeners = new Set();
|
||||
// Log configuration for different categories
|
||||
this.logConfig = {
|
||||
calendar: true,
|
||||
grid: true,
|
||||
event: true,
|
||||
scroll: true,
|
||||
navigation: true,
|
||||
view: true,
|
||||
default: true
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Subscribe to an event via DOM addEventListener
|
||||
*/
|
||||
on(eventType, handler, options) {
|
||||
document.addEventListener(eventType, handler, options);
|
||||
// Track for cleanup
|
||||
this.listeners.add({ eventType, handler, options });
|
||||
// Return unsubscribe function
|
||||
return () => this.off(eventType, handler);
|
||||
}
|
||||
/**
|
||||
* Subscribe to an event once
|
||||
*/
|
||||
once(eventType, handler) {
|
||||
return this.on(eventType, handler, { once: true });
|
||||
}
|
||||
/**
|
||||
* Unsubscribe from an event
|
||||
*/
|
||||
off(eventType, handler) {
|
||||
document.removeEventListener(eventType, handler);
|
||||
// Remove from tracking
|
||||
for (const listener of this.listeners) {
|
||||
if (listener.eventType === eventType && listener.handler === handler) {
|
||||
this.listeners.delete(listener);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Emit an event via DOM CustomEvent
|
||||
*/
|
||||
emit(eventType, detail = {}) {
|
||||
// Validate eventType
|
||||
if (!eventType) {
|
||||
return false;
|
||||
}
|
||||
const event = new CustomEvent(eventType, {
|
||||
detail: detail ?? {},
|
||||
bubbles: true,
|
||||
cancelable: true
|
||||
});
|
||||
// Log event with grouping
|
||||
if (this.debug) {
|
||||
this.logEventWithGrouping(eventType, detail);
|
||||
}
|
||||
this.eventLog.push({
|
||||
type: eventType,
|
||||
detail: detail ?? {},
|
||||
timestamp: Date.now()
|
||||
});
|
||||
// Emit on document (only DOM events now)
|
||||
return !document.dispatchEvent(event);
|
||||
}
|
||||
/**
|
||||
* Log event with console grouping
|
||||
*/
|
||||
logEventWithGrouping(eventType, detail) {
|
||||
// Extract category from event type (e.g., 'calendar:datechanged' → 'calendar')
|
||||
const category = this.extractCategory(eventType);
|
||||
// Only log if category is enabled
|
||||
if (!this.logConfig[category]) {
|
||||
return;
|
||||
}
|
||||
// Get category emoji and color
|
||||
const { emoji, color } = this.getCategoryStyle(category);
|
||||
// Use collapsed group to reduce visual noise
|
||||
}
|
||||
/**
|
||||
* Extract category from event type
|
||||
*/
|
||||
extractCategory(eventType) {
|
||||
if (!eventType) {
|
||||
return 'unknown';
|
||||
}
|
||||
if (eventType.includes(':')) {
|
||||
return eventType.split(':')[0];
|
||||
}
|
||||
// Fallback: try to detect category from event name patterns
|
||||
const lowerType = eventType.toLowerCase();
|
||||
if (lowerType.includes('grid') || lowerType.includes('rendered'))
|
||||
return 'grid';
|
||||
if (lowerType.includes('event') || lowerType.includes('sync'))
|
||||
return 'event';
|
||||
if (lowerType.includes('scroll'))
|
||||
return 'scroll';
|
||||
if (lowerType.includes('nav') || lowerType.includes('date'))
|
||||
return 'navigation';
|
||||
if (lowerType.includes('view'))
|
||||
return 'view';
|
||||
return 'default';
|
||||
}
|
||||
/**
|
||||
* Get styling for different categories
|
||||
*/
|
||||
getCategoryStyle(category) {
|
||||
const styles = {
|
||||
calendar: { emoji: '🗓️', color: '#2196F3' },
|
||||
grid: { emoji: '📊', color: '#4CAF50' },
|
||||
event: { emoji: '📅', color: '#FF9800' },
|
||||
scroll: { emoji: '📜', color: '#9C27B0' },
|
||||
navigation: { emoji: '🧭', color: '#F44336' },
|
||||
view: { emoji: '👁️', color: '#00BCD4' },
|
||||
default: { emoji: '📢', color: '#607D8B' }
|
||||
};
|
||||
return styles[category] || styles.default;
|
||||
}
|
||||
/**
|
||||
* Configure logging for specific categories
|
||||
*/
|
||||
setLogConfig(config) {
|
||||
this.logConfig = { ...this.logConfig, ...config };
|
||||
}
|
||||
/**
|
||||
* Get current log configuration
|
||||
*/
|
||||
getLogConfig() {
|
||||
return { ...this.logConfig };
|
||||
}
|
||||
/**
|
||||
* Get event history
|
||||
*/
|
||||
getEventLog(eventType) {
|
||||
if (eventType) {
|
||||
return this.eventLog.filter(e => e.type === eventType);
|
||||
}
|
||||
return this.eventLog;
|
||||
}
|
||||
/**
|
||||
* Enable/disable debug mode
|
||||
*/
|
||||
setDebug(enabled) {
|
||||
this.debug = enabled;
|
||||
}
|
||||
}
|
||||
// Create singleton instance
|
||||
export const eventBus = new EventBus();
|
||||
//# sourceMappingURL=EventBus.js.map
|
||||
1
wwwroot/js/core/EventBus.js.map
Normal file
1
wwwroot/js/core/EventBus.js.map
Normal file
|
|
@ -0,0 +1 @@
|
|||
{"version":3,"file":"EventBus.js","sourceRoot":"","sources":["../../../src/core/EventBus.ts"],"names":[],"mappings":"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"}
|
||||
Loading…
Add table
Add a link
Reference in a new issue