Some ignored filles was missing

This commit is contained in:
Janus C. H. Knudsen 2026-02-03 00:02:25 +01:00
parent 7db22245e2
commit fd5ab6bc0d
268 changed files with 31970 additions and 4 deletions

225
wwwroot/js/core/CalendarConfig.d.ts vendored Normal file
View 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 {};

View 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

File diff suppressed because one or more lines are too long

60
wwwroot/js/core/EventBus.d.ts vendored Normal file
View 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
View 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

View file

@ -0,0 +1 @@
{"version":3,"file":"EventBus.js","sourceRoot":"","sources":["../../../src/core/EventBus.ts"],"names":[],"mappings":"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"}