Feat: Offline-Funktionalität mit IndexedDB implementiert
This commit is contained in:
144
static/js/db.js
Normal file
144
static/js/db.js
Normal file
@@ -0,0 +1,144 @@
|
||||
// IndexedDB Konfiguration
|
||||
const DB_NAME = 'mediCustomersDB';
|
||||
const DB_VERSION = 1;
|
||||
const STORE_NAME = 'customers';
|
||||
|
||||
// Datenbank initialisieren
|
||||
const initDB = () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const request = indexedDB.open(DB_NAME, DB_VERSION);
|
||||
|
||||
request.onerror = () => {
|
||||
console.error('Fehler beim Öffnen der Datenbank:', request.error);
|
||||
reject(request.error);
|
||||
};
|
||||
|
||||
request.onsuccess = () => {
|
||||
console.log('Datenbank erfolgreich geöffnet');
|
||||
resolve(request.result);
|
||||
};
|
||||
|
||||
request.onupgradeneeded = (event) => {
|
||||
const db = event.target.result;
|
||||
if (!db.objectStoreNames.contains(STORE_NAME)) {
|
||||
const store = db.createObjectStore(STORE_NAME, { keyPath: 'nummer' });
|
||||
// Indizes für die Suche erstellen
|
||||
store.createIndex('name', 'name', { unique: false });
|
||||
store.createIndex('ort', 'ort', { unique: false });
|
||||
store.createIndex('plz', 'plz', { unique: false });
|
||||
store.createIndex('fachrichtung', 'fachrichtung', { unique: false });
|
||||
}
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
// Kunden in IndexedDB speichern
|
||||
const saveCustomers = async (customers) => {
|
||||
const db = await initDB();
|
||||
const tx = db.transaction(STORE_NAME, 'readwrite');
|
||||
const store = tx.objectStore(STORE_NAME);
|
||||
|
||||
return Promise.all(customers.map(customer => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const request = store.put(customer);
|
||||
request.onsuccess = () => resolve();
|
||||
request.onerror = () => reject(request.error);
|
||||
});
|
||||
}));
|
||||
};
|
||||
|
||||
// Kunden aus IndexedDB suchen
|
||||
const searchCustomersOffline = async (searchParams) => {
|
||||
const db = await initDB();
|
||||
const tx = db.transaction(STORE_NAME, 'readonly');
|
||||
const store = tx.objectStore(STORE_NAME);
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
const request = store.getAll();
|
||||
|
||||
request.onsuccess = () => {
|
||||
let results = request.result;
|
||||
|
||||
// Filtern basierend auf den Suchparametern
|
||||
if (searchParams.q) {
|
||||
const searchTerms = searchParams.q.toLowerCase().split(' ');
|
||||
const operator = searchParams.operator || 'or';
|
||||
|
||||
results = results.filter(customer => {
|
||||
const searchableText = `${customer.name} ${customer.ort} ${customer.nummer} ${customer.plz} ${customer.fachrichtung}`.toLowerCase();
|
||||
|
||||
if (operator === 'and') {
|
||||
return searchTerms.every(term => searchableText.includes(term));
|
||||
} else {
|
||||
return searchTerms.some(term => searchableText.includes(term));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Spezifische Feldsuche
|
||||
if (searchParams.name) {
|
||||
results = results.filter(c => c.name.toLowerCase().includes(searchParams.name.toLowerCase()));
|
||||
}
|
||||
if (searchParams.ort) {
|
||||
results = results.filter(c => c.ort.toLowerCase().includes(searchParams.ort.toLowerCase()));
|
||||
}
|
||||
if (searchParams.nummer) {
|
||||
results = results.filter(c => c.nummer.toString().includes(searchParams.nummer));
|
||||
}
|
||||
if (searchParams.plz) {
|
||||
results = results.filter(c => c.plz.includes(searchParams.plz));
|
||||
}
|
||||
if (searchParams.fachrichtung) {
|
||||
results = results.filter(c => c.fachrichtung.toLowerCase().includes(searchParams.fachrichtung.toLowerCase()));
|
||||
}
|
||||
|
||||
resolve(results);
|
||||
};
|
||||
|
||||
request.onerror = () => {
|
||||
reject(request.error);
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
// Synchronisationsstatus speichern
|
||||
const syncStatus = {
|
||||
lastSync: null,
|
||||
isOnline: navigator.onLine
|
||||
};
|
||||
|
||||
// Event Listener für Online/Offline Status
|
||||
window.addEventListener('online', () => {
|
||||
syncStatus.isOnline = true;
|
||||
document.body.classList.remove('offline');
|
||||
synchronizeData();
|
||||
});
|
||||
|
||||
window.addEventListener('offline', () => {
|
||||
syncStatus.isOnline = false;
|
||||
document.body.classList.add('offline');
|
||||
});
|
||||
|
||||
// Daten mit dem Server synchronisieren
|
||||
const synchronizeData = async () => {
|
||||
if (!syncStatus.isOnline) return;
|
||||
|
||||
try {
|
||||
const response = await fetch('/api/customers');
|
||||
const customers = await response.json();
|
||||
await saveCustomers(customers);
|
||||
syncStatus.lastSync = new Date();
|
||||
console.log('Daten erfolgreich synchronisiert');
|
||||
} catch (error) {
|
||||
console.error('Fehler bei der Synchronisation:', error);
|
||||
}
|
||||
};
|
||||
|
||||
// Export der Funktionen
|
||||
window.dbHelper = {
|
||||
initDB,
|
||||
saveCustomers,
|
||||
searchCustomersOffline,
|
||||
synchronizeData,
|
||||
syncStatus
|
||||
};
|
Reference in New Issue
Block a user