Implements offline-first calendar sync infrastructure

Adds IndexedDB and operation queue for robust offline synchronization
Introduces SyncManager to handle background data synchronization
Supports local event operations with automatic remote sync queuing

Enhances application reliability and user experience in low/no connectivity scenarios
This commit is contained in:
Janus C. H. Knudsen 2025-11-05 00:37:57 +01:00
parent 9c765b35ab
commit e7011526e3
20 changed files with 3822 additions and 57 deletions

View file

@ -36,12 +36,12 @@ export class EventRenderingService {
/**
* Render events in a specific container for a given period
*/
public renderEvents(context: IRenderContext): void {
public async renderEvents(context: IRenderContext): Promise<void> {
// Clear existing events in the specific container first
this.strategy.clearEvents(context.container);
// Get events from EventManager for the period
const events = this.eventManager.getEventsForPeriod(
const events = await this.eventManager.getEventsForPeriod(
context.startDate,
context.endDate
);
@ -159,7 +159,7 @@ export class EventRenderingService {
}
private setupDragEndListener(): void {
this.eventBus.on('drag:end', (event: Event) => {
this.eventBus.on('drag:end', async (event: Event) => {
const { originalElement: draggedElement, sourceColumn, finalPosition, target } = (event as CustomEvent<IDragEndEventPayload>).detail;
const finalColumn = finalPosition.column;
@ -181,7 +181,7 @@ export class EventRenderingService {
const newStart = swpEvent.start;
const newEnd = swpEvent.end;
this.eventManager.updateEvent(eventId, {
await this.eventManager.updateEvent(eventId, {
start: newStart,
end: newEnd
});
@ -262,7 +262,7 @@ export class EventRenderingService {
}
private setupResizeEndListener(): void {
this.eventBus.on('resize:end', (event: Event) => {
this.eventBus.on('resize:end', async (event: Event) => {
const { eventId, element } = (event as CustomEvent<IResizeEndEventPayload>).detail;
// Update event data in EventManager with new end time from resized element
@ -270,7 +270,7 @@ export class EventRenderingService {
const newStart = swpEvent.start;
const newEnd = swpEvent.end;
this.eventManager.updateEvent(eventId, {
await this.eventManager.updateEvent(eventId, {
start: newStart,
end: newEnd
});