Introduces comprehensive data management system for calendar V2 - Adds IndexedDB storage with pluggable entity services - Implements EventBus for decoupled event communication - Creates data seeding mechanism for initial application setup - Establishes sync and repository abstractions for flexible data handling
113 lines
4.2 KiB
TypeScript
113 lines
4.2 KiB
TypeScript
import { CalendarOrchestrator } from '../core/CalendarOrchestrator';
|
|
import { TimeAxisRenderer } from '../features/timeaxis/TimeAxisRenderer';
|
|
import { NavigationAnimator } from '../core/NavigationAnimator';
|
|
import { DateService } from '../core/DateService';
|
|
import { ScrollManager } from '../core/ScrollManager';
|
|
import { HeaderDrawerManager } from '../core/HeaderDrawerManager';
|
|
import { ViewConfig } from '../core/ViewConfig';
|
|
import { IndexedDBContext } from '../storage/IndexedDBContext';
|
|
import { DataSeeder } from '../workers/DataSeeder';
|
|
|
|
export class DemoApp {
|
|
private animator!: NavigationAnimator;
|
|
private container!: HTMLElement;
|
|
private weekOffset = 0;
|
|
private views!: Record<string, ViewConfig>;
|
|
|
|
constructor(
|
|
private orchestrator: CalendarOrchestrator,
|
|
private timeAxisRenderer: TimeAxisRenderer,
|
|
private dateService: DateService,
|
|
private scrollManager: ScrollManager,
|
|
private headerDrawerManager: HeaderDrawerManager,
|
|
private indexedDBContext: IndexedDBContext,
|
|
private dataSeeder: DataSeeder
|
|
) {}
|
|
|
|
async init(): Promise<void> {
|
|
// Initialize IndexedDB
|
|
await this.indexedDBContext.initialize();
|
|
console.log('[DemoApp] IndexedDB initialized');
|
|
|
|
// Seed data if empty
|
|
await this.dataSeeder.seedIfEmpty();
|
|
console.log('[DemoApp] Data seeding complete');
|
|
|
|
this.container = document.querySelector('swp-calendar-container') as HTMLElement;
|
|
|
|
// NavigationAnimator har DOM-dependencies - tilladt med new
|
|
this.animator = new NavigationAnimator(
|
|
document.querySelector('swp-header-track') as HTMLElement,
|
|
document.querySelector('swp-content-track') as HTMLElement
|
|
);
|
|
|
|
// View configs
|
|
const dates = this.dateService.getWeekDates();
|
|
this.views = {
|
|
simple: { templateId: 'simple', groupings: [{ type: 'date', values: dates }] },
|
|
resource: {
|
|
templateId: 'resource',
|
|
groupings: [
|
|
{ type: 'resource', values: ['alice', 'bob', 'carol'] },
|
|
{ type: 'date', values: dates.slice(0, 3) }
|
|
]
|
|
},
|
|
team: {
|
|
templateId: 'team',
|
|
groupings: [
|
|
{ type: 'team', values: ['alpha', 'beta'] },
|
|
{ type: 'resource', values: ['alice', 'bob', 'carol', 'dave'], parentKey: 'teamId' },
|
|
{ type: 'date', values: dates.slice(0, 3) }
|
|
]
|
|
}
|
|
};
|
|
|
|
// Render time axis (06:00 - 18:00)
|
|
this.timeAxisRenderer.render(document.getElementById('time-axis') as HTMLElement, 6, 18);
|
|
|
|
// Init scroll synkronisering
|
|
this.scrollManager.init(this.container);
|
|
|
|
// Init header drawer
|
|
this.headerDrawerManager.init(this.container);
|
|
|
|
// Setup event handlers
|
|
this.setupNavigation();
|
|
this.setupViewSwitchers();
|
|
this.setupDrawerToggle();
|
|
|
|
// Initial render
|
|
this.orchestrator.render(this.views.simple, this.container);
|
|
}
|
|
|
|
private setupNavigation(): void {
|
|
document.getElementById('btn-prev')!.onclick = () => {
|
|
this.weekOffset--;
|
|
this.views.simple.groupings[0].values = this.dateService.getWeekDates(this.weekOffset);
|
|
this.animator.slide('right', () => this.orchestrator.render(this.views.simple, this.container));
|
|
};
|
|
|
|
document.getElementById('btn-next')!.onclick = () => {
|
|
this.weekOffset++;
|
|
this.views.simple.groupings[0].values = this.dateService.getWeekDates(this.weekOffset);
|
|
this.animator.slide('left', () => this.orchestrator.render(this.views.simple, this.container));
|
|
};
|
|
}
|
|
|
|
private setupViewSwitchers(): void {
|
|
document.getElementById('btn-simple')!.onclick = () =>
|
|
this.animator.slide('right', () => this.orchestrator.render(this.views.simple, this.container));
|
|
|
|
document.getElementById('btn-resource')!.onclick = () =>
|
|
this.animator.slide('left', () => this.orchestrator.render(this.views.resource, this.container));
|
|
|
|
document.getElementById('btn-team')!.onclick = () =>
|
|
this.animator.slide('left', () => this.orchestrator.render(this.views.team, this.container));
|
|
}
|
|
|
|
private setupDrawerToggle(): void {
|
|
document.getElementById('btn-drawer')!.onclick = () => {
|
|
this.headerDrawerManager.toggle();
|
|
};
|
|
}
|
|
}
|