Enhances IndexedDB service with booking and resource support
Updates IndexedDB database schema to version 2 Adds support for bookings, customers, and resources stores Includes new serialization methods for booking data Extends events store with additional indexes for improved querying
This commit is contained in:
parent
6174dc895e
commit
88cccb3456
6 changed files with 990 additions and 1 deletions
|
|
@ -1,4 +1,5 @@
|
|||
import { ICalendarEvent } from '../types/CalendarTypes';
|
||||
import { IBooking } from '../types/BookingTypes';
|
||||
|
||||
/**
|
||||
* Operation for the sync queue
|
||||
|
|
@ -18,10 +19,13 @@ export interface IQueueOperation {
|
|||
*/
|
||||
export class IndexedDBService {
|
||||
private static readonly DB_NAME = 'CalendarDB';
|
||||
private static readonly DB_VERSION = 1;
|
||||
private static readonly DB_VERSION = 2;
|
||||
private static readonly EVENTS_STORE = 'events';
|
||||
private static readonly QUEUE_STORE = 'operationQueue';
|
||||
private static readonly SYNC_STATE_STORE = 'syncState';
|
||||
private static readonly BOOKINGS_STORE = 'bookings';
|
||||
private static readonly CUSTOMERS_STORE = 'customers';
|
||||
private static readonly RESOURCES_STORE = 'resources';
|
||||
|
||||
private db: IDBDatabase | null = null;
|
||||
private initialized: boolean = false;
|
||||
|
|
@ -45,6 +49,7 @@ export class IndexedDBService {
|
|||
|
||||
request.onupgradeneeded = (event) => {
|
||||
const db = (event.target as IDBOpenDBRequest).result;
|
||||
const oldVersion = (event as IDBVersionChangeEvent).oldVersion;
|
||||
|
||||
// Create events store
|
||||
if (!db.objectStoreNames.contains(IndexedDBService.EVENTS_STORE)) {
|
||||
|
|
@ -52,6 +57,27 @@ export class IndexedDBService {
|
|||
eventsStore.createIndex('start', 'start', { unique: false });
|
||||
eventsStore.createIndex('end', 'end', { unique: false });
|
||||
eventsStore.createIndex('syncStatus', 'syncStatus', { unique: false });
|
||||
eventsStore.createIndex('resourceId', 'resourceId', { unique: false });
|
||||
eventsStore.createIndex('customerId', 'customerId', { unique: false });
|
||||
eventsStore.createIndex('bookingId', 'bookingId', { unique: false });
|
||||
eventsStore.createIndex('startEnd', ['start', 'end'], { unique: false });
|
||||
} else if (oldVersion < 2) {
|
||||
// Upgrade from version 1: Add new indexes to existing events store
|
||||
const transaction = (event.target as IDBOpenDBRequest).transaction!;
|
||||
const eventsStore = transaction.objectStore(IndexedDBService.EVENTS_STORE);
|
||||
|
||||
if (!eventsStore.indexNames.contains('resourceId')) {
|
||||
eventsStore.createIndex('resourceId', 'resourceId', { unique: false });
|
||||
}
|
||||
if (!eventsStore.indexNames.contains('customerId')) {
|
||||
eventsStore.createIndex('customerId', 'customerId', { unique: false });
|
||||
}
|
||||
if (!eventsStore.indexNames.contains('bookingId')) {
|
||||
eventsStore.createIndex('bookingId', 'bookingId', { unique: false });
|
||||
}
|
||||
if (!eventsStore.indexNames.contains('startEnd')) {
|
||||
eventsStore.createIndex('startEnd', ['start', 'end'], { unique: false });
|
||||
}
|
||||
}
|
||||
|
||||
// Create operation queue store
|
||||
|
|
@ -64,6 +90,28 @@ export class IndexedDBService {
|
|||
if (!db.objectStoreNames.contains(IndexedDBService.SYNC_STATE_STORE)) {
|
||||
db.createObjectStore(IndexedDBService.SYNC_STATE_STORE, { keyPath: 'key' });
|
||||
}
|
||||
|
||||
// Create bookings store (v2)
|
||||
if (!db.objectStoreNames.contains(IndexedDBService.BOOKINGS_STORE)) {
|
||||
const bookingsStore = db.createObjectStore(IndexedDBService.BOOKINGS_STORE, { keyPath: 'id' });
|
||||
bookingsStore.createIndex('customerId', 'customerId', { unique: false });
|
||||
bookingsStore.createIndex('status', 'status', { unique: false });
|
||||
bookingsStore.createIndex('createdAt', 'createdAt', { unique: false });
|
||||
}
|
||||
|
||||
// Create customers store (v2)
|
||||
if (!db.objectStoreNames.contains(IndexedDBService.CUSTOMERS_STORE)) {
|
||||
const customersStore = db.createObjectStore(IndexedDBService.CUSTOMERS_STORE, { keyPath: 'id' });
|
||||
customersStore.createIndex('name', 'name', { unique: false });
|
||||
customersStore.createIndex('phone', 'phone', { unique: false });
|
||||
}
|
||||
|
||||
// Create resources store (v2)
|
||||
if (!db.objectStoreNames.contains(IndexedDBService.RESOURCES_STORE)) {
|
||||
const resourcesStore = db.createObjectStore(IndexedDBService.RESOURCES_STORE, { keyPath: 'id' });
|
||||
resourcesStore.createIndex('type', 'type', { unique: false });
|
||||
resourcesStore.createIndex('isActive', 'isActive', { unique: false });
|
||||
}
|
||||
};
|
||||
});
|
||||
}
|
||||
|
|
@ -334,6 +382,26 @@ export class IndexedDBService {
|
|||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialize booking for IndexedDB storage (convert Dates to ISO strings)
|
||||
*/
|
||||
private serializeBooking(booking: IBooking): any {
|
||||
return {
|
||||
...booking,
|
||||
createdAt: booking.createdAt instanceof Date ? booking.createdAt.toISOString() : booking.createdAt
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Deserialize booking from IndexedDB (convert ISO strings to Dates)
|
||||
*/
|
||||
private deserializeBooking(booking: any): IBooking {
|
||||
return {
|
||||
...booking,
|
||||
createdAt: typeof booking.createdAt === 'string' ? new Date(booking.createdAt) : booking.createdAt
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Close database connection
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
* - One service can be performed by one resource
|
||||
* - Multiple services can be performed by different resources
|
||||
* - Example: Hårvask by Student, Bundfarve by Master (same booking, 2 resources)
|
||||
* - Equal-split: Two services with same type but different resources (e.g., "Bryllupsfrisure Del 1" by Karina, "Bryllupsfrisure Del 2" by Nanna)
|
||||
*
|
||||
* Matches backend Booking table structure
|
||||
*/
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue