cinu
This commit is contained in:
230
RS_system/wwwroot/js/colaboraciones-offline-db.js
Normal file
230
RS_system/wwwroot/js/colaboraciones-offline-db.js
Normal file
@@ -0,0 +1,230 @@
|
||||
/**
|
||||
* IndexedDB Wrapper for Offline Colaboraciones
|
||||
* Stores pending colaboraciones when offline using GUID-based IDs
|
||||
*/
|
||||
|
||||
const ColaboracionesOfflineDB = {
|
||||
dbName: 'ColaboracionesOfflineDB',
|
||||
version: 1,
|
||||
storeName: 'colaboraciones',
|
||||
|
||||
/**
|
||||
* Initialize the database
|
||||
*/
|
||||
async init() {
|
||||
return new Promise((resolve, reject) => {
|
||||
const request = indexedDB.open(this.dbName, this.version);
|
||||
|
||||
request.onerror = () => reject(request.error);
|
||||
request.onsuccess = () => resolve(request.result);
|
||||
|
||||
request.onupgradeneeded = (event) => {
|
||||
const db = event.target.result;
|
||||
|
||||
// Create object store if it doesn't exist
|
||||
if (!db.objectStoreNames.contains(this.storeName)) {
|
||||
const objectStore = db.createObjectStore(this.storeName, {
|
||||
keyPath: 'id' // GUID generated client-side
|
||||
});
|
||||
|
||||
// Indexes for querying
|
||||
objectStore.createIndex('syncStatus', 'syncStatus', { unique: false });
|
||||
objectStore.createIndex('timestamp', 'timestamp', { unique: false });
|
||||
objectStore.createIndex('updatedAt', 'updatedAt', { unique: false });
|
||||
objectStore.createIndex('miembroId', 'miembroId', { unique: false });
|
||||
}
|
||||
};
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Generate a GUID (v4 UUID)
|
||||
*/
|
||||
generateGuid() {
|
||||
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
|
||||
const r = Math.random() * 16 | 0;
|
||||
const v = c === 'x' ? r : (r & 0x3 | 0x8);
|
||||
return v.toString(16);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Add a new colaboracion to offline queue
|
||||
*/
|
||||
async addColaboracion(colaboracionData) {
|
||||
const db = await this.init();
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
const transaction = db.transaction([this.storeName], 'readwrite');
|
||||
const store = transaction.objectStore(this.storeName);
|
||||
|
||||
// Prepare record with GUID and sync metadata
|
||||
const record = {
|
||||
id: this.generateGuid(), // GUID generated client-side
|
||||
miembroId: colaboracionData.miembroId,
|
||||
mesInicial: colaboracionData.mesInicial,
|
||||
anioInicial: colaboracionData.anioInicial,
|
||||
mesFinal: colaboracionData.mesFinal,
|
||||
anioFinal: colaboracionData.anioFinal,
|
||||
montoTotal: colaboracionData.montoTotal,
|
||||
observaciones: colaboracionData.observaciones || '',
|
||||
tiposSeleccionados: colaboracionData.tiposSeleccionados || [],
|
||||
tipoPrioritario: colaboracionData.tipoPrioritario || null,
|
||||
registradoPor: colaboracionData.registradoPor || 'Usuario',
|
||||
syncStatus: 'pending', // pending, syncing, synced, failed
|
||||
timestamp: new Date().toISOString(),
|
||||
updatedAt: new Date().toISOString(),
|
||||
retryCount: 0
|
||||
};
|
||||
|
||||
const request = store.add(record);
|
||||
|
||||
request.onsuccess = () => {
|
||||
console.log('[OfflineDB] Colaboración guardada con ID:', record.id);
|
||||
resolve(record);
|
||||
};
|
||||
request.onerror = () => {
|
||||
console.error('[OfflineDB] Error al guardar:', request.error);
|
||||
reject(request.error);
|
||||
};
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Get all pending colaboraciones
|
||||
*/
|
||||
async getPending() {
|
||||
const db = await this.init();
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
const transaction = db.transaction([this.storeName], 'readonly');
|
||||
const store = transaction.objectStore(this.storeName);
|
||||
const index = store.index('syncStatus');
|
||||
const request = index.getAll('pending');
|
||||
|
||||
request.onsuccess = () => resolve(request.result);
|
||||
request.onerror = () => reject(request.error);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Get all colaboraciones (any status)
|
||||
*/
|
||||
async getAll() {
|
||||
const db = await this.init();
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
const transaction = db.transaction([this.storeName], 'readonly');
|
||||
const store = transaction.objectStore(this.storeName);
|
||||
const request = store.getAll();
|
||||
|
||||
request.onsuccess = () => resolve(request.result);
|
||||
request.onerror = () => reject(request.error);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Update sync status of a colaboracion
|
||||
*/
|
||||
async updateSyncStatus(id, status, retryCount = 0) {
|
||||
const db = await this.init();
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
const transaction = db.transaction([this.storeName], 'readwrite');
|
||||
const store = transaction.objectStore(this.storeName);
|
||||
const getRequest = store.get(id);
|
||||
|
||||
getRequest.onsuccess = () => {
|
||||
const record = getRequest.result;
|
||||
if (record) {
|
||||
record.syncStatus = status;
|
||||
record.retryCount = retryCount;
|
||||
record.lastSyncAttempt = new Date().toISOString();
|
||||
|
||||
const updateRequest = store.put(record);
|
||||
updateRequest.onsuccess = () => resolve(record);
|
||||
updateRequest.onerror = () => reject(updateRequest.error);
|
||||
} else {
|
||||
reject(new Error('Record not found'));
|
||||
}
|
||||
};
|
||||
getRequest.onerror = () => reject(getRequest.error);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Remove a colaboracion by ID (after successful sync)
|
||||
*/
|
||||
async remove(id) {
|
||||
const db = await this.init();
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
const transaction = db.transaction([this.storeName], 'readwrite');
|
||||
const store = transaction.objectStore(this.storeName);
|
||||
const request = store.delete(id);
|
||||
|
||||
request.onsuccess = () => {
|
||||
console.log('[OfflineDB] Colaboración eliminada:', id);
|
||||
resolve();
|
||||
};
|
||||
request.onerror = () => reject(request.error);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Get count of pending colaboraciones
|
||||
*/
|
||||
async getPendingCount() {
|
||||
const db = await this.init();
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
const transaction = db.transaction([this.storeName], 'readonly');
|
||||
const store = transaction.objectStore(this.storeName);
|
||||
const index = store.index('syncStatus');
|
||||
const request = index.count('pending');
|
||||
|
||||
request.onsuccess = () => resolve(request.result);
|
||||
request.onerror = () => reject(request.error);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Clear all records (use with caution)
|
||||
*/
|
||||
async clearAll() {
|
||||
const db = await this.init();
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
const transaction = db.transaction([this.storeName], 'readwrite');
|
||||
const store = transaction.objectStore(this.storeName);
|
||||
const request = store.clear();
|
||||
|
||||
request.onsuccess = () => {
|
||||
console.log('[OfflineDB] All records cleared');
|
||||
resolve();
|
||||
};
|
||||
request.onerror = () => reject(request.error);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Get a specific colaboracion by ID
|
||||
*/
|
||||
async getById(id) {
|
||||
const db = await this.init();
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
const transaction = db.transaction([this.storeName], 'readonly');
|
||||
const store = transaction.objectStore(this.storeName);
|
||||
const request = store.get(id);
|
||||
|
||||
request.onsuccess = () => resolve(request.result);
|
||||
request.onerror = () => reject(request.error);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// Initialize database when script loads
|
||||
ColaboracionesOfflineDB.init().catch(error => {
|
||||
console.error('[OfflineDB] Initialization failed:', error);
|
||||
});
|
||||
Reference in New Issue
Block a user