PlanTempusApp/PlanTempus.Application/wwwroot/ts/modules/calendar.ts
Janus C. H. Knudsen 51f3b92d69 Enhances application menu and adds calendar feature
Adds new calendar page and module with comprehensive initialization

Introduces quick actions group in side menu with create booking and sale options
Updates menu service to include new menu groups and rearrange sort order
Configures custom npm registry and esbuild configuration
Adds localization for new menu items and calendar section

Implements calendar controller with dependency injection and settings seeding
2026-02-02 22:42:18 +01:00

119 lines
3.4 KiB
TypeScript

/**
* Calendar Controller
*
* Integrates the calendar package into PlanTempus.
* Uses NovaDI for dependency injection and IndexedDB for offline storage.
*/
import { Container } from '@novadi/core';
import {
registerCoreServices,
CalendarApp,
IndexedDBContext,
SettingsService,
ViewConfigService,
EventBus,
CalendarEvents
} from 'calendar';
import { registerSchedules } from 'calendar/schedules';
export class CalendarController {
private app: Container | null = null;
private calendarApp: CalendarApp | null = null;
constructor() {
const containerEl = document.querySelector('swp-calendar-container');
if (!containerEl) return;
this.init(containerEl as HTMLElement).catch(err => {
console.error('[CalendarController] Init failed:', err);
});
}
private async init(containerEl: HTMLElement): Promise<void> {
console.log('[CalendarController] Starting init...');
// Create DI container using the pattern from README
const container = new Container();
const builder = container.builder();
registerCoreServices(builder, {
dbConfig: { dbName: 'PlanTempusCalendarDB', dbVersion: 1 }
});
registerSchedules(builder);
this.app = builder.build();
console.log('[CalendarController] Container built');
// Initialize IndexedDB
const dbContext = this.app.resolveType<IndexedDBContext>();
await dbContext.initialize();
console.log('[CalendarController] IndexedDB initialized');
// Seed required settings
await this.seedSettings();
console.log('[CalendarController] Settings seeded');
// Initialize CalendarApp
this.calendarApp = this.app.resolveType<CalendarApp>();
await this.calendarApp.init(containerEl);
console.log('[CalendarController] CalendarApp initialized');
// Render default view
const eventBus = this.app.resolveType<EventBus>();
eventBus.emit(CalendarEvents.CMD_RENDER, { viewId: 'simple' });
console.log('[CalendarController] Render command emitted');
}
private async seedSettings(): Promise<void> {
if (!this.app) return;
const settingsService = this.app.resolveType<SettingsService>();
const viewConfigService = this.app.resolveType<ViewConfigService>();
// Grid settings
await settingsService.save({
id: 'grid',
dayStartHour: 8,
dayEndHour: 18,
workStartHour: 9,
workEndHour: 17,
hourHeight: 64,
snapInterval: 15,
syncStatus: 'synced'
});
// Workweek settings
await settingsService.save({
id: 'workweek',
presets: {
standard: { id: 'standard', label: 'Standard', workDays: [1, 2, 3, 4, 5], periodDays: 7 }
},
defaultPreset: 'standard',
firstDayOfWeek: 1,
syncStatus: 'synced'
});
// View configuration
await viewConfigService.save({
id: 'simple',
groupings: [{ type: 'date', values: [], idProperty: 'date', derivedFrom: 'start' }],
syncStatus: 'synced'
});
}
navigatePrev(): void {
if (!this.app) return;
const eventBus = this.app.resolveType<EventBus>();
eventBus.emit(CalendarEvents.CMD_NAVIGATE_PREV);
}
navigateNext(): void {
if (!this.app) return;
const eventBus = this.app.resolveType<EventBus>();
eventBus.emit(CalendarEvents.CMD_NAVIGATE_NEXT);
}
toggleDrawer(): void {
if (!this.app) return;
const eventBus = this.app.resolveType<EventBus>();
eventBus.emit(CalendarEvents.CMD_DRAWER_TOGGLE);
}
}