improve data sync
This commit is contained in:
parent
4349b4d034
commit
014d9492ac
5 changed files with 79 additions and 18 deletions
|
@ -136,7 +136,8 @@ const EventRequestForm: React.FC = () => {
|
|||
other_logos: [],
|
||||
room_booking_files: [],
|
||||
invoice: null,
|
||||
invoice_files: []
|
||||
invoice_files: [],
|
||||
savedAt: Date.now() // Add timestamp for stale data detection
|
||||
};
|
||||
|
||||
localStorage.setItem('eventRequestFormData', JSON.stringify(dataToStore));
|
||||
|
@ -153,12 +154,27 @@ const EventRequestForm: React.FC = () => {
|
|||
if (savedData) {
|
||||
try {
|
||||
const parsedData = JSON.parse(savedData);
|
||||
|
||||
// Check if the saved data is stale (older than 24 hours)
|
||||
const now = Date.now();
|
||||
const savedTime = parsedData.savedAt || 0;
|
||||
const staleThreshold = 24 * 60 * 60 * 1000; // 24 hours
|
||||
|
||||
if (now - savedTime > staleThreshold) {
|
||||
// Clear stale data
|
||||
localStorage.removeItem('eventRequestFormData');
|
||||
console.log('Cleared stale form data from localStorage');
|
||||
} else {
|
||||
// Load the saved data
|
||||
setFormData(prevData => ({
|
||||
...prevData,
|
||||
...parsedData
|
||||
}));
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('Error parsing saved form data:', e);
|
||||
// Clear corrupted data
|
||||
localStorage.removeItem('eventRequestFormData');
|
||||
}
|
||||
}
|
||||
}, []);
|
||||
|
@ -186,7 +202,8 @@ const EventRequestForm: React.FC = () => {
|
|||
other_logos: [],
|
||||
room_booking_files: [],
|
||||
invoice: null,
|
||||
invoice_files: []
|
||||
invoice_files: [],
|
||||
savedAt: Date.now() // Add timestamp for stale data detection
|
||||
};
|
||||
localStorage.setItem('eventRequestFormData', JSON.stringify(dataToStore));
|
||||
|
||||
|
@ -355,8 +372,8 @@ const EventRequestForm: React.FC = () => {
|
|||
// This will send the data to the server
|
||||
const record = await update.create('event_request', submissionData);
|
||||
|
||||
// Force sync the event requests collection to update IndexedDB
|
||||
await dataSync.syncCollection(Collections.EVENT_REQUESTS);
|
||||
// Force sync the event requests collection to update IndexedDB with deletion detection
|
||||
await dataSync.syncCollection(Collections.EVENT_REQUESTS, "", "-created", {}, true);
|
||||
|
||||
console.log('Event request record created:', record.id);
|
||||
|
||||
|
|
|
@ -258,12 +258,14 @@ const UserEventRequests: React.FC<UserEventRequestsProps> = ({ eventRequests: in
|
|||
return;
|
||||
}
|
||||
|
||||
// Use DataSyncService to get data from IndexedDB with forced sync
|
||||
// Use DataSyncService to get data from IndexedDB with forced sync and deletion detection
|
||||
const updatedRequests = await dataSync.getData<EventRequest>(
|
||||
Collections.EVENT_REQUESTS,
|
||||
true, // Force sync
|
||||
`requested_user="${userId}"`,
|
||||
'-created'
|
||||
'-created',
|
||||
{}, // expand
|
||||
true // Enable deletion detection for user-specific requests
|
||||
);
|
||||
|
||||
setEventRequests(updatedRequests);
|
||||
|
|
|
@ -68,13 +68,14 @@ const EventRequestManagementTable = ({
|
|||
|
||||
// console.log("Fetching event requests...");
|
||||
|
||||
// Use DataSyncService to get data from IndexedDB with forced sync
|
||||
// Use DataSyncService to get data from IndexedDB with forced sync and deletion detection
|
||||
const updatedRequests = await dataSync.getData<ExtendedEventRequest>(
|
||||
Collections.EVENT_REQUESTS,
|
||||
true, // Force sync
|
||||
'', // No filter
|
||||
'', // No filter - get all requests
|
||||
'-created',
|
||||
'requested_user' // This is correct but we need to ensure it's working in the DataSyncService
|
||||
'requested_user', // Expand user data
|
||||
true // Enable deletion detection for all event requests
|
||||
);
|
||||
|
||||
// If we still have "Unknown" users, try to fetch them directly
|
||||
|
|
|
@ -269,9 +269,9 @@ const EventRequestModal: React.FC<EventRequestModalProps> = ({ eventRequests })
|
|||
const update = Update.getInstance();
|
||||
await update.updateField("event_request", id, "status", status);
|
||||
|
||||
// Force sync to update IndexedDB
|
||||
// Force sync to update IndexedDB with deletion detection enabled
|
||||
const dataSync = DataSyncService.getInstance();
|
||||
await dataSync.syncCollection(Collections.EVENT_REQUESTS);
|
||||
await dataSync.syncCollection(Collections.EVENT_REQUESTS, "", "-created", {}, true);
|
||||
|
||||
// Find the request to get its name and previous status
|
||||
const request = localEventRequests.find((req) => req.id === id);
|
||||
|
|
|
@ -106,6 +106,7 @@ export class DataSyncService {
|
|||
filter: string = "",
|
||||
sort: string = "-created",
|
||||
expand: Record<string, any> | string[] | string = {},
|
||||
detectDeletions: boolean = true,
|
||||
): Promise<T[]> {
|
||||
// Skip in non-browser environments
|
||||
if (!isBrowser) {
|
||||
|
@ -169,12 +170,15 @@ export class DataSyncService {
|
|||
return [];
|
||||
}
|
||||
|
||||
// Get existing items to handle conflicts
|
||||
// Get existing items to handle conflicts and deletions
|
||||
const existingItems = await table.toArray();
|
||||
const existingItemsMap = new Map(
|
||||
existingItems.map((item) => [item.id, item]),
|
||||
);
|
||||
|
||||
// Create a set of server item IDs for efficient deletion detection
|
||||
const serverItemIds = new Set(items.map(item => item.id));
|
||||
|
||||
// Handle conflicts and merge changes
|
||||
const itemsToStore = await Promise.all(
|
||||
items.map(async (item) => {
|
||||
|
@ -206,7 +210,43 @@ export class DataSyncService {
|
|||
}),
|
||||
);
|
||||
|
||||
// Store in IndexedDB
|
||||
// Handle deletions: find items that exist locally but not on server
|
||||
// Only detect deletions when:
|
||||
// 1. detectDeletions is true AND
|
||||
// 2. No filter is applied (full collection sync) OR filter is a user-specific filter
|
||||
const shouldDetectDeletions = detectDeletions && (!filter || filter.includes('requested_user=') || filter.includes('user='));
|
||||
|
||||
if (shouldDetectDeletions) {
|
||||
const itemsToDelete = existingItems.filter(localItem => {
|
||||
// For user-specific filters, only delete items that match the filter criteria
|
||||
// but don't exist on the server
|
||||
if (filter && filter.includes('requested_user=')) {
|
||||
// Extract user ID from filter
|
||||
const userMatch = filter.match(/requested_user="([^"]+)"/);
|
||||
const userId = userMatch ? userMatch[1] : null;
|
||||
|
||||
// Only consider items for deletion if they belong to the same user
|
||||
if (userId && (localItem as any).requested_user === userId) {
|
||||
return !serverItemIds.has(localItem.id);
|
||||
}
|
||||
return false; // Don't delete items that don't match the user filter
|
||||
}
|
||||
|
||||
// For full collection syncs, delete any item not on the server
|
||||
return !serverItemIds.has(localItem.id);
|
||||
});
|
||||
|
||||
// Perform deletions
|
||||
if (itemsToDelete.length > 0) {
|
||||
// console.log(`Deleting ${itemsToDelete.length} items from ${collection} that no longer exist on server`);
|
||||
|
||||
// Delete items that no longer exist on the server
|
||||
const idsToDelete = itemsToDelete.map(item => item.id);
|
||||
await table.bulkDelete(idsToDelete);
|
||||
}
|
||||
}
|
||||
|
||||
// Store/update items from the server
|
||||
await table.bulkPut(itemsToStore);
|
||||
|
||||
// Update last sync timestamp
|
||||
|
@ -448,6 +488,7 @@ export class DataSyncService {
|
|||
filter: string = "",
|
||||
sort: string = "-created",
|
||||
expand: Record<string, any> | string[] | string = {},
|
||||
detectDeletions: boolean = true,
|
||||
): Promise<T[]> {
|
||||
const db = this.dexieService.getDB();
|
||||
const table = this.getTableForCollection(collection);
|
||||
|
@ -464,7 +505,7 @@ export class DataSyncService {
|
|||
|
||||
if (!this.offlineMode && (forceSync || now - lastSync > syncThreshold)) {
|
||||
try {
|
||||
await this.syncCollection<T>(collection, filter, sort, expand);
|
||||
await this.syncCollection<T>(collection, filter, sort, expand, detectDeletions);
|
||||
} catch (error) {
|
||||
console.error(`Error syncing ${collection}, using cached data:`, error);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue